19a409b68faf92a95cbf3b97a4fe1c0c84b232c7
[external/binutils.git] / gdb / cli / cli-decode.c
1 /* Handle lists of commands, their decoding and documentation, for GDB.
2    Copyright 1986, 1989, 1990, 1991, 1998, 2000, 2001
3    Free Software Foundation, Inc.
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
20 #include "defs.h"
21 #include "symtab.h"
22 #include <ctype.h>
23 #include "gnu-regex.h"
24
25 #ifdef UI_OUT
26 #include "ui-out.h"
27 #endif
28
29 #include "cli/cli-cmds.h"
30 #include "cli/cli-decode.h"
31
32 /* Prototypes for local functions */
33
34 static void undef_cmd_error (char *, char *);
35
36 static struct cmd_list_element *find_cmd (char *command,
37                                           int len,
38                                           struct cmd_list_element *clist,
39                                           int ignore_help_classes,
40                                           int *nfound);
41
42 static void help_all (struct ui_file *stream);
43 \f
44 /* Add element named NAME.
45    CLASS is the top level category into which commands are broken down
46    for "help" purposes.
47    FUN should be the function to execute the command;
48    it will get a character string as argument, with leading
49    and trailing blanks already eliminated.
50
51    DOC is a documentation string for the command.
52    Its first line should be a complete sentence.
53    It should start with ? for a command that is an abbreviation
54    or with * for a command that most users don't need to know about.
55
56    Add this command to command list *LIST.  
57
58    Returns a pointer to the added command (not necessarily the head 
59    of *LIST). */
60
61 struct cmd_list_element *
62 add_cmd (char *name, enum command_class class, void (*fun) (char *, int),
63          char *doc, struct cmd_list_element **list)
64 {
65   register struct cmd_list_element *c
66   = (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
67   struct cmd_list_element *p;
68
69   delete_cmd (name, list);
70
71   if (*list == NULL || strcmp ((*list)->name, name) >= 0)
72     {
73       c->next = *list;
74       *list = c;
75     }
76   else
77     {
78       p = *list;
79       while (p->next && strcmp (p->next->name, name) <= 0)
80         {
81           p = p->next;
82         }
83       c->next = p->next;
84       p->next = c;
85     }
86
87   c->name = name;
88   c->class = class;
89   c->function.cfunc = fun;
90   c->doc = doc;
91   c->flags = 0;
92   c->replacement = NULL;
93   c->hook_pre  = NULL;
94   c->hook_post = NULL;
95   c->hook_in = 0;
96   c->prefixlist = NULL;
97   c->prefixname = NULL;
98   c->allow_unknown = 0;
99   c->abbrev_flag = 0;
100   c->completer = make_symbol_completion_list;
101   c->type = not_set_cmd;
102   c->var = NULL;
103   c->var_type = var_boolean;
104   c->enums = NULL;
105   c->user_commands = NULL;
106   c->hookee_pre = NULL;
107   c->hookee_post = NULL;
108   c->cmd_pointer = NULL;
109
110   return c;
111 }
112
113 /* Same as above, except that the abbrev_flag is set. */
114 /* Note: Doesn't seem to be used anywhere currently. */
115
116 struct cmd_list_element *
117 add_abbrev_cmd (char *name, enum command_class class, void (*fun) (char *, int),
118                 char *doc, struct cmd_list_element **list)
119 {
120   register struct cmd_list_element *c
121   = add_cmd (name, class, fun, doc, list);
122
123   c->abbrev_flag = 1;
124   return c;
125 }
126
127 /* Deprecates a command CMD.
128    REPLACEMENT is the name of the command which should be used in place
129    of this command, or NULL if no such command exists.
130
131    This function does not check to see if command REPLACEMENT exists
132    since gdb may not have gotten around to adding REPLACEMENT when this
133    function is called.
134
135    Returns a pointer to the deprecated command.  */
136
137 struct cmd_list_element *
138 deprecate_cmd (struct cmd_list_element *cmd, char *replacement)
139 {
140   cmd->flags |= (CMD_DEPRECATED | DEPRECATED_WARN_USER);
141
142   if (replacement != NULL)
143     cmd->replacement = replacement;
144   else
145     cmd->replacement = NULL;
146
147   return cmd;
148 }
149
150 struct cmd_list_element *
151 add_alias_cmd (char *name, char *oldname, enum command_class class,
152                int abbrev_flag, struct cmd_list_element **list)
153 {
154   /* Must do this since lookup_cmd tries to side-effect its first arg */
155   char *copied_name;
156   register struct cmd_list_element *old;
157   register struct cmd_list_element *c;
158   copied_name = (char *) alloca (strlen (oldname) + 1);
159   strcpy (copied_name, oldname);
160   old = lookup_cmd (&copied_name, *list, "", 1, 1);
161
162   if (old == 0)
163     {
164       delete_cmd (name, list);
165       return 0;
166     }
167
168   c = add_cmd (name, class, old->function.cfunc, old->doc, list);
169   c->prefixlist = old->prefixlist;
170   c->prefixname = old->prefixname;
171   c->allow_unknown = old->allow_unknown;
172   c->abbrev_flag = abbrev_flag;
173   c->cmd_pointer = old;
174   return c;
175 }
176
177 /* Like add_cmd but adds an element for a command prefix:
178    a name that should be followed by a subcommand to be looked up
179    in another command list.  PREFIXLIST should be the address
180    of the variable containing that list.  */
181
182 struct cmd_list_element *
183 add_prefix_cmd (char *name, enum command_class class, void (*fun) (char *, int),
184                 char *doc, struct cmd_list_element **prefixlist,
185                 char *prefixname, int allow_unknown,
186                 struct cmd_list_element **list)
187 {
188   register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
189   c->prefixlist = prefixlist;
190   c->prefixname = prefixname;
191   c->allow_unknown = allow_unknown;
192   return c;
193 }
194
195 /* Like add_prefix_cmd but sets the abbrev_flag on the new command. */
196
197 struct cmd_list_element *
198 add_abbrev_prefix_cmd (char *name, enum command_class class,
199                        void (*fun) (char *, int), char *doc,
200                        struct cmd_list_element **prefixlist, char *prefixname,
201                        int allow_unknown, struct cmd_list_element **list)
202 {
203   register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
204   c->prefixlist = prefixlist;
205   c->prefixname = prefixname;
206   c->allow_unknown = allow_unknown;
207   c->abbrev_flag = 1;
208   return c;
209 }
210
211 /* This is an empty "cfunc".  */
212 void
213 not_just_help_class_command (char *args, int from_tty)
214 {
215 }
216
217 /* This is an empty "sfunc".  */
218 static void empty_sfunc (char *, int, struct cmd_list_element *);
219
220 static void
221 empty_sfunc (char *args, int from_tty, struct cmd_list_element *c)
222 {
223 }
224
225 /* Add element named NAME to command list LIST (the list for set
226    or some sublist thereof).
227    CLASS is as in add_cmd.
228    VAR_TYPE is the kind of thing we are setting.
229    VAR is address of the variable being controlled by this command.
230    DOC is the documentation string.  */
231
232 struct cmd_list_element *
233 add_set_cmd (char *name,
234              enum command_class class,
235              var_types var_type,
236              void *var,
237              char *doc,
238              struct cmd_list_element **list)
239 {
240   struct cmd_list_element *c
241   = add_cmd (name, class, NO_FUNCTION, doc, list);
242
243   c->type = set_cmd;
244   c->var_type = var_type;
245   c->var = var;
246   /* This needs to be something besides NO_FUNCTION so that this isn't
247      treated as a help class.  */
248   c->function.sfunc = empty_sfunc;
249   return c;
250 }
251
252 /* Add element named NAME to command list LIST (the list for set
253    or some sublist thereof).
254    CLASS is as in add_cmd.
255    ENUMLIST is a list of strings which may follow NAME.
256    VAR is address of the variable which will contain the matching string
257    (from ENUMLIST).
258    DOC is the documentation string.  */
259
260 struct cmd_list_element *
261 add_set_enum_cmd (char *name,
262                   enum command_class class,
263                   const char *enumlist[],
264                   const char **var,
265                   char *doc,
266                   struct cmd_list_element **list)
267 {
268   struct cmd_list_element *c
269   = add_set_cmd (name, class, var_enum, var, doc, list);
270   c->enums = enumlist;
271
272   return c;
273 }
274
275 /* Add element named NAME to command list LIST (the list for set
276    or some sublist thereof).
277    CLASS is as in add_cmd.
278    VAR is address of the variable which will contain the value.
279    DOC is the documentation string.  */
280 struct cmd_list_element *
281 add_set_auto_boolean_cmd (char *name,
282                           enum command_class class,
283                           enum cmd_auto_boolean *var,
284                           char *doc,
285                           struct cmd_list_element **list)
286 {
287   static const char *auto_boolean_enums[] = { "on", "off", "auto", NULL };
288   struct cmd_list_element *c;
289   c = add_set_cmd (name, class, var_auto_boolean, var, doc, list);
290   c->enums = auto_boolean_enums;
291   return c;
292 }
293
294 /* Where SETCMD has already been added, add the corresponding show
295    command to LIST and return a pointer to the added command (not 
296    necessarily the head of LIST).  */
297 struct cmd_list_element *
298 add_show_from_set (struct cmd_list_element *setcmd,
299                    struct cmd_list_element **list)
300 {
301   struct cmd_list_element *showcmd =
302   (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
303   struct cmd_list_element *p;
304
305   memcpy (showcmd, setcmd, sizeof (struct cmd_list_element));
306   delete_cmd (showcmd->name, list);
307   showcmd->type = show_cmd;
308
309   /* Replace "set " at start of docstring with "show ".  */
310   if (setcmd->doc[0] == 'S' && setcmd->doc[1] == 'e'
311       && setcmd->doc[2] == 't' && setcmd->doc[3] == ' ')
312     showcmd->doc = concat ("Show ", setcmd->doc + 4, NULL);
313   else
314     fprintf_unfiltered (gdb_stderr, "GDB internal error: Bad docstring for set command\n");
315
316   if (*list == NULL || strcmp ((*list)->name, showcmd->name) >= 0)
317     {
318       showcmd->next = *list;
319       *list = showcmd;
320     }
321   else
322     {
323       p = *list;
324       while (p->next && strcmp (p->next->name, showcmd->name) <= 0)
325         {
326           p = p->next;
327         }
328       showcmd->next = p->next;
329       p->next = showcmd;
330     }
331
332   return showcmd;
333 }
334
335 /* Remove the command named NAME from the command list.  */
336
337 void
338 delete_cmd (char *name, struct cmd_list_element **list)
339 {
340   register struct cmd_list_element *c;
341   struct cmd_list_element *p;
342
343   while (*list && STREQ ((*list)->name, name))
344     {
345       if ((*list)->hookee_pre)
346       (*list)->hookee_pre->hook_pre = 0;   /* Hook slips out of its mouth */
347       if ((*list)->hookee_post)
348       (*list)->hookee_post->hook_post = 0; /* Hook slips out of its bottom  */
349       p = (*list)->next;
350       xfree (* list);
351       *list = p;
352     }
353
354   if (*list)
355     for (c = *list; c->next;)
356       {
357         if (STREQ (c->next->name, name))
358           {
359           if (c->next->hookee_pre)
360             c->next->hookee_pre->hook_pre = 0; /* hooked cmd gets away.  */
361           if (c->next->hookee_post)
362             c->next->hookee_post->hook_post = 0; /* remove post hook */
363                                                /* :( no fishing metaphore */
364             p = c->next->next;
365             xfree (c->next);
366             c->next = p;
367           }
368         else
369           c = c->next;
370       }
371 }
372 \f
373 /* Shorthands to the commands above. */
374
375 /* Add an element to the list of info subcommands.  */
376
377 struct cmd_list_element *
378 add_info (char *name, void (*fun) (char *, int), char *doc)
379 {
380   return add_cmd (name, no_class, fun, doc, &infolist);
381 }
382
383 /* Add an alias to the list of info subcommands.  */
384
385 struct cmd_list_element *
386 add_info_alias (char *name, char *oldname, int abbrev_flag)
387 {
388   return add_alias_cmd (name, oldname, 0, abbrev_flag, &infolist);
389 }
390
391 /* Add an element to the list of commands.  */
392
393 struct cmd_list_element *
394 add_com (char *name, enum command_class class, void (*fun) (char *, int),
395          char *doc)
396 {
397   return add_cmd (name, class, fun, doc, &cmdlist);
398 }
399
400 /* Add an alias or abbreviation command to the list of commands.  */
401
402 struct cmd_list_element *
403 add_com_alias (char *name, char *oldname, enum command_class class,
404                int abbrev_flag)
405 {
406   return add_alias_cmd (name, oldname, class, abbrev_flag, &cmdlist);
407 }
408 \f
409 /* Recursively walk the commandlist structures, and print out the
410    documentation of commands that match our regex in either their
411    name, or their documentation.
412 */
413 void 
414 apropos_cmd (struct ui_file *stream, struct cmd_list_element *commandlist,
415                          struct re_pattern_buffer *regex, char *prefix)
416 {
417   register struct cmd_list_element *c;
418   int returnvalue=1; /*Needed to avoid double printing*/
419   /* Walk through the commands */
420   for (c=commandlist;c;c=c->next)
421     {
422       if (c->name != NULL)
423         {
424           /* Try to match against the name*/
425           returnvalue=re_search(regex,c->name,strlen(c->name),0,strlen(c->name),NULL);
426           if (returnvalue >= 0)
427             {
428               /* Stolen from help_cmd_list. We don't directly use
429                * help_cmd_list because it doesn't let us print out
430                * single commands
431                */
432               fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
433               print_doc_line (stream, c->doc);
434               fputs_filtered ("\n", stream);
435               returnvalue=0; /*Set this so we don't print it again.*/
436             }
437         }
438       if (c->doc != NULL && returnvalue != 0)
439         {
440           /* Try to match against documentation */
441           if (re_search(regex,c->doc,strlen(c->doc),0,strlen(c->doc),NULL) >=0)
442             {
443               /* Stolen from help_cmd_list. We don't directly use
444                * help_cmd_list because it doesn't let us print out
445                * single commands
446                */
447               fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
448               print_doc_line (stream, c->doc);
449               fputs_filtered ("\n", stream);
450             }
451         }
452       /* Check if this command has subcommands */
453       if (c->prefixlist != NULL)
454         {
455           /* Recursively call ourselves on the subcommand list,
456              passing the right prefix in.
457           */
458           apropos_cmd (stream,*c->prefixlist,regex,c->prefixname);
459         }
460     }
461 }
462
463 /* This command really has to deal with two things:
464  *     1) I want documentation on *this string* (usually called by
465  * "help commandname").
466  *     2) I want documentation on *this list* (usually called by
467  * giving a command that requires subcommands.  Also called by saying
468  * just "help".)
469  *
470  *   I am going to split this into two seperate comamnds, help_cmd and
471  * help_list. 
472  */
473
474 void
475 help_cmd (char *command, struct ui_file *stream)
476 {
477   struct cmd_list_element *c;
478   extern struct cmd_list_element *cmdlist;
479
480   if (!command)
481     {
482       help_list (cmdlist, "", all_classes, stream);
483       return;
484     }
485
486   if (strcmp (command, "all") == 0)
487     {
488       help_all (stream);
489       return;
490     }
491
492   c = lookup_cmd (&command, cmdlist, "", 0, 0);
493
494   if (c == 0)
495     return;
496
497   /* There are three cases here.
498      If c->prefixlist is nonzero, we have a prefix command.
499      Print its documentation, then list its subcommands.
500
501      If c->function is nonzero, we really have a command.
502      Print its documentation and return.
503
504      If c->function is zero, we have a class name.
505      Print its documentation (as if it were a command)
506      and then set class to the number of this class
507      so that the commands in the class will be listed.  */
508
509   fputs_filtered (c->doc, stream);
510   fputs_filtered ("\n", stream);
511
512   if (c->prefixlist == 0 && c->function.cfunc != NULL)
513     return;
514   fprintf_filtered (stream, "\n");
515
516   /* If this is a prefix command, print it's subcommands */
517   if (c->prefixlist)
518     help_list (*c->prefixlist, c->prefixname, all_commands, stream);
519
520   /* If this is a class name, print all of the commands in the class */
521   if (c->function.cfunc == NULL)
522     help_list (cmdlist, "", c->class, stream);
523
524   if (c->hook_pre || c->hook_post)
525     fprintf_filtered (stream,
526                       "\nThis command has a hook (or hooks) defined:\n");
527
528   if (c->hook_pre)
529     fprintf_filtered (stream, 
530                       "\tThis command is run after  : %s (pre hook)\n",
531                     c->hook_pre->name);
532   if (c->hook_post)
533     fprintf_filtered (stream, 
534                       "\tThis command is run before : %s (post hook)\n",
535                     c->hook_post->name);
536 }
537
538 /*
539  * Get a specific kind of help on a command list.
540  *
541  * LIST is the list.
542  * CMDTYPE is the prefix to use in the title string.
543  * CLASS is the class with which to list the nodes of this list (see
544  * documentation for help_cmd_list below),  As usual, ALL_COMMANDS for
545  * everything, ALL_CLASSES for just classes, and non-negative for only things
546  * in a specific class.
547  * and STREAM is the output stream on which to print things.
548  * If you call this routine with a class >= 0, it recurses.
549  */
550 void
551 help_list (struct cmd_list_element *list, char *cmdtype,
552            enum command_class class, struct ui_file *stream)
553 {
554   int len;
555   char *cmdtype1, *cmdtype2;
556
557   /* If CMDTYPE is "foo ", CMDTYPE1 gets " foo" and CMDTYPE2 gets "foo sub"  */
558   len = strlen (cmdtype);
559   cmdtype1 = (char *) alloca (len + 1);
560   cmdtype1[0] = 0;
561   cmdtype2 = (char *) alloca (len + 4);
562   cmdtype2[0] = 0;
563   if (len)
564     {
565       cmdtype1[0] = ' ';
566       strncpy (cmdtype1 + 1, cmdtype, len - 1);
567       cmdtype1[len] = 0;
568       strncpy (cmdtype2, cmdtype, len - 1);
569       strcpy (cmdtype2 + len - 1, " sub");
570     }
571
572   if (class == all_classes)
573     fprintf_filtered (stream, "List of classes of %scommands:\n\n", cmdtype2);
574   else
575     fprintf_filtered (stream, "List of %scommands:\n\n", cmdtype2);
576
577   help_cmd_list (list, class, cmdtype, (int) class >= 0, stream);
578
579   if (class == all_classes)
580     fprintf_filtered (stream, "\n\
581 Type \"help%s\" followed by a class name for a list of commands in that class.",
582                       cmdtype1);
583
584   fprintf_filtered (stream, "\n\
585 Type \"help%s\" followed by %scommand name for full documentation.\n\
586 Command name abbreviations are allowed if unambiguous.\n",
587                     cmdtype1, cmdtype2);
588 }
589
590 static void
591 help_all (struct ui_file *stream)
592 {
593   struct cmd_list_element *c;
594   extern struct cmd_list_element *cmdlist;
595
596   for (c = cmdlist; c; c = c->next)
597     {
598       if (c->abbrev_flag)
599         continue;
600       /* If this is a prefix command, print it's subcommands */
601       if (c->prefixlist)
602         help_cmd_list (*c->prefixlist, all_commands, c->prefixname, 0, stream);
603     
604       /* If this is a class name, print all of the commands in the class */
605       else if (c->function.cfunc == NULL)
606         help_cmd_list (cmdlist, c->class, "", 0, stream);
607     }
608 }
609
610 /* Print only the first line of STR on STREAM.  */
611 void
612 print_doc_line (struct ui_file *stream, char *str)
613 {
614   static char *line_buffer = 0;
615   static int line_size;
616   register char *p;
617
618   if (!line_buffer)
619     {
620       line_size = 80;
621       line_buffer = (char *) xmalloc (line_size);
622     }
623
624   p = str;
625   while (*p && *p != '\n' && *p != '.' && *p != ',')
626     p++;
627   if (p - str > line_size - 1)
628     {
629       line_size = p - str + 1;
630       xfree (line_buffer);
631       line_buffer = (char *) xmalloc (line_size);
632     }
633   strncpy (line_buffer, str, p - str);
634   line_buffer[p - str] = '\0';
635   if (islower (line_buffer[0]))
636     line_buffer[0] = toupper (line_buffer[0]);
637 #ifdef UI_OUT
638   ui_out_text (uiout, line_buffer);
639 #else
640   fputs_filtered (line_buffer, stream);
641 #endif
642 }
643
644 /*
645  * Implement a help command on command list LIST.
646  * RECURSE should be non-zero if this should be done recursively on
647  * all sublists of LIST.
648  * PREFIX is the prefix to print before each command name.
649  * STREAM is the stream upon which the output should be written.
650  * CLASS should be:
651  *      A non-negative class number to list only commands in that
652  * class.
653  *      ALL_COMMANDS to list all commands in list.
654  *      ALL_CLASSES  to list all classes in list.
655  *
656  *   Note that RECURSE will be active on *all* sublists, not just the
657  * ones selected by the criteria above (ie. the selection mechanism
658  * is at the low level, not the high-level).
659  */
660 void
661 help_cmd_list (struct cmd_list_element *list, enum command_class class,
662                char *prefix, int recurse, struct ui_file *stream)
663 {
664   register struct cmd_list_element *c;
665
666   for (c = list; c; c = c->next)
667     {
668       if (c->abbrev_flag == 0 &&
669           (class == all_commands
670            || (class == all_classes && c->function.cfunc == NULL)
671            || (class == c->class && c->function.cfunc != NULL)))
672         {
673           fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
674           print_doc_line (stream, c->doc);
675           fputs_filtered ("\n", stream);
676         }
677       if (recurse
678           && c->prefixlist != 0
679           && c->abbrev_flag == 0)
680         help_cmd_list (*c->prefixlist, class, c->prefixname, 1, stream);
681     }
682 }
683 \f
684
685 /* Search the input clist for 'command'.  Return the command if
686    found (or NULL if not), and return the number of commands
687    found in nfound */
688
689 static struct cmd_list_element *
690 find_cmd (char *command, int len, struct cmd_list_element *clist,
691           int ignore_help_classes, int *nfound)
692 {
693   struct cmd_list_element *found, *c;
694
695   found = (struct cmd_list_element *) NULL;
696   *nfound = 0;
697   for (c = clist; c; c = c->next)
698     if (!strncmp (command, c->name, len)
699         && (!ignore_help_classes || c->function.cfunc))
700       {
701         found = c;
702         (*nfound)++;
703         if (c->name[len] == '\0')
704           {
705             *nfound = 1;
706             break;
707           }
708       }
709   return found;
710 }
711
712 /* This routine takes a line of TEXT and a CLIST in which to start the
713    lookup.  When it returns it will have incremented the text pointer past
714    the section of text it matched, set *RESULT_LIST to point to the list in
715    which the last word was matched, and will return a pointer to the cmd
716    list element which the text matches.  It will return NULL if no match at
717    all was possible.  It will return -1 (cast appropriately, ick) if ambigous
718    matches are possible; in this case *RESULT_LIST will be set to point to
719    the list in which there are ambiguous choices (and *TEXT will be set to
720    the ambiguous text string).
721
722    If the located command was an abbreviation, this routine returns the base
723    command of the abbreviation.
724
725    It does no error reporting whatsoever; control will always return
726    to the superior routine.
727
728    In the case of an ambiguous return (-1), *RESULT_LIST will be set to point
729    at the prefix_command (ie. the best match) *or* (special case) will be NULL
730    if no prefix command was ever found.  For example, in the case of "info a",
731    "info" matches without ambiguity, but "a" could be "args" or "address", so
732    *RESULT_LIST is set to the cmd_list_element for "info".  So in this case
733    RESULT_LIST should not be interpeted as a pointer to the beginning of a
734    list; it simply points to a specific command.  In the case of an ambiguous
735    return *TEXT is advanced past the last non-ambiguous prefix (e.g.
736    "info t" can be "info types" or "info target"; upon return *TEXT has been
737    advanced past "info ").
738
739    If RESULT_LIST is NULL, don't set *RESULT_LIST (but don't otherwise
740    affect the operation).
741
742    This routine does *not* modify the text pointed to by TEXT.
743
744    If IGNORE_HELP_CLASSES is nonzero, ignore any command list elements which
745    are actually help classes rather than commands (i.e. the function field of
746    the struct cmd_list_element is NULL).  */
747
748 struct cmd_list_element *
749 lookup_cmd_1 (char **text, struct cmd_list_element *clist,
750               struct cmd_list_element **result_list, int ignore_help_classes)
751 {
752   char *p, *command;
753   int len, tmp, nfound;
754   struct cmd_list_element *found, *c;
755   char *line = *text;
756
757   while (**text == ' ' || **text == '\t')
758     (*text)++;
759
760   /* Treating underscores as part of command words is important
761      so that "set args_foo()" doesn't get interpreted as
762      "set args _foo()".  */
763   for (p = *text;
764        *p && (isalnum (*p) || *p == '-' || *p == '_' ||
765               (tui_version &&
766                (*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
767               (xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
768        p++)
769     ;
770
771   /* If nothing but whitespace, return 0.  */
772   if (p == *text)
773     return 0;
774
775   len = p - *text;
776
777   /* *text and p now bracket the first command word to lookup (and
778      it's length is len).  We copy this into a local temporary */
779
780
781   command = (char *) alloca (len + 1);
782   for (tmp = 0; tmp < len; tmp++)
783     {
784       char x = (*text)[tmp];
785       command[tmp] = x;
786     }
787   command[len] = '\0';
788
789   /* Look it up.  */
790   found = 0;
791   nfound = 0;
792   found = find_cmd (command, len, clist, ignore_help_classes, &nfound);
793
794   /* 
795      ** We didn't find the command in the entered case, so lower case it
796      ** and search again.
797    */
798   if (!found || nfound == 0)
799     {
800       for (tmp = 0; tmp < len; tmp++)
801         {
802           char x = command[tmp];
803           command[tmp] = isupper (x) ? tolower (x) : x;
804         }
805       found = find_cmd (command, len, clist, ignore_help_classes, &nfound);
806     }
807
808   /* If nothing matches, we have a simple failure.  */
809   if (nfound == 0)
810     return 0;
811
812   if (nfound > 1)
813     {
814       if (result_list != NULL)
815         /* Will be modified in calling routine
816            if we know what the prefix command is.  */
817         *result_list = 0;
818       return (struct cmd_list_element *) -1;    /* Ambiguous.  */
819     }
820
821   /* We've matched something on this list.  Move text pointer forward. */
822
823   *text = p;
824
825   if (found->cmd_pointer)
826     {
827       /* We drop the alias (abbreviation) in favor of the command it is
828        pointing to.  If the alias is deprecated, though, we need to
829        warn the user about it before we drop it.  Note that while we
830        are warning about the alias, we may also warn about the command
831        itself and we will adjust the appropriate DEPRECATED_WARN_USER
832        flags */
833       
834       if (found->flags & DEPRECATED_WARN_USER)
835       deprecated_cmd_warning (&line);
836       found = found->cmd_pointer;
837     }
838   /* If we found a prefix command, keep looking.  */
839
840   if (found->prefixlist)
841     {
842       c = lookup_cmd_1 (text, *found->prefixlist, result_list,
843                         ignore_help_classes);
844       if (!c)
845         {
846           /* Didn't find anything; this is as far as we got.  */
847           if (result_list != NULL)
848             *result_list = clist;
849           return found;
850         }
851       else if (c == (struct cmd_list_element *) -1)
852         {
853           /* We've gotten this far properly, but the next step
854              is ambiguous.  We need to set the result list to the best
855              we've found (if an inferior hasn't already set it).  */
856           if (result_list != NULL)
857             if (!*result_list)
858               /* This used to say *result_list = *found->prefixlist
859                  If that was correct, need to modify the documentation
860                  at the top of this function to clarify what is supposed
861                  to be going on.  */
862               *result_list = found;
863           return c;
864         }
865       else
866         {
867           /* We matched!  */
868           return c;
869         }
870     }
871   else
872     {
873       if (result_list != NULL)
874         *result_list = clist;
875       return found;
876     }
877 }
878
879 /* All this hair to move the space to the front of cmdtype */
880
881 static void
882 undef_cmd_error (char *cmdtype, char *q)
883 {
884   error ("Undefined %scommand: \"%s\".  Try \"help%s%.*s\".",
885          cmdtype,
886          q,
887          *cmdtype ? " " : "",
888          strlen (cmdtype) - 1,
889          cmdtype);
890 }
891
892 /* Look up the contents of *LINE as a command in the command list LIST.
893    LIST is a chain of struct cmd_list_element's.
894    If it is found, return the struct cmd_list_element for that command
895    and update *LINE to point after the command name, at the first argument.
896    If not found, call error if ALLOW_UNKNOWN is zero
897    otherwise (or if error returns) return zero.
898    Call error if specified command is ambiguous,
899    unless ALLOW_UNKNOWN is negative.
900    CMDTYPE precedes the word "command" in the error message.
901
902    If INGNORE_HELP_CLASSES is nonzero, ignore any command list
903    elements which are actually help classes rather than commands (i.e.
904    the function field of the struct cmd_list_element is 0).  */
905
906 struct cmd_list_element *
907 lookup_cmd (char **line, struct cmd_list_element *list, char *cmdtype,
908             int allow_unknown, int ignore_help_classes)
909 {
910   struct cmd_list_element *last_list = 0;
911   struct cmd_list_element *c =
912   lookup_cmd_1 (line, list, &last_list, ignore_help_classes);
913
914   /* Note: Do not remove trailing whitespace here because this
915      would be wrong for complete_command.  Jim Kingdon  */
916
917   if (!c)
918     {
919       if (!allow_unknown)
920         {
921           if (!*line)
922             error ("Lack of needed %scommand", cmdtype);
923           else
924             {
925               char *p = *line, *q;
926
927               while (isalnum (*p) || *p == '-')
928                 p++;
929
930               q = (char *) alloca (p - *line + 1);
931               strncpy (q, *line, p - *line);
932               q[p - *line] = '\0';
933               undef_cmd_error (cmdtype, q);
934             }
935         }
936       else
937         return 0;
938     }
939   else if (c == (struct cmd_list_element *) -1)
940     {
941       /* Ambigous.  Local values should be off prefixlist or called
942          values.  */
943       int local_allow_unknown = (last_list ? last_list->allow_unknown :
944                                  allow_unknown);
945       char *local_cmdtype = last_list ? last_list->prefixname : cmdtype;
946       struct cmd_list_element *local_list =
947       (last_list ? *(last_list->prefixlist) : list);
948
949       if (local_allow_unknown < 0)
950         {
951           if (last_list)
952             return last_list;   /* Found something.  */
953           else
954             return 0;           /* Found nothing.  */
955         }
956       else
957         {
958           /* Report as error.  */
959           int amb_len;
960           char ambbuf[100];
961
962           for (amb_len = 0;
963                ((*line)[amb_len] && (*line)[amb_len] != ' '
964                 && (*line)[amb_len] != '\t');
965                amb_len++)
966             ;
967
968           ambbuf[0] = 0;
969           for (c = local_list; c; c = c->next)
970             if (!strncmp (*line, c->name, amb_len))
971               {
972                 if (strlen (ambbuf) + strlen (c->name) + 6 < (int) sizeof ambbuf)
973                   {
974                     if (strlen (ambbuf))
975                       strcat (ambbuf, ", ");
976                     strcat (ambbuf, c->name);
977                   }
978                 else
979                   {
980                     strcat (ambbuf, "..");
981                     break;
982                   }
983               }
984           error ("Ambiguous %scommand \"%s\": %s.", local_cmdtype,
985                  *line, ambbuf);
986           return 0;             /* lint */
987         }
988     }
989   else
990     {
991       /* We've got something.  It may still not be what the caller
992          wants (if this command *needs* a subcommand).  */
993       while (**line == ' ' || **line == '\t')
994         (*line)++;
995
996       if (c->prefixlist && **line && !c->allow_unknown)
997         undef_cmd_error (c->prefixname, *line);
998
999       /* Seems to be what he wants.  Return it.  */
1000       return c;
1001     }
1002   return 0;
1003 }
1004
1005 /* We are here presumably because an alias or command in *TEXT is 
1006    deprecated and a warning message should be generated.  This function
1007    decodes *TEXT and potentially generates a warning message as outlined
1008    below.
1009    
1010    Example for 'set endian big' which has a fictitious alias 'seb'.
1011    
1012    If alias wasn't used in *TEXT, and the command is deprecated:
1013    "warning: 'set endian big' is deprecated." 
1014    
1015    If alias was used, and only the alias is deprecated:
1016    "warning: 'seb' an alias for the command 'set endian big' is deprecated."
1017    
1018    If alias was used and command is deprecated (regardless of whether the
1019    alias itself is deprecated:
1020    
1021    "warning: 'set endian big' (seb) is deprecated."
1022
1023    After the message has been sent, clear the appropriate flags in the
1024    command and/or the alias so the user is no longer bothered.
1025    
1026 */
1027 void
1028 deprecated_cmd_warning (char **text)
1029 {
1030   struct cmd_list_element *alias = NULL;
1031   struct cmd_list_element *prefix_cmd = NULL;
1032   struct cmd_list_element *cmd = NULL;
1033   struct cmd_list_element *c;
1034   char *type;
1035  
1036   if (!lookup_cmd_composition (*text, &alias, &prefix_cmd, &cmd))
1037     /* return if text doesn't evaluate to a command */
1038     return;
1039
1040   if (!((alias ? (alias->flags & DEPRECATED_WARN_USER) : 0)
1041       || (cmd->flags & DEPRECATED_WARN_USER) ) ) 
1042     /* return if nothing is deprecated */
1043     return;
1044   
1045   printf_filtered ("Warning:");
1046   
1047   if (alias && !(cmd->flags & CMD_DEPRECATED))
1048     printf_filtered (" '%s', an alias for the", alias->name);
1049     
1050   printf_filtered (" command '");
1051   
1052   if (prefix_cmd)
1053     printf_filtered ("%s", prefix_cmd->prefixname);
1054   
1055   printf_filtered ("%s", cmd->name);
1056
1057   if (alias && (cmd->flags & CMD_DEPRECATED))
1058     printf_filtered ("' (%s) is deprecated.\n", alias->name);
1059   else
1060     printf_filtered ("' is deprecated.\n"); 
1061   
1062
1063   /* if it is only the alias that is deprecated, we want to indicate the
1064      new alias, otherwise we'll indicate the new command */
1065
1066   if (alias && !(cmd->flags & CMD_DEPRECATED))
1067     {
1068       if (alias->replacement)
1069       printf_filtered ("Use '%s'.\n\n", alias->replacement);
1070       else
1071       printf_filtered ("No alternative known.\n\n");
1072      }  
1073   else
1074     {
1075       if (cmd->replacement)
1076       printf_filtered ("Use '%s'.\n\n", cmd->replacement);
1077       else
1078       printf_filtered ("No alternative known.\n\n");
1079     }
1080
1081   /* We've warned you, now we'll keep quiet */
1082   if (alias)
1083     alias->flags &= ~DEPRECATED_WARN_USER;
1084   
1085   cmd->flags &= ~DEPRECATED_WARN_USER;
1086 }
1087
1088
1089
1090 /* Look up the contents of LINE as a command in the command list 'cmdlist'. 
1091    Return 1 on success, 0 on failure.
1092    
1093    If LINE refers to an alias, *alias will point to that alias.
1094    
1095    If LINE is a postfix command (i.e. one that is preceeded by a prefix
1096    command) set *prefix_cmd.
1097    
1098    Set *cmd to point to the command LINE indicates.
1099    
1100    If any of *alias, *prefix_cmd, or *cmd cannot be determined or do not 
1101    exist, they are NULL when we return.
1102    
1103 */
1104 int
1105 lookup_cmd_composition (char *text,
1106                       struct cmd_list_element **alias,
1107                       struct cmd_list_element **prefix_cmd, 
1108                       struct cmd_list_element **cmd)
1109 {
1110   char *p, *command;
1111   int len, tmp, nfound;
1112   struct cmd_list_element *cur_list;
1113   struct cmd_list_element *prev_cmd;
1114   *alias = NULL;
1115   *prefix_cmd = NULL;
1116   *cmd = NULL;
1117   
1118   cur_list = cmdlist;
1119   
1120   while (1)
1121     { 
1122       /* Go through as many command lists as we need to 
1123        to find the command TEXT refers to. */
1124       
1125       prev_cmd = *cmd;
1126       
1127       while (*text == ' ' || *text == '\t')
1128       (text)++;
1129       
1130       /* Treating underscores as part of command words is important
1131        so that "set args_foo()" doesn't get interpreted as
1132        "set args _foo()".  */
1133       for (p = text;
1134          *p && (isalnum (*p) || *p == '-' || *p == '_' ||
1135                 (tui_version &&
1136                  (*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
1137                 (xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
1138          p++)
1139       ;
1140       
1141       /* If nothing but whitespace, return.  */
1142       if (p == text)
1143       return 0;
1144       
1145       len = p - text;
1146       
1147       /* text and p now bracket the first command word to lookup (and
1148        it's length is len).  We copy this into a local temporary */
1149       
1150       command = (char *) alloca (len + 1);
1151       for (tmp = 0; tmp < len; tmp++)
1152       {
1153         char x = text[tmp];
1154         command[tmp] = x;
1155       }
1156       command[len] = '\0';
1157       
1158       /* Look it up.  */
1159       *cmd = 0;
1160       nfound = 0;
1161       *cmd = find_cmd (command, len, cur_list, 1, &nfound);
1162       
1163       /* We didn't find the command in the entered case, so lower case it
1164        and search again.
1165       */
1166       if (!*cmd || nfound == 0)
1167       {
1168         for (tmp = 0; tmp < len; tmp++)
1169           {
1170             char x = command[tmp];
1171             command[tmp] = isupper (x) ? tolower (x) : x;
1172           }
1173         *cmd = find_cmd (command, len, cur_list, 1, &nfound);
1174       }
1175       
1176       if (*cmd == (struct cmd_list_element *) -1)
1177       {
1178         return 0;              /* ambiguous */
1179       }
1180       
1181       if (*cmd == NULL)
1182       return 0;                /* nothing found */
1183       else
1184       {
1185         if ((*cmd)->cmd_pointer)
1186           {
1187             /* cmd was actually an alias, we note that an alias was used 
1188                (by assigning *alais) and we set *cmd. 
1189              */
1190             *alias = *cmd;
1191             *cmd = (*cmd)->cmd_pointer;
1192           }
1193         *prefix_cmd = prev_cmd;
1194       }
1195       if ((*cmd)->prefixlist)
1196       cur_list = *(*cmd)->prefixlist;
1197       else
1198       return 1;
1199       
1200       text = p;
1201     }
1202 }
1203
1204 /* Helper function for SYMBOL_COMPLETION_FUNCTION.  */
1205
1206 /* Return a vector of char pointers which point to the different
1207    possible completions in LIST of TEXT.  
1208
1209    WORD points in the same buffer as TEXT, and completions should be
1210    returned relative to this position.  For example, suppose TEXT is "foo"
1211    and we want to complete to "foobar".  If WORD is "oo", return
1212    "oobar"; if WORD is "baz/foo", return "baz/foobar".  */
1213
1214 char **
1215 complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
1216 {
1217   struct cmd_list_element *ptr;
1218   char **matchlist;
1219   int sizeof_matchlist;
1220   int matches;
1221   int textlen = strlen (text);
1222
1223   sizeof_matchlist = 10;
1224   matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
1225   matches = 0;
1226
1227   for (ptr = list; ptr; ptr = ptr->next)
1228     if (!strncmp (ptr->name, text, textlen)
1229         && !ptr->abbrev_flag
1230         && (ptr->function.cfunc
1231             || ptr->prefixlist))
1232       {
1233         if (matches == sizeof_matchlist)
1234           {
1235             sizeof_matchlist *= 2;
1236             matchlist = (char **) xrealloc ((char *) matchlist,
1237                                             (sizeof_matchlist
1238                                              * sizeof (char *)));
1239           }
1240
1241         matchlist[matches] = (char *)
1242           xmalloc (strlen (word) + strlen (ptr->name) + 1);
1243         if (word == text)
1244           strcpy (matchlist[matches], ptr->name);
1245         else if (word > text)
1246           {
1247             /* Return some portion of ptr->name.  */
1248             strcpy (matchlist[matches], ptr->name + (word - text));
1249           }
1250         else
1251           {
1252             /* Return some of text plus ptr->name.  */
1253             strncpy (matchlist[matches], word, text - word);
1254             matchlist[matches][text - word] = '\0';
1255             strcat (matchlist[matches], ptr->name);
1256           }
1257         ++matches;
1258       }
1259
1260   if (matches == 0)
1261     {
1262       xfree (matchlist);
1263       matchlist = 0;
1264     }
1265   else
1266     {
1267       matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
1268                                                         * sizeof (char *)));
1269       matchlist[matches] = (char *) 0;
1270     }
1271
1272   return matchlist;
1273 }
1274
1275 /* Helper function for SYMBOL_COMPLETION_FUNCTION.  */
1276
1277 /* Return a vector of char pointers which point to the different
1278    possible completions in CMD of TEXT.  
1279
1280    WORD points in the same buffer as TEXT, and completions should be
1281    returned relative to this position.  For example, suppose TEXT is "foo"
1282    and we want to complete to "foobar".  If WORD is "oo", return
1283    "oobar"; if WORD is "baz/foo", return "baz/foobar".  */
1284
1285 char **
1286 complete_on_enum (const char *enumlist[],
1287                   char *text,
1288                   char *word)
1289 {
1290   char **matchlist;
1291   int sizeof_matchlist;
1292   int matches;
1293   int textlen = strlen (text);
1294   int i;
1295   const char *name;
1296
1297   sizeof_matchlist = 10;
1298   matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
1299   matches = 0;
1300
1301   for (i = 0; (name = enumlist[i]) != NULL; i++)
1302     if (strncmp (name, text, textlen) == 0)
1303       {
1304         if (matches == sizeof_matchlist)
1305           {
1306             sizeof_matchlist *= 2;
1307             matchlist = (char **) xrealloc ((char *) matchlist,
1308                                             (sizeof_matchlist
1309                                              * sizeof (char *)));
1310           }
1311
1312         matchlist[matches] = (char *)
1313           xmalloc (strlen (word) + strlen (name) + 1);
1314         if (word == text)
1315           strcpy (matchlist[matches], name);
1316         else if (word > text)
1317           {
1318             /* Return some portion of name.  */
1319             strcpy (matchlist[matches], name + (word - text));
1320           }
1321         else
1322           {
1323             /* Return some of text plus name.  */
1324             strncpy (matchlist[matches], word, text - word);
1325             matchlist[matches][text - word] = '\0';
1326             strcat (matchlist[matches], name);
1327           }
1328         ++matches;
1329       }
1330
1331   if (matches == 0)
1332     {
1333       xfree (matchlist);
1334       matchlist = 0;
1335     }
1336   else
1337     {
1338       matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
1339                                                         * sizeof (char *)));
1340       matchlist[matches] = (char *) 0;
1341     }
1342
1343   return matchlist;
1344 }
1345