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));
555 cl_console::cl_console(FILE *fin, FILE *fout, class cl_sim *asim):
566 * use the port number supplied to connect to localhost for
572 connect_to_port(int portnum)
574 int sock= socket(AF_INET,SOCK_STREAM,0);
575 struct sockaddr_in sin;
577 sin.sin_family = AF_INET;
578 sin.sin_port = htons(portnum);
579 sin.sin_addr.s_addr = inet_addr("127.0.0.1");
581 if (connect(sock, (struct sockaddr *)&sin, sizeof(sin))) {
582 fprintf(stderr, "Connect to port %d: %s\n", portnum, strerror(errno));
588 cl_console::cl_console(int portnumber, class cl_sim *asim)
590 int sock= connect_to_port(portnumber);
594 if (!(in= fdopen(sock, "r+")))
595 fprintf(stderr, "cannot open port for input\n");
596 if (!(out= fdopen(sock, "w+")))
597 fprintf(stderr, "cannot open port for output\n");
598 //fprintf(stderr, "init socket done\n");
603 cl_console::init(void)
607 flags&= ~CONS_PROMPT;
612 cl_console::~cl_console(void)
637 cl_console::welcome(void)
640 "ucsim %s, Copyright (C) 1997 Daniel Drotos, Talker Bt.\n"
641 "ucsim comes with ABSOLUTELY NO WARRANTY; for details type "
643 "This is free software, and you are welcome to redistribute it\n"
644 "under certain conditions; type `show c' for details.\n",
650 cl_console::print_prompt(void)
654 if (flags & (CONS_PROMPT|CONS_FROZEN))
659 if (sim->arg_avail('P'))
662 fprintf(out, "%s", (prompt && prompt[0])?prompt:
663 ((p= sim->get_sarg(0, "prompt"))?p:"> "));
668 cl_console::printf(char *format, ...)
675 va_start(ap, format);
676 ret= cmd_do_print(out, format, ap);
683 cl_console::print_bin(long data, int bits)
689 mask= mask << ((bits >= 1)?(bits-1):0);
692 fprintf(out, "%c", (data&mask)?'1':'0');
702 cl_console::match(int fdnum)
711 cl_console::get_in_fd(void)
713 return(in?fileno(in):-1);
717 cl_console::input_avail(void)
722 if ((i= get_in_fd()) < 0)
727 tv.tv_sec= tv.tv_usec= 0;
728 i= select(i+1, &s, NULL, NULL, &tv);
733 cl_console::read_line(void)
738 if (getline(&s, 0, in) < 0)
742 # ifdef HAVE_GETDELIM
744 s= (char *)malloc(n);
745 if (getdelim(&s, &n, '\n', in) < 0)
753 s= (char *)malloc(300);
754 if (fgets(s, 300, in) == NULL)
762 s[strlen(s)-1]= '\0';
763 if (s[strlen(s)-1] == '\r')
764 s[strlen(s)-1]= '\0';
765 flags&= ~CONS_PROMPT;
770 cl_console::proc_input(void)
776 fprintf(out, "End\n");
779 char *cmd= read_line();
782 if (flags & CONS_FROZEN)
785 flags&= ~CONS_FROZEN;
789 retval= sim->do_cmd(cmd, this);
797 * Old version, sim->do_cmd() falls into this if it doesn't find a new
798 * command object which can handle enetered command
802 cl_console::interpret(char *cmd)
804 fprintf(out, "New interpreter does not known this command\n");
810 * This console listen on a socket and can accept connection requests
814 cl_listen_console::cl_listen_console(int serverport, class cl_sim *asim)
818 if ((sock= make_server_socket(serverport)) >= 0)
820 if (listen(sock, 10) < 0)
821 fprintf(stderr, "Listen on port %d: %s\n",
822 serverport, strerror(errno));
828 cl_listen_console::match(int fdnum)
830 return(sock == fdnum);
834 cl_listen_console::get_in_fd(void)
840 cl_listen_console::proc_input(void)
844 struct sockaddr_in sock_addr;
846 size= sizeof(struct sockaddr);
847 newsock= accept(sock, (struct sockaddr*)&sock_addr, &size);
853 if (!(in= fdopen(newsock, "r+")))
854 fprintf(stderr, "cannot open port for input\n");
855 if (!(out= fdopen(newsock, "w+")))
856 fprintf(stderr, "cannot open port for output\n");
857 sim->cmd->add_console(sim->cmd->mk_console(in, out, sim));
862 #endif /* SOCKET_AVAIL */
866 * Command interpreter
867 *____________________________________________________________________________
870 cl_commander::cl_commander(class cl_sim *asim):
873 cons= new cl_list(1, 1);
874 actual_console= frozen_console= 0;
879 cl_commander::init(void)
884 if (sim->arg_avail('c'))
885 add_console(mk_console(sim->get_sarg('c', 0),
886 sim->get_sarg('c', 0), sim));
888 if (sim->arg_avail('Z'))
889 add_console(mk_console(sim->get_iarg(0, "Zport"), sim));
890 if (sim->arg_avail('r'))
891 add_console(mk_console(sim->get_iarg('r', 0), sim));
893 if (cons->get_count() == 0)
894 add_console(mk_console(stdin, stdout, sim));
898 cl_commander::~cl_commander(void)
904 cl_commander::mk_console(char *fin, char *fout, class cl_sim *asim)
906 return(new cl_console(fin, fout, asim));
910 cl_commander::mk_console(FILE *fin, FILE *fout, class cl_sim *asim)
912 return(new cl_console(fin, fout, asim));
917 cl_commander::mk_console(int portnumber, class cl_sim *asim)
919 return(new cl_listen_console(portnumber, asim));
924 cl_commander::add_console(class cl_console *console)
932 cl_commander::del_console(class cl_console *console)
934 cons->disconn(console);
939 cl_commander::set_fd_set(void)
945 for (i= 0; i < cons->count; i++)
948 class cl_console *c= (class cl_console*)(cons->at(i));
949 if ((fd= c->get_in_fd()) >= 0)
953 FD_SET(fd, &read_set);
961 * Printing to all consoles
965 cl_commander::all_printf(char *format, ...)
970 for (i= 0; i < cons->count; i++)
972 class cl_console *c= (class cl_console*)(cons->at(i));
975 va_start(ap, format);
976 ret= cmd_do_print(c->out, format, ap);
984 cl_commander::all_print(char *string, int length)
988 for (i= 0; i < cons->count; i++)
990 class cl_console *c= (class cl_console*)(cons->at(i));
993 for (int j= 0; j < length; j++)
994 putc(string[j], c->out);
1001 * Printing to actual_console
1005 cl_commander::printf(char *format, ...)
1010 if (actual_console &&
1011 actual_console->out)
1013 va_start(ap, format);
1014 ret= cmd_do_print(actual_console->out, format, ap);
1021 * Printing to consoles which have CONS_DEBUG flag set
1025 cl_commander::debug(char *format, ...)
1030 for (i= 0; i < cons->count; i++)
1032 class cl_console *c= (class cl_console*)(cons->at(i));
1034 c->flags & CONS_DEBUG)
1036 va_start(ap, format);
1037 ret= cmd_do_print(c->out, format, ap);
1045 cl_commander::flag_printf(int iflags, char *format, ...)
1050 for (i= 0; i < cons->count; i++)
1052 class cl_console *c= (class cl_console*)(cons->at(i));
1054 (c->flags & iflags) == iflags)
1056 va_start(ap, format);
1057 ret= cmd_do_print(c->out, format, ap);
1065 cl_commander::input_avail(void)
1070 tv.tv_sec= tv.tv_usec= 0;
1071 active_set= read_set;
1072 i= select(fd_num/*FD_SETSIZE*/, &active_set, NULL, NULL, &tv);
1077 cl_commander::input_avail_on_frozen(void)
1079 if (!frozen_console)
1081 return(frozen_console->input_avail());
1085 cl_commander::wait_input(void)
1089 active_set= read_set;
1090 i= select(fd_num/*FD_SETSIZE*/, &active_set, NULL, NULL, NULL);
1095 cl_commander::proc_input(void)
1099 for (i= 0; i < fd_num/*FD_SETSIZE*/; i++)
1100 if (FD_ISSET(i, &active_set))
1102 class cl_console *c;
1104 for (j= 0; j < cons->count; j++)
1106 c= (class cl_console*)(cons->at(j));
1110 int retval= c->proc_input();
1117 return(cons->count == 0);
1125 /* End of newcmd.cc */