Imported Upstream version 2.9.0
[debian/cc1111] / sim / ucsim / cmd.src / newcmd.cc
1 /*
2  * Simulator of microcontrollers (cmd.src/newcmd.cc)
3  *
4  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
5  * Copyright (C) 2006, Borut Razem - borut.razem@siol.net
6  *
7  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
8  *
9  */
10
11 /* This file is part of microcontroller simulator: ucsim.
12
13 UCSIM is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 UCSIM is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with UCSIM; see the file COPYING.  If not, write to the Free
25 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 02111-1307, USA. */
27 /*@1@*/
28
29 #include "ddconfig.h"
30
31 #include <stdio.h>
32 #include <errno.h>
33 #include <stdarg.h>
34 #include <stdlib.h>
35 #include <ctype.h>
36 #include "i_string.h"
37
38 #include "cmdlexcl.h"
39 #include "cmdpars.h"
40
41 // prj
42 #include "globals.h"
43 #include "utils.h"
44
45 // sim
46 #include "simcl.h"
47 #include "argcl.h"
48 #include "appcl.h"
49
50 // local
51 #include "newcmdcl.h"
52 #include "cmdutil.h"
53
54
55 /*
56  * Options of console
57  */
58
59 cl_prompt_option::cl_prompt_option(class cl_console_base *console):
60   cl_optref(console)
61 {
62   con= console;
63 }
64
65 int
66 cl_prompt_option::init(void)
67 {
68   char *help;
69   help= format_string("Prompt string of console%d", con->get_id());
70   create(con, string_opt, "prompt", help);
71   //fprintf(stderr," **new prompt option %p\"%s\", value=%p str=%p\n",option,object_name(option),option->get_value(),option->get_value()->sval);
72   free(help);
73   default_option("prompt");
74   //fprintf(stderr,"opt=%p\"%s\" value after default set=%p str=%p\n",option,object_name(option),option->get_value(),option->get_value()->sval);
75   return(0);
76 }
77
78 void
79 cl_prompt_option::option_changed(void)
80 {
81   if (!con)
82     return;
83   char *s;
84   option->get_value(&s);
85   con->set_prompt(s);
86 }
87
88
89 cl_debug_option::cl_debug_option(class cl_console_base *console):
90   cl_prompt_option(console)
91 {}
92
93 int
94 cl_debug_option::init(void)
95 {
96   char *help;
97   help= format_string("Debug messages to console%d", con->get_id());
98   create(con, bool_opt, "debug", help);
99   free(help);
100   default_option("debug");
101   return(0);
102 }
103
104 void
105 cl_debug_option::option_changed(void)
106 {
107   if (!con)
108     return;
109   bool b;
110   option->get_value(&b);
111   if (b)
112     con->flags|= CONS_DEBUG;
113   else
114     con->flags&= ~CONS_DEBUG;
115 }
116
117
118 /*
119  * Command console
120  *____________________________________________________________________________
121  */
122
123 int
124 cl_console_base::init(void)
125 {
126   cl_base::init();
127   prompt_option= new cl_prompt_option(this);
128   prompt_option->init();
129   null_prompt_option= new cl_optref(this);
130   null_prompt_option->init();
131   null_prompt_option->use("null_prompt");
132   debug_option= new cl_debug_option(this);
133   debug_option->init();
134   welcome();
135   flags&= ~CONS_PROMPT;
136   //print_prompt();
137   last_command= 0;
138   last_cmdline= 0;
139   return(0);
140 }
141
142 void
143 cl_console_base::welcome(void)
144 {
145   if (!(flags & CONS_NOWELCOME))
146     {
147       dd_printf("uCsim %s, Copyright (C) 1997 Daniel Drotos, Talker Bt.\n"
148         "uCsim comes with ABSOLUTELY NO WARRANTY; for details type "
149         "`show w'.\n"
150         "This is free software, and you are welcome to redistribute it\n"
151         "under certain conditions; type `show c' for details.\n",
152         VERSIONSTR);
153     }
154 }
155
156 void
157 cl_console_base::print_prompt(void)
158 {
159   if (flags & (CONS_PROMPT | CONS_FROZEN | CONS_INACTIVE))
160     return;
161
162   flags |= CONS_PROMPT;
163   if (/*app->args->arg_avail('P')*/null_prompt_option->get_value(bool(0)))
164     {
165       dd_printf("%c", 0);
166     }
167   else
168     {
169       dd_printf("%d%s", id, (prompt && prompt[0]) ? prompt : "> ");
170       //              ((p= app->args->get_sarg(0, "prompt"))?p:"> "));
171     }
172 }
173
174 int
175 cl_console_base::dd_printf(const char *format, ...)
176 {
177   va_list ap;
178   int ret= 0;
179
180   va_start(ap, format);
181   ret= cmd_do_print(format, ap);
182   va_end(ap);
183
184   return(ret);
185 }
186
187 int
188 cl_console_base::debug(const char *format, ...)
189 {
190   if ((flags & CONS_DEBUG) == 0)
191     return(0);
192
193   va_list ap;
194   int ret= 0;
195
196   va_start(ap, format);
197   ret= cmd_do_print(format, ap);
198   va_end(ap);
199
200   return(ret);
201 }
202
203 /*
204  * Printing out an integer in binary format
205  */
206
207 void
208 cl_console_base::print_bin(long data, int bits)
209 {
210   long mask= 1;
211
212   mask= mask << ((bits >= 1)?(bits-1):0);
213   while (bits--)
214     {
215       dd_printf("%c", (data&mask)?'1':'0');
216       mask>>= 1;
217     }
218 }
219
220 void
221 cl_console_base::print_char_octal(char c)
222 {
223   if (strchr("\a\b\f\n\r\t\v\"", c))
224     switch (c)
225       {
226       case '\a': dd_printf("\a"); break;
227       case '\b': dd_printf("\b"); break;
228       case '\f': dd_printf("\f"); break;
229       case '\n': dd_printf("\n"); break;
230       case '\r': dd_printf("\r"); break;
231       case '\t': dd_printf("\t"); break;
232       case '\v': dd_printf("\v"); break;
233       case '\"': dd_printf("\""); break;
234       }
235   else if (isprint(c))
236     dd_printf("%c", c);
237   else
238     dd_printf("\\%03hho", c);
239 }
240
241 int
242 cl_console_base::interpret(char *cmd)
243 {
244   dd_printf("Unknown command\n");
245   return(0);
246 }
247
248 void
249 cl_console_base::set_id(int new_id)
250 {
251   char *s;
252
253   id= new_id;
254   set_name(s= format_string("console%d", id));
255   free(s);
256 }
257
258 void
259 cl_console_base::set_prompt(char *p)
260 {
261   if (prompt)
262     free(prompt);
263   if (p && *p)
264     prompt= strdup(p);
265   else
266     prompt= 0;
267 }
268
269 bool
270 cl_console_base::input_active(void) const
271 {
272   if (((flags & CONS_FROZEN) == 0 ||
273     (flags & CONS_INTERACTIVE) != 0) &&
274     (flags & CONS_INACTIVE) == 0)
275     {
276       return true;
277     }
278   else
279     return false;
280 }
281
282 int
283 cl_console_base::proc_input(class cl_cmdset *cmdset)
284 {
285   int retval = 0;
286
287   un_redirect();
288   if (is_eof())
289     {
290       dd_printf("End\n");
291       return 1;
292     }
293   char *cmdstr = read_line();
294   if (!cmdstr)
295     return 1;
296   if (flags & CONS_FROZEN)
297     {
298       app->get_sim()->stop(resUSER);
299       flags&= ~CONS_FROZEN;
300       retval = 0;
301     }
302   else
303     {
304       if (cmdstr && *cmdstr == '\004')
305         retval = 1;
306       else
307         {
308           class cl_cmdline *cmdline= 0;
309           class cl_cmd *cm = 0;
310           if (flags & CONS_ECHO)
311             dd_printf("%s\n", cmdstr);
312           cmdline= new cl_cmdline(app, cmdstr, this);
313           cmdline->init();
314           if (cmdline->repeat() &&
315               accept_last() &&
316               last_command)
317             {
318               cm = last_command;
319               delete cmdline;
320               cmdline = last_cmdline;
321             }
322           else
323             {
324               cm= cmdset->get_cmd(cmdline, accept_last());
325               if (last_cmdline)
326                 {
327                   delete last_cmdline;
328                   last_cmdline = 0;
329                 }
330               last_command = 0;
331             }
332           if (cm)
333             {
334               retval= cm->work(app, cmdline, this);
335               if (cm->can_repeat)
336                 {
337                   last_command = cm;
338                   last_cmdline = cmdline;
339                 }
340               else
341                 delete cmdline;
342             }
343           else
344             {
345               class YY_cl_ucsim_parser_CLASS *pars;
346               class cl_ucsim_lexer *lexer;
347               lexer = new cl_ucsim_lexer(cmdstr);
348               pars = new YY_cl_ucsim_parser_CLASS(lexer);
349               pars->yyparse();
350               delete cmdline;
351               delete pars;
352             }
353           /*if (!cm)
354             retval= interpret(cmdstr);*/
355         }
356     }
357   //retval= sim->do_cmd(cmd, this);
358   un_redirect();
359   /*if (!retval)
360     print_prompt();*/
361   free(cmdstr);
362   return(retval);
363 }
364
365
366 /*
367  * Command interpreter
368  *____________________________________________________________________________
369  */
370
371 cl_commander_base::cl_commander_base(class cl_app *the_app, class cl_cmdset *acmdset):
372   cl_base()
373 {
374   app= the_app;
375   cons= new cl_list(1, 1, "consoles");
376   actual_console= frozen_console= 0;
377   cmdset= acmdset;
378 }
379
380 cl_commander_base::~cl_commander_base(void)
381 {
382   delete cons;
383   delete cmdset;
384 }
385
386 void
387 cl_commander_base::add_console(class cl_console_base *console)
388 {
389   if (!console)
390     return;
391   int i=cons->add(console);
392   console->set_id(i);
393   console->init();
394   set_fd_set();
395 }
396
397 void
398 cl_commander_base::del_console(class cl_console_base *console)
399 {
400   cons->disconn(console);
401   set_fd_set();
402 }
403
404 void
405 cl_commander_base::activate_console(class cl_console_base *console)
406 {
407   console->flags&= ~CONS_INACTIVE;
408   //console->print_prompt();
409   set_fd_set();
410 }
411
412 void
413 cl_commander_base::deactivate_console(class cl_console_base *console)
414 {
415   console->flags|= CONS_INACTIVE;
416   set_fd_set();
417 }
418
419 /*
420  * Printing to all consoles
421  */
422
423 int
424 cl_commander_base::all_printf(const char *format, ...)
425 {
426   va_list ap;
427   int i, ret= 0;
428
429   for (i= 0; i < cons->count; i++)
430     {
431       class cl_console_base *c= (class cl_console_base*)(cons->at(i));
432
433       va_start(ap, format);
434       ret= c->cmd_do_print(format, ap);
435       va_end(ap);
436     }
437   return(ret);
438 }
439
440 void
441 cl_commander_base::prompt(void)
442 {
443   int i;
444
445   for (i= 0; i < cons->count; i++)
446     {
447       class cl_console_base *c= (class cl_console_base*)(cons->at(i));
448       c->print_prompt();
449     }
450 }
451
452 /*
453  * Printing to actual_console
454  */
455
456 int
457 cl_commander_base::dd_printf(const char *format, va_list ap)
458 {
459   int ret= 0;
460   class cl_console_base *con;
461
462   if (actual_console)
463     {
464       con= actual_console;
465     }
466   else if (frozen_console)
467     {
468       con= frozen_console;
469     }
470   else
471     {
472       con= 0;
473     }
474   if (con)
475     {
476       ret= con->cmd_do_print(format, ap);
477     }
478   return(ret);
479 }
480
481 int
482 cl_commander_base::dd_printf(const char *format, ...)
483 {
484   va_list ap;
485   int ret= 0;
486
487   va_start(ap, format);
488   ret= dd_printf(format, ap);
489   va_end(ap);
490
491   return(ret);
492 }
493
494 /*
495  * Printing to consoles which have CONS_DEBUG flag set
496  */
497
498 int
499 cl_commander_base::debug(const char *format, ...)
500 {
501   va_list ap;
502   int i, ret= 0;
503
504   for (i= 0; i < cons->count; i++)
505     {
506       class cl_console_base *c= (class cl_console_base*)(cons->at(i));
507       if (c->flags & CONS_DEBUG)
508         {
509           va_start(ap, format);
510           ret= c->cmd_do_print(format, ap);
511           va_end(ap);
512         }
513     }
514   return(ret);
515 }
516
517 int
518 cl_commander_base::debug(const char *format, va_list ap)
519 {
520   int i, ret= 0;
521
522   for (i= 0; i < cons->count; i++)
523     {
524       class cl_console_base *c= (class cl_console_base*)(cons->at(i));
525       if (c->flags & CONS_DEBUG)
526         {
527           ret= c->cmd_do_print(format, ap);
528         }
529     }
530   return(ret);
531 }
532
533 int
534 cl_commander_base::flag_printf(int iflags, const char *format, ...)
535 {
536   va_list ap;
537   int i, ret= 0;
538
539   for (i= 0; i < cons->count; i++)
540     {
541       class cl_console_base *c= (class cl_console_base*)(cons->at(i));
542       if ((c->flags & iflags) == iflags)
543         {
544           va_start(ap, format);
545           ret= c->cmd_do_print(format, ap);
546           va_end(ap);
547         }
548     }
549   return(ret);
550 }
551
552 int
553 cl_commander_base::input_avail_on_frozen(void)
554 {
555   if (!frozen_console || frozen_console->is_tty())
556     return(0);
557   return(frozen_console->input_avail());
558 }
559
560 void
561 cl_commander_base::exec_on(class cl_console_base *cons, char *file_name)
562 {
563   if (!cons || !file_name || !fopen(file_name, "r"))
564     return;
565
566   class cl_console_base *subcon = cons->clone_for_exec(file_name);
567   subcon->flags |= CONS_NOWELCOME;
568   add_console(subcon);
569 }
570
571
572 /* End of cmd.src/newcmd.cc */