/*
- * Simulator of microcontrollers (newcmd.cc)
+ * Simulator of microcontrollers (cmd.src/newcmd.cc)
*
* Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
*
#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 "argcl.h"
+#include "appcl.h"
// local
#include "newcmdcl.h"
#include "cmdutil.h"
-extern "C" int vasprintf();
-extern "C" int vsnprintf();
-
-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);
-}
+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);
/*
- * Command line
- *____________________________________________________________________________
+ * Options of console
*/
-cl_cmdline::cl_cmdline(char *acmd)
-{
- cmd= strdup(acmd);
- params= new cl_list(2, 2);
- tokens= new cl_ustrings(2, 2);
- name= 0;
-}
-
-cl_cmdline::~cl_cmdline(void)
+cl_prompt_option::cl_prompt_option(class cl_console *console):
+ cl_optref(console)
{
- if (cmd)
- free(cmd);
- if (name)
- free(name);
- delete params;
- delete tokens;
+ con= console;
}
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)
-{
- char *start= cmd;
- int i;
-
- 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 != '"')
- end++;
- if (*end == '"')
- end--;
- else
- simulator->cmd->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));
- 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= simulator->mk_cmd_int_arg((long long)
- strtol(param_str, 0, 0));
- else
- sfr= simulator->mk_cmd_sym_arg(param_str);
- if (*dot == '\0')
- {
- bit= 0;
- simulator->cmd->printf("Uncomplete bit address\n");
- }
- else
- {
- if (strchr("0123456789", *dot) != NULL)
- bit= simulator->mk_cmd_int_arg((long long)
- strtol(dot, 0, 0));
- else
- bit= simulator->mk_cmd_sym_arg(dot);
- }
- 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)));
- }
- else
- {
- // symbol
- params->add(simulator->mk_cmd_sym_arg(param_str));
- }
- free(param_str);
- }
- start= end;
- start= skip_delims(start);
- }
+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);
}
-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);
-}
-
-
-/*
- * Command
- *____________________________________________________________________________
- */
-
-cl_cmd::cl_cmd(class cl_sim *asim,
- char *aname,
- int can_rep,
- char *short_hlp,
- char *long_hlp):
- cl_base()
-{
- sim= asim;
- 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)
+cl_prompt_option::option_changed(void)
{
- 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);
+ if (!con)
+ return;
+ char *s;
+ option->get_value(&s);
+ con->set_prompt(s);
}
-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);
-}
+cl_debug_option::cl_debug_option(class cl_console *console):
+ cl_prompt_option(console)
+{}
int
-cl_cmd::work(class cl_cmdline *cmdline, class cl_console *con)
+cl_debug_option::init(void)
{
- if (!syntax_ok(cmdline))
- return(0);
- 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)));
+ 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);
}
-
-/*
- * Set of commands
- *____________________________________________________________________________
- */
-
-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);
-}
-
-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)
+cl_debug_option::option_changed(void)
{
- int i;
-
- if (!name)
+ if (!con)
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);
- }
- }
-}
-
-
-/*
- * Composed command: subset of commands
- *____________________________________________________________________________
- */
-
-cl_super_cmd::cl_super_cmd(class cl_sim *asim,
- 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)
-{
- commands= acommands;
-}
-
-cl_super_cmd::~cl_super_cmd(void)
-{
- if (commands)
- delete commands;
-}
-
-int
-cl_super_cmd::work(class cl_cmdline *cmdline, class cl_console *con)
-{
- class cl_cmd *cmd;
-
- if (!commands)
- return(0);
-
- if (!cmdline->shift())
- {
- 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(cmdline, con));
+ bool b;
+ option->get_value(&b);
+ if (b)
+ con->flags|= CONS_DEBUG;
+ else
+ con->flags&= ~CONS_DEBUG;
}
*____________________________________________________________________________
*/
-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
+ ;//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_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
+ ;//fprintf(stderr, "Warning: non-interactive console\n");
+ rout= 0;
+ id= 0;
+ lines_printed= new cl_ustrings(100, 100, "console_cache");
}
/*
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;
- if (!(in= fdopen(sock, "r+")))
+ app= the_app;
+ 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)
{
- fprintf(out,
- "ucsim %s, Copyright (C) 1997 Daniel Drotos, Talker Bt.\n"
- "ucsim comes with ABSOLUTELY NO WARRANTY; for details type "
+ FILE *Out= rout?rout:out;
+
+ if (!Out ||
+ (flags & CONS_NOWELCOME))
+ 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",
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 (sim->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= sim->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
-cl_console::proc_input(void)
+cl_console::proc_input(class cl_cmdset *cmdset)
{
- int retval;
+ int retval= 0;
+ un_redirect();
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);
- if (!retval)
- print_prompt();
- free(cmd);
+ {
+ 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);
+ un_redirect();
+ /*if (!retval)
+ print_prompt();*/
+ 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");
+ 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
*/
#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);
}
#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_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()
{
- cons= new cl_list(1, 1);
+ app= the_app;
+ cons= new cl_list(1, 1, "consoles");
actual_console= frozen_console= 0;
- sim= asim;
+ cmdset= acmdset;
}
int
cl_commander::init(void)
{
+ 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;
+
+ 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();
- if (!sim)
- return(1);
- if (sim->arg_avail('c'))
- add_console(mk_console(sim->get_sarg('c', 0),
- sim->get_sarg('c', 0), sim));
+ set_name("Commander");
+
+ bool need_config= DD_TRUE;
+
#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 (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, sim));
+ {
+ 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);
}
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
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)
{
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++;
}
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);
}
}
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);
+ prompt();
+ 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);
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 newcmd.cc */
+/* End of cmd.src/newcmd.cc */