2 * Simulator of microcontrollers (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>
35 #ifdef HAVE_SYS_SOCKET_H
36 # include <sys/socket.h>
37 # include <netinet/in.h>
38 # include <arpa/inet.h>
60 extern "C" int vasprintf();
61 extern "C" int vsnprintf();
64 cmd_do_print(FILE *f, char *format, va_list ap)
69 vasprintf(&msg, format, ap);
70 ret= fprintf(f, "%s", msg);
73 # ifdef HAVE_VSNPRINTF
75 vsnprintf(msg, 80*25, format, ap);
76 ret= fprintf(f, "%s", msg);
80 vsprintf(msg, format, ap); /* Dangerous */
81 ret= fprintf(f, "%s", msg);
85 /*strcpy(msg, "Unimplemented printf has called.\n");*/
87 /*strcpy(msg, "printf can not be implemented, upgrade your libc.\n");*/
99 *____________________________________________________________________________
102 cl_cmdline::cl_cmdline(char *acmd)
105 params= new cl_list(2, 2);
106 tokens= new cl_ustrings(2, 2);
110 cl_cmdline::~cl_cmdline(void)
121 cl_cmdline::init(void)
128 cl_cmdline::skip_delims(char *start)
131 strchr(" \t\v\r,", *start))
137 cl_cmdline::split(void)
146 start+= strspn(start, " \t\v\r,");
150 name= (char*)malloc(2);
156 i= strcspn(start, " \t\v\r,");
159 name= (char*)malloc(i+1);
160 strncpy(name, start, i);
164 start= skip_delims(start);
168 char *end, *param_str;
180 simulator->cmd->printf("Unterminated string\n");
181 param_str= (char *)malloc(end-start+2);
182 strncpy(param_str, start, 1+end-start);
183 param_str[1+end-start]= '\0';
184 tokens->add(strdup(param_str));
185 params->add(simulator->mk_cmd_str_arg(param_str));
195 i= strcspn(start, " \t\v\r,");
197 param_str= (char *)malloc(i+1);
198 strncpy(param_str, start, i);
200 tokens->add(strdup(param_str));
201 if ((dot= strchr(param_str, '.')) != NULL)
204 class cl_cmd_arg *sfr, *bit;
207 if (strchr("0123456789", *param_str) != NULL)
208 sfr= simulator->mk_cmd_int_arg((long long)
209 strtol(param_str, 0, 0));
211 sfr= simulator->mk_cmd_sym_arg(param_str);
215 simulator->cmd->printf("Uncomplete bit address\n");
219 if (strchr("0123456789", *dot) != NULL)
220 bit= simulator->mk_cmd_int_arg((long long)
223 bit= simulator->mk_cmd_sym_arg(dot);
225 params->add(simulator->mk_cmd_bit_arg(sfr, bit));
227 else if (strchr("0123456789", *param_str) != NULL)
230 params->add(simulator->mk_cmd_int_arg((long long)
231 strtol(param_str, 0, 0)));
236 params->add(simulator->mk_cmd_sym_arg(param_str));
241 start= skip_delims(start);
247 cl_cmdline::shift(void)
249 char *s= skip_delims(cmd);
256 strchr(" \t\v\r,", *s) == NULL)
263 params= new cl_list(2, 2);
266 return(name && *name);
270 cl_cmdline::repeat(void)
277 cl_cmdline::param(int num)
279 if (num >= params->count)
281 return((class cl_cmd_arg *)(params->at(num)));
285 cl_cmdline::insert_param(int pos, class cl_cmd_arg *param)
287 if (pos >= params->count)
290 params->add_at(pos, param);
296 *____________________________________________________________________________
299 cl_cmd::cl_cmd(class cl_sim *asim,
307 names= new cl_strings(1, 1);
308 names->add(aname?strdup(aname):strdup("unknown"));
310 short_help= short_hlp?strdup(short_hlp):NULL;
311 long_help= long_hlp?strdup(long_hlp):NULL;
314 /*cl_cmd::cl_cmd(class cl_sim *asim):
318 name= short_help= long_help= 0;
322 cl_cmd::~cl_cmd(void)
332 cl_cmd::add_name(char *name)
335 names->add(strdup(name));
339 cl_cmd::name_match(char *aname, int strict)
343 if (names->count == 0 &&
350 for (i= 0; i < names->count; i++)
352 char *n= (char*)(names->at(i));
353 if (strcmp(aname, n) == 0)
359 for (i= 0; i < names->count; i++)
361 char *n= (char*)(names->at(i));
362 if (strstr(n, aname) == n)
370 cl_cmd::name_match(class cl_cmdline *cmdline, int strict)
372 return(name_match(cmdline->name, strict));
376 cl_cmd::syntax_ok(class cl_cmdline *cmdline)
382 cl_cmd::work(class cl_cmdline *cmdline, class cl_console *con)
384 if (!syntax_ok(cmdline))
386 return(do_work(cmdline, con));
390 cl_cmd::do_work(class cl_cmdline *cmdline, class cl_console *con)
392 con->printf("Command \"%s\" does nothing.\n", (char*)(names->at(0)));
399 *____________________________________________________________________________
402 cl_cmdset::cl_cmdset(class cl_sim *asim):
410 cl_cmdset::get_cmd(class cl_cmdline *cmdline)
414 if (cmdline->repeat())
417 return(last_command);
422 for (i= 0; i < count; i++)
424 class cl_cmd *c= (class cl_cmd *)at(i);
425 if (c->name_match(cmdline, 1))
429 class cl_cmd *c_matched= 0;
430 for (i= 0; i < count; i++)
432 class cl_cmd *c= (class cl_cmd *)at(i);
433 if (c->name_match(cmdline, 0))
446 cl_cmdset::del(char *name)
452 for (i= 0; i < count; i++)
454 class cl_cmd *cmd= (class cl_cmd *)(at(i));
455 if (cmd->name_match(name, 1))
461 cl_cmdset::replace(char *name, class cl_cmd *cmd)
467 for (i= 0; i < count; i++)
469 class cl_cmd *c= (class cl_cmd *)(at(i));
470 if (c->name_match(name, 1))
480 * Composed command: subset of commands
481 *____________________________________________________________________________
484 cl_super_cmd::cl_super_cmd(class cl_sim *asim,
489 class cl_cmdset *acommands):
490 cl_cmd(asim, aname, can_rep, short_hlp, long_hlp)
495 cl_super_cmd::~cl_super_cmd(void)
502 cl_super_cmd::work(class cl_cmdline *cmdline, class cl_console *con)
509 if (!cmdline->shift())
512 con->printf("\"%s\" must be followed by the name of a subcommand\n"
513 "List of subcommands:\n", (char*)(names->at(0)));
514 for (i= 0; i < commands->count; i++)
516 cmd= (class cl_cmd *)(commands->at(i));
517 con->printf("%s\n", cmd->short_help);
521 if ((cmd= commands->get_cmd(cmdline)) == NULL)
523 con->printf("Undefined subcommand: \"%s\". Try \"help %s\".\n",
524 cmdline->name, (char*)(names->at(0)));
527 return(cmd->work(cmdline, con));
533 *____________________________________________________________________________
536 cl_console::cl_console(char *fin, char *fout, class cl_sim *asim):
545 if (f= fopen(fin, "r+"), in= f?f:stdin, !f)
546 fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));
549 if (f= fopen(fout, "w+"), out= f?f:stdout, !f)
550 fprintf(stderr, "Can't open `%s': %s\n", fout, strerror(errno));
554 cl_console::cl_console(FILE *fin, FILE *fout, class cl_sim *asim):
564 * use the port number supplied to connect to localhost for
570 connect_to_port(int portnum)
572 int sock= socket(AF_INET,SOCK_STREAM,0);
573 struct sockaddr_in sin;
575 sin.sin_family = AF_INET;
576 sin.sin_port = htons(portnum);
577 sin.sin_addr.s_addr = inet_addr("127.0.0.1");
579 if (connect(sock, (struct sockaddr *)&sin, sizeof(sin))) {
580 fprintf(stderr, "Connect to port %d: %s\n", portnum, strerror(errno));
586 cl_console::cl_console(int portnumber, class cl_sim *asim)
588 int sock= connect_to_port(portnumber);
592 if (!(in= fdopen(sock, "r+")))
593 fprintf(stderr, "cannot open port for input\n");
594 if (!(out= fdopen(sock, "w+")))
595 fprintf(stderr, "cannot open port for output\n");
596 //fprintf(stderr, "init socket done\n");
601 cl_console::init(void)
605 flags&= ~CONS_PROMPT;
610 cl_console::~cl_console(void)
635 cl_console::welcome(void)
638 "ucsim %s, Copyright (C) 1997 Daniel Drotos, Talker Bt.\n"
639 "ucsim comes with ABSOLUTELY NO WARRANTY; for details type "
641 "This is free software, and you are welcome to redistribute it\n"
642 "under certain conditions; type `show c' for details.\n",
648 cl_console::print_prompt(void)
652 if (flags & (CONS_PROMPT|CONS_FROZEN))
657 if (sim->arg_avail('P'))
660 fprintf(out, "%s", prompt?prompt:
661 ((p= sim->get_sarg(0, "prompt"))?p:"> "));
666 cl_console::printf(char *format, ...)
673 va_start(ap, format);
674 ret= cmd_do_print(out, format, ap);
681 cl_console::print_bin(long data, int bits)
687 mask= mask << ((bits >= 1)?(bits-1):0);
690 fprintf(out, "%c", (data&mask)?'1':'0');
700 cl_console::match(int fdnum)
709 cl_console::get_in_fd(void)
711 return(in?fileno(in):-1);
715 cl_console::input_avail(void)
720 if ((i= get_in_fd()) < 0)
725 tv.tv_sec= tv.tv_usec= 0;
726 i= select(i+1, &s, NULL, NULL, &tv);
731 cl_console::read_line(void)
736 if (getline(&s, 0, in) < 0)
740 # ifdef HAVE_GETDELIM
742 s= (char *)malloc(n);
743 if (getdelim(&s, &n, '\n', in) < 0)
751 s= (char *)malloc(300);
752 if (fgets(s, 300, in) == NULL)
760 s[strlen(s)-1]= '\0';
761 if (s[strlen(s)-1] == '\r')
762 s[strlen(s)-1]= '\0';
763 flags&= ~CONS_PROMPT;
768 cl_console::proc_input(void)
774 fprintf(out, "End\n");
777 char *cmd= read_line();
780 if (flags & CONS_FROZEN)
783 flags&= ~CONS_FROZEN;
787 retval= sim->do_cmd(cmd, this);
795 * Old version, sim->do_cmd() falls into this if it doesn't find a new
796 * command object which can handle enetered command
800 cl_console::interpret(char *cmd)
802 fprintf(out, "New interpreter does not known this command\n");
808 * This console listen on a socket and can accept connection requests
812 cl_listen_console::cl_listen_console(int serverport, class cl_sim *asim)
816 if ((sock= make_server_socket(serverport)) >= 0)
818 if (listen(sock, 10) < 0)
819 fprintf(stderr, "Listen on port %d: %s\n",
820 serverport, strerror(errno));
826 cl_listen_console::match(int fdnum)
828 return(sock == fdnum);
832 cl_listen_console::get_in_fd(void)
838 cl_listen_console::proc_input(void)
842 struct sockaddr_in sock_addr;
844 size= sizeof(struct sockaddr);
845 newsock= accept(sock, (struct sockaddr*)&sock_addr, &size);
851 if (!(in= fdopen(newsock, "r+")))
852 fprintf(stderr, "cannot open port for input\n");
853 if (!(out= fdopen(newsock, "w+")))
854 fprintf(stderr, "cannot open port for output\n");
855 sim->cmd->add_console(sim->cmd->mk_console(in, out, sim));
860 #endif /* SOCKET_AVAIL */
864 * Command interpreter
865 *____________________________________________________________________________
868 cl_commander::cl_commander(class cl_sim *asim):
871 cons= new cl_list(1, 1);
872 actual_console= frozen_console= 0;
877 cl_commander::init(void)
882 if (sim->arg_avail('c'))
884 add_console(mk_console(sim->get_sarg('c', 0),
885 sim->get_sarg('c', 0), sim));
888 if (sim->arg_avail('Z'))
890 add_console(mk_console(sim->get_iarg(0, "Zport"), sim));
892 if (sim->arg_avail('r'))
894 add_console(mk_console(sim->get_iarg('r', 0), sim));
897 if (cons->get_count() == 0)
899 add_console(mk_console(stdin, stdout, sim));
904 cl_commander::~cl_commander(void)
910 cl_commander::mk_console(char *fin, char *fout, class cl_sim *asim)
912 return(new cl_console(fin, fout, asim));
916 cl_commander::mk_console(FILE *fin, FILE *fout, class cl_sim *asim)
918 return(new cl_console(fin, fout, asim));
923 cl_commander::mk_console(int portnumber, class cl_sim *asim)
925 return(new cl_listen_console(portnumber, asim));
930 cl_commander::add_console(class cl_console *console)
938 cl_commander::del_console(class cl_console *console)
940 cons->disconn(console);
945 cl_commander::set_fd_set(void)
951 for (i= 0; i < cons->count; i++)
954 class cl_console *c= (class cl_console*)(cons->at(i));
955 if ((fd= c->get_in_fd()) >= 0)
959 FD_SET(fd, &read_set);
967 * Printing to all consoles
971 cl_commander::all_printf(char *format, ...)
976 for (i= 0; i < cons->count; i++)
978 class cl_console *c= (class cl_console*)(cons->at(i));
981 va_start(ap, format);
982 ret= cmd_do_print(c->out, format, ap);
990 * Printing to actual_console
994 cl_commander::printf(char *format, ...)
999 if (actual_console &&
1000 actual_console->out)
1002 va_start(ap, format);
1003 ret= cmd_do_print(actual_console->out, format, ap);
1010 * Printing to consoles which have CONS_DEBUG flag set
1014 cl_commander::debug(char *format, ...)
1019 for (i= 0; i < cons->count; i++)
1021 class cl_console *c= (class cl_console*)(cons->at(i));
1023 c->flags & CONS_DEBUG)
1025 va_start(ap, format);
1026 ret= cmd_do_print(c->out, format, ap);
1034 cl_commander::flag_printf(int iflags, char *format, ...)
1039 for (i= 0; i < cons->count; i++)
1041 class cl_console *c= (class cl_console*)(cons->at(i));
1043 (c->flags & iflags) == iflags)
1045 va_start(ap, format);
1046 ret= cmd_do_print(c->out, format, ap);
1054 cl_commander::input_avail(void)
1059 tv.tv_sec= tv.tv_usec= 0;
1060 active_set= read_set;
1061 i= select(fd_num/*FD_SETSIZE*/, &active_set, NULL, NULL, &tv);
1066 cl_commander::input_avail_on_frozen(void)
1068 if (!frozen_console)
1070 return(frozen_console->input_avail());
1074 cl_commander::wait_input(void)
1078 active_set= read_set;
1079 i= select(fd_num/*FD_SETSIZE*/, &active_set, NULL, NULL, NULL);
1084 cl_commander::proc_input(void)
1088 for (i= 0; i < fd_num/*FD_SETSIZE*/; i++)
1089 if (FD_ISSET(i, &active_set))
1091 class cl_console *c;
1093 for (j= 0; j < cons->count; j++)
1095 c= (class cl_console*)(cons->at(j));
1099 int retval= c->proc_input();
1106 return(cons->count == 0);
1114 /* End of newcmd.cc */