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