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));
369 //printf("Checking %s as %c\n",parm->get_svalue(),*p);
374 if (!parm->as_address(uc))
376 //printf("ADDRESS match %lx\n",parm->value.address);
379 if (!parm->as_memory(uc))
381 //printf("MEMORY match %s\n",parm->value.memory->class_name);
384 if (!parm->as_bit(uc))
391 if (!parm->as_number())
395 if (!parm->as_data())
399 if (!parm->as_hw(uc))
403 if (!parm->as_string())
407 if (!set_data_list(parm, &iparam))
415 if (iparam < params->count)
416 parm= (class cl_cmd_arg *)(params->at(iparam));
423 matched_syntax= syntax;
430 cl_cmdline::set_data_list(class cl_cmd_arg *parm, int *iparm)
432 class cl_cmd_arg *next_parm;
438 for (i= *iparm, next_parm= param(i); next_parm; i++, next_parm= param(i))
440 if (next_parm->is_string())
444 //s= proc_escape(next_parm->get_svalue(), &l);
445 if (!next_parm->as_string())
447 s= next_parm->value.string.string;
448 l= next_parm->value.string.len;
450 array= (t_mem*)malloc(sizeof(t_mem)*l);
452 array= (t_mem*)realloc(array, sizeof(t_mem)*(l+len));
453 for (j= 0; j < l; j++)
463 if (!next_parm->as_data())
470 array= (t_mem*)malloc(sizeof(t_mem));
472 array= (t_mem*)realloc(array, sizeof(t_mem)*(1+len));
473 array[len]= next_parm->value.data;
478 parm->value.data_list.array= array;
479 parm->value.data_list.len= len;
486 *____________________________________________________________________________
489 cl_cmd::cl_cmd(enum cmd_operate_on op_on,
497 names= new cl_strings(1, 1);
498 names->add(aname?strdup(aname):strdup("unknown"));
500 short_help= short_hlp?strdup(short_hlp):NULL;
501 long_help= long_hlp?strdup(long_hlp):NULL;
504 /*cl_cmd::cl_cmd(class cl_sim *asim):
508 name= short_help= long_help= 0;
512 cl_cmd::~cl_cmd(void)
522 cl_cmd::add_name(char *nam)
525 names->add(strdup(nam));
529 cl_cmd::name_match(char *aname, int strict)
533 if (names->count == 0 &&
540 for (i= 0; i < names->count; i++)
542 char *n= (char*)(names->at(i));
543 if (strcmp(aname, n) == 0)
549 for (i= 0; i < names->count; i++)
551 char *n= (char*)(names->at(i));
552 if (strstr(n, aname) == n)
560 cl_cmd::name_match(class cl_cmdline *cmdline, int strict)
562 return(name_match(cmdline->get_name(), strict));
566 cl_cmd::syntax_ok(class cl_cmdline *cmdline)
572 cl_cmd::work(class cl_app *app,
573 class cl_cmdline *cmdline, class cl_console *con)
575 if (!syntax_ok(cmdline))
577 class cl_sim *sim= app->get_sim();
586 con->dd_printf("There is no application to work on!\n");
589 return(do_work(app, cmdline, con));
593 con->dd_printf("There is no simulator to work on!\n");
596 return(do_work(sim, cmdline, con));
600 con->dd_printf("There is no microcontroller to work on!\n");
603 return(do_work(uc, cmdline, con));
605 return(do_work(cmdline, con));
610 cl_cmd::do_work(class cl_cmdline *cmdline, class cl_console *con)
612 con->dd_printf("Command \"%s\" does nothing.\n",
613 (char*)(names->at(0)));
618 cl_cmd::do_work(class cl_app *app,
619 class cl_cmdline *cmdline, class cl_console *con)
621 con->dd_printf("Command \"%s\" does nothing on application.\n",
622 (char*)(names->at(0)));
627 cl_cmd::do_work(class cl_sim *sim,
628 class cl_cmdline *cmdline, class cl_console *con)
630 con->dd_printf("Command \"%s\" does nothing on simulator.\n",
631 (char*)(names->at(0)));
636 cl_cmd::do_work(class cl_uc *uc,
637 class cl_cmdline *cmdline, class cl_console *con)
639 con->dd_printf("Command \"%s\" does nothing on microcontroller.\n",
640 (char*)(names->at(0)));
647 *____________________________________________________________________________
650 cl_cmdset::cl_cmdset(void):
657 /*cl_cmdset::cl_cmdset(class cl_sim *asim):
665 cl_cmdset::get_cmd(class cl_cmdline *cmdline)
669 if (cmdline->repeat())
672 return(last_command);
677 for (i= 0; i < count; i++)
679 class cl_cmd *c= (class cl_cmd *)at(i);
680 if (c->name_match(cmdline, 1))
684 class cl_cmd *c_matched= 0;
685 for (i= 0; i < count; i++)
687 class cl_cmd *c= (class cl_cmd *)at(i);
688 if (c->name_match(cmdline, 0))
701 cl_cmdset::get_cmd(char *cmd_name)
705 for (i= 0; i < count; i++)
707 class cl_cmd *c= (class cl_cmd *)at(i);
708 if (c->name_match(cmd_name, 1))
715 cl_cmdset::del(char *nam)
721 for (i= 0; i < count; i++)
723 class cl_cmd *cmd= (class cl_cmd *)(at(i));
724 if (cmd->name_match(nam, 1))
730 cl_cmdset::replace(char *nam, class cl_cmd *cmd)
736 for (i= 0; i < count; i++)
738 class cl_cmd *c= (class cl_cmd *)(at(i));
739 if (c->name_match(nam, 1))
749 * Composed command: subset of commands
750 *____________________________________________________________________________
753 cl_super_cmd::cl_super_cmd(char *aname,
757 class cl_cmdset *acommands):
758 cl_cmd(operate_on_none, aname, can_rep, short_hlp, long_hlp)
763 cl_super_cmd::~cl_super_cmd(void)
770 cl_super_cmd::work(class cl_app *app,
771 class cl_cmdline *cmdline, class cl_console *con)
773 class cl_cmd *cmd= 0;
778 if (!cmdline->shift())
780 if ((cmd= commands->get_cmd("_no_parameters_")) != 0)
781 return(cmd->work(app, cmdline, con));
783 con->dd_printf("\"%s\" must be followed by the name of a subcommand\n"
784 "List of subcommands:\n", (char*)(names->at(0)));
785 for (i= 0; i < commands->count; i++)
787 cmd= (class cl_cmd *)(commands->at(i));
788 con->dd_printf("%s\n", cmd->short_help);
792 if ((cmd= commands->get_cmd(cmdline)) == NULL)
794 con->dd_printf("Undefined subcommand: \"%s\". Try \"help %s\".\n",
795 cmdline->get_name(), (char*)(names->at(0)));
798 return(cmd->work(app, cmdline, con));
802 /* End of cmd.src/command.cc */