[ucsim] Update email and file info, fix stm8 flash controller
[sdcc.git] / sdcc / sim / ucsim / src / core / cmd.src / command.cc
blobe37f09255bc19be401b66f3e4edf3b846be13da8
1 /*
2 * Simulator of microcontrollers (cmd.src/command.cc)
4 * Copyright (C) 2002,02 Drotos Daniel
5 *
6 * To contact author send email to dr.dkdb@gmail.com
8 */
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
25 02111-1307, USA. */
26 /*@1@*/
28 //#include "ddconfig.h"
30 #include <stdio.h>
31 #include <stdlib.h>
32 //#include <stdarg.h>
33 #include <string.h>
34 #include <unistd.h>
36 //#include "i_string.h"
38 // prj
39 //#include "fiocl.h"
40 //#include "utils.h"
41 #include "appcl.h"
43 // local, cmd
44 #include "commandcl.h"
45 //#include "argcl.h"
49 * Command line
50 *____________________________________________________________________________
53 cl_cmdline::cl_cmdline(class cl_app *the_app,
54 const char *acmd, class cl_console_base *acon):
55 cl_base()
57 app= the_app;
58 cmd= strdup(acmd);
59 params= new cl_list(2, 2, "command line params");
60 tokens= new cl_ustrings(2, 2, "command line tokens");
61 set_name(0);
62 matched_syntax= 0;
63 con= acon;
66 cl_cmdline::~cl_cmdline(void)
68 if (cmd)
69 free(cmd);
70 delete params;
71 delete tokens;
74 int
75 cl_cmdline::init(void)
77 rest= NULL;
78 params->free_all();
79 tokens->free_all();
80 split();
81 return(0);
84 char *
85 cl_cmdline::skip_delims(char *start)
87 while (*start &&
88 strchr(" \t\v\r,", *start))
89 start++;
90 return(start);
93 int
94 cl_cmdline::split(void)
96 //class cl_sim *sim;
97 char *start= cmd;
98 int i;//, j;
99 class cl_cmd_arg *arg;
101 set_name("\n");
102 if (!cmd ||
103 !*cmd)
104 return(0);
105 start+= strspn(start, " \t\v\r,");
106 if (!start)
107 return 0;
108 set_name(0);
109 if (*start == '\n')
111 // never, as \n stripped by readline
112 set_name("\n");
113 return(0);
115 else if (*start == '#')
116 return *start= 0;
117 else if (*start == ';')
119 rest= start+1;
120 *start= 0;
121 return 0;
123 if (!*start)
124 return(0);
125 // start now points to first word
126 i= strcspn(start, " \t\v\r,;#");
127 // i should be at end of it
128 if (i)
130 if (*start == '#')
131 return set_name("\n"), *start= 0;
132 char *n= (char*)malloc(i+1);
133 strncpy(n, start, i);
134 n[i]= '\0';
135 set_name(n);
136 free(n);
138 start+= i;
139 start= skip_delims(start);
140 while (*start)
142 char *end= start, *param_str;
143 if (*start == '#')
144 return *start= '\0';
145 else if (*start == ';')
147 rest= start+1;
148 *start= 0;
149 return 0;
151 else if (*start == '"')
152 split_out_string(&start, &end);
153 else if (*start == '>')
154 split_out_output_redirection(&start, &end);
155 else
157 char *dot;
158 i= strcspn(start, " \t\v\r,#;");
159 end= start+i;
160 /*param_str= (char *)malloc(i+1);
161 strncpy(param_str, start, i);
162 param_str[i]= '\0';
164 chars ps;
165 ps.appendn(start, i);
166 expand_commands(&ps);
167 tokens->add(strdup(/*param_str*/ps.c_str()));
168 param_str= (char*)ps.c_str();
169 if ((dot= strchr(param_str, '[')) != NULL)
171 char *p;
172 for (p= dot+1; *p && *p != ']' && *p != ':'; p++);
173 if (*p == ':')
174 split_out_bit(dot, param_str);
175 else
176 split_out_array(dot, param_str);
178 else if ((dot= strchr(param_str, '.')) != NULL && dot != param_str)
179 split_out_bit(dot, param_str);
180 else if (param_str[0] == '0' && param_str[1] == 'b')
182 long n= 0;
183 int ii;
184 for (ii= 2; param_str[ii] == '0' || param_str[ii] == '1'; ii++)
185 n = (n << 1) | (param_str[ii] == '0' ? 0 : 1);
186 params->add(arg= new cl_cmd_int_arg(n));
187 arg->init();
189 else if (strchr("0123456789-+", *param_str) != NULL)
191 // number
192 params->add(arg= new cl_cmd_int_arg((long)
193 strtol(param_str, 0, 0)));
194 arg->init();
196 else
198 // symbol
199 params->add(arg= new cl_cmd_sym_arg(param_str));
200 arg->init();
202 //free(param_str);
204 start= end;
205 start= skip_delims(start);
207 return(0);
210 void
211 cl_cmdline::split_out_string(char **_start, char **_end)
213 char *start= *_start, *end;
214 start++;
215 end= start;
216 while (*end &&
217 *end != '"')
219 if (*end == '\\')
221 end++;
222 if (*end)
223 end++;
225 else
226 end++;
228 if (*end == '"')
229 end--;
230 else
231 con->dd_cprintf("error", "Unterminated string\n");
232 chars ps;
233 ps.appendn(start, 1+end-start);
234 expand_commands(&ps);
235 tokens->add(strdup(ps.c_str()));
236 class cl_cmd_arg *arg;
237 params->add(arg= new cl_cmd_str_arg(ps.c_str()));
238 arg->init();
239 //free(param_str);
240 if (*end)
241 end++;
242 if (*end == '"')
243 end++;
244 *_start= start;
245 *_end= end;
248 void
249 cl_cmdline::split_out_output_redirection(char **_start, char **_end)
251 char *start= *_start;
252 char *end;
253 int j;
254 char mode[2];
256 mode[0]= 'w';
257 mode[1]= '\0';
258 start++;
259 if (*start=='>')
261 mode[0]= 'a';
262 start++;
264 j= token_length(start);
265 end= start+j;
266 con->redirect(get_token(start).c_str(), mode);
267 *_start= start;
268 *_end= end;
271 void
272 cl_cmdline::add_bit(char *dot, char *colon, class cl_cmd_arg *sfr)
274 class cl_cmd_arg *bit_low = NULL, *bit_high = NULL;
276 if (colon)
278 *(colon++) = '\0';
280 char *end = strchr(colon, ']');
282 if (end)
283 *end = '\0';
284 else
286 con->dd_cprintf("error", "Incomplete bit address\n");
287 delete sfr;
288 return;
292 if (*dot == '\0')
294 con->dd_cprintf("error", "Incomplete bit address\n");
295 delete sfr;
296 return;
299 while (dot)
301 bit_high= bit_low;
303 if (strchr("0123456789", *dot) != NULL)
305 bit_low= new cl_cmd_int_arg((long)strtol(dot, 0, 0));
306 bit_low->init();
308 else
310 bit_low= new cl_cmd_sym_arg(dot);
311 bit_low->init();
314 dot= colon;
315 colon= NULL;
318 class cl_cmd_arg *arg;
319 params->add(arg= new cl_cmd_bit_arg(sfr, bit_low, bit_high));
320 arg->init();
323 void
324 cl_cmdline::split_out_bit(char *dot, char *param_str)
326 char *colon = NULL;
327 class cl_cmd_arg *sfr;
329 if (*dot == '[')
330 colon = strchr(dot+1, ':');
332 *(dot++) = '\0';
334 if (strchr("0123456789", *param_str) != NULL)
336 sfr= new cl_cmd_int_arg((long)strtol(param_str, 0, 0));
337 sfr->init();
339 else
341 sfr= new cl_cmd_sym_arg(param_str);
342 sfr->init();
345 add_bit(dot, colon, sfr);
348 void
349 cl_cmdline::split_out_array(char *dot, char *param_str)
351 class cl_cmd_arg *aname, *aindex;
353 *dot= '\0';
354 dot++;
355 if (strchr("0123456789", *param_str) != NULL)
357 aname= new cl_cmd_int_arg((long)strtol(param_str, 0, 0));
358 aname->init();
360 else
362 aname= new cl_cmd_sym_arg(param_str);
363 aname->init();
365 if (*dot == '\0')
367 aname= 0;
368 con->dd_cprintf("error", "Incomplete array\n");
370 else
372 char *p = strchr(dot, ']');
373 if (!p)
375 con->dd_cprintf("error", "Missing ']' in array index\n");
376 delete aname;
378 else
380 *(p++)= '\0';
381 if (strlen(dot) == 0)
383 con->dd_cprintf("error", "Incomplete array index\n");
384 delete aname;
386 else
388 if (strchr("0123456789", *dot) != NULL)
390 aindex= new cl_cmd_int_arg((long)strtol(dot, 0, 0));
391 aindex->init();
393 else
395 aindex= new cl_cmd_sym_arg(dot);
396 aindex->init();
398 class cl_cmd_arg *arg= new cl_cmd_array_arg(aname, aindex);
399 arg->init();
400 if (*p == '.' || *p == '[')
401 add_bit(p+1, strchr(p+1, ':'), arg);
402 else
403 params->add(arg);
410 cl_cmdline::token_length(char *start)
412 if (start==NULL ||
413 *start=='\0')
414 return 0;
415 if (*start == '\"')
417 int i;
418 char c;
419 for (i=1; start[i]!=0 && start[i]!='\"'; i++)
421 c= start[i];
422 if (c == '\\')
423 i+= 2;
425 return i+1;
427 else
428 return strcspn(start, " \t\v\r,;");
431 chars
432 cl_cmdline::get_token(char *start)
434 int i;
435 char c;
436 chars cs= chars();
437 if (start==NULL ||
438 *start=='\0')
439 return cs;
440 if (*start == '\"')
442 for (i=1; start[i]!=0 && start[i]!='\"'; i++)
444 c= start[i];
445 if (c == '\\')
447 i++;
448 if (start[i])
450 switch (start[i])
452 case 'a': cs+= '\a'; break;
453 case 'b': cs+= '\b'; break;
454 case 'e': cs+= '\x1b'; break;
455 case 'f': cs+= '\f'; break;
456 case 'n': cs+= '\n'; break;
457 case 'r': cs+= '\r'; break;
458 case 't': cs+= '\t'; break;
459 case 'v': cs+= '\v'; break;
460 case '\'': cs+= '\''; break;
461 case '\"': cs+= '\"'; break;
462 default:
463 cs+= start[i];
464 break;
467 //i++;
469 else
470 cs+= c;
472 return cs;
474 else
476 int l= strcspn(start, " \t\v\r,;");
477 for (i=0; i<l; i++)
478 cs+= start[i];
480 return cs;
483 bool
484 cl_cmdline::expand_commands(chars *params)
486 int start= -1, end= -1;
487 int i, level= 0;
488 char *s= params->str();
489 if (params->empty())
490 return false;
491 for (i= 0; s[i]; i++)
493 if (s[i] == '\\')
495 i++;
497 else if (s[i] == '$')
499 if (s[++i] == '(')
501 if ((level == 0) && s[i+1])
502 start= ++i;
503 level++;
506 else if (s[i] == ')')
508 level--;
509 if (level == 0)
510 end= i-1;
513 //printf("S:%d E:%d L:%d\n",start,end,level);
514 if ((start < 0) && (end < 0))
515 return true;
516 if ((start < 0) || (end < 0) || (level != 0))
518 con->dd_cprintf("error", "Syntax error: unbalanced command expansion\n");
519 return false;
521 chars cmd;
522 cmd.appendn(&s[start], end-start+1);
523 //printf("OK |%s|\n", cmd.c_str());
524 return true;
528 cl_cmdline::shift(void)
530 char *s= skip_delims(cmd);
532 params->free_all();
533 tokens->free_all();
534 set_name(0);
535 if (s && *s)
537 while (*s &&
538 strchr(" \t\v\r,;#", *s) == NULL)
539 s++;
540 s= skip_delims(s);
541 char *p= strdup(s), *r= rest?strdup(rest):(char*)NULL;
542 free(cmd);
543 cmd= p;
544 rest= r;
545 //params= new cl_list(2, 2, "params");
546 split();
547 if (strcmp(get_name(), "\n") == 0)
548 set_name(0);
550 return(have_real_name());
554 cl_cmdline::repeat(void)
556 const char *n;
557 return((n= get_name()) &&
558 *n == '\n');
561 class cl_cmd_arg *
562 cl_cmdline::param(int num)
564 if (num >= params->count)
565 return(0);
566 return((class cl_cmd_arg *)(params->at(num)));
569 void
570 cl_cmdline::insert_param(int pos, class cl_cmd_arg *param)
572 if (pos >= params->count)
573 params->add(param);
574 else
575 params->add_at(pos, param);
578 bool
579 cl_cmdline::syntax_match(class cl_uc *uc, const char *syntax)
581 if (!syntax)
582 return(false);
583 if (!*syntax &&
584 !params->count)
586 matched_syntax= syntax;
587 return(true);
589 if (!params->count)
590 return(false);
591 //printf("syntax %s?\n",syntax);
592 const char *p= syntax;
593 int iparam= 0;
594 class cl_cmd_arg *parm= (class cl_cmd_arg *)(params->at(iparam));
595 while (*p &&
596 parm)
598 //printf("***Checking %s as %c\n",parm->get_svalue(),*p);
599 if (uc)
601 switch (*p)
603 case SY_ADDR:
604 if (!parm->as_address(uc))
605 return(false);
606 //printf("ADDRESS match %lx\n",parm->value.address);
607 break;
608 case SY_MEMORY:
609 if (!parm->as_memory(uc))
610 return(false);
611 //printf("MEMORY match %s\n",parm->value.memory->class_name);
612 break;
613 case SY_BIT:
614 if (!parm->as_bit(uc))
615 return(false);
616 break;
617 case SY_HW:
618 if (!parm->as_hw(uc))
619 return(false);
620 break;
621 case SY_CELL:
622 if (!parm->as_cell(uc))
623 return false;
624 break;
627 //else
629 switch (*p)
631 case SY_ADDR: case SY_MEMORY: case SY_BIT: break;
632 case SY_NUMBER:
633 if (!parm->as_number())
634 return(false);
635 break;
636 case SY_DATA:
637 if (!parm->as_data())
638 return(false);
639 break;
640 case SY_STRING:
641 if (!parm->as_string())
642 return(false);
643 break;
644 case SY_DATALIST:
645 if (!set_data_list(parm, &iparam))
646 return(false);
647 break;
648 //default: return(false);
651 p++;
652 iparam++;
653 if (iparam < params->count)
654 parm= (class cl_cmd_arg *)(params->at(iparam));
655 else
656 parm= 0;
658 if (!*p &&
659 !parm)
661 matched_syntax= syntax;
662 return(true);
664 return(false);
667 bool
668 cl_cmdline::set_data_list(class cl_cmd_arg *parm, int *iparm)
670 class cl_cmd_arg *next_parm;
671 int len, i, j;
672 t_mem *array, *temp;
674 len= 0;
675 array= 0;
676 for (i= *iparm, next_parm= param(i); next_parm; i++, next_parm= param(i))
678 if (next_parm->is_string())
680 int l;
681 char *s;
682 //s= proc_escape(next_parm->get_svalue(), &l);
683 if (!next_parm->as_string())
684 continue;
685 s= next_parm->value.string.string;
686 l= next_parm->value.string.len;
687 if (!array)
688 array= (t_mem*)malloc(sizeof(t_mem)*l);
689 else
691 temp= (t_mem*)realloc(array, sizeof(t_mem)*(l+len));
692 if (temp == NULL)
693 break;
694 array= temp;
696 for (j= 0; j < l; j++)
698 array[len]= s[j];
699 len++;
701 //if (s)
702 //free(s);
704 else
706 if (!next_parm->as_data())
708 if (array)
709 free(array);
710 return(false);
712 if (!array)
713 array= (t_mem*)malloc(sizeof(t_mem));
714 else
716 temp= (t_mem*)realloc(array, sizeof(t_mem)*(1+len));
717 if (temp == NULL)
718 break;
719 array= temp;
721 array[len]= next_parm->value.data;
722 len++;
725 *iparm= i;
726 parm->value.data_list.array= array;
727 parm->value.data_list.len= len;
728 return(true);
731 bool
732 cl_cmdline::restart_at_rest(void)
734 char *newcmd;
735 if ((rest == NULL) ||
736 (*rest == 0))
738 return false;
740 newcmd= strdup(rest);
741 if (cmd)
742 free(cmd);
743 cmd= newcmd;
744 return true;
749 * Command
750 *____________________________________________________________________________
753 cl_cmd::cl_cmd(enum cmd_operate_on op_on,
754 const char *aname,
755 int can_rep):
756 cl_base()
758 operate_on= op_on;
759 names= new cl_strings(1, 1, "names of a command");
760 names->add(aname?strdup(aname):strdup("unknown"));
761 can_repeat= can_rep;
762 usage_help= 0;
763 short_help= 0;//short_hlp;//?strdup(short_hlp):NULL;
764 long_help= 0;//long_hlp;//?strdup(long_hlp):NULL;
767 /*cl_cmd::cl_cmd(class cl_sim *asim):
768 cl_base()
770 sim= asim;
771 name= short_help= long_help= 0;
772 can_repeat= 0;
775 void
776 cl_cmd::set_help(const char *usage_hlp, const char *short_hlp, const char *long_hlp)
778 usage_help= usage_hlp;
779 short_help= short_hlp;
780 long_help= long_hlp;
783 cl_cmd::~cl_cmd(void)
785 delete names;
786 //if (short_help) free((void*)short_help);
787 //if (long_help) free((void*)long_help);
790 void
791 cl_cmd::add_name(const char *nam)
793 if (nam)
794 names->add(strdup(nam));
798 cl_cmd::name_match(const char *aname, int strict)
800 int i;
802 if (names->count == 0 &&
803 !aname)
804 return(1);
805 if (!aname)
806 return(0);
807 if (strict)
809 for (i= 0; i < names->count; i++)
811 const char *n= names->at(i);
812 if (strcmp(aname, n) == 0)
813 return(1);
816 else
818 for (i= 0; i < names->count; i++)
820 const char *n= names->at(i);
821 if (strstr(n, aname) == n)
822 return(1);
825 return(0);
829 cl_cmd::name_match(class cl_cmdline *cmdline, int strict)
831 return(name_match(cmdline->get_name(), strict));
835 cl_cmd::syntax_ok(class cl_cmdline *cmdline)
837 return(1);
841 cl_cmd::work(class cl_app *app,
842 class cl_cmdline *cmdline, class cl_console_base *con)
844 if (!syntax_ok(cmdline))
845 return(0);
846 class cl_sim *sim= app->get_sim();
847 class cl_uc *uc= 0;
848 if (sim)
849 uc= sim->uc;
850 switch (operate_on)
852 case operate_on_app:
853 if (!app)
855 con->dd_cprintf("error", "There is no application to work on!\n");
856 return(false);
858 return(do_work(app, cmdline, con));
859 case operate_on_sim:
860 if (!sim)
862 con->dd_cprintf("error", "There is no simulator to work on!\n");
863 return(false);
865 return(do_work(sim, cmdline, con));
866 case operate_on_uc:
867 if (!uc)
869 con->dd_cprintf("error", "There is no microcontroller to work on!\n");
870 return(false);
872 return(do_work(uc, cmdline, con));
873 default:
874 return(do_work(cmdline, con));
879 cl_cmd::do_work(class cl_cmdline *cmdline, class cl_console_base *con)
881 con->dd_cprintf("answer", "Command \"%s\" does nothing.\n",
882 names->at(0));
883 return(0);
887 cl_cmd::do_work(class cl_app *app,
888 class cl_cmdline *cmdline, class cl_console_base *con)
890 con->dd_cprintf("answer", "Command \"%s\" does nothing on application.\n",
891 names->at(0));
892 return(0);
896 cl_cmd::do_work(class cl_sim *sim,
897 class cl_cmdline *cmdline, class cl_console_base *con)
899 con->dd_cprintf("answer", "Command \"%s\" does nothing on simulator.\n",
900 names->at(0));
901 return(0);
905 cl_cmd::do_work(class cl_uc *uc,
906 class cl_cmdline *cmdline, class cl_console_base *con)
908 con->dd_cprintf("answer", "Command \"%s\" does nothing on microcontroller.\n",
909 names->at(0));
910 return(0);
913 void
914 cl_cmd::print_short(class cl_console_base *con)
916 int l= usage_help.len();
918 if (!con)
919 return;
921 if (usage_help.nempty())
922 con->dd_printf("%s", usage_help.c_str());
923 if (l > 19)
925 con->dd_printf("\n");
926 l=0;
928 while (l < 20)
930 con->dd_printf(" ");
931 l++;
933 if (short_help.nempty())
935 con->dd_printf("%s", short_help.c_str());
937 else
938 con->dd_printf("%s", names->at(0));
939 con->dd_printf("\n");
942 void
943 cl_cmd::syntax_error(class cl_console_base *con)
945 if (con)
947 if (short_help.nempty())
948 print_short(con);
949 else
950 con->dd_cprintf("error", "Error: wrong syntax\n");
955 * Set of commands
956 *____________________________________________________________________________
959 cl_cmdset::cl_cmdset(void):
960 cl_list(5, 5, "cmdset")
962 //sim= 0;
963 //last_command= 0;
966 /*cl_cmdset::cl_cmdset(class cl_sim *asim):
967 cl_list(5, 5)
969 sim= asim;
970 last_command= 0;
973 class cl_cmd *
974 cl_cmdset::get_cmd(class cl_cmdline *cmdline, bool accept_last)
976 int i;
978 // exact match
979 for (i= 0; i < count; i++)
981 class cl_cmd *c= (class cl_cmd *)at(i);
982 if (c->name_match(cmdline, 1))
983 return(c);
985 // not exact match
986 class cl_cmd *c_matched= 0;
987 for (i= 0; i < count; i++)
989 class cl_cmd *c= (class cl_cmd *)at(i);
990 if (c->name_match(cmdline, 0))
992 if (!c_matched)
993 c_matched= c;
994 else
995 return(0);
998 return(c_matched);
999 //return(0);
1002 class cl_cmd *
1003 cl_cmdset::get_cmd(const char *cmd_name)
1005 int i;
1007 for (i= 0; i < count; i++)
1009 class cl_cmd *c= (class cl_cmd *)at(i);
1010 if (c->name_match(cmd_name, 1))
1011 return(c);
1013 return(0);
1016 void
1017 cl_cmdset::del(char *nam)
1019 int i;
1021 if (!nam)
1022 return;
1023 for (i= 0; i < count; i++)
1025 class cl_cmd *cmd= (class cl_cmd *)(at(i));
1026 if (cmd->name_match(nam, 1))
1027 free_at(i);
1031 void
1032 cl_cmdset::replace(char *nam, class cl_cmd *cmd)
1034 int i;
1036 if (!nam)
1037 return;
1038 for (i= 0; i < count; i++)
1040 class cl_cmd *c= (class cl_cmd *)(at(i));
1041 if (c->name_match(nam, 1))
1043 delete c;
1044 put_at(i, cmd);
1051 * Composed command: subset of commands
1052 *____________________________________________________________________________
1055 cl_super_cmd::cl_super_cmd(const char *aname,
1056 int can_rep,
1057 class cl_cmdset *acommands):
1058 cl_cmd(operate_on_none, aname, can_rep)
1060 commands= acommands;
1063 cl_super_cmd::~cl_super_cmd(void)
1065 if (commands)
1066 delete commands;
1070 cl_super_cmd::work(class cl_app *app,
1071 class cl_cmdline *cmdline, class cl_console_base *con)
1073 class cl_cmd *cmd= 0;
1075 if (!commands)
1076 return(0);
1078 if (!cmdline->shift())
1080 if ((cmd= commands->get_cmd("_no_parameters_")) != 0)
1081 return(cmd->work(app, cmdline, con));
1082 int i;
1083 con->dd_printf("\"%s\" must be followed by the name of a subcommand\n"
1084 "List of subcommands:\n", names->at(0));
1085 for (i= 0; i < commands->count; i++)
1087 cmd= (class cl_cmd *)(commands->at(i));
1088 //con->dd_printf("%s\n", cmd->short_help.c_str());
1089 cmd->print_short(con);
1091 return(0);
1093 if ((cmd= commands->get_cmd(cmdline, con->is_interactive())) == NULL)
1095 con->dd_printf("Undefined subcommand: \"%s\". Try \"help %s\".\n",
1096 cmdline->get_name(), names->at(0));
1097 return(0);
1099 return(cmd->work(app, cmdline, con));
1103 /* End of cmd.src/command.cc */