2 * Simulator of microcontrollers (cmd.src/newcmd.cc)
4 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
10 /* This file is part of microcontroller simulator: ucsim.
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
34 #include <sys/types.h>
37 # include HEADER_SOCKET
38 # if defined HAVE_SYS_SOCKET_H
39 # include <netinet/in.h>
40 # include <arpa/inet.h>
73 cl_prompt_option::cl_prompt_option(class cl_console *console):
80 cl_prompt_option::init(void)
83 help= format_string("Prompt string of console%d", con->get_id());
84 create(con, string_opt, "prompt", help);
85 //fprintf(stderr," **new prompt option %p\"%s\", value=%p str=%p\n",option,object_name(option),option->get_value(),option->get_value()->sval);
87 default_option("prompt");
88 //fprintf(stderr,"opt=%p\"%s\" value after default set=%p str=%p\n",option,object_name(option),option->get_value(),option->get_value()->sval);
93 cl_prompt_option::option_changed(void)
98 option->get_value(&s);
103 cl_debug_option::cl_debug_option(class cl_console *console):
104 cl_prompt_option(console)
108 cl_debug_option::init(void)
111 help= format_string("Debug messages to console%d", con->get_id());
112 create(con, bool_opt, "debug", help);
114 default_option("debug");
119 cl_debug_option::option_changed(void)
124 option->get_value(&b);
126 con->flags|= CONS_DEBUG;
128 con->flags&= ~CONS_DEBUG;
134 *____________________________________________________________________________
137 cl_console::cl_console(char *fin, char *fout, class cl_app *the_app):
145 if (f= fopen(fin, "r"), in= f, !f)
146 fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));
149 if (f= fopen(fout, "w"), out= f, !f)
150 fprintf(stderr, "Can't open `%s': %s\n", fout, strerror(errno));
155 flags|= CONS_INTERACTIVE;
157 ;//fprintf(stderr, "Warning: non-interactive console\n");
160 lines_printed= new cl_ustrings(100, 100, "console_cache");
163 cl_console::cl_console(FILE *fin, FILE *fout, class cl_app *the_app):
173 flags|= CONS_INTERACTIVE;
175 ;//fprintf(stderr, "Warning: non-interactive console\n");
178 lines_printed= new cl_ustrings(100, 100, "console_cache");
182 * use the port number supplied to connect to localhost for
188 connect_to_port(int portnum)
190 int sock= socket(AF_INET,SOCK_STREAM,0);
191 struct sockaddr_in sin;
193 sin.sin_family = AF_INET;
194 sin.sin_port = htons(portnum);
195 sin.sin_addr.s_addr = inet_addr("127.0.0.1");
197 if (connect(sock, (struct sockaddr *)&sin, sizeof(sin))) {
198 fprintf(stderr, "Connect to port %d: %s\n", portnum, strerror(errno));
204 cl_console::cl_console(int portnumber, class cl_app *the_app)
206 int sock= connect_to_port(portnumber);
209 if (!(in= fdopen(sock, "r")))
210 fprintf(stderr, "cannot open port for input\n");
211 if (!(out= fdopen(sock, "w")))
212 fprintf(stderr, "cannot open port for output\n");
213 //fprintf(stderr, "init socket done\n");
215 lines_printed= new cl_ustrings(1, 1, "console_cache");
220 cl_console::clone_for_exec(char *fin)
226 if (fi= fopen(fin, "r"), !fi)
228 fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));
231 if ((fo= fdopen(dup(fileno(out)), "a")) == 0)
234 fprintf(stderr, "Can't re-open output file: %s\n", strerror(errno));
237 class cl_console *con= new cl_sub_console(this, fi, fo, app);
242 cl_console::init(void)
245 prompt_option= new cl_prompt_option(this);
246 prompt_option->init();
247 null_prompt_option= new cl_optref(this);
248 null_prompt_option->init();
249 null_prompt_option->use("null_prompt");
250 debug_option= new cl_debug_option(this);
251 debug_option->init();
253 flags&= ~CONS_PROMPT;
260 cl_console::~cl_console(void)
267 if (flags & CONS_PROMPT)
272 delete prompt_option;
273 delete null_prompt_option;
286 cl_console::accept_last(void)
290 if (isatty(fileno(in)))
301 cl_console::welcome(void)
303 if (!(flags & CONS_NOWELCOME))
305 dd_printf("uCsim %s, Copyright (C) 1997 Daniel Drotos, Talker Bt.\n"
306 "uCsim comes with ABSOLUTELY NO WARRANTY; for details type "
308 "This is free software, and you are welcome to redistribute it\n"
309 "under certain conditions; type `show c' for details.\n",
315 cl_console::redirect(char *fname, char *mode)
317 if ((rout= fopen(fname, mode)) == NULL)
318 dd_printf("Unable to open file '%s' for %s: %s\n",
319 fname, (mode[0]=='w')?"write":"append", strerror(errno));
323 cl_console::un_redirect(void)
333 cl_console::cmd_do_print(char *format, va_list ap)
340 ret= vfprintf(f, format, ap);
350 cl_console::print_prompt(void)
352 if (flags & (CONS_PROMPT|CONS_FROZEN|CONS_INACTIVE))
355 if (/*app->args->arg_avail('P')*/null_prompt_option->get_value(bool(0)))
357 FILE *Out = get_out();
366 dd_printf("%d%s", id, (prompt && prompt[0])?prompt:"> ");
367 // ((p= app->args->get_sarg(0, "prompt"))?p:"> "));
372 cl_console::dd_printf(char *format, ...)
377 va_start(ap, format);
378 ret= cmd_do_print(format, ap);
385 cl_console::debug(char *format, ...)
387 if ((flags & CONS_DEBUG) == 0)
393 va_start(ap, format);
394 ret= cmd_do_print(format, ap);
401 cl_console::print_bin(long data, int bits)
405 mask= mask << ((bits >= 1)?(bits-1):0);
408 dd_printf("%c", (data&mask)?'1':'0');
414 cl_console::print_char_octal(char c)
416 FILE *Out= get_out();
419 ::print_char_octal(c, Out);
428 cl_console::get_in_fd(void)
430 if (flags & CONS_INACTIVE)
432 return(in?fileno(in):-1);
436 cl_console::input_avail(void)
441 if ((i= get_in_fd()) < 0)
446 tv.tv_sec= tv.tv_usec= 0;
447 i= select(i+1, &s, NULL, NULL, &tv);
452 cl_console::read_line(void)
457 if (getline(&s, 0, in) < 0)
459 #elif defined HAVE_GETDELIM
461 s= (char *)malloc(n);
462 if (getdelim(&s, &n, '\n', in) < 0)
467 #elif defined HAVE_FGETS
468 s= (char *)malloc(300);
469 if (fgets(s, 300, in) == NULL)
475 s[strlen(s)-1]= '\0';
476 if (s[strlen(s)-1] == '\r')
477 s[strlen(s)-1]= '\0';
478 flags&= ~CONS_PROMPT;
483 cl_console::proc_input(class cl_cmdset *cmdset)
490 fprintf(out, "End\n");
493 char *cmdstr= read_line();
496 if (flags & CONS_FROZEN)
498 app->get_sim()->stop(resUSER);
499 flags&= ~CONS_FROZEN;
509 class cl_cmdline *cmdline= 0;
511 if (flags & CONS_ECHO)
512 dd_printf("%s\n", cmdstr);
513 cmdline= new cl_cmdline(app, cmdstr, this);
515 if (cmdline->repeat() &&
521 cmdline= last_cmdline;
525 cm= cmdset->get_cmd(cmdline, accept_last());
535 retval= cm->work(app, cmdline, this);
539 last_cmdline= cmdline;
546 class YY_cl_ucsim_parser_CLASS *pars;
547 class cl_ucsim_lexer *lexer;
548 lexer= new cl_ucsim_lexer(cmdstr);
549 pars= new YY_cl_ucsim_parser_CLASS(lexer);
555 retval= interpret(cmdstr);*/
558 //retval= sim->do_cmd(cmd, this);
567 * Old version, sim->do_cmd() falls into this if it doesn't find a new
568 * command object which can handle entered command
572 cl_console::interpret(char *cmd)
574 dd_printf("Unknown command\n");
579 cl_console::set_id(int new_id)
584 set_name(s= format_string("console%d", id));
589 cl_console::set_prompt(char *p)
602 * This console listen on a socket and can accept connection requests
606 cl_listen_console::cl_listen_console(int serverport, class cl_app *the_app)
609 if ((sock= make_server_socket(serverport)) >= 0)
611 if (listen(sock, 10) < 0)
612 fprintf(stderr, "Listen on port %d: %s\n",
613 serverport, strerror(errno));
619 cl_listen_console::get_in_fd(void)
625 cl_listen_console::proc_input(class cl_cmdset *cmdset)
628 ACCEPT_SOCKLEN_T size;
629 struct sockaddr_in sock_addr;
630 class cl_commander *cmd;
632 cmd= app->get_commander();
633 size= sizeof(struct sockaddr);
634 newsock= accept(sock, (struct sockaddr*)&sock_addr, &size);
640 if (!(in= fdopen(newsock, "r+")))
641 fprintf(stderr, "cannot open port for input\n");
642 if (!(out= fdopen(newsock, "w+")))
643 fprintf(stderr, "cannot open port for output\n");
644 class cl_console *c= cmd->mk_console(in, out);
645 c->flags|= CONS_INTERACTIVE;
651 #endif /* SOCKET_AVAIL */
658 cl_sub_console::cl_sub_console(class cl_console *the_parent,
659 FILE *fin, FILE *fout, class cl_app *the_app):
660 cl_console(fin, fout, the_app)
665 cl_sub_console::~cl_sub_console(void)
667 class cl_commander *c= app->get_commander();
671 c->activate_console(parent);
676 cl_sub_console::init(void)
678 class cl_commander *c= app->get_commander();
682 c->deactivate_console(parent);
691 * Command interpreter
692 *____________________________________________________________________________
695 cl_commander::cl_commander(class cl_app *the_app, class cl_cmdset *acmdset
696 /*, class cl_sim *asim*/):
700 cons= new cl_list(1, 1, "consoles");
701 actual_console= frozen_console= 0;
706 cl_commander::init(void)
708 class cl_optref console_on_option(this);
709 class cl_optref config_file_option(this);
710 class cl_optref port_number_option(this);
711 class cl_console *con;
713 console_on_option.init();
714 console_on_option.use("console_on");
715 config_file_option.init();
716 config_file_option.use("config_file");
717 port_number_option.init();
720 set_name("Commander");
722 bool need_config= DD_TRUE;
725 if (port_number_option.use("port_number"))
726 add_console(mk_console(port_number_option.get_value((long)0)));
729 /* The following code is commented out because it produces gcc warnings
730 * newcmd.cc: In member function `virtual int cl_commander::init()':
731 * newcmd.cc:785: warning: 'Config' might be used uninitialized in this function
732 * newcmd.cc:786: warning: 'cn' might be used uninitialized in this function
735 char *Config= config_file_option.get_value(Config);
736 char *cn= console_on_option.get_value(cn);
738 /* Here shoud probably be something else, but is still better then the former code... */
739 char *Config= config_file_option.get_value("");
740 char *cn= console_on_option.get_value("");
744 add_console(con= mk_console(cn, cn));
745 exec_on(con, Config);
746 need_config= DD_FALSE;
748 if (cons->get_count() == 0)
750 add_console(con= mk_console(stdin, stdout));
751 exec_on(con, Config);
752 need_config= DD_FALSE;
758 FILE *fc= fopen(Config, "r");
760 fprintf(stderr, "Can't open `%s': %s\n", Config, strerror(errno));
763 con= mk_console(fc, stderr);
764 con->flags|= CONS_NOWELCOME|CONS_ECHO;
771 cl_commander::~cl_commander(void)
778 cl_commander::mk_console(char *fin, char *fout)
780 return(new cl_console(fin, fout, app));
784 cl_commander::mk_console(FILE *fin, FILE *fout)
786 return(new cl_console(fin, fout, app));
791 cl_commander::mk_console(int portnumber)
793 return(new cl_listen_console(portnumber, app));
798 cl_commander::add_console(class cl_console *console)
802 int i=cons->add(console);
809 cl_commander::del_console(class cl_console *console)
811 cons->disconn(console);
816 cl_commander::activate_console(class cl_console *console)
818 console->flags&= ~CONS_INACTIVE;
819 //console->print_prompt();
824 cl_commander::deactivate_console(class cl_console *console)
826 console->flags|= CONS_INACTIVE;
831 cl_commander::set_fd_set(void)
835 //fprintf(stderr, "** Setting fd set\n");
838 for (i= 0; i < cons->count; i++)
841 class cl_console *c= (class cl_console*)(cons->at(i));
842 if ((fd= c->get_in_fd()) >= 0)
844 if ((c->flags & CONS_FROZEN) == 0 ||
845 (c->flags & CONS_INTERACTIVE) != 0)
847 FD_SET(fd, &read_set);
853 ;//fprintf(stderr, "** Skipping console %p\n",c);
860 * Printing to all consoles
864 cl_commander::all_printf(char *format, ...)
869 for (i= 0; i < cons->count; i++)
871 class cl_console *c= (class cl_console*)(cons->at(i));
873 va_start(ap, format);
874 ret= c->cmd_do_print(format, ap);
881 cl_commander::prompt(void)
885 for (i= 0; i < cons->count; i++)
887 class cl_console *c= (class cl_console*)(cons->at(i));
893 * Printing to actual_console
897 cl_commander::dd_printf(char *format, va_list ap)
900 class cl_console *con;
906 else if (frozen_console)
916 ret= con->cmd_do_print(format, ap);
922 cl_commander::dd_printf(char *format, ...)
927 va_start(ap, format);
928 ret= dd_printf(format, ap);
935 * Printing to consoles which have CONS_DEBUG flag set
939 cl_commander::debug(char *format, ...)
944 for (i= 0; i < cons->count; i++)
946 class cl_console *c= (class cl_console*)(cons->at(i));
947 if (c->flags & CONS_DEBUG)
949 va_start(ap, format);
950 ret= c->cmd_do_print(format, ap);
958 cl_commander::debug(char *format, va_list ap)
962 for (i= 0; i < cons->count; i++)
964 class cl_console *c= (class cl_console*)(cons->at(i));
965 if (c->flags & CONS_DEBUG)
967 ret= c->cmd_do_print(format, ap);
974 cl_commander::flag_printf(int iflags, char *format, ...)
979 for (i= 0; i < cons->count; i++)
981 class cl_console *c= (class cl_console*)(cons->at(i));
982 if ((c->flags & iflags) == iflags)
984 va_start(ap, format);
985 ret= c->cmd_do_print(format, ap);
993 cl_commander::input_avail(void)
998 tv.tv_sec= tv.tv_usec= 0;
999 active_set= read_set;
1000 i= select(fd_num, &active_set, NULL, NULL, &tv);
1005 cl_commander::input_avail_on_frozen(void)
1009 if (!frozen_console)
1011 if ((fd= frozen_console->get_in_fd()) >= 0 &&
1014 return(frozen_console->input_avail());
1018 cl_commander::wait_input(void)
1022 active_set= read_set;
1024 i= select(fd_num, &active_set, NULL, NULL, NULL);
1029 cl_commander::proc_input(void)
1031 for (int j = 0; j < cons->count; j++)
1033 class cl_console *c = (class cl_console*)(cons->at(j));
1035 int fd = c->get_in_fd();
1036 if (fd >= 0 && FD_ISSET(fd, &active_set))
1039 int retval = c->proc_input(cmdset);
1046 return(0 == cons->count);
1053 cl_commander::exec_on(class cl_console *cons, char *file_name)
1055 FILE *fi= fopen(file_name, "r");
1060 class cl_console *subcon= cons->clone_for_exec(file_name);
1061 subcon->flags|= CONS_NOWELCOME;
1062 add_console(subcon);
1066 /* End of cmd.src/newcmd.cc */