/*
- * Simulator of microcontrollers (newcmd.cc)
+ * Simulator of microcontrollers (cmd.src/newcmd.cc)
*
* Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
*
// sim
#include "simcl.h"
#include "argcl.h"
+#include "appcl.h"
// local
#include "newcmdcl.h"
*____________________________________________________________________________
*/
-cl_cmdline::cl_cmdline(char *acmd)
+cl_cmdline::cl_cmdline(class cl_app *the_app,
+ char *acmd, class cl_console *acon):
+ cl_base()
{
+ app= the_app;
cmd= strdup(acmd);
params= new cl_list(2, 2);
tokens= new cl_ustrings(2, 2);
name= 0;
+ matched_syntax= 0;
+ con= acon;
}
cl_cmdline::~cl_cmdline(void)
int
cl_cmdline::split(void)
{
+ //class cl_sim *sim;
char *start= cmd;
int i;
+ class cl_cmd_arg *arg;
+ //sim= app->get_sim();
name= 0;
if (!cmd ||
!*cmd)
end= start;
while (*end &&
*end != '"')
- end++;
+ {
+ if (*end == '\\')
+ {
+ end++;
+ if (*end)
+ end++;
+ }
+ else
+ end++;
+ }
if (*end == '"')
end--;
else
- simulator->cmd->printf("Unterminated string\n");
+ con->dd_printf("Unterminated string\n");
param_str= (char *)malloc(end-start+2);
strncpy(param_str, start, 1+end-start);
param_str[1+end-start]= '\0';
tokens->add(strdup(param_str));
- params->add(simulator->mk_cmd_str_arg(param_str));
+ params->add(arg= new cl_cmd_str_arg(param_str));
+ arg->init();
free(param_str);
if (*end)
end++;
*dot= '\0';
dot++;
if (strchr("0123456789", *param_str) != NULL)
- sfr= simulator->mk_cmd_int_arg((long long)
- strtol(param_str, 0, 0));
+ {
+ sfr= new cl_cmd_int_arg((long)strtol(param_str, 0, 0));
+ sfr->init();
+ }
else
- sfr= simulator->mk_cmd_sym_arg(param_str);
+ {
+ sfr= new cl_cmd_sym_arg(param_str);
+ sfr->init();
+ }
if (*dot == '\0')
{
bit= 0;
- simulator->cmd->printf("Uncomplete bit address\n");
+ con->dd_printf("Uncomplete bit address\n");
+ delete sfr;
}
else
{
if (strchr("0123456789", *dot) != NULL)
- bit= simulator->mk_cmd_int_arg((long long)
- strtol(dot, 0, 0));
+ {
+ bit= new cl_cmd_int_arg((long)strtol(dot, 0, 0));
+ bit->init();
+ }
else
- bit= simulator->mk_cmd_sym_arg(dot);
+ {
+ bit= new cl_cmd_sym_arg(dot);
+ bit->init();
+ }
+ params->add(arg= new cl_cmd_bit_arg(sfr, bit));
+ arg->init();
+ }
+ }
+ else if ((dot= strchr(param_str, '[')) != NULL)
+ {
+ // array
+ class cl_cmd_arg *aname, *aindex;
+ *dot= '\0';
+ dot++;
+ if (strchr("0123456789", *param_str) != NULL)
+ {
+ aname= new cl_cmd_int_arg((long)strtol(param_str, 0, 0));
+ aname->init();
+ }
+ else
+ {
+ aname= new cl_cmd_sym_arg(param_str);
+ aname->init();
+ }
+ if (*dot == '\0')
+ {
+ aname= 0;
+ con->dd_printf("Uncomplete array\n");
+ }
+ else
+ {
+ char *p;
+ p= dot + strlen(dot) - 1;
+ while (p > dot &&
+ *p != ']')
+ {
+ *p= '\0';
+ p--;
+ }
+ if (*p == ']')
+ *p= '\0';
+ if (strlen(dot) == 0)
+ {
+ con->dd_printf("Uncomplete array index\n");
+ delete aname;
+ }
+ else
+ {
+ if (strchr("0123456789", *dot) != NULL)
+ {
+ aindex= new cl_cmd_int_arg((long)strtol(dot, 0, 0));
+ aindex->init();
+ }
+ else
+ {
+ aindex= new cl_cmd_sym_arg(dot);
+ aindex->init();
+ }
+ params->add(arg= new cl_cmd_array_arg(aname, aindex));
+ arg->init();
+ }
}
- params->add(simulator->mk_cmd_bit_arg(sfr, bit));
}
else if (strchr("0123456789", *param_str) != NULL)
{
// number
- params->add(simulator->mk_cmd_int_arg((long long)
- strtol(param_str, 0, 0)));
+ params->add(arg= new cl_cmd_int_arg((long)
+ strtol(param_str, 0, 0)));
+ arg->init();
}
else
{
// symbol
- params->add(simulator->mk_cmd_sym_arg(param_str));
+ params->add(arg= new cl_cmd_sym_arg(param_str));
+ arg->init();
}
free(param_str);
}
params->add_at(pos, param);
}
+bool
+cl_cmdline::syntax_match(class cl_uc *uc, char *syntax)
+{
+ if (!syntax)
+ return(DD_FALSE);
+ if (!*syntax &&
+ !params->count)
+ {
+ matched_syntax= syntax;
+ return(DD_TRUE);
+ }
+ if (!params->count)
+ return(DD_FALSE);
+ //printf("syntax %s?\n",syntax);
+ char *p= syntax;
+ int iparam= 0;
+ class cl_cmd_arg *parm= (class cl_cmd_arg *)(params->at(iparam));
+ while (*p &&
+ parm)
+ {
+ //printf("Checking %s as %c\n",parm->get_svalue(),*p);
+ switch (*p)
+ {
+ case SY_ADDR:
+ if (!parm->as_address(uc))
+ return(DD_FALSE);
+ //printf("ADDRESS match %lx\n",parm->value.address);
+ break;
+ case SY_NUMBER:
+ if (!parm->as_number())
+ return(DD_FALSE);
+ break;
+ case SY_DATA:
+ if (!parm->as_data())
+ return(DD_FALSE);
+ break;
+ case SY_MEMORY:
+ if (!parm->as_memory(uc))
+ return(DD_FALSE);
+ //printf("MEMORY match %s\n",parm->value.memory->class_name);
+ break;
+ case SY_HW:
+ if (!parm->as_hw(uc))
+ return(DD_FALSE);
+ break;
+ case SY_STRING:
+ if (!parm->as_string())
+ return(DD_FALSE);
+ break;
+ case SY_DATALIST:
+ if (!set_data_list(parm, &iparam))
+ return(DD_FALSE);
+ break;
+ case SY_BIT:
+ if (!parm->as_bit(uc))
+ return(DD_FALSE);
+ break;
+ default:
+ return(DD_FALSE);
+ }
+ p++;
+ iparam++;
+ if (iparam < params->count)
+ parm= (class cl_cmd_arg *)(params->at(iparam));
+ else
+ parm= 0;
+ }
+ if (!*p &&
+ !parm)
+ {
+ matched_syntax= syntax;
+ return(DD_TRUE);
+ }
+ return(DD_FALSE);
+}
+
+bool
+cl_cmdline::set_data_list(class cl_cmd_arg *parm, int *iparm)
+{
+ class cl_cmd_arg *next_parm;
+ int len, i, j;
+ t_mem *array;
+
+ len= 0;
+ array= 0;
+ for (i= *iparm, next_parm= param(i); next_parm; i++, next_parm= param(i))
+ {
+ if (next_parm->is_string())
+ {
+ int l;
+ char *s;
+ //s= proc_escape(next_parm->get_svalue(), &l);
+ if (!next_parm->as_string())
+ continue;
+ s= next_parm->value.string.string;
+ l= next_parm->value.string.len;
+ if (!array)
+ array= (t_mem*)malloc(sizeof(t_mem)*l);
+ else
+ array= (t_mem*)realloc(array, sizeof(t_mem)*(l+len));
+ for (j= 0; j < l; j++)
+ {
+ array[len]= s[j];
+ len++;
+ }
+ //if (s)
+ //free(s);
+ }
+ else
+ {
+ if (!next_parm->as_data())
+ {
+ if (array)
+ free(array);
+ return(DD_FALSE);
+ }
+ if (!array)
+ array= (t_mem*)malloc(sizeof(t_mem));
+ else
+ array= (t_mem*)realloc(array, sizeof(t_mem)*(1+len));
+ array[len]= next_parm->value.data;
+ len++;
+ }
+ }
+ *iparm= i;
+ parm->value.data_list.array= array;
+ parm->value.data_list.len= len;
+ return(DD_TRUE);
+}
+
/*
* Command
*____________________________________________________________________________
*/
-cl_cmd::cl_cmd(class cl_sim *asim,
+cl_cmd::cl_cmd(enum cmd_operate_on op_on,
char *aname,
int can_rep,
char *short_hlp,
char *long_hlp):
cl_base()
{
- sim= asim;
+ operate_on= op_on;
names= new cl_strings(1, 1);
names->add(aname?strdup(aname):strdup("unknown"));
can_repeat= can_rep;
}
int
-cl_cmd::work(class cl_cmdline *cmdline, class cl_console *con)
+cl_cmd::work(class cl_app *app,
+ class cl_cmdline *cmdline, class cl_console *con)
{
if (!syntax_ok(cmdline))
return(0);
- return(do_work(cmdline, con));
+ class cl_sim *sim= app->get_sim();
+ class cl_uc *uc= 0;
+ if (sim)
+ uc= sim->uc;
+ switch (operate_on)
+ {
+ case operate_on_app:
+ if (!app)
+ {
+ con->dd_printf("There is no application to work on!\n");
+ return(DD_TRUE);
+ }
+ return(do_work(app, cmdline, con));
+ case operate_on_sim:
+ if (!sim)
+ {
+ con->dd_printf("There is no simulator to work on!\n");
+ return(DD_TRUE);
+ }
+ return(do_work(sim, cmdline, con));
+ case operate_on_uc:
+ if (!sim)
+ {
+ con->dd_printf("There is no microcontroller to work on!\n");
+ return(DD_TRUE);
+ }
+ return(do_work(uc, cmdline, con));
+ default:
+ return(do_work(cmdline, con));
+ }
}
int
cl_cmd::do_work(class cl_cmdline *cmdline, class cl_console *con)
{
- con->printf("Command \"%s\" does nothing.\n", (char*)(names->at(0)));
+ con->dd_printf("Command \"%s\" does nothing.\n",
+ (char*)(names->at(0)));
+ return(0);
+}
+
+int
+cl_cmd::do_work(class cl_app *app,
+ class cl_cmdline *cmdline, class cl_console *con)
+{
+ con->dd_printf("Command \"%s\" does nothing on application.\n",
+ (char*)(names->at(0)));
+ return(0);
+}
+
+int
+cl_cmd::do_work(class cl_sim *sim,
+ class cl_cmdline *cmdline, class cl_console *con)
+{
+ con->dd_printf("Command \"%s\" does nothing on simulator.\n",
+ (char*)(names->at(0)));
+ return(0);
+}
+
+int
+cl_cmd::do_work(class cl_uc *uc,
+ class cl_cmdline *cmdline, class cl_console *con)
+{
+ con->dd_printf("Command \"%s\" does nothing on microcontroller.\n",
+ (char*)(names->at(0)));
return(0);
}
*____________________________________________________________________________
*/
-cl_cmdset::cl_cmdset(class cl_sim *asim):
+cl_cmdset::cl_cmdset(void):
cl_list(5, 5)
{
- sim= asim;
+ //sim= 0;
last_command= 0;
}
+/*cl_cmdset::cl_cmdset(class cl_sim *asim):
+ cl_list(5, 5)
+{
+ sim= asim;
+ last_command= 0;
+}*/
+
class cl_cmd *
cl_cmdset::get_cmd(class cl_cmdline *cmdline)
{
//return(0);
}
+class cl_cmd *
+cl_cmdset::get_cmd(char *cmd_name)
+{
+ int i;
+
+ for (i= 0; i < count; i++)
+ {
+ class cl_cmd *c= (class cl_cmd *)at(i);
+ if (c->name_match(cmd_name, 1))
+ return(c);
+ }
+ return(0);
+}
+
void
cl_cmdset::del(char *name)
{
*____________________________________________________________________________
*/
-cl_super_cmd::cl_super_cmd(class cl_sim *asim,
- char *aname,
+cl_super_cmd::cl_super_cmd(char *aname,
int can_rep,
char *short_hlp,
char *long_hlp,
class cl_cmdset *acommands):
- cl_cmd(asim, aname, can_rep, short_hlp, long_hlp)
+ cl_cmd(operate_on_none, aname, can_rep, short_hlp, long_hlp)
{
commands= acommands;
}
}
int
-cl_super_cmd::work(class cl_cmdline *cmdline, class cl_console *con)
+cl_super_cmd::work(class cl_app *app,
+ class cl_cmdline *cmdline, class cl_console *con)
{
- class cl_cmd *cmd;
+ class cl_cmd *cmd= 0;
if (!commands)
return(0);
if (!cmdline->shift())
{
+ if ((cmd= commands->get_cmd("_no_parameters_")) != 0)
+ return(cmd->work(app, cmdline, con));
int i;
- con->printf("\"%s\" must be followed by the name of a subcommand\n"
- "List of subcommands:\n", (char*)(names->at(0)));
+ con->dd_printf("\"%s\" must be followed by the name of a subcommand\n"
+ "List of subcommands:\n", (char*)(names->at(0)));
for (i= 0; i < commands->count; i++)
{
cmd= (class cl_cmd *)(commands->at(i));
- con->printf("%s\n", cmd->short_help);
+ con->dd_printf("%s\n", cmd->short_help);
}
return(0);
}
if ((cmd= commands->get_cmd(cmdline)) == NULL)
{
- con->printf("Undefined subcommand: \"%s\". Try \"help %s\".\n",
- cmdline->name, (char*)(names->at(0)));
+ con->dd_printf("Undefined subcommand: \"%s\". Try \"help %s\".\n",
+ cmdline->name, (char*)(names->at(0)));
return(0);
}
- return(cmd->work(cmdline, con));
+ return(cmd->work(app, cmdline, con));
}
*____________________________________________________________________________
*/
-cl_console::cl_console(char *fin, char *fout, class cl_sim *asim):
+cl_console::cl_console(char *fin, char *fout, class cl_app *the_app):
cl_base()
{
FILE *f;
last_command= NULL;
- sim= asim;
- in= stdin;
+ app= the_app;
+ in= 0;
if (fin)
- if (f= fopen(fin, "r+"), in= f?f:stdin, !f)
+ if (f= fopen(fin, "r+"), in= f, !f)
fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));
- out= stdout;
+ out= 0;
if (fout)
- if (f= fopen(fout, "w+"), out= f?f:stdout, !f)
+ if (f= fopen(fout, "w+"), out= f, !f)
fprintf(stderr, "Can't open `%s': %s\n", fout, strerror(errno));
prompt= 0;
flags= CONS_NONE;
+ if (in &&
+ isatty(fileno(in)))
+ flags|= CONS_INTERACTIVE;
+ else
+ dd_printf("Warning: non-interactive console\n");
}
-cl_console::cl_console(FILE *fin, FILE *fout, class cl_sim *asim):
+cl_console::cl_console(FILE *fin, FILE *fout, class cl_app *the_app):
cl_base()
{
last_command= NULL;
- sim= asim;
+ app= the_app;
in = fin;
out= fout;
+ prompt= 0;
flags= CONS_NONE;
+ if (in &&
+ isatty(fileno(in)))
+ flags|= CONS_INTERACTIVE;
+ else
+ dd_printf("Warning: non-interactive console\n");
}
/*
return sock;
}
-cl_console::cl_console(int portnumber, class cl_sim *asim)
+cl_console::cl_console(int portnumber, class cl_app *the_app)
{
int sock= connect_to_port(portnumber);
last_command= NULL;
- sim= asim;
+ app= the_app;
if (!(in= fdopen(sock, "r+")))
fprintf(stderr, "cannot open port for input\n");
if (!(out= fdopen(sock, "w+")))
void
cl_console::welcome(void)
{
- fprintf(out,
- "ucsim %s, Copyright (C) 1997 Daniel Drotos, Talker Bt.\n"
- "ucsim comes with ABSOLUTELY NO WARRANTY; for details type "
+ if (!out)
+ return;
+ fprintf(out, "uCsim %s, Copyright (C) 1997 Daniel Drotos, Talker Bt.\n"
+ "uCsim comes with ABSOLUTELY NO WARRANTY; for details type "
"`show w'.\n"
"This is free software, and you are welcome to redistribute it\n"
"under certain conditions; type `show c' for details.\n",
flags|= CONS_PROMPT;
if (!out)
return;
- if (sim->arg_avail('P'))
+ if (app->args->arg_avail('P'))
putc('\0', out);
else
fprintf(out, "%s", (prompt && prompt[0])?prompt:
- ((p= sim->get_sarg(0, "prompt"))?p:"> "));
+ ((p= app->args->get_sarg(0, "prompt"))?p:"> "));
fflush(out);
}
int
-cl_console::printf(char *format, ...)
+cl_console::dd_printf(char *format, ...)
{
va_list ap;
int ret= 0;
}
int
-cl_console::proc_input(void)
+cl_console::proc_input(class cl_cmdset *cmdset)
{
- int retval;
+ int retval= 0;
if (feof(in))
{
fprintf(out, "End\n");
return(1);
}
- char *cmd= read_line();
- if (!cmd)
+ char *cmdstr= read_line();
+ if (!cmdstr)
return(1);
if (flags & CONS_FROZEN)
{
- sim->stop(resUSER);
+ app->get_sim()->stop(resUSER);
flags&= ~CONS_FROZEN;
retval= 0;
}
else
- retval= sim->do_cmd(cmd, this);
+ {
+ class cl_cmdline *cmdline;
+ class cl_cmd *cm;
+ cmdline= new cl_cmdline(app, cmdstr, this);
+ cmdline->init();
+ cm= cmdset->get_cmd(cmdline);
+ if (cm)
+ retval= cm->work(app, cmdline, this);
+ delete cmdline;
+ if (!cm)
+ retval= interpret(cmdstr);
+ }
+ //retval= sim->do_cmd(cmd, this);
if (!retval)
print_prompt();
- free(cmd);
+ free(cmdstr);
return(retval);
}
/*
* Old version, sim->do_cmd() falls into this if it doesn't find a new
- * command object which can handle enetered command
+ * command object which can handle entered command
*/
int
cl_console::interpret(char *cmd)
{
- fprintf(out, "New interpreter does not known this command\n");
+ fprintf(out, "Unknown command\n");
return(0);
}
*/
#ifdef SOCKET_AVAIL
-cl_listen_console::cl_listen_console(int serverport, class cl_sim *asim)
+cl_listen_console::cl_listen_console(int serverport, class cl_app *the_app)
{
last_command= NULL;
- sim= asim;
+ app= the_app;
if ((sock= make_server_socket(serverport)) >= 0)
{
if (listen(sock, 10) < 0)
}
int
-cl_listen_console::proc_input(void)
+cl_listen_console::proc_input(class cl_cmdset *cmdset)
{
int newsock;
ACCEPT_SOCKLEN_T size;
struct sockaddr_in sock_addr;
+ class cl_commander *cmd;
+ cmd= app->get_commander();
size= sizeof(struct sockaddr);
newsock= accept(sock, (struct sockaddr*)&sock_addr, &size);
if (newsock < 0)
fprintf(stderr, "cannot open port for input\n");
if (!(out= fdopen(newsock, "w+")))
fprintf(stderr, "cannot open port for output\n");
- sim->cmd->add_console(sim->cmd->mk_console(in, out, sim));
+ class cl_console *c= cmd->mk_console(in, out);
+ c->flags|= CONS_INTERACTIVE;
+ cmd->add_console(c);
in= out= 0;
return(0);
}
*____________________________________________________________________________
*/
-cl_commander::cl_commander(class cl_sim *asim):
+cl_commander::cl_commander(class cl_app *the_app, class cl_cmdset *acmdset
+ /*, class cl_sim *asim*/):
cl_base()
{
+ app= the_app;
cons= new cl_list(1, 1);
actual_console= frozen_console= 0;
- sim= asim;
+ cmdset= acmdset;
}
int
cl_commander::init(void)
{
cl_base::init();
- if (!sim)
- return(1);
- if (sim->arg_avail('c'))
- add_console(mk_console(sim->get_sarg('c', 0),
- sim->get_sarg('c', 0), sim));
+
+ char *Config= app->args->get_sarg(0, "Config");
+ if (Config)
+ {
+ class cl_console *con= mk_console(0/*"/dev/tty"*/);
+ add_console(con);
+ }
+
+ if (app->args->arg_avail('c'))
+ add_console(mk_console(app->args->get_sarg('c', 0),
+ app->args->get_sarg('c', 0)));
#ifdef SOCKET_AVAIL
- if (sim->arg_avail('Z'))
- add_console(mk_console(sim->get_iarg(0, "Zport"), sim));
- if (sim->arg_avail('r'))
- add_console(mk_console(sim->get_iarg('r', 0), sim));
+ if (app->args->arg_avail('Z'))
+ add_console(mk_console(app->args->get_iarg(0, "Zport")));
+ if (app->args->arg_avail('r'))
+ add_console(mk_console(app->args->get_iarg('r', 0)));
#endif
if (cons->get_count() == 0)
- add_console(mk_console(stdin, stdout, sim));
+ add_console(mk_console(stdin, stdout));
return(0);
}
cl_commander::~cl_commander(void)
{
delete cons;
+ delete cmdset;
}
class cl_console *
-cl_commander::mk_console(char *fin, char *fout, class cl_sim *asim)
+cl_commander::mk_console(char *fin, char *fout)
{
- return(new cl_console(fin, fout, asim));
+ return(new cl_console(fin, fout, app));
}
class cl_console *
-cl_commander::mk_console(FILE *fin, FILE *fout, class cl_sim *asim)
+cl_commander::mk_console(FILE *fin, FILE *fout)
{
- return(new cl_console(fin, fout, asim));
+ return(new cl_console(fin, fout, app));
}
#ifdef SOCKET_AVAIL
class cl_console *
-cl_commander::mk_console(int portnumber, class cl_sim *asim)
+cl_commander::mk_console(int portnumber)
{
- return(new cl_listen_console(portnumber, asim));
+ return(new cl_listen_console(portnumber, app));
}
#endif
cl_commander::set_fd_set(void)
{
int i;
-
+
+ //fprintf(stderr, "** Setting fd set\n");
FD_ZERO(&read_set);
fd_num= 0;
for (i= 0; i < cons->count; i++)
class cl_console *c= (class cl_console*)(cons->at(i));
if ((fd= c->get_in_fd()) >= 0)
{
- if (fd > fd_num)
- fd_num= fd;
- FD_SET(fd, &read_set);
+ if ((c->flags & CONS_FROZEN) == 0 ||
+ (c->flags & CONS_INTERACTIVE) != 0)
+ {
+ FD_SET(fd, &read_set);
+ if (fd > fd_num)
+ fd_num= fd;
+ }
}
+ else
+ ;//fprintf(stderr, "** Skipping console %p\n",c);
}
fd_num++;
}
*/
int
-cl_commander::printf(char *format, ...)
+cl_commander::dd_printf(char *format, ...)
{
va_list ap;
int ret= 0;
tv.tv_sec= tv.tv_usec= 0;
active_set= read_set;
- i= select(fd_num/*FD_SETSIZE*/, &active_set, NULL, NULL, &tv);
+ i= select(fd_num, &active_set, NULL, NULL, &tv);
return(i);
}
int
cl_commander::input_avail_on_frozen(void)
{
+ int fd;
+
if (!frozen_console)
return(0);
+ if ((fd= frozen_console->get_in_fd()) >= 0 &&
+ !isatty(fd))
+ return(0);
return(frozen_console->input_avail());
}
int i;
active_set= read_set;
- i= select(fd_num/*FD_SETSIZE*/, &active_set, NULL, NULL, NULL);
+ i= select(fd_num, &active_set, NULL, NULL, NULL);
return(i);
}
{
int i;
- for (i= 0; i < fd_num/*FD_SETSIZE*/; i++)
+ for (i= 0; i < fd_num; i++)
if (FD_ISSET(i, &active_set))
{
class cl_console *c;
if (c->match(i))
{
actual_console= c;
- int retval= c->proc_input();
+ int retval= c->proc_input(cmdset);
if (retval)
{
del_console(c);
}
-/* End of newcmd.cc */
+/* End of cmd.src/newcmd.cc */