code cleaned a little bit too much ;-)
[fw/sdcc] / sim / ucsim / cmd.src / newcmd.cc
1 /*
2  * Simulator of microcontrollers (cmd.src/newcmd.cc)
3  *
4  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
5  * 
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  *
8  */
9
10 /* This file is part of microcontroller simulator: ucsim.
11
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.
16
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.
21
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
25 02111-1307, USA. */
26 /*@1@*/
27
28 #include "ddconfig.h"
29
30 #include <stdio.h>
31 #include <errno.h>
32 #include <stdarg.h>
33 #include <stdlib.h>
34 #include <sys/types.h>
35 #include <sys/time.h>
36 #ifdef SOCKET_AVAIL
37 # include HEADER_SOCKET
38 # if defined HAVE_SYS_SOCKET_H
39 #  include <netinet/in.h>
40 #  include <arpa/inet.h>
41 #  include <netdb.h>
42 # endif
43 #endif
44 #if FD_HEADER_OK
45 # include HEADER_FD
46 #endif
47 #ifdef HAVE_UNISTD_H
48 # include <unistd.h>
49 #endif
50 #include "i_string.h"
51
52 #include "cmdlexcl.h"
53 #include "cmdpars.h"
54
55 // prj
56 #include "globals.h"
57 #include "utils.h"
58
59 // sim
60 #include "simcl.h"
61 #include "argcl.h"
62 #include "appcl.h"
63
64 // local
65 #include "newcmdcl.h"
66 #include "cmdutil.h"
67
68
69 extern "C" int vasprintf(char **strp, const  char *format, va_list ap);
70 extern "C" int vsnprintf(char *str, size_t size,const char *format,va_list ap);
71
72
73 /*
74  * Options of console
75  */
76
77 cl_prompt_option::cl_prompt_option(class cl_console *console):
78   cl_optref(console)
79 {
80   con= console;
81 }
82
83 int
84 cl_prompt_option::init(void)
85 {
86   char *help;
87   help= format_string("Prompt string of console%d", con->get_id());
88   create(con, string_opt, "prompt", help);
89   //fprintf(stderr," **new prompt option %p\"%s\", value=%p str=%p\n",option,object_name(option),option->get_value(),option->get_value()->sval);
90   free(help);
91   default_option("prompt");
92   //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   return(0);
94 }
95
96 void
97 cl_prompt_option::option_changed(void)
98 {
99   if (!con)
100     return;
101   char *s;
102   option->get_value(&s);
103   con->set_prompt(s);
104 }
105
106
107 cl_debug_option::cl_debug_option(class cl_console *console):
108   cl_prompt_option(console)
109 {}
110
111 int
112 cl_debug_option::init(void)
113 {
114   char *help;
115   help= format_string("Debug messages to console%d", con->get_id());
116   create(con, bool_opt, "debug", help);
117   free(help);
118   default_option("debug");
119   return(0);
120 }
121
122 void
123 cl_debug_option::option_changed(void)
124 {
125   if (!con)
126     return;
127   bool b;
128   option->get_value(&b);
129   if (b)
130     con->flags|= CONS_DEBUG;
131   else
132     con->flags&= ~CONS_DEBUG;
133 }
134
135
136 /*
137  * Command console
138  *____________________________________________________________________________
139  */
140
141 cl_console::cl_console(char *fin, char *fout, class cl_app *the_app):
142   cl_base()
143 {
144   FILE *f;
145
146   app= the_app;
147   in= 0;
148   if (fin)
149     if (f= fopen(fin, "r"), in= f, !f)
150       fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));
151   out= 0;
152   if (fout)
153     if (f= fopen(fout, "w"), out= f, !f)
154       fprintf(stderr, "Can't open `%s': %s\n", fout, strerror(errno));
155   prompt= 0;
156   flags= CONS_NONE;
157   if (in &&
158       isatty(fileno(in)))
159     flags|= CONS_INTERACTIVE;
160   else
161     ;//fprintf(stderr, "Warning: non-interactive console\n");
162   rout= 0;
163   id= 0;
164   lines_printed= new cl_ustrings(100, 100, "console_cache");
165 }
166
167 cl_console::cl_console(FILE *fin, FILE *fout, class cl_app *the_app):
168   cl_base()
169 {
170   app= the_app;
171   in = fin;
172   out= fout;
173   prompt= 0;
174   flags= CONS_NONE;
175   if (in &&
176       isatty(fileno(in)))
177     flags|= CONS_INTERACTIVE;
178   else
179     ;//fprintf(stderr, "Warning: non-interactive console\n");
180   rout= 0;
181   id= 0;
182   lines_printed= new cl_ustrings(100, 100, "console_cache");
183 }
184
185 /*
186  * use the port number supplied to connect to localhost for 
187  * (by Sandeep)
188  */
189
190 #ifdef SOCKET_AVAIL
191 static int
192 connect_to_port(int portnum)
193 {
194   int sock= socket(AF_INET,SOCK_STREAM,0);
195   struct sockaddr_in sin;
196
197   sin.sin_family = AF_INET;
198   sin.sin_port = htons(portnum);
199   sin.sin_addr.s_addr = inet_addr("127.0.0.1");
200
201   if (connect(sock, (struct sockaddr *)&sin, sizeof(sin))) {
202     fprintf(stderr, "Connect to port %d: %s\n", portnum, strerror(errno));
203     return -1;
204   }
205   return sock;
206 }
207
208 cl_console::cl_console(int portnumber, class cl_app *the_app)
209 {
210   int sock= connect_to_port(portnumber);
211
212   app= the_app;
213   if (!(in= fdopen(sock, "r")))
214     fprintf(stderr, "cannot open port for input\n");
215   if (!(out= fdopen(sock, "w")))
216     fprintf(stderr, "cannot open port for output\n");
217   //fprintf(stderr, "init socket done\n");
218   id= 0;
219   lines_printed= new cl_ustrings(1, 1, "console_cache");
220 }
221 #endif
222
223 class cl_console *
224 cl_console::clone_for_exec(char *fin)
225 {
226   FILE *fi= 0, *fo= 0;
227
228   if (!fin)
229     return(0);
230   if (fi= fopen(fin, "r"), !fi)
231     {
232       fprintf(stderr, "Can't open `%s': %s\n", fin, strerror(errno));
233       return(0);
234     }
235   if ((fo= fdopen(dup(fileno(out)), "a")) == 0)
236     {
237       fclose(fi);
238       fprintf(stderr, "Can't re-open output file: %s\n", strerror(errno));
239       return(0);
240     }
241   class cl_console *con= new cl_sub_console(this, fi, fo, app);
242   return(con);
243 }
244
245 int
246 cl_console::init(void)
247 {
248   cl_base::init();
249   prompt_option= new cl_prompt_option(this);
250   prompt_option->init();
251   null_prompt_option= new cl_optref(this);
252   null_prompt_option->init();
253   null_prompt_option->use("null_prompt");
254   debug_option= new cl_debug_option(this);
255   debug_option->init();
256   welcome();
257   flags&= ~CONS_PROMPT;
258   //print_prompt();
259   last_command= 0;
260   last_cmdline= 0;
261   return(0);
262 }
263
264 cl_console::~cl_console(void)
265 {
266   if (in)
267     fclose(in);
268   un_redirect();
269   if (out)
270     {
271       if (flags & CONS_PROMPT)
272         fprintf(out, "\n");
273       fflush(out);
274       fclose(out);
275     }
276   delete prompt_option;
277   delete null_prompt_option;
278   delete debug_option;
279 #ifdef SOCKET_AVAIL
280   /*  if (sock)
281     {
282       shutdown(sock, 2);
283       close(sock);
284       }*/
285 #endif
286 }
287
288
289 bool
290 cl_console::accept_last(void)
291 {
292   if (!in)
293     return(DD_FALSE);
294   if (isatty(fileno(in)))
295     return(DD_TRUE);
296   return(DD_FALSE);
297 }
298
299
300 /*
301  * Output functions
302  */
303
304 void
305 cl_console::welcome(void)
306 {
307   if (!(flags & CONS_NOWELCOME))
308     {
309       dd_printf("uCsim %s, Copyright (C) 1997 Daniel Drotos, Talker Bt.\n"
310         "uCsim comes with ABSOLUTELY NO WARRANTY; for details type "
311         "`show w'.\n"
312         "This is free software, and you are welcome to redistribute it\n"
313         "under certain conditions; type `show c' for details.\n",
314         VERSIONSTR);
315     }
316 }
317
318 void
319 cl_console::redirect(char *fname, char *mode)
320 {
321   if ((rout= fopen(fname, mode)) == NULL)
322     dd_printf("Unable to open file '%s' for %s: %s\n",
323               fname, (mode[0]=='w')?"write":"append", strerror(errno));
324 }
325
326 void
327 cl_console::un_redirect(void)
328 {
329   if (!rout)
330     return;
331   fclose(rout);
332   rout= NULL;
333 }
334
335
336 int
337 cl_console::cmd_do_print(char *format, va_list ap)
338 {
339   FILE *f = get_out();
340   int ret = 0;
341
342   if (f)
343    {
344       vfprintf(f, format, ap);
345       fflush(f);
346     }
347
348   return(ret);
349 }
350
351 void
352 cl_console::print_prompt(void)
353 {
354   if (flags & (CONS_PROMPT|CONS_FROZEN|CONS_INACTIVE))
355     return;
356   flags|= CONS_PROMPT;
357   if (/*app->args->arg_avail('P')*/null_prompt_option->get_value(bool(0)))
358     {
359       FILE *Out = get_out();
360       if (Out)
361         {
362           putc('\0', Out);
363           fflush(Out);
364         }
365     }
366   else
367     {
368       dd_printf("%d%s", id, (prompt && prompt[0])?prompt:"> ");
369       //              ((p= app->args->get_sarg(0, "prompt"))?p:"> "));
370     }
371 }
372
373 int
374 cl_console::dd_printf(char *format, ...)
375 {
376   va_list ap;
377   int ret= 0;
378
379   va_start(ap, format);
380   ret= cmd_do_print(format, ap);
381   va_end(ap);
382
383   return(ret);
384 }
385
386 int
387 cl_console::debug(char *format, ...)
388 {
389   if ((flags & CONS_DEBUG) == 0)
390     return(0);
391
392   va_list ap;
393   int ret= 0;
394
395   va_start(ap, format);
396   ret= cmd_do_print(format, ap);
397   va_end(ap);
398
399   return(ret);
400 }
401
402 void
403 cl_console::print_bin(long data, int bits)
404 {
405   long mask= 1;
406
407   mask= mask << ((bits >= 1)?(bits-1):0);
408   while (bits--)
409     {
410       dd_printf("%c", (data&mask)?'1':'0');
411       mask>>= 1;
412     }
413 }
414
415 void
416 cl_console::print_char_octal(char c)
417 {
418   FILE *Out= get_out();
419
420   if (Out)
421     ::print_char_octal(c, Out);
422 }
423
424
425 /*
426  * Input functions
427  */
428
429 int
430 cl_console::match(int fdnum)
431 {
432   if (in &&
433       fileno(in) == fdnum)
434     return(1);
435   return(0);
436 }
437
438 int
439 cl_console::get_in_fd(void)
440 {
441   if (flags & CONS_INACTIVE)
442     return(-2);
443   return(in?fileno(in):-1);
444 }
445
446 int
447 cl_console::input_avail(void)
448 {
449   struct timeval tv;
450   UCSOCKET_T i;
451   
452   if ((i= get_in_fd()) < 0)
453     return(0);
454   fd_set s;
455   FD_ZERO(&s);
456   FD_SET(i, &s);
457   tv.tv_sec= tv.tv_usec= 0;
458   i= select(i+1, &s, NULL, NULL, &tv);
459   return(i);
460 }
461
462 char *
463 cl_console::read_line(void)
464 {
465   char *s= NULL;
466
467 #ifdef HAVE_GETLINE
468   if (getline(&s, 0, in) < 0)
469     return(0);
470 #else
471
472 # ifdef HAVE_GETDELIM
473   size_t n= 30;
474   s= (char *)malloc(n);
475   if (getdelim(&s, &n, '\n', in) < 0)
476     {
477       free(s);
478       return(0);
479     }
480 # else
481
482 #  ifdef HAVE_FGETS
483   s= (char *)malloc(300);
484   if (fgets(s, 300, in) == NULL)
485     {
486       free(s);
487       return(0);
488     }
489 #  endif
490 # endif
491 #endif
492   s[strlen(s)-1]= '\0';
493   if (s[strlen(s)-1] == '\r')
494     s[strlen(s)-1]= '\0';
495   flags&= ~CONS_PROMPT;
496   return(s);
497 }
498
499 int
500 cl_console::proc_input(class cl_cmdset *cmdset)
501 {
502   int retval= 0;
503
504   un_redirect();
505   if (feof(in))
506     {
507       fprintf(out, "End\n");
508       return(1);
509     }
510   char *cmdstr= read_line();
511   if (!cmdstr)
512     return(1);
513   if (flags & CONS_FROZEN)
514     {
515       app->get_sim()->stop(resUSER);
516       flags&= ~CONS_FROZEN;
517       retval= 0;
518     }
519   else
520     {
521       if (cmdstr &&
522           *cmdstr == '\004')
523         retval= 1;
524       else
525         {
526           class cl_cmdline *cmdline= 0;
527           class cl_cmd *cm= 0;
528           if (flags & CONS_ECHO)
529             dd_printf("%s\n", cmdstr);
530           cmdline= new cl_cmdline(app, cmdstr, this);
531           cmdline->init();
532           if (cmdline->repeat() &&
533               accept_last() &&
534               last_command)
535             {
536               cm= last_command;
537               delete cmdline;
538               cmdline= last_cmdline;
539             }
540           else
541             {
542               cm= cmdset->get_cmd(cmdline, accept_last());
543               if (last_cmdline)
544                 {
545                   delete last_cmdline;
546                   last_cmdline= 0;
547                 }
548               last_command= 0;
549             }
550           if (cm)
551             {
552               retval= cm->work(app, cmdline, this);
553               if (cm->can_repeat)
554                 {
555                   last_command= cm;
556                   last_cmdline= cmdline;
557                 }
558               else
559                 delete cmdline;
560             }
561           else
562             {
563               class YY_cl_ucsim_parser_CLASS *pars;
564               class cl_ucsim_lexer *lexer;
565               lexer= new cl_ucsim_lexer(cmdstr);
566               pars= new YY_cl_ucsim_parser_CLASS(lexer);
567               pars->yyparse();
568               delete cmdline;
569               delete pars;
570             }
571           /*if (!cm)
572             retval= interpret(cmdstr);*/
573         }
574     }
575   //retval= sim->do_cmd(cmd, this);
576   un_redirect();
577   /*if (!retval)
578     print_prompt();*/
579   free(cmdstr);
580   return(retval);
581 }
582
583 /*
584  * Old version, sim->do_cmd() falls into this if it doesn't find a new
585  * command object which can handle entered command
586  */
587
588 int
589 cl_console::interpret(char *cmd)
590 {
591   dd_printf("Unknown command\n");
592   return(0);
593 }
594
595 void
596 cl_console::set_id(int new_id)
597 {
598   char *s;
599
600   id= new_id;
601   set_name(s= format_string("console%d", id));
602   free(s);
603 }
604
605 void
606 cl_console::set_prompt(char *p)
607 {
608   if (prompt)
609     free(prompt);
610   if (p &&
611       *p)
612     prompt= strdup(p);
613   else
614     prompt= 0;
615 }
616
617
618 /*
619  * This console listen on a socket and can accept connection requests
620  */
621 #ifdef SOCKET_AVAIL
622
623 cl_listen_console::cl_listen_console(int serverport, class cl_app *the_app)
624 {
625   app= the_app;
626   if ((sock= make_server_socket(serverport)) >= 0)
627     {
628       if (listen(sock, 10) < 0)
629         fprintf(stderr, "Listen on port %d: %s\n",
630                 serverport, strerror(errno));
631     }
632   in= out= 0;
633 }
634
635 int
636 cl_listen_console::match(int fdnum)
637 {
638   return(sock == fdnum);
639 }
640
641 int
642 cl_listen_console::get_in_fd(void)
643 {
644   return(sock);
645 }
646
647 int
648 cl_listen_console::proc_input(class cl_cmdset *cmdset)
649 {
650   int newsock;
651   ACCEPT_SOCKLEN_T size;
652   struct sockaddr_in sock_addr;
653   class cl_commander *cmd;
654
655   cmd= app->get_commander();
656   size= sizeof(struct sockaddr); 
657   newsock= accept(sock, (struct sockaddr*)&sock_addr, &size);
658   if (newsock < 0)
659     {
660       perror("accept");
661       return(0);
662     }
663   if (!(in= fdopen(newsock, "r+")))
664     fprintf(stderr, "cannot open port for input\n");
665   if (!(out= fdopen(newsock, "w+")))
666     fprintf(stderr, "cannot open port for output\n");
667   class cl_console *c= cmd->mk_console(in, out);
668   c->flags|= CONS_INTERACTIVE;
669   cmd->add_console(c);
670   in= out= 0;
671   return(0);
672 }
673
674 #endif /* SOCKET_AVAIL */
675
676
677 /*
678  * Sub-console
679  */
680
681 cl_sub_console::cl_sub_console(class cl_console *the_parent,
682                                FILE *fin, FILE *fout, class cl_app *the_app):
683   cl_console(fin, fout, the_app)
684 {
685   parent= the_parent;
686 }
687
688 cl_sub_console::~cl_sub_console(void)
689 {
690   class cl_commander *c= app->get_commander();
691
692   if (parent && c)
693     {
694       c->activate_console(parent);
695     }
696 }
697
698 int
699 cl_sub_console::init(void)
700 {
701   class cl_commander *c= app->get_commander();
702
703   if (parent && c)
704     {
705       c->deactivate_console(parent);
706     }
707   cl_console::init();
708   flags|= CONS_ECHO;
709   return(0);
710 }
711
712
713 /*
714  * Command interpreter
715  *____________________________________________________________________________
716  */
717
718 cl_commander::cl_commander(class cl_app *the_app, class cl_cmdset *acmdset
719                            /*, class cl_sim *asim*/):
720   cl_base()
721 {
722   app= the_app;
723   cons= new cl_list(1, 1, "consoles"); 
724   actual_console= frozen_console= 0;
725   cmdset= acmdset;
726 }
727
728 int
729 cl_commander::init(void)
730 {
731   class cl_optref console_on_option(this);
732   class cl_optref config_file_option(this);
733   class cl_optref port_number_option(this);
734   class cl_console *con;
735
736   console_on_option.init();
737   console_on_option.use("console_on");
738   config_file_option.init();
739   config_file_option.use("config_file");
740   port_number_option.init();
741
742   cl_base::init();
743   set_name("Commander");
744   
745   bool need_config= DD_TRUE;
746
747 #ifdef SOCKET_AVAIL
748   if (port_number_option.use("port_number"))
749     add_console(mk_console(port_number_option.get_value((long)0)));
750 #endif
751
752   /* The following code is commented out because it produces gcc warnings
753    * newcmd.cc: In member function `virtual int cl_commander::init()':
754    * newcmd.cc:785: warning: 'Config' might be used uninitialized in this function
755    * newcmd.cc:786: warning: 'cn' might be used uninitialized in this function
756    */
757   /*
758   char *Config= config_file_option.get_value(Config);
759   char *cn= console_on_option.get_value(cn);
760    */
761   /* Here shoud probably be something else, but is still better then the former code... */
762   char *Config= config_file_option.get_value("");
763   char *cn= console_on_option.get_value("");
764
765   if (cn)
766     {
767       add_console(con= mk_console(cn, cn));
768       exec_on(con, Config);
769       need_config= DD_FALSE;
770     }
771   if (cons->get_count() == 0)
772     {
773       add_console(con= mk_console(stdin, stdout));
774       exec_on(con, Config);
775       need_config= DD_FALSE;
776     }
777   if (need_config &&
778       Config &&
779       *Config)
780     {
781       FILE *fc= fopen(Config, "r");
782       if (!fc)
783         fprintf(stderr, "Can't open `%s': %s\n", Config, strerror(errno));
784       else
785         {
786           con= mk_console(fc, stderr);
787           con->flags|= CONS_NOWELCOME|CONS_ECHO;
788           add_console(con);
789         }
790     }
791   return(0);
792 }
793
794 cl_commander::~cl_commander(void)
795 {
796   delete cons;
797   delete cmdset;
798 }
799
800 class cl_console *
801 cl_commander::mk_console(char *fin, char *fout)
802 {
803   return(new cl_console(fin, fout, app));
804 }
805
806 class cl_console *
807 cl_commander::mk_console(FILE *fin, FILE *fout)
808 {
809   return(new cl_console(fin, fout, app));
810 }
811
812 #ifdef SOCKET_AVAIL
813 class cl_console *
814 cl_commander::mk_console(int portnumber)
815 {
816   return(new cl_listen_console(portnumber, app));
817 }
818 #endif
819
820 void
821 cl_commander::add_console(class cl_console *console)
822 {
823   if (!console)
824     return;
825   int i=cons->add(console);
826   console->set_id(i);
827   console->init();
828   set_fd_set();
829 }
830
831 void
832 cl_commander::del_console(class cl_console *console)
833 {
834   cons->disconn(console);
835   set_fd_set();
836 }
837
838 void
839 cl_commander::activate_console(class cl_console *console)
840 {
841   console->flags&= ~CONS_INACTIVE;
842   //console->print_prompt();
843   set_fd_set();
844 }
845
846 void
847 cl_commander::deactivate_console(class cl_console *console)
848 {
849   console->flags|= CONS_INACTIVE;
850   set_fd_set();
851 }
852
853 void
854 cl_commander::set_fd_set(void)
855 {
856   int i;
857
858   //fprintf(stderr, "** Setting fd set\n");  
859   FD_ZERO(&read_set);
860   fd_num= 0;
861   for (i= 0; i < cons->count; i++)
862     {
863       UCSOCKET_T fd;
864       class cl_console *c= (class cl_console*)(cons->at(i));
865       if ((fd= c->get_in_fd()) >= 0)
866         {
867           if ((c->flags & CONS_FROZEN) == 0 ||
868               (c->flags & CONS_INTERACTIVE) != 0)
869             {
870               FD_SET(fd, &read_set);
871               if (fd > fd_num)
872                 fd_num= fd;
873             }
874         }
875       else
876         ;//fprintf(stderr, "** Skipping console %p\n",c);
877     }
878   fd_num++;
879 }
880
881
882 /*
883  * Printing to all consoles
884  */
885
886 int
887 cl_commander::all_printf(char *format, ...)
888 {
889   va_list ap;
890   int i, ret= 0;
891   
892   for (i= 0; i < cons->count; i++)
893     {
894       class cl_console *c= (class cl_console*)(cons->at(i));
895
896       va_start(ap, format);
897       ret= c->cmd_do_print(format, ap);
898       va_end(ap);
899     }
900   return(ret);
901 }
902
903 void
904 cl_commander::prompt(void)
905 {
906   int i;
907   
908   for (i= 0; i < cons->count; i++)
909     {
910       class cl_console *c= (class cl_console*)(cons->at(i));
911       c->print_prompt();
912     }
913 }
914
915 /*
916  * Printing to actual_console
917  */
918
919 int
920 cl_commander::dd_printf(char *format, va_list ap)
921 {
922   int ret= 0;
923   class cl_console *con;
924
925   if (actual_console)
926     {
927       con= actual_console;
928     }
929   else if (frozen_console)
930     {
931       con= frozen_console;
932     }
933   else
934     {
935       con= 0;
936     }
937   if (con)
938     {
939       ret= con->cmd_do_print(format, ap);
940     }
941   return(ret);
942 }
943
944 int
945 cl_commander::dd_printf(char *format, ...)
946 {
947   va_list ap;
948   int ret= 0;
949
950   va_start(ap, format);
951   ret= dd_printf(format, ap);
952   va_end(ap);
953
954   return(ret);
955 }
956
957 /*
958  * Printing to consoles which have CONS_DEBUG flag set
959  */
960
961 int
962 cl_commander::debug(char *format, ...)
963 {
964   va_list ap;
965   int i, ret= 0;
966
967   for (i= 0; i < cons->count; i++)
968     {
969       class cl_console *c= (class cl_console*)(cons->at(i));
970       if (c->flags & CONS_DEBUG)
971         {
972           va_start(ap, format);
973           ret= c->cmd_do_print(format, ap);
974           va_end(ap);
975         }
976     }
977   return(ret);
978 }
979
980 int
981 cl_commander::debug(char *format, va_list ap)
982 {
983   int i, ret= 0;
984
985   for (i= 0; i < cons->count; i++)
986     {
987       class cl_console *c= (class cl_console*)(cons->at(i));
988       if (c->flags & CONS_DEBUG)
989         {
990           ret= c->cmd_do_print(format, ap);
991         }
992     }
993   return(ret);
994 }
995
996 int
997 cl_commander::flag_printf(int iflags, char *format, ...)
998 {
999   va_list ap;
1000   int i, ret= 0;
1001
1002   for (i= 0; i < cons->count; i++)
1003     {
1004       class cl_console *c= (class cl_console*)(cons->at(i));
1005       if ((c->flags & iflags) == iflags)
1006         {
1007           va_start(ap, format);
1008           ret= c->cmd_do_print(format, ap);
1009           va_end(ap);
1010         }
1011     }
1012   return(ret);
1013 }
1014
1015 int
1016 cl_commander::input_avail(void)
1017 {
1018   struct timeval tv;
1019   int i;
1020
1021   tv.tv_sec= tv.tv_usec= 0;
1022   active_set= read_set;
1023   i= select(fd_num, &active_set, NULL, NULL, &tv);
1024   return(i);
1025 }
1026
1027 int
1028 cl_commander::input_avail_on_frozen(void)
1029 {
1030   int fd;
1031
1032   if (!frozen_console)
1033     return(0);
1034   if ((fd= frozen_console->get_in_fd()) >= 0 &&
1035       !isatty(fd))
1036     return(0);
1037   return(frozen_console->input_avail());
1038 }
1039
1040 int
1041 cl_commander::wait_input(void)
1042 {
1043   int i;
1044
1045   active_set= read_set;
1046   prompt();
1047   i= select(fd_num, &active_set, NULL, NULL, NULL);
1048   return(i);
1049 }
1050
1051 int
1052 cl_commander::proc_input(void)
1053 {
1054   UCSOCKET_T i;
1055
1056   for (i= 0; i < fd_num; i++)
1057     if (FD_ISSET(i, &active_set))
1058       {
1059         class cl_console *c;
1060         int j;
1061         for (j= 0; j < cons->count; j++)
1062           {
1063             c= (class cl_console*)(cons->at(j));
1064             if (c->match(i))
1065               {
1066                 actual_console= c;
1067                 int retval= c->proc_input(cmdset);
1068                 if (retval)
1069                   {
1070                     del_console(c);
1071                     delete c;
1072                   }
1073                 actual_console= 0;
1074                 return(cons->count == 0);
1075               }
1076           }
1077       }
1078   return(0);
1079 }
1080
1081 void
1082 cl_commander::exec_on(class cl_console *cons, char *file_name)
1083 {
1084   FILE *fi= fopen(file_name, "r");
1085
1086   if (!cons ||
1087       !fi)
1088     return;
1089   class cl_console *subcon= cons->clone_for_exec(file_name);
1090   subcon->flags|= CONS_NOWELCOME;
1091   add_console(subcon);
1092 }
1093
1094
1095 /* End of cmd.src/newcmd.cc */