#include <unistd.h>
#include "i_string.h"
+#include "cmdlexcl.h"
+#include "cmdpars.h"
+
// prj
#include "globals.h"
+#include "utils.h"
// sim
#include "simcl.h"
#include "cmdutil.h"
-extern "C" int vasprintf(char **strp, const char *format, va_list ap);
-extern "C" int vsnprintf(char *str, size_t size,const char *format,va_list ap);
-
-static int
-cmd_do_print(FILE *f, char *format, va_list ap)
-{
- int ret;
-#ifdef HAVE_VASPRINTF
- char *msg= NULL;
- vasprintf(&msg, format, ap);
- ret= fprintf(f, "%s", msg);
- free(msg);
-#else
-# ifdef HAVE_VSNPRINTF
- char msg[80*25];
- vsnprintf(msg, 80*25, format, ap);
- ret= fprintf(f, "%s", msg);
-# else
-# ifdef HAVE_VPRINTF
- char msg[80*25];
- vsprintf(msg, format, ap); /* Dangerous */
- ret= fprintf(f, "%s", msg);
-# else
-# ifdef HAVE_DOPRNT
- /* ??? */
- /*strcpy(msg, "Unimplemented printf has called.\n");*/
-# else
- /*strcpy(msg, "printf can not be implemented, upgrade your libc.\n");*/
-# endif
-# endif
-# endif
-#endif
- fflush(f);
- return(ret);
-}
-
-
-/*
- * Command line
- *____________________________________________________________________________
- */
-
-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)
-{
- if (cmd)
- free(cmd);
- if (name)
- free(name);
- delete params;
- delete tokens;
-}
-
-int
-cl_cmdline::init(void)
-{
- split();
- return(0);
-}
-
-char *
-cl_cmdline::skip_delims(char *start)
-{
- while (*start &&
- strchr(" \t\v\r,", *start))
- start++;
- return(start);
-}
-
-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)
- return(0);
- start+= strspn(start, " \t\v\r,");
- if (start &&
- *start == '\n')
- {
- name= (char*)malloc(2);
- strcpy(name, "\n");
- return(0);
- }
- if (!*start)
- return(0);
- i= strcspn(start, " \t\v\r,");
- if (i)
- {
- name= (char*)malloc(i+1);
- strncpy(name, start, i);
- name[i]= '\0';
- }
- start+= i;
- start= skip_delims(start);
- // skip delimiters
- while (*start)
- {
- char *end, *param_str;
- if (*start == '"')
- {
- // string
- start++;
- end= start;
- while (*end &&
- *end != '"')
- {
- if (*end == '\\')
- {
- end++;
- if (*end)
- end++;
- }
- else
- end++;
- }
- if (*end == '"')
- end--;
- else
- con->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(arg= new cl_cmd_str_arg(param_str));
- arg->init();
- free(param_str);
- if (*end)
- end++;
- if (*end == '"')
- end++;
- }
- else
- {
- char *dot;
- i= strcspn(start, " \t\v\r,");
- end= start+i;
- param_str= (char *)malloc(i+1);
- strncpy(param_str, start, i);
- param_str[i]= '\0';
- tokens->add(strdup(param_str));
- if ((dot= strchr(param_str, '.')) != NULL)
- {
- // bit
- class cl_cmd_arg *sfr, *bit;
- *dot= '\0';
- dot++;
- if (strchr("0123456789", *param_str) != NULL)
- {
- sfr= new cl_cmd_int_arg((long)strtol(param_str, 0, 0));
- sfr->init();
- }
- else
- {
- sfr= new cl_cmd_sym_arg(param_str);
- sfr->init();
- }
- if (*dot == '\0')
- {
- bit= 0;
- con->printf("Uncomplete bit address\n");
- delete sfr;
- }
- else
- {
- if (strchr("0123456789", *dot) != NULL)
- {
- bit= new cl_cmd_int_arg((long)strtol(dot, 0, 0));
- bit->init();
- }
- else
- {
- 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->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->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();
- }
- }
- }
- else if (strchr("0123456789", *param_str) != NULL)
- {
- // number
- params->add(arg= new cl_cmd_int_arg((long)
- strtol(param_str, 0, 0)));
- arg->init();
- }
- else
- {
- // symbol
- params->add(arg= new cl_cmd_sym_arg(param_str));
- arg->init();
- }
- free(param_str);
- }
- start= end;
- start= skip_delims(start);
- }
- return(0);
-}
-
-int
-cl_cmdline::shift(void)
-{
- char *s= skip_delims(cmd);
-
- free(name);
- name= NULL;
- if (s && *s)
- {
- while (*s &&
- strchr(" \t\v\r,", *s) == NULL)
- s++;
- s= skip_delims(s);
- char *p= strdup(s);
- free(cmd);
- cmd= p;
- delete params;
- params= new cl_list(2, 2);
- split();
- }
- return(name && *name);
-}
-
-int
-cl_cmdline::repeat(void)
-{
- return(name &&
- *name == '\n');
-}
-
-class cl_cmd_arg *
-cl_cmdline::param(int num)
-{
- if (num >= params->count)
- return(0);
- return((class cl_cmd_arg *)(params->at(num)));
-}
-
-void
-cl_cmdline::insert_param(int pos, class cl_cmd_arg *param)
-{
- if (pos >= params->count)
- params->add(param);
- else
- 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(enum cmd_operate_on op_on,
- char *aname,
- int can_rep,
- char *short_hlp,
- char *long_hlp):
- cl_base()
-{
- operate_on= op_on;
- names= new cl_strings(1, 1);
- names->add(aname?strdup(aname):strdup("unknown"));
- can_repeat= can_rep;
- short_help= short_hlp?strdup(short_hlp):NULL;
- long_help= long_hlp?strdup(long_hlp):NULL;
-}
-
-/*cl_cmd::cl_cmd(class cl_sim *asim):
- cl_base()
-{
- sim= asim;
- name= short_help= long_help= 0;
- can_repeat= 0;
-}*/
-
-cl_cmd::~cl_cmd(void)
-{
- delete names;
- if (short_help)
- free(short_help);
- if (long_help)
- free(long_help);
-}
-
-void
-cl_cmd::add_name(char *name)
-{
- if (name)
- names->add(strdup(name));
-}
-
-int
-cl_cmd::name_match(char *aname, int strict)
-{
- int i;
-
- if (names->count == 0 &&
- !aname)
- return(1);
- if (!aname)
- return(0);
- if (strict)
- {
- for (i= 0; i < names->count; i++)
- {
- char *n= (char*)(names->at(i));
- if (strcmp(aname, n) == 0)
- return(1);
- }
- }
- else
- {
- for (i= 0; i < names->count; i++)
- {
- char *n= (char*)(names->at(i));
- if (strstr(n, aname) == n)
- return(1);
- }
- }
- return(0);
-}
-
-int
-cl_cmd::name_match(class cl_cmdline *cmdline, int strict)
-{
- return(name_match(cmdline->name, strict));
-}
-
-int
-cl_cmd::syntax_ok(class cl_cmdline *cmdline)
-{
- return(1);
-}
-
-int
-cl_cmd::work(class cl_app *app,
- class cl_cmdline *cmdline, class cl_console *con)
-{
- if (!syntax_ok(cmdline))
- return(0);
- 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->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->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->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)));
- return(0);
-}
-
-int
-cl_cmd::do_work(class cl_app *app,
- class cl_cmdline *cmdline, class cl_console *con)
-{
- con->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->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->printf("Command \"%s\" does nothing on microcontroller.\n",
- (char*)(names->at(0)));
- return(0);
-}
-
-
-/*
- * Set of commands
- *____________________________________________________________________________
- */
-
-cl_cmdset::cl_cmdset(void):
- cl_list(5, 5)
-{
- //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)
-{
- int i;
-
- if (cmdline->repeat())
- {
- if (last_command)
- return(last_command);
- else
- return(0);
- }
- // exact match
- for (i= 0; i < count; i++)
- {
- class cl_cmd *c= (class cl_cmd *)at(i);
- if (c->name_match(cmdline, 1))
- return(c);
- }
- // not exact match
- class cl_cmd *c_matched= 0;
- for (i= 0; i < count; i++)
- {
- class cl_cmd *c= (class cl_cmd *)at(i);
- if (c->name_match(cmdline, 0))
- {
- if (!c_matched)
- c_matched= c;
- else
- return(0);
- }
- }
- return(c_matched);
- //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)
-{
- int i;
-
- if (!name)
- return;
- for (i= 0; i < count; i++)
- {
- class cl_cmd *cmd= (class cl_cmd *)(at(i));
- if (cmd->name_match(name, 1))
- free_at(i);
- }
-}
-
-void
-cl_cmdset::replace(char *name, class cl_cmd *cmd)
-{
- int i;
-
- if (!name)
- return;
- for (i= 0; i < count; i++)
- {
- class cl_cmd *c= (class cl_cmd *)(at(i));
- if (c->name_match(name, 1))
- {
- delete c;
- put_at(i, cmd);
- }
- }
-}
+extern "C" int vasprintf(char **strp, const char *format, va_list ap);
+extern "C" int vsnprintf(char *str, size_t size,const char *format,va_list ap);
/*
- * Composed command: subset of commands
- *____________________________________________________________________________
+ * Options of console
*/
-cl_super_cmd::cl_super_cmd(char *aname,
- int can_rep,
- char *short_hlp,
- char *long_hlp,
- class cl_cmdset *acommands):
- cl_cmd(operate_on_none, aname, can_rep, short_hlp, long_hlp)
+cl_prompt_option::cl_prompt_option(class cl_console *console):
+ cl_optref(console)
{
- commands= acommands;
+ con= console;
+}
+
+int
+cl_prompt_option::init(void)
+{
+ char *help;
+ help= format_string("Prompt string of console%d", con->get_id());
+ create(con, string_opt, "prompt", help);
+ //fprintf(stderr," **new prompt option %p\"%s\", value=%p str=%p\n",option,object_name(option),option->get_value(),option->get_value()->sval);
+ free(help);
+ default_option("prompt");
+ //fprintf(stderr,"opt=%p\"%s\" value after default set=%p str=%p\n",option,object_name(option),option->get_value(),option->get_value()->sval);
+ return(0);
}
-cl_super_cmd::~cl_super_cmd(void)
+void
+cl_prompt_option::option_changed(void)
{
- if (commands)
- delete commands;
+ if (!con)
+ return;
+ char *s;
+ option->get_value(&s);
+ con->set_prompt(s);
}
+
+cl_debug_option::cl_debug_option(class cl_console *console):
+ cl_prompt_option(console)
+{}
+
int
-cl_super_cmd::work(class cl_app *app,
- class cl_cmdline *cmdline, class cl_console *con)
+cl_debug_option::init(void)
{
- class cl_cmd *cmd= 0;
+ char *help;
+ help= format_string("Debug messages to console%d", con->get_id());
+ create(con, bool_opt, "debug", help);
+ free(help);
+ default_option("debug");
+ return(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)));
- for (i= 0; i < commands->count; i++)
- {
- cmd= (class cl_cmd *)(commands->at(i));
- con->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)));
- return(0);
- }
- return(cmd->work(app, cmdline, con));
+void
+cl_debug_option::option_changed(void)
+{
+ if (!con)
+ return;
+ bool b;
+ option->get_value(&b);
+ if (b)
+ con->flags|= CONS_DEBUG;
+ else
+ con->flags&= ~CONS_DEBUG;
}
{
FILE *f;
- last_command= NULL;
app= the_app;
in= 0;
if (fin)
- if (f= fopen(fin, "r+"), in= f, !f)
+ if (f= fopen(fin, "r"), in= f, !f)
fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));
out= 0;
if (fout)
- if (f= fopen(fout, "w+"), out= f, !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;
isatty(fileno(in)))
flags|= CONS_INTERACTIVE;
else
- printf("Warning: non-interactive console\n");
+ ;//fprintf(stderr, "Warning: non-interactive console\n");
+ rout= 0;
+ id= 0;
+ lines_printed= new cl_ustrings(100, 100, "console_cache");
}
cl_console::cl_console(FILE *fin, FILE *fout, class cl_app *the_app):
cl_base()
{
- last_command= NULL;
app= the_app;
in = fin;
out= fout;
isatty(fileno(in)))
flags|= CONS_INTERACTIVE;
else
- printf("Warning: non-interactive console\n");
+ ;//fprintf(stderr, "Warning: non-interactive console\n");
+ rout= 0;
+ id= 0;
+ lines_printed= new cl_ustrings(100, 100, "console_cache");
}
/*
{
int sock= connect_to_port(portnumber);
- last_command= NULL;
app= the_app;
- if (!(in= fdopen(sock, "r+")))
+ if (!(in= fdopen(sock, "r")))
fprintf(stderr, "cannot open port for input\n");
- if (!(out= fdopen(sock, "w+")))
+ if (!(out= fdopen(sock, "w")))
fprintf(stderr, "cannot open port for output\n");
//fprintf(stderr, "init socket done\n");
+ id= 0;
+ lines_printed= new cl_ustrings(1, 1, "console_cache");
}
#endif
+class cl_console *
+cl_console::clone_for_exec(char *fin)
+{
+ FILE *fi= 0, *fo= 0;
+
+ if (!fin)
+ return(0);
+ if (fi= fopen(fin, "r"), !fi)
+ {
+ fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));
+ return(0);
+ }
+ if ((fo= fdopen(dup(fileno(out)), "a")) == 0)
+ {
+ fclose(fi);
+ fprintf(stderr, "Can't re-open output file: %s\n", strerror(errno));
+ return(0);
+ }
+ class cl_console *con= new cl_sub_console(this, fi, fo, app);
+ return(con);
+}
+
int
cl_console::init(void)
{
cl_base::init();
+ prompt_option= new cl_prompt_option(this);
+ prompt_option->init();
+ null_prompt_option= new cl_optref(this);
+ null_prompt_option->init();
+ null_prompt_option->use("null_prompt");
+ debug_option= new cl_debug_option(this);
+ debug_option->init();
welcome();
flags&= ~CONS_PROMPT;
- print_prompt();
+ //print_prompt();
+ last_command= 0;
+ last_cmdline= 0;
return(0);
}
{
if (in)
fclose(in);
+ un_redirect();
if (out)
{
- fprintf(out, "\n");
+ if (flags & CONS_PROMPT)
+ fprintf(out, "\n");
fflush(out);
fclose(out);
}
+ delete prompt_option;
+ delete null_prompt_option;
+ delete debug_option;
#ifdef SOCKET_AVAIL
/* if (sock)
{
}
+bool
+cl_console::accept_last(void)
+{
+ if (!in)
+ return(DD_FALSE);
+ if (isatty(fileno(in)))
+ return(DD_TRUE);
+ return(DD_FALSE);
+}
+
+
/*
* Output functions
*/
void
cl_console::welcome(void)
{
- if (!out)
+ FILE *Out= rout?rout:out;
+
+ if (!Out ||
+ (flags & CONS_NOWELCOME))
return;
- fprintf(out, "uCsim %s, Copyright (C) 1997 Daniel Drotos, Talker Bt.\n"
+ 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",
VERSIONSTR);
- fflush(out);
+ fflush(Out);
+}
+
+void
+cl_console::redirect(char *fname, char *mode)
+{
+ if ((rout= fopen(fname, mode)) == NULL)
+ dd_printf("Unable to open file '%s' for %s: %s\n",
+ fname, (mode[0]=='w')?"write":"append", strerror(errno));
+}
+
+void
+cl_console::un_redirect(void)
+{
+ if (!rout)
+ return;
+ fclose(rout);
+ rout= NULL;
+}
+
+
+int
+cl_console::cmd_do_print(FILE *f, char *format, va_list ap)
+{
+ int ret;
+#ifdef HAVE_VASPRINTF
+ char *msg= NULL;
+ vasprintf(&msg, format, ap);
+ ret= fprintf(f, "%s", msg);
+ free(msg);
+#else
+# ifdef HAVE_VSNPRINTF
+ char msg[80*25];
+ vsnprintf(msg, 80*25, format, ap);
+ ret= fprintf(f, "%s", msg);
+# else
+# ifdef HAVE_VPRINTF
+ char msg[80*25];
+ vsprintf(msg, format, ap); /* Dangerous */
+ ret= fprintf(f, "%s", msg);
+# else
+# ifdef HAVE_DOPRNT
+ /* ??? */
+ /*strcpy(msg, "Unimplemented printf has called.\n");*/
+# else
+ /*strcpy(msg, "printf can not be implemented, upgrade your libc.\n");*/
+# endif
+# endif
+# endif
+#endif
+ fflush(f);
+ return(ret);
}
void
cl_console::print_prompt(void)
{
- char *p;
+ //char *p;
+ FILE *Out= rout?rout:out;
- if (flags & (CONS_PROMPT|CONS_FROZEN))
+ if (flags & (CONS_PROMPT|CONS_FROZEN|CONS_INACTIVE))
return;
flags|= CONS_PROMPT;
- if (!out)
+ if (!Out)
return;
- if (app->args->arg_avail('P'))
- putc('\0', out);
+ if (/*app->args->arg_avail('P')*/null_prompt_option->get_value(bool(0)))
+ putc('\0', Out);
else
- fprintf(out, "%s", (prompt && prompt[0])?prompt:
- ((p= app->args->get_sarg(0, "prompt"))?p:"> "));
- fflush(out);
+ {
+ fprintf(Out, "%d", id);
+ fprintf(Out, "%s", (prompt && prompt[0])?prompt:"> ");
+ // ((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;
+ FILE *Out= rout?rout:out;
- if (out)
+ if (Out)
+ {
+ va_start(ap, format);
+ ret= cmd_do_print(Out, format, ap);
+ va_end(ap);
+ }
+ return(ret);
+}
+
+int
+cl_console::debug(char *format, ...)
+{
+ if ((flags & CONS_DEBUG) == 0)
+ return(0);
+
+ va_list ap;
+ int ret= 0;
+ FILE *Out= rout?rout:out;
+
+ if (Out)
{
va_start(ap, format);
- ret= cmd_do_print(out, format, ap);
+ ret= cmd_do_print(Out, format, ap);
va_end(ap);
}
return(ret);
cl_console::print_bin(long data, int bits)
{
long mask= 1;
+ FILE *Out= rout?rout:out;
- if (!out)
+ if (!Out)
return;
mask= mask << ((bits >= 1)?(bits-1):0);
while (bits--)
{
- fprintf(out, "%c", (data&mask)?'1':'0');
+ fprintf(Out, "%c", (data&mask)?'1':'0');
mask>>= 1;
}
}
+void
+cl_console::print_char_octal(char c)
+{
+ FILE *Out= rout?rout:out;
+
+ if (Out)
+ ::print_char_octal(c, Out);
+}
+
+
/*
* Input functions
*/
int
cl_console::get_in_fd(void)
{
+ if (flags & CONS_INACTIVE)
+ return(-2);
return(in?fileno(in):-1);
}
{
int retval= 0;
+ un_redirect();
if (feof(in))
{
fprintf(out, "End\n");
}
else
{
- 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);
+ if (cmdstr &&
+ *cmdstr == '\004')
+ retval= 1;
+ else
+ {
+ class cl_cmdline *cmdline= 0;
+ class cl_cmd *cm= 0;
+ if (flags & CONS_ECHO)
+ dd_printf("%s\n", cmdstr);
+ cmdline= new cl_cmdline(app, cmdstr, this);
+ cmdline->init();
+ if (cmdline->repeat() &&
+ accept_last() &&
+ last_command)
+ {
+ cm= last_command;
+ delete cmdline;
+ cmdline= last_cmdline;
+ }
+ else
+ {
+ cm= cmdset->get_cmd(cmdline, accept_last());
+ if (last_cmdline)
+ {
+ delete last_cmdline;
+ last_cmdline= 0;
+ }
+ last_command= 0;
+ }
+ if (cm)
+ {
+ retval= cm->work(app, cmdline, this);
+ if (cm->can_repeat)
+ {
+ last_command= cm;
+ last_cmdline= cmdline;
+ }
+ else
+ delete cmdline;
+ }
+ else
+ {
+ class YY_cl_ucsim_parser_CLASS *pars;
+ class cl_ucsim_lexer *lexer;
+ lexer= new cl_ucsim_lexer(cmdstr);
+ pars= new YY_cl_ucsim_parser_CLASS(lexer);
+ pars->yyparse();
+ delete cmdline;
+ delete pars;
+ }
+ /*if (!cm)
+ retval= interpret(cmdstr);*/
+ }
}
//retval= sim->do_cmd(cmd, this);
- if (!retval)
- print_prompt();
+ un_redirect();
+ /*if (!retval)
+ print_prompt();*/
free(cmdstr);
return(retval);
}
int
cl_console::interpret(char *cmd)
{
- fprintf(out, "Unknown command\n");
+ FILE *Out= rout?rout:out;
+
+ fprintf(Out, "Unknown command\n");
return(0);
}
+void
+cl_console::set_id(int new_id)
+{
+ char *s;
+
+ id= new_id;
+ set_name(s= format_string("console%d", id));
+ free(s);
+}
+
+void
+cl_console::set_prompt(char *p)
+{
+ if (prompt)
+ free(prompt);
+ if (p &&
+ *p)
+ prompt= strdup(p);
+ else
+ prompt= 0;
+}
+
/*
* This console listen on a socket and can accept connection requests
cl_listen_console::cl_listen_console(int serverport, class cl_app *the_app)
{
- last_command= NULL;
app= the_app;
if ((sock= make_server_socket(serverport)) >= 0)
{
#endif /* SOCKET_AVAIL */
+/*
+ * Sub-console
+ */
+
+cl_sub_console::cl_sub_console(class cl_console *the_parent,
+ FILE *fin, FILE *fout, class cl_app *the_app):
+ cl_console(fin, fout, the_app)
+{
+ parent= the_parent;
+}
+
+cl_sub_console::~cl_sub_console(void)
+{
+ class cl_commander *c= app->get_commander();
+
+ if (parent && c)
+ {
+ c->activate_console(parent);
+ }
+}
+
+int
+cl_sub_console::init(void)
+{
+ class cl_commander *c= app->get_commander();
+
+ if (parent && c)
+ {
+ c->deactivate_console(parent);
+ }
+ cl_console::init();
+ flags|= CONS_ECHO;
+ return(0);
+}
+
+
/*
* Command interpreter
*____________________________________________________________________________
cl_base()
{
app= the_app;
- cons= new cl_list(1, 1);
+ cons= new cl_list(1, 1, "consoles");
actual_console= frozen_console= 0;
cmdset= acmdset;
}
int
cl_commander::init(void)
{
- cl_base::init();
+ class cl_optref console_on_option(this);
+ class cl_optref config_file_option(this);
+ class cl_optref port_number_option(this);
+ class cl_console *con;
- char *Config= app->args->get_sarg(0, "Config");
- if (Config)
- {
- class cl_console *con= mk_console(0/*"/dev/tty"*/);
- add_console(con);
- }
+ console_on_option.init();
+ console_on_option.use("console_on");
+ config_file_option.init();
+ config_file_option.use("config_file");
+ port_number_option.init();
+
+ cl_base::init();
+ set_name("Commander");
+
+ bool need_config= DD_TRUE;
- 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 (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)));
+ if (port_number_option.use("port_number"))
+ add_console(mk_console(port_number_option.get_value((long)0)));
#endif
+
+ char *Config= config_file_option.get_value(Config);
+ char *cn= console_on_option.get_value(cn);
+
+ if (cn)
+ {
+ add_console(con= mk_console(cn, cn));
+ exec_on(con, Config);
+ need_config= DD_FALSE;
+ }
if (cons->get_count() == 0)
- add_console(mk_console(stdin, stdout));
+ {
+ add_console(con= mk_console(stdin, stdout));
+ exec_on(con, Config);
+ need_config= DD_FALSE;
+ }
+ if (need_config)
+ {
+ FILE *fc= fopen(Config, "r");
+ if (!fc)
+ fprintf(stderr, "Can't open `%s': %s\n", Config, strerror(errno));
+ else
+ {
+ con= mk_console(fc, stderr);
+ con->flags|= CONS_NOWELCOME|CONS_ECHO;
+ add_console(con);
+ }
+ }
return(0);
}
void
cl_commander::add_console(class cl_console *console)
{
+ if (!console)
+ return;
+ int i=cons->add(console);
+ console->set_id(i);
console->init();
- cons->add(console);
set_fd_set();
}
set_fd_set();
}
+void
+cl_commander::activate_console(class cl_console *console)
+{
+ console->flags&= ~CONS_INACTIVE;
+ //console->print_prompt();
+ set_fd_set();
+}
+
+void
+cl_commander::deactivate_console(class cl_console *console)
+{
+ console->flags|= CONS_INACTIVE;
+ set_fd_set();
+}
+
void
cl_commander::set_fd_set(void)
{
for (i= 0; i < cons->count; i++)
{
class cl_console *c= (class cl_console*)(cons->at(i));
- if (c->out)
+ FILE *Out= c->get_out();
+ if (Out)
{
va_start(ap, format);
- ret= cmd_do_print(c->out, format, ap);
+ ret= c->cmd_do_print(Out, format, ap);
va_end(ap);
}
}
return(ret);
}
+void
+cl_commander::prompt(void)
+{
+ int i;
+
+ for (i= 0; i < cons->count; i++)
+ {
+ class cl_console *c= (class cl_console*)(cons->at(i));
+ c->print_prompt();
+ }
+}
+
int
cl_commander::all_print(char *string, int length)
{
for (i= 0; i < cons->count; i++)
{
class cl_console *c= (class cl_console*)(cons->at(i));
- if (c->out)
+ FILE *Out= c->get_out();
+ if (Out)
{
for (int j= 0; j < length; j++)
- putc(string[j], c->out);
+ putc(string[j], Out);
}
}
return(0);
*/
int
-cl_commander::printf(char *format, ...)
+cl_commander::dd_printf(char *format, ...)
{
va_list ap;
int ret= 0;
+ FILE *f;
+ class cl_console *con;
- if (actual_console &&
- actual_console->out)
+ if (actual_console)
+ {
+ f= actual_console->get_out();
+ con= actual_console;
+ }
+ else if (frozen_console)
+ {
+ f= frozen_console->get_out();
+ con= frozen_console;
+ }
+ else
+ {
+ f= 0;
+ con= 0;
+ }
+ if (/*actual_console &&
+ actual_console->out*/f &&
+ con)
{
va_start(ap, format);
- ret= cmd_do_print(actual_console->out, format, ap);
+ ret= con->cmd_do_print(f/*actual_console->out*/, format, ap);
va_end(ap);
}
return(ret);
}
+int
+cl_commander::dd_printf(char *format, va_list ap)
+{
+ int ret= 0;
+ FILE *f;
+ class cl_console *con;
+
+ if (actual_console)
+ {
+ f= actual_console->get_out();
+ con= actual_console;
+ }
+ else if (frozen_console)
+ {
+ f= frozen_console->get_out();
+ con= frozen_console;
+ }
+ else
+ {
+ f= 0;
+ con= 0;
+ }
+ if (/*actual_console &&
+ actual_console->out*/f &&
+ con)
+ {
+ ret= con->cmd_do_print(f/*actual_console->out*/, format, ap);
+ }
+ return(ret);
+}
+
/*
* Printing to consoles which have CONS_DEBUG flag set
*/
for (i= 0; i < cons->count; i++)
{
class cl_console *c= (class cl_console*)(cons->at(i));
- if (c->out &&
+ FILE *Out= c->get_out();
+ if (Out &&
c->flags & CONS_DEBUG)
{
va_start(ap, format);
- ret= cmd_do_print(c->out, format, ap);
+ ret= c->cmd_do_print(Out, format, ap);
va_end(ap);
}
}
return(ret);
}
+int
+cl_commander::debug(char *format, va_list ap)
+{
+ int i, ret= 0;
+
+ for (i= 0; i < cons->count; i++)
+ {
+ class cl_console *c= (class cl_console*)(cons->at(i));
+ FILE *Out= c->get_out();
+ if (Out &&
+ c->flags & CONS_DEBUG)
+ {
+ ret= c->cmd_do_print(Out, format, ap);
+ }
+ }
+ return(ret);
+}
+
int
cl_commander::flag_printf(int iflags, char *format, ...)
{
for (i= 0; i < cons->count; i++)
{
class cl_console *c= (class cl_console*)(cons->at(i));
- if (c->out &&
+ FILE *Out= c->get_out();
+ if (Out &&
(c->flags & iflags) == iflags)
{
va_start(ap, format);
- ret= cmd_do_print(c->out, format, ap);
+ ret= c->cmd_do_print(Out, format, ap);
va_end(ap);
}
}
int i;
active_set= read_set;
+ prompt();
i= select(fd_num, &active_set, NULL, NULL, NULL);
return(i);
}
return(0);
}
+void
+cl_commander::exec_on(class cl_console *cons, char *file_name)
+{
+ FILE *fi= fopen(file_name, "r");
+
+ if (!cons ||
+ !fi)
+ return;
+ class cl_console *subcon= cons->clone_for_exec(file_name);
+ subcon->flags|= CONS_NOWELCOME;
+ add_console(subcon);
+}
+
/* End of cmd.src/newcmd.cc */