2 * Simulator of microcontrollers (cmd.src/command.cc)
4 * Copyright (C) 2002,02 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
10 /* This file is part of microcontroller simulator: ucsim.
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
36 #include "commandcl.h"
41 *____________________________________________________________________________
44 cl_cmdline::cl_cmdline(class cl_app *the_app,
45 char *acmd, class cl_console *acon):
50 params= new cl_list(2, 2, "command line params");
51 tokens= new cl_ustrings(2, 2, "command line tokens");
57 cl_cmdline::~cl_cmdline(void)
66 cl_cmdline::init(void)
73 cl_cmdline::skip_delims(char *start)
76 strchr(" \t\v\r,", *start))
82 cl_cmdline::split(void)
87 class cl_cmd_arg *arg;
89 //sim= app->get_sim();
94 start+= strspn(start, " \t\v\r,");
98 char *n= (char*)malloc(2);
105 i= strcspn(start, " \t\v\r,");
108 char *n= (char*)malloc(i+1);
109 strncpy(n, start, i);
114 start= skip_delims(start);
118 char *end= start, *param_str;
120 split_out_string(&start, &end);
121 else if (*start == '>')
122 split_out_output_redirection(&start, &end);
126 i= strcspn(start, " \t\v\r,");
128 param_str= (char *)malloc(i+1);
129 strncpy(param_str, start, i);
131 tokens->add(strdup(param_str));
132 if ((dot= strchr(param_str, '.')) != NULL)
133 split_out_bit(dot, param_str);
134 else if ((dot= strchr(param_str, '[')) != NULL)
135 split_out_array(dot, param_str);
136 else if (strchr("0123456789-+", *param_str) != NULL)
139 params->add(arg= new cl_cmd_int_arg((long)
140 strtol(param_str, 0, 0)));
146 params->add(arg= new cl_cmd_sym_arg(param_str));
152 start= skip_delims(start);
158 cl_cmdline::split_out_string(char **_start, char **_end)
160 char *start= *_start, *end;
178 con->dd_printf("Unterminated string\n");
179 char *param_str= (char *)malloc(end-start+2);
180 strncpy(param_str, start, 1+end-start);
181 param_str[1+end-start]= '\0';
182 tokens->add(strdup(param_str));
183 class cl_cmd_arg *arg;
184 params->add(arg= new cl_cmd_str_arg(param_str));
196 cl_cmdline::split_out_output_redirection(char **_start, char **_end)
198 char *start= *_start, *end/*= *_end*/;
205 i= strcspn(start, " \t\v\r,");
207 char *param_str= (char *)malloc(i+1);
209 strncpy(param_str, start, i);
217 tokens->add(strdup(n));
218 con->redirect(n, mode);
225 cl_cmdline::split_out_bit(char *dot, char *param_str)
227 class cl_cmd_arg *sfr, *bit;
231 if (strchr("0123456789", *param_str) != NULL)
233 sfr= new cl_cmd_int_arg((long)strtol(param_str, 0, 0));
238 sfr= new cl_cmd_sym_arg(param_str);
244 con->dd_printf("Uncomplete bit address\n");
249 if (strchr("0123456789", *dot) != NULL)
251 bit= new cl_cmd_int_arg((long)strtol(dot, 0, 0));
256 bit= new cl_cmd_sym_arg(dot);
259 class cl_cmd_arg *arg;
260 params->add(arg= new cl_cmd_bit_arg(sfr, bit));
266 cl_cmdline::split_out_array(char *dot, char *param_str)
268 class cl_cmd_arg *aname, *aindex;
272 if (strchr("0123456789", *param_str) != NULL)
274 aname= new cl_cmd_int_arg((long)strtol(param_str, 0, 0));
279 aname= new cl_cmd_sym_arg(param_str);
285 con->dd_printf("Uncomplete array\n");
290 p= dot + strlen(dot) - 1;
299 if (strlen(dot) == 0)
301 con->dd_printf("Uncomplete array index\n");
306 if (strchr("0123456789", *dot) != NULL)
308 aindex= new cl_cmd_int_arg((long)strtol(dot, 0, 0));
313 aindex= new cl_cmd_sym_arg(dot);
316 class cl_cmd_arg *arg;
317 params->add(arg= new cl_cmd_array_arg(aname, aindex));
324 cl_cmdline::shift(void)
326 char *s= skip_delims(cmd);
332 strchr(" \t\v\r,", *s) == NULL)
339 params= new cl_list(2, 2, "params");
341 if (strcmp(get_name(), "\n") == 0)
344 return(have_real_name());
348 cl_cmdline::repeat(void)
351 return((n= get_name()) &&
356 cl_cmdline::param(int num)
358 if (num >= params->count)
360 return((class cl_cmd_arg *)(params->at(num)));
364 cl_cmdline::insert_param(int pos, class cl_cmd_arg *param)
366 if (pos >= params->count)
369 params->add_at(pos, param);
373 cl_cmdline::syntax_match(class cl_uc *uc, char *syntax)
380 matched_syntax= syntax;
385 //printf("syntax %s?\n",syntax);
388 class cl_cmd_arg *parm= (class cl_cmd_arg *)(params->at(iparam));
392 //printf("***Checking %s as %c\n",parm->get_svalue(),*p);
397 if (!parm->as_address(uc))
399 //printf("ADDRESS match %lx\n",parm->value.address);
402 if (!parm->as_memory(uc))
404 //printf("MEMORY match %s\n",parm->value.memory->class_name);
407 if (!parm->as_bit(uc))
413 case SY_ADDR: case SY_MEMORY: case SY_BIT: break;
415 if (!parm->as_number())
419 if (!parm->as_data())
423 if (!parm->as_hw(uc))
427 if (!parm->as_string())
431 if (!set_data_list(parm, &iparam))
439 if (iparam < params->count)
440 parm= (class cl_cmd_arg *)(params->at(iparam));
447 matched_syntax= syntax;
454 cl_cmdline::set_data_list(class cl_cmd_arg *parm, int *iparm)
456 class cl_cmd_arg *next_parm;
462 for (i= *iparm, next_parm= param(i); next_parm; i++, next_parm= param(i))
464 if (next_parm->is_string())
468 //s= proc_escape(next_parm->get_svalue(), &l);
469 if (!next_parm->as_string())
471 s= next_parm->value.string.string;
472 l= next_parm->value.string.len;
474 array= (t_mem*)malloc(sizeof(t_mem)*l);
476 array= (t_mem*)realloc(array, sizeof(t_mem)*(l+len));
477 for (j= 0; j < l; j++)
487 if (!next_parm->as_data())
494 array= (t_mem*)malloc(sizeof(t_mem));
496 array= (t_mem*)realloc(array, sizeof(t_mem)*(1+len));
497 array[len]= next_parm->value.data;
502 parm->value.data_list.array= array;
503 parm->value.data_list.len= len;
510 *____________________________________________________________________________
513 cl_cmd::cl_cmd(enum cmd_operate_on op_on,
521 names= new cl_strings(1, 1, "names of a command");
522 names->add(aname?strdup(aname):strdup("unknown"));
524 short_help= short_hlp?strdup(short_hlp):NULL;
525 long_help= long_hlp?strdup(long_hlp):NULL;
528 /*cl_cmd::cl_cmd(class cl_sim *asim):
532 name= short_help= long_help= 0;
536 cl_cmd::~cl_cmd(void)
546 cl_cmd::add_name(char *nam)
549 names->add(strdup(nam));
553 cl_cmd::name_match(char *aname, int strict)
557 if (names->count == 0 &&
564 for (i= 0; i < names->count; i++)
566 char *n= (char*)(names->at(i));
567 if (strcmp(aname, n) == 0)
573 for (i= 0; i < names->count; i++)
575 char *n= (char*)(names->at(i));
576 if (strstr(n, aname) == n)
584 cl_cmd::name_match(class cl_cmdline *cmdline, int strict)
586 return(name_match(cmdline->get_name(), strict));
590 cl_cmd::syntax_ok(class cl_cmdline *cmdline)
596 cl_cmd::work(class cl_app *app,
597 class cl_cmdline *cmdline, class cl_console *con)
599 if (!syntax_ok(cmdline))
601 class cl_sim *sim= app->get_sim();
610 con->dd_printf("There is no application to work on!\n");
613 return(do_work(app, cmdline, con));
617 con->dd_printf("There is no simulator to work on!\n");
620 return(do_work(sim, cmdline, con));
624 con->dd_printf("There is no microcontroller to work on!\n");
627 return(do_work(uc, cmdline, con));
629 return(do_work(cmdline, con));
634 cl_cmd::do_work(class cl_cmdline *cmdline, class cl_console *con)
636 con->dd_printf("Command \"%s\" does nothing.\n",
637 (char*)(names->at(0)));
642 cl_cmd::do_work(class cl_app *app,
643 class cl_cmdline *cmdline, class cl_console *con)
645 con->dd_printf("Command \"%s\" does nothing on application.\n",
646 (char*)(names->at(0)));
651 cl_cmd::do_work(class cl_sim *sim,
652 class cl_cmdline *cmdline, class cl_console *con)
654 con->dd_printf("Command \"%s\" does nothing on simulator.\n",
655 (char*)(names->at(0)));
660 cl_cmd::do_work(class cl_uc *uc,
661 class cl_cmdline *cmdline, class cl_console *con)
663 con->dd_printf("Command \"%s\" does nothing on microcontroller.\n",
664 (char*)(names->at(0)));
671 *____________________________________________________________________________
674 cl_cmdset::cl_cmdset(void):
675 cl_list(5, 5, "cmdset")
681 /*cl_cmdset::cl_cmdset(class cl_sim *asim):
689 cl_cmdset::get_cmd(class cl_cmdline *cmdline, bool accept_last)
694 for (i= 0; i < count; i++)
696 class cl_cmd *c= (class cl_cmd *)at(i);
697 if (c->name_match(cmdline, 1))
701 class cl_cmd *c_matched= 0;
702 for (i= 0; i < count; i++)
704 class cl_cmd *c= (class cl_cmd *)at(i);
705 if (c->name_match(cmdline, 0))
718 cl_cmdset::get_cmd(char *cmd_name)
722 for (i= 0; i < count; i++)
724 class cl_cmd *c= (class cl_cmd *)at(i);
725 if (c->name_match(cmd_name, 1))
732 cl_cmdset::del(char *nam)
738 for (i= 0; i < count; i++)
740 class cl_cmd *cmd= (class cl_cmd *)(at(i));
741 if (cmd->name_match(nam, 1))
747 cl_cmdset::replace(char *nam, class cl_cmd *cmd)
753 for (i= 0; i < count; i++)
755 class cl_cmd *c= (class cl_cmd *)(at(i));
756 if (c->name_match(nam, 1))
766 * Composed command: subset of commands
767 *____________________________________________________________________________
770 cl_super_cmd::cl_super_cmd(char *aname,
774 class cl_cmdset *acommands):
775 cl_cmd(operate_on_none, aname, can_rep, short_hlp, long_hlp)
780 cl_super_cmd::~cl_super_cmd(void)
787 cl_super_cmd::work(class cl_app *app,
788 class cl_cmdline *cmdline, class cl_console *con)
790 class cl_cmd *cmd= 0;
795 if (!cmdline->shift())
797 if ((cmd= commands->get_cmd("_no_parameters_")) != 0)
798 return(cmd->work(app, cmdline, con));
800 con->dd_printf("\"%s\" must be followed by the name of a subcommand\n"
801 "List of subcommands:\n", (char*)(names->at(0)));
802 for (i= 0; i < commands->count; i++)
804 cmd= (class cl_cmd *)(commands->at(i));
805 con->dd_printf("%s\n", cmd->short_help);
809 if ((cmd= commands->get_cmd(cmdline, con->accept_last())) == NULL)
811 con->dd_printf("Undefined subcommand: \"%s\". Try \"help %s\".\n",
812 cmdline->get_name(), (char*)(names->at(0)));
815 return(cmd->work(app, cmdline, con));
819 /* End of cmd.src/command.cc */