X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=sim%2Fucsim%2Fcmd.src%2Fnewcmd.cc;h=cf32c05c4f610af5932f7eb0d0be499334679f8e;hb=f27da39dbcab5678aca6d8462f1cc37a643f37e9;hp=c1ca1db61f3281cb81d2a209f7b50f4f0ce422f0;hpb=f27cbdc6513b26748661452e50ed3af99fac16a2;p=fw%2Fsdcc diff --git a/sim/ucsim/cmd.src/newcmd.cc b/sim/ucsim/cmd.src/newcmd.cc index c1ca1db6..cf32c05c 100644 --- a/sim/ucsim/cmd.src/newcmd.cc +++ b/sim/ucsim/cmd.src/newcmd.cc @@ -45,12 +45,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #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" @@ -60,676 +65,67 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 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 - *____________________________________________________________________________ + * Options of console */ -cl_cmdline::cl_cmdline(char *acmd, class cl_console *acon) -{ - 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) +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(); +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); } -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 != '"') - { - 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(con->sim->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= con->sim->mk_cmd_int_arg((long long) - strtol(param_str, 0, 0)); - else - sfr= con->sim->mk_cmd_sym_arg(param_str); - if (*dot == '\0') - { - bit= 0; - con->printf("Uncomplete bit address\n"); - delete sfr; - } - else - { - if (strchr("0123456789", *dot) != NULL) - bit= con->sim->mk_cmd_int_arg((long long) - strtol(dot, 0, 0)); - else - bit= con->sim->mk_cmd_sym_arg(dot); - params->add(con->sim->mk_cmd_bit_arg(sfr, bit)); - } - } - else if ((dot= strchr(param_str, '[')) != NULL) - { - // array - class cl_cmd_arg *aname, *aindex; - *dot= '\0'; - dot++; - if (strchr("0123456789", *param_str) != NULL) - aname= con->sim->mk_cmd_int_arg((long long) - strtol(param_str, 0, 0)); - else - aname= con->sim->mk_cmd_sym_arg(param_str); - 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= con->sim->mk_cmd_int_arg((long long) - strtol(dot, 0, 0)); - else - aindex= con->sim->mk_cmd_sym_arg(dot); - params->add(con->sim->mk_cmd_array_arg(aname, aindex)); - } - } - } - else if (strchr("0123456789", *param_str) != NULL) - { - // number - params->add(con->sim->mk_cmd_int_arg((long long) - strtol(param_str, 0, 0))); - } - else - { - // symbol - params->add(con->sim->mk_cmd_sym_arg(param_str)); - } - 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_sim *sim, char *syntax) +cl_prompt_option::option_changed(void) { - 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()) - 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()) - return(DD_FALSE); - //printf("MEMORY match %s\n",parm->value.memory->class_name); - break; - case SY_HW: - if (!parm->as_hw(sim->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(sim->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, - 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) -{ - 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)); + if (!con) + return; + char *s; + option->get_value(&s); + con->set_prompt(s); } -int -cl_cmd::syntax_ok(class cl_cmdline *cmdline) -{ - return(1); -} -int -cl_cmd::work(class cl_sim *sim, - class cl_cmdline *cmdline, class cl_console *con) -{ - if (!syntax_ok(cmdline)) - return(0); - return(do_work(sim, cmdline, con)); -} +cl_debug_option::cl_debug_option(class cl_console *console): + cl_prompt_option(console) +{} int -cl_cmd::do_work(class cl_sim *sim, - class cl_cmdline *cmdline, class cl_console *con) -{ - con->printf("Command \"%s\" does nothing.\n", (char*)(names->at(0))); - 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); -} - -class cl_cmd * -cl_cmdset::get_cmd(char *cmd_name) +cl_debug_option::init(void) { - 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); - } + 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); } 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(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_sim *sim, - class cl_cmdline *cmdline, class cl_console *con) -{ - class cl_cmd *cmd= 0; - - if (!commands) - return(0); - - if (!cmdline->shift()) - { - if ((cmd= commands->get_cmd("_no_parameters_")) != 0) - return(cmd->work(sim, 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(sim, cmdline, con)); + bool b; + option->get_value(&b); + if (b) + con->flags|= CONS_DEBUG; + else + con->flags&= ~CONS_DEBUG; } @@ -738,20 +134,19 @@ cl_super_cmd::work(class cl_sim *sim, *____________________________________________________________________________ */ -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; + 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; @@ -759,14 +154,16 @@ cl_console::cl_console(char *fin, char *fout, class cl_sim *asim): 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_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; @@ -775,7 +172,10 @@ cl_console::cl_console(FILE *fin, FILE *fout, class cl_sim *asim): 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"); } /* @@ -801,27 +201,59 @@ connect_to_port(int portnum) 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); } @@ -829,12 +261,17 @@ cl_console::~cl_console(void) { 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) { @@ -845,6 +282,17 @@ cl_console::~cl_console(void) } +bool +cl_console::accept_last(void) +{ + if (!in) + return(DD_FALSE); + if (isatty(fileno(in))) + return(DD_TRUE); + return(DD_FALSE); +} + + /* * Output functions */ @@ -852,45 +300,123 @@ cl_console::~cl_console(void) 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" - "ucsim comes with ABSOLUTELY NO WARRANTY; for details type " + 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); @@ -900,17 +426,28 @@ void 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 */ @@ -927,6 +464,8 @@ cl_console::match(int fdnum) int cl_console::get_in_fd(void) { + if (flags & CONS_INACTIVE) + return(-2); return(in?fileno(in):-1); } @@ -988,6 +527,7 @@ cl_console::proc_input(class cl_cmdset *cmdset) { int retval= 0; + un_redirect(); if (feof(in)) { fprintf(out, "End\n"); @@ -998,26 +538,70 @@ cl_console::proc_input(class cl_cmdset *cmdset) return(1); if (flags & CONS_FROZEN) { - sim->stop(resUSER); + app->get_sim()->stop(resUSER); flags&= ~CONS_FROZEN; retval= 0; } else { - class cl_cmdline *cmdline; - class cl_cmd *cm; - cmdline= new cl_cmdline(cmdstr, this); - cmdline->init(); - cm= cmdset->get_cmd(cmdline); - if (cm) - retval= cm->work(sim, 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); } @@ -1030,20 +614,43 @@ cl_console::proc_input(class cl_cmdset *cmdset) 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) @@ -1071,7 +678,9 @@ 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) @@ -1083,10 +692,9 @@ cl_listen_console::proc_input(class cl_cmdset *cmdset) fprintf(stderr, "cannot open port for input\n"); if (!(out= fdopen(newsock, "w+"))) fprintf(stderr, "cannot open port for output\n"); - class cl_console *c= sim->cmd->mk_console(in, out, sim); + class cl_console *c= cmd->mk_console(in, out); c->flags|= CONS_INTERACTIVE; - c->init(); - sim->cmd->add_console(c); + cmd->add_console(c); in= out= 0; return(0); } @@ -1094,37 +702,108 @@ cl_listen_console::proc_input(class cl_cmdset *cmdset) #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_cmdset *acmdset, 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; cmdset= acmdset; - sim= asim; } 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); } @@ -1135,30 +814,33 @@ cl_commander::~cl_commander(void) } 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(); } @@ -1169,6 +851,21 @@ cl_commander::del_console(class cl_console *console) 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) { @@ -1211,16 +908,29 @@ cl_commander::all_printf(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) { 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) { @@ -1229,10 +939,11 @@ 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); @@ -1243,21 +954,70 @@ cl_commander::all_print(char *string, int length) */ 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 */ @@ -1271,17 +1031,36 @@ cl_commander::debug(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 & 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, ...) { @@ -1291,11 +1070,12 @@ 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); } } @@ -1333,6 +1113,7 @@ cl_commander::wait_input(void) int i; active_set= read_set; + prompt(); i= select(fd_num, &active_set, NULL, NULL, NULL); return(i); } @@ -1367,5 +1148,18 @@ cl_commander::proc_input(void) 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 */