X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=sim%2Fucsim%2Fcmd.src%2Fnewcmd.cc;h=4717409eaf72fdb037af51559a84c086b1da680f;hb=c1eaba671c4e92256210763db2c0bd062deace1d;hp=6b1001f5d8996658fe5991b2b0c50362dc312414;hpb=cf31e5693118709ef0ae23e9d3fd44e89a70e7a4;p=fw%2Fsdcc diff --git a/sim/ucsim/cmd.src/newcmd.cc b/sim/ucsim/cmd.src/newcmd.cc index 6b1001f5..4717409e 100644 --- a/sim/ucsim/cmd.src/newcmd.cc +++ b/sim/ucsim/cmd.src/newcmd.cc @@ -1,5 +1,5 @@ /* - * Simulator of microcontrollers (newcmd.cc) + * Simulator of microcontrollers (cmd.src/newcmd.cc) * * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. * @@ -32,499 +32,100 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include #include -#ifdef HAVE_SYS_SOCKET_H -# include -# include -# include -# include -#endif #include +#ifdef SOCKET_AVAIL +# include HEADER_SOCKET +# if defined HAVE_SYS_SOCKET_H +# include +# include +# include +# endif +#endif #if FD_HEADER_OK # include HEADER_FD #endif -#include +#ifdef HAVE_UNISTD_H +# include +#endif #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); -} - - /* - * 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) -{ - 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) +cl_prompt_option::cl_prompt_option(class cl_console *console): + cl_optref(console) { - while (*start && - strchr(" \t\v\r,", *start)) - start++; - return(start); + con= console; } int -cl_cmdline::split(void) +cl_prompt_option::init(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); - } + 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); -} - -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_cmdline *cmdline, class cl_console *con) -{ - if (!syntax_ok(cmdline)) - return(0); - return(do_work(cmdline, con)); -} +cl_debug_option::cl_debug_option(class cl_console *console): + cl_prompt_option(console) +{} int -cl_cmd::do_work(class cl_cmdline *cmdline, class cl_console *con) +cl_debug_option::init(void) { - 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) +cl_debug_option::option_changed(void) { - int i; - - if (!name) + if (!con) 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); - } - } -} - - -/* - * 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; } @@ -533,31 +134,48 @@ cl_super_cmd::work(class cl_cmdline *cmdline, class cl_console *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 + ;//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"); } /* @@ -583,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); } @@ -611,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) { @@ -627,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 */ @@ -634,46 +300,100 @@ cl_console::~cl_console(void) 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 " - "`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); + if (!(flags & CONS_NOWELCOME)) + { + dd_printf("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); + } } void -cl_console::print_prompt(void) +cl_console::redirect(char *fname, char *mode) { - char *p; + 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)); +} - if (flags & (CONS_PROMPT|CONS_FROZEN)) +void +cl_console::un_redirect(void) +{ + if (!rout) return; - flags|= CONS_PROMPT; - if (!out) + fclose(rout); + rout= NULL; +} + + +int +cl_console::cmd_do_print(char *format, va_list ap) +{ + int ret; + FILE *f = get_out(); + + if (f) + { + ret= vfprintf(f, format, ap); + fflush(f); + } + else + ret= 0; + + return(ret); +} + +void +cl_console::print_prompt(void) +{ + if (flags & (CONS_PROMPT|CONS_FROZEN|CONS_INACTIVE)) return; - if (sim->arg_avail('P')) - putc('\0', out); + flags|= CONS_PROMPT; + if (/*app->args->arg_avail('P')*/null_prompt_option->get_value(bool(0))) + { + FILE *Out = get_out(); + if (Out) + { + putc('\0', Out); + fflush(Out); + } + } else - fprintf(out, "%s", prompt?prompt: - ((p= sim->get_sarg(0, "prompt"))?p:"> ")); - fflush(out); + { + dd_printf("%d%s", id, (prompt && prompt[0])?prompt:"> "); + // ((p= app->args->get_sarg(0, "prompt"))?p:"> ")); + } } int -cl_console::printf(char *format, ...) +cl_console::dd_printf(char *format, ...) { va_list ap; int ret= 0; - if (out) - { - va_start(ap, format); - ret= cmd_do_print(out, format, ap); - va_end(ap); - } + va_start(ap, format); + ret= cmd_do_print(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; + + va_start(ap, format); + ret= cmd_do_print(format, ap); + va_end(ap); + return(ret); } @@ -682,32 +402,33 @@ cl_console::print_bin(long data, int bits) { long mask= 1; - if (!out) - return; mask= mask << ((bits >= 1)?(bits-1):0); while (bits--) { - fprintf(out, "%c", (data&mask)?'1':'0'); + dd_printf("%c", (data&mask)?'1':'0'); mask>>= 1; } } +void +cl_console::print_char_octal(char c) +{ + FILE *Out= get_out(); + + if (Out) + ::print_char_octal(c, Out); +} + + /* * Input functions */ -int -cl_console::match(int fdnum) -{ - if (in && - fileno(in) == fdnum) - return(1); - return(0); -} - int cl_console::get_in_fd(void) { + if (flags & CONS_INACTIVE) + return(-2); return(in?fileno(in):-1); } @@ -715,7 +436,7 @@ int cl_console::input_avail(void) { struct timeval tv; - int i; + UCSOCKET_T i; if ((i= get_in_fd()) < 0) return(0); @@ -735,9 +456,7 @@ cl_console::read_line(void) #ifdef HAVE_GETLINE if (getline(&s, 0, in) < 0) return(0); -#else - -# ifdef HAVE_GETDELIM +#elif defined HAVE_GETDELIM size_t n= 30; s= (char *)malloc(n); if (getdelim(&s, &n, '\n', in) < 0) @@ -745,17 +464,13 @@ cl_console::read_line(void) free(s); return(0); } -# else - -# ifdef HAVE_FGETS +#elif defined HAVE_FGETS s= (char *)malloc(300); if (fgets(s, 300, in) == NULL) { free(s); return(0); } -# endif -# endif #endif s[strlen(s)-1]= '\0'; if (s[strlen(s)-1] == '\r') @@ -765,69 +480,141 @@ cl_console::read_line(void) } 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"); + dd_printf("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) - fprintf(stderr, "Listen on port %d: %s\n", - serverport, strerror(errno)); + fprintf(stderr, "Listen on port %d: %s\n", + serverport, strerror(errno)); } in= out= 0; } -int -cl_listen_console::match(int fdnum) -{ - return(sock == fdnum); -} - int cl_listen_console::get_in_fd(void) { @@ -835,12 +622,14 @@ cl_listen_console::get_in_fd(void) } int -cl_listen_console::proc_input(void) +cl_listen_console::proc_input(class cl_cmdset *cmdset) { int newsock; - uint size; + 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) @@ -852,7 +641,9 @@ cl_listen_console::proc_input(void) 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); } @@ -860,43 +651,119 @@ cl_listen_console::proc_input(void) #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')) + if (port_number_option.use("port_number")) + add_console(mk_console(port_number_option.get_value((long)0))); +#endif + + /* The following code is commented out because it produces gcc warnings + * newcmd.cc: In member function `virtual int cl_commander::init()': + * newcmd.cc:785: warning: 'Config' might be used uninitialized in this function + * newcmd.cc:786: warning: 'cn' might be used uninitialized in this function + */ + /* + char *Config= config_file_option.get_value(Config); + char *cn= console_on_option.get_value(cn); + */ + /* Here shoud probably be something else, but is still better then the former code... */ + char *Config= config_file_option.get_value(""); + char *cn= console_on_option.get_value(""); + + if (cn) { - add_console(mk_console(sim->get_iarg(0, "Zport"), sim)); + add_console(con= mk_console(cn, cn)); + exec_on(con, Config); + need_config= DD_FALSE; } - if (sim->arg_avail('r')) + if (cons->get_count() == 0) { - add_console(mk_console(sim->get_iarg('r', 0), sim)); + add_console(con= mk_console(stdin, stdout)); + exec_on(con, Config); + need_config= DD_FALSE; } -#endif - if (cons->get_count() == 0) + if (need_config && + Config && + *Config) { - add_console(mk_console(stdin, stdout, sim)); + 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); } @@ -904,33 +771,37 @@ cl_commander::init(void) 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(); } @@ -941,23 +812,45 @@ 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) { int i; - + + //fprintf(stderr, "** Setting fd set\n"); FD_ZERO(&read_set); fd_num= 0; for (i= 0; i < cons->count; i++) { - int fd; + UCSOCKET_T fd; 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++; } @@ -976,33 +869,65 @@ 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) - { - va_start(ap, format); - ret= cmd_do_print(c->out, format, ap); - va_end(ap); - } + + va_start(ap, format); + ret= c->cmd_do_print(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(); + } +} + /* * Printing to actual_console */ int -cl_commander::printf(char *format, ...) +cl_commander::dd_printf(char *format, va_list ap) { - va_list ap; int ret= 0; + class cl_console *con; - if (actual_console && - actual_console->out) + if (actual_console) { - va_start(ap, format); - ret= cmd_do_print(actual_console->out, format, ap); - va_end(ap); + con= actual_console; + } + else if (frozen_console) + { + con= frozen_console; + } + else + { + con= 0; } + if (con) + { + ret= con->cmd_do_print(format, ap); + } + return(ret); +} + +int +cl_commander::dd_printf(char *format, ...) +{ + va_list ap; + int ret= 0; + + va_start(ap, format); + ret= dd_printf(format, ap); + va_end(ap); + return(ret); } @@ -1019,13 +944,28 @@ 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 && - c->flags & CONS_DEBUG) - { - va_start(ap, format); - ret= cmd_do_print(c->out, format, ap); - va_end(ap); - } + if (c->flags & CONS_DEBUG) + { + va_start(ap, format); + ret= c->cmd_do_print(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)); + if (c->flags & CONS_DEBUG) + { + ret= c->cmd_do_print(format, ap); + } } return(ret); } @@ -1039,13 +979,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 && - (c->flags & iflags) == iflags) - { - va_start(ap, format); - ret= cmd_do_print(c->out, format, ap); - va_end(ap); - } + if ((c->flags & iflags) == iflags) + { + va_start(ap, format); + ret= c->cmd_do_print(format, ap); + va_end(ap); + } } return(ret); } @@ -1058,15 +997,20 @@ cl_commander::input_avail(void) 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()); } @@ -1076,39 +1020,47 @@ cl_commander::wait_input(void) 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 cl_commander::proc_input(void) { - int i; + for (int j = 0; j < cons->count; j++) + { + class cl_console *c = (class cl_console*)(cons->at(j)); + + int fd = c->get_in_fd(); + if (fd >= 0 && FD_ISSET(fd, &active_set)) + { + actual_console = c; + int retval = c->proc_input(cmdset); + if (retval) + { + del_console(c); + delete c; + } + actual_console = 0; + return(0 == cons->count); + } + } + return 0; +} - for (i= 0; i < fd_num/*FD_SETSIZE*/; i++) - if (FD_ISSET(i, &active_set)) - { - class cl_console *c; - int j; - for (j= 0; j < cons->count; j++) - { - c= (class cl_console*)(cons->at(j)); - if (c->match(i)) - { - actual_console= c; - int retval= c->proc_input(); - if (retval) - { - del_console(c); - delete c; - } - actual_console= 0; - return(cons->count == 0); - } - } - } - 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 */