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