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);
51 tokens= new cl_ustrings(2, 2);
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, *param_str;
139 con->dd_printf("Unterminated string\n");
140 param_str= (char *)malloc(end-start+2);
141 strncpy(param_str, start, 1+end-start);
142 param_str[1+end-start]= '\0';
143 tokens->add(strdup(param_str));
144 params->add(arg= new cl_cmd_str_arg(param_str));
155 i= strcspn(start, " \t\v\r,");
157 param_str= (char *)malloc(i+1);
158 strncpy(param_str, start, i);
160 if (strchr(">", *start))
162 char *fn, mode[3]= "w\0";
169 con->dd_printf("Unspecified redirection\n");
177 con->redirect(fn, mode);
184 start= skip_delims(start);
187 tokens->add(strdup(param_str));
188 if ((dot= strchr(param_str, '.')) != NULL)
191 class cl_cmd_arg *sfr, *bit;
194 if (strchr("0123456789", *param_str) != NULL)
196 sfr= new cl_cmd_int_arg((long)strtol(param_str, 0, 0));
201 sfr= new cl_cmd_sym_arg(param_str);
207 con->dd_printf("Uncomplete bit address\n");
212 if (strchr("0123456789", *dot) != NULL)
214 bit= new cl_cmd_int_arg((long)strtol(dot, 0, 0));
219 bit= new cl_cmd_sym_arg(dot);
222 params->add(arg= new cl_cmd_bit_arg(sfr, bit));
226 else if ((dot= strchr(param_str, '[')) != NULL)
229 class cl_cmd_arg *aname, *aindex;
232 if (strchr("0123456789", *param_str) != NULL)
234 aname= new cl_cmd_int_arg((long)strtol(param_str, 0, 0));
239 aname= new cl_cmd_sym_arg(param_str);
245 con->dd_printf("Uncomplete array\n");
250 p= dot + strlen(dot) - 1;
259 if (strlen(dot) == 0)
261 con->dd_printf("Uncomplete array index\n");
266 if (strchr("0123456789", *dot) != NULL)
268 aindex= new cl_cmd_int_arg((long)strtol(dot, 0, 0));
273 aindex= new cl_cmd_sym_arg(dot);
276 params->add(arg= new cl_cmd_array_arg(aname, aindex));
281 else if (strchr("0123456789", *param_str) != NULL)
284 params->add(arg= new cl_cmd_int_arg((long)
285 strtol(param_str, 0, 0)));
291 params->add(arg= new cl_cmd_sym_arg(param_str));
297 start= skip_delims(start);
303 cl_cmdline::shift(void)
305 char *s= skip_delims(cmd);
311 strchr(" \t\v\r,", *s) == NULL)
318 params= new cl_list(2, 2);
321 return(have_real_name());
325 cl_cmdline::repeat(void)
328 return((n= get_name()) &&
333 cl_cmdline::param(int num)
335 if (num >= params->count)
337 return((class cl_cmd_arg *)(params->at(num)));
341 cl_cmdline::insert_param(int pos, class cl_cmd_arg *param)
343 if (pos >= params->count)
346 params->add_at(pos, param);
350 cl_cmdline::syntax_match(class cl_uc *uc, char *syntax)
357 matched_syntax= syntax;
362 //printf("syntax %s?\n",syntax);
365 class cl_cmd_arg *parm= (class cl_cmd_arg *)(params->at(iparam));
370 //printf("Checking %s as %c\n",parm->get_svalue(),*p);
375 match= parm->as_address(uc);
378 //printf("ADDRESS match %lx\n",parm->value.address);
381 match= parm->as_memory(uc);
384 //printf("MEMORY match %s\n",parm->value.memory->class_name);
387 if (!parm->as_bit(uc))
393 case SY_ADDR: case SY_MEMORY: case SY_BIT: break;
395 if (!parm->as_number())
399 if (!parm->as_data())
403 if (!parm->as_hw(uc))
407 if (!parm->as_string())
411 if (!set_data_list(parm, &iparam))
419 if (iparam < params->count)
420 parm= (class cl_cmd_arg *)(params->at(iparam));
427 matched_syntax= syntax;
434 cl_cmdline::set_data_list(class cl_cmd_arg *parm, int *iparm)
436 class cl_cmd_arg *next_parm;
442 for (i= *iparm, next_parm= param(i); next_parm; i++, next_parm= param(i))
444 if (next_parm->is_string())
448 //s= proc_escape(next_parm->get_svalue(), &l);
449 if (!next_parm->as_string())
451 s= next_parm->value.string.string;
452 l= next_parm->value.string.len;
454 array= (t_mem*)malloc(sizeof(t_mem)*l);
456 array= (t_mem*)realloc(array, sizeof(t_mem)*(l+len));
457 for (j= 0; j < l; j++)
467 if (!next_parm->as_data())
474 array= (t_mem*)malloc(sizeof(t_mem));
476 array= (t_mem*)realloc(array, sizeof(t_mem)*(1+len));
477 array[len]= next_parm->value.data;
482 parm->value.data_list.array= array;
483 parm->value.data_list.len= len;
490 *____________________________________________________________________________
493 cl_cmd::cl_cmd(enum cmd_operate_on op_on,
501 names= new cl_strings(1, 1);
502 names->add(aname?strdup(aname):strdup("unknown"));
504 short_help= short_hlp?strdup(short_hlp):NULL;
505 long_help= long_hlp?strdup(long_hlp):NULL;
508 /*cl_cmd::cl_cmd(class cl_sim *asim):
512 name= short_help= long_help= 0;
516 cl_cmd::~cl_cmd(void)
526 cl_cmd::add_name(char *nam)
529 names->add(strdup(nam));
533 cl_cmd::name_match(char *aname, int strict)
537 if (names->count == 0 &&
544 for (i= 0; i < names->count; i++)
546 char *n= (char*)(names->at(i));
547 if (strcmp(aname, n) == 0)
553 for (i= 0; i < names->count; i++)
555 char *n= (char*)(names->at(i));
556 if (strstr(n, aname) == n)
564 cl_cmd::name_match(class cl_cmdline *cmdline, int strict)
566 return(name_match(cmdline->get_name(), strict));
570 cl_cmd::syntax_ok(class cl_cmdline *cmdline)
576 cl_cmd::work(class cl_app *app,
577 class cl_cmdline *cmdline, class cl_console *con)
579 if (!syntax_ok(cmdline))
581 class cl_sim *sim= app->get_sim();
590 con->dd_printf("There is no application to work on!\n");
593 return(do_work(app, cmdline, con));
597 con->dd_printf("There is no simulator to work on!\n");
600 return(do_work(sim, cmdline, con));
604 con->dd_printf("There is no microcontroller to work on!\n");
607 return(do_work(uc, cmdline, con));
609 return(do_work(cmdline, con));
614 cl_cmd::do_work(class cl_cmdline *cmdline, class cl_console *con)
616 con->dd_printf("Command \"%s\" does nothing.\n",
617 (char*)(names->at(0)));
622 cl_cmd::do_work(class cl_app *app,
623 class cl_cmdline *cmdline, class cl_console *con)
625 con->dd_printf("Command \"%s\" does nothing on application.\n",
626 (char*)(names->at(0)));
631 cl_cmd::do_work(class cl_sim *sim,
632 class cl_cmdline *cmdline, class cl_console *con)
634 con->dd_printf("Command \"%s\" does nothing on simulator.\n",
635 (char*)(names->at(0)));
640 cl_cmd::do_work(class cl_uc *uc,
641 class cl_cmdline *cmdline, class cl_console *con)
643 con->dd_printf("Command \"%s\" does nothing on microcontroller.\n",
644 (char*)(names->at(0)));
651 *____________________________________________________________________________
654 cl_cmdset::cl_cmdset(void):
661 /*cl_cmdset::cl_cmdset(class cl_sim *asim):
669 cl_cmdset::get_cmd(class cl_cmdline *cmdline)
673 if (cmdline->repeat())
676 return(last_command);
681 for (i= 0; i < count; i++)
683 class cl_cmd *c= (class cl_cmd *)at(i);
684 if (c->name_match(cmdline, 1))
688 class cl_cmd *c_matched= 0;
689 for (i= 0; i < count; i++)
691 class cl_cmd *c= (class cl_cmd *)at(i);
692 if (c->name_match(cmdline, 0))
705 cl_cmdset::get_cmd(char *cmd_name)
709 for (i= 0; i < count; i++)
711 class cl_cmd *c= (class cl_cmd *)at(i);
712 if (c->name_match(cmd_name, 1))
719 cl_cmdset::del(char *nam)
725 for (i= 0; i < count; i++)
727 class cl_cmd *cmd= (class cl_cmd *)(at(i));
728 if (cmd->name_match(nam, 1))
734 cl_cmdset::replace(char *nam, class cl_cmd *cmd)
740 for (i= 0; i < count; i++)
742 class cl_cmd *c= (class cl_cmd *)(at(i));
743 if (c->name_match(nam, 1))
753 * Composed command: subset of commands
754 *____________________________________________________________________________
757 cl_super_cmd::cl_super_cmd(char *aname,
761 class cl_cmdset *acommands):
762 cl_cmd(operate_on_none, aname, can_rep, short_hlp, long_hlp)
767 cl_super_cmd::~cl_super_cmd(void)
774 cl_super_cmd::work(class cl_app *app,
775 class cl_cmdline *cmdline, class cl_console *con)
777 class cl_cmd *cmd= 0;
782 if (!cmdline->shift())
784 if ((cmd= commands->get_cmd("_no_parameters_")) != 0)
785 return(cmd->work(app, cmdline, con));
787 con->dd_printf("\"%s\" must be followed by the name of a subcommand\n"
788 "List of subcommands:\n", (char*)(names->at(0)));
789 for (i= 0; i < commands->count; i++)
791 cmd= (class cl_cmd *)(commands->at(i));
792 con->dd_printf("%s\n", cmd->short_help);
796 if ((cmd= commands->get_cmd(cmdline)) == NULL)
798 con->dd_printf("Undefined subcommand: \"%s\". Try \"help %s\".\n",
799 cmdline->get_name(), (char*)(names->at(0)));
802 return(cmd->work(app, cmdline, con));
806 /* End of cmd.src/command.cc */