1b725ae77Skettenis /* Handle lists of commands, their decoding and documentation, for GDB.
2b725ae77Skettenis
311efff7fSkettenis Copyright 1986, 1989, 1990, 1991, 1998, 2000, 2001, 2002, 2004 Free
4b725ae77Skettenis Software Foundation, Inc.
5b725ae77Skettenis
6b725ae77Skettenis This program is free software; you can redistribute it and/or modify
7b725ae77Skettenis it under the terms of the GNU General Public License as published by
8b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
9b725ae77Skettenis (at your option) any later version.
10b725ae77Skettenis
11b725ae77Skettenis This program is distributed in the hope that it will be useful,
12b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
13b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14b725ae77Skettenis GNU General Public License for more details.
15b725ae77Skettenis
16b725ae77Skettenis You should have received a copy of the GNU General Public License
17b725ae77Skettenis along with this program; if not, write to the Free Software
18b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
19b725ae77Skettenis Boston, MA 02111-1307, USA. */
20b725ae77Skettenis
21b725ae77Skettenis #include "defs.h"
22b725ae77Skettenis #include "symtab.h"
23b725ae77Skettenis #include <ctype.h>
24b725ae77Skettenis #include "gdb_regex.h"
25b725ae77Skettenis #include "gdb_string.h"
26b725ae77Skettenis
27b725ae77Skettenis #include "ui-out.h"
28b725ae77Skettenis
29b725ae77Skettenis #include "cli/cli-cmds.h"
30b725ae77Skettenis #include "cli/cli-decode.h"
31b725ae77Skettenis
32b725ae77Skettenis #ifdef TUI
33b725ae77Skettenis #include "tui/tui.h" /* For tui_active et.al. */
34b725ae77Skettenis #endif
35b725ae77Skettenis
36b725ae77Skettenis #include "gdb_assert.h"
37b725ae77Skettenis
38b725ae77Skettenis /* Prototypes for local functions */
39b725ae77Skettenis
40b725ae77Skettenis static void undef_cmd_error (char *, char *);
41b725ae77Skettenis
42b725ae77Skettenis static struct cmd_list_element *find_cmd (char *command,
43b725ae77Skettenis int len,
44b725ae77Skettenis struct cmd_list_element *clist,
45b725ae77Skettenis int ignore_help_classes,
46b725ae77Skettenis int *nfound);
47b725ae77Skettenis
48b725ae77Skettenis static void help_all (struct ui_file *stream);
49b725ae77Skettenis
50b725ae77Skettenis /* Set the callback function for the specified command. For each both
51b725ae77Skettenis the commands callback and func() are set. The latter set to a
52b725ae77Skettenis bounce function (unless cfunc / sfunc is NULL that is). */
53b725ae77Skettenis
54b725ae77Skettenis static void
do_cfunc(struct cmd_list_element * c,char * args,int from_tty)55b725ae77Skettenis do_cfunc (struct cmd_list_element *c, char *args, int from_tty)
56b725ae77Skettenis {
57b725ae77Skettenis c->function.cfunc (args, from_tty); /* Ok. */
58b725ae77Skettenis }
59b725ae77Skettenis
60b725ae77Skettenis void
set_cmd_cfunc(struct cmd_list_element * cmd,cmd_cfunc_ftype * cfunc)61b725ae77Skettenis set_cmd_cfunc (struct cmd_list_element *cmd, cmd_cfunc_ftype *cfunc)
62b725ae77Skettenis {
63b725ae77Skettenis if (cfunc == NULL)
64b725ae77Skettenis cmd->func = NULL;
65b725ae77Skettenis else
66b725ae77Skettenis cmd->func = do_cfunc;
67b725ae77Skettenis cmd->function.cfunc = cfunc; /* Ok. */
68b725ae77Skettenis }
69b725ae77Skettenis
70b725ae77Skettenis static void
do_sfunc(struct cmd_list_element * c,char * args,int from_tty)71b725ae77Skettenis do_sfunc (struct cmd_list_element *c, char *args, int from_tty)
72b725ae77Skettenis {
73b725ae77Skettenis c->function.sfunc (args, from_tty, c); /* Ok. */
74b725ae77Skettenis }
75b725ae77Skettenis
76b725ae77Skettenis void
set_cmd_sfunc(struct cmd_list_element * cmd,cmd_sfunc_ftype * sfunc)77b725ae77Skettenis set_cmd_sfunc (struct cmd_list_element *cmd, cmd_sfunc_ftype *sfunc)
78b725ae77Skettenis {
79b725ae77Skettenis if (sfunc == NULL)
80b725ae77Skettenis cmd->func = NULL;
81b725ae77Skettenis else
82b725ae77Skettenis cmd->func = do_sfunc;
83b725ae77Skettenis cmd->function.sfunc = sfunc; /* Ok. */
84b725ae77Skettenis }
85b725ae77Skettenis
86b725ae77Skettenis int
cmd_cfunc_eq(struct cmd_list_element * cmd,void (* cfunc)(char * args,int from_tty))87b725ae77Skettenis cmd_cfunc_eq (struct cmd_list_element *cmd,
88b725ae77Skettenis void (*cfunc) (char *args, int from_tty))
89b725ae77Skettenis {
90b725ae77Skettenis return cmd->func == do_cfunc && cmd->function.cfunc == cfunc;
91b725ae77Skettenis }
92b725ae77Skettenis
93b725ae77Skettenis void
set_cmd_context(struct cmd_list_element * cmd,void * context)94b725ae77Skettenis set_cmd_context (struct cmd_list_element *cmd, void *context)
95b725ae77Skettenis {
96b725ae77Skettenis cmd->context = context;
97b725ae77Skettenis }
98b725ae77Skettenis
99b725ae77Skettenis void *
get_cmd_context(struct cmd_list_element * cmd)100b725ae77Skettenis get_cmd_context (struct cmd_list_element *cmd)
101b725ae77Skettenis {
102b725ae77Skettenis return cmd->context;
103b725ae77Skettenis }
104b725ae77Skettenis
105b725ae77Skettenis enum cmd_types
cmd_type(struct cmd_list_element * cmd)106b725ae77Skettenis cmd_type (struct cmd_list_element *cmd)
107b725ae77Skettenis {
108b725ae77Skettenis return cmd->type;
109b725ae77Skettenis }
110b725ae77Skettenis
111b725ae77Skettenis void
set_cmd_completer(struct cmd_list_element * cmd,char ** (* completer)(char * text,char * word))112b725ae77Skettenis set_cmd_completer (struct cmd_list_element *cmd,
113b725ae77Skettenis char **(*completer) (char *text, char *word))
114b725ae77Skettenis {
115b725ae77Skettenis cmd->completer = completer; /* Ok. */
116b725ae77Skettenis }
117b725ae77Skettenis
118b725ae77Skettenis
119b725ae77Skettenis /* Add element named NAME.
120b725ae77Skettenis CLASS is the top level category into which commands are broken down
121b725ae77Skettenis for "help" purposes.
122b725ae77Skettenis FUN should be the function to execute the command;
123b725ae77Skettenis it will get a character string as argument, with leading
124b725ae77Skettenis and trailing blanks already eliminated.
125b725ae77Skettenis
126b725ae77Skettenis DOC is a documentation string for the command.
127b725ae77Skettenis Its first line should be a complete sentence.
128b725ae77Skettenis It should start with ? for a command that is an abbreviation
129b725ae77Skettenis or with * for a command that most users don't need to know about.
130b725ae77Skettenis
131b725ae77Skettenis Add this command to command list *LIST.
132b725ae77Skettenis
133b725ae77Skettenis Returns a pointer to the added command (not necessarily the head
134b725ae77Skettenis of *LIST). */
135b725ae77Skettenis
136b725ae77Skettenis struct cmd_list_element *
add_cmd(char * name,enum command_class class,void (* fun)(char *,int),char * doc,struct cmd_list_element ** list)137b725ae77Skettenis add_cmd (char *name, enum command_class class, void (*fun) (char *, int),
138b725ae77Skettenis char *doc, struct cmd_list_element **list)
139b725ae77Skettenis {
140b725ae77Skettenis struct cmd_list_element *c
141b725ae77Skettenis = (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
142b725ae77Skettenis struct cmd_list_element *p;
143b725ae77Skettenis
144b725ae77Skettenis delete_cmd (name, list);
145b725ae77Skettenis
146b725ae77Skettenis if (*list == NULL || strcmp ((*list)->name, name) >= 0)
147b725ae77Skettenis {
148b725ae77Skettenis c->next = *list;
149b725ae77Skettenis *list = c;
150b725ae77Skettenis }
151b725ae77Skettenis else
152b725ae77Skettenis {
153b725ae77Skettenis p = *list;
154b725ae77Skettenis while (p->next && strcmp (p->next->name, name) <= 0)
155b725ae77Skettenis {
156b725ae77Skettenis p = p->next;
157b725ae77Skettenis }
158b725ae77Skettenis c->next = p->next;
159b725ae77Skettenis p->next = c;
160b725ae77Skettenis }
161b725ae77Skettenis
162b725ae77Skettenis c->name = name;
163b725ae77Skettenis c->class = class;
164b725ae77Skettenis set_cmd_cfunc (c, fun);
165b725ae77Skettenis set_cmd_context (c, NULL);
166b725ae77Skettenis c->doc = doc;
167b725ae77Skettenis c->flags = 0;
168b725ae77Skettenis c->replacement = NULL;
169b725ae77Skettenis c->pre_show_hook = NULL;
170b725ae77Skettenis c->hook_pre = NULL;
171b725ae77Skettenis c->hook_post = NULL;
172b725ae77Skettenis c->hook_in = 0;
173b725ae77Skettenis c->prefixlist = NULL;
174b725ae77Skettenis c->prefixname = NULL;
175b725ae77Skettenis c->allow_unknown = 0;
176b725ae77Skettenis c->abbrev_flag = 0;
177b725ae77Skettenis set_cmd_completer (c, make_symbol_completion_list);
178b725ae77Skettenis c->type = not_set_cmd;
179b725ae77Skettenis c->var = NULL;
180b725ae77Skettenis c->var_type = var_boolean;
181b725ae77Skettenis c->enums = NULL;
182b725ae77Skettenis c->user_commands = NULL;
183b725ae77Skettenis c->hookee_pre = NULL;
184b725ae77Skettenis c->hookee_post = NULL;
185b725ae77Skettenis c->cmd_pointer = NULL;
186b725ae77Skettenis
187b725ae77Skettenis return c;
188b725ae77Skettenis }
189b725ae77Skettenis
190b725ae77Skettenis /* Deprecates a command CMD.
191b725ae77Skettenis REPLACEMENT is the name of the command which should be used in place
192b725ae77Skettenis of this command, or NULL if no such command exists.
193b725ae77Skettenis
194b725ae77Skettenis This function does not check to see if command REPLACEMENT exists
195b725ae77Skettenis since gdb may not have gotten around to adding REPLACEMENT when this
196b725ae77Skettenis function is called.
197b725ae77Skettenis
198b725ae77Skettenis Returns a pointer to the deprecated command. */
199b725ae77Skettenis
200b725ae77Skettenis struct cmd_list_element *
deprecate_cmd(struct cmd_list_element * cmd,char * replacement)201b725ae77Skettenis deprecate_cmd (struct cmd_list_element *cmd, char *replacement)
202b725ae77Skettenis {
203b725ae77Skettenis cmd->flags |= (CMD_DEPRECATED | DEPRECATED_WARN_USER);
204b725ae77Skettenis
205b725ae77Skettenis if (replacement != NULL)
206b725ae77Skettenis cmd->replacement = replacement;
207b725ae77Skettenis else
208b725ae77Skettenis cmd->replacement = NULL;
209b725ae77Skettenis
210b725ae77Skettenis return cmd;
211b725ae77Skettenis }
212b725ae77Skettenis
213b725ae77Skettenis struct cmd_list_element *
add_alias_cmd(char * name,char * oldname,enum command_class class,int abbrev_flag,struct cmd_list_element ** list)214b725ae77Skettenis add_alias_cmd (char *name, char *oldname, enum command_class class,
215b725ae77Skettenis int abbrev_flag, struct cmd_list_element **list)
216b725ae77Skettenis {
217b725ae77Skettenis /* Must do this since lookup_cmd tries to side-effect its first arg */
218b725ae77Skettenis char *copied_name;
219b725ae77Skettenis struct cmd_list_element *old;
220b725ae77Skettenis struct cmd_list_element *c;
221b725ae77Skettenis copied_name = (char *) alloca (strlen (oldname) + 1);
222b725ae77Skettenis strcpy (copied_name, oldname);
223b725ae77Skettenis old = lookup_cmd (&copied_name, *list, "", 1, 1);
224b725ae77Skettenis
225b725ae77Skettenis if (old == 0)
226b725ae77Skettenis {
227b725ae77Skettenis delete_cmd (name, list);
228b725ae77Skettenis return 0;
229b725ae77Skettenis }
230b725ae77Skettenis
231b725ae77Skettenis c = add_cmd (name, class, NULL, old->doc, list);
232b725ae77Skettenis /* NOTE: Both FUNC and all the FUNCTIONs need to be copied. */
233b725ae77Skettenis c->func = old->func;
234b725ae77Skettenis c->function = old->function;
235b725ae77Skettenis c->prefixlist = old->prefixlist;
236b725ae77Skettenis c->prefixname = old->prefixname;
237b725ae77Skettenis c->allow_unknown = old->allow_unknown;
238b725ae77Skettenis c->abbrev_flag = abbrev_flag;
239b725ae77Skettenis c->cmd_pointer = old;
240b725ae77Skettenis return c;
241b725ae77Skettenis }
242b725ae77Skettenis
243b725ae77Skettenis /* Like add_cmd but adds an element for a command prefix:
244b725ae77Skettenis a name that should be followed by a subcommand to be looked up
245b725ae77Skettenis in another command list. PREFIXLIST should be the address
246b725ae77Skettenis of the variable containing that list. */
247b725ae77Skettenis
248b725ae77Skettenis struct cmd_list_element *
add_prefix_cmd(char * name,enum command_class class,void (* fun)(char *,int),char * doc,struct cmd_list_element ** prefixlist,char * prefixname,int allow_unknown,struct cmd_list_element ** list)249b725ae77Skettenis add_prefix_cmd (char *name, enum command_class class, void (*fun) (char *, int),
250b725ae77Skettenis char *doc, struct cmd_list_element **prefixlist,
251b725ae77Skettenis char *prefixname, int allow_unknown,
252b725ae77Skettenis struct cmd_list_element **list)
253b725ae77Skettenis {
254b725ae77Skettenis struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
255b725ae77Skettenis c->prefixlist = prefixlist;
256b725ae77Skettenis c->prefixname = prefixname;
257b725ae77Skettenis c->allow_unknown = allow_unknown;
258b725ae77Skettenis return c;
259b725ae77Skettenis }
260b725ae77Skettenis
261b725ae77Skettenis /* Like add_prefix_cmd but sets the abbrev_flag on the new command. */
262b725ae77Skettenis
263b725ae77Skettenis struct cmd_list_element *
add_abbrev_prefix_cmd(char * name,enum command_class class,void (* fun)(char *,int),char * doc,struct cmd_list_element ** prefixlist,char * prefixname,int allow_unknown,struct cmd_list_element ** list)264b725ae77Skettenis add_abbrev_prefix_cmd (char *name, enum command_class class,
265b725ae77Skettenis void (*fun) (char *, int), char *doc,
266b725ae77Skettenis struct cmd_list_element **prefixlist, char *prefixname,
267b725ae77Skettenis int allow_unknown, struct cmd_list_element **list)
268b725ae77Skettenis {
269b725ae77Skettenis struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
270b725ae77Skettenis c->prefixlist = prefixlist;
271b725ae77Skettenis c->prefixname = prefixname;
272b725ae77Skettenis c->allow_unknown = allow_unknown;
273b725ae77Skettenis c->abbrev_flag = 1;
274b725ae77Skettenis return c;
275b725ae77Skettenis }
276b725ae77Skettenis
277b725ae77Skettenis /* This is an empty "cfunc". */
278b725ae77Skettenis void
not_just_help_class_command(char * args,int from_tty)279b725ae77Skettenis not_just_help_class_command (char *args, int from_tty)
280b725ae77Skettenis {
281b725ae77Skettenis }
282b725ae77Skettenis
283b725ae77Skettenis /* This is an empty "sfunc". */
284b725ae77Skettenis static void empty_sfunc (char *, int, struct cmd_list_element *);
285b725ae77Skettenis
286b725ae77Skettenis static void
empty_sfunc(char * args,int from_tty,struct cmd_list_element * c)287b725ae77Skettenis empty_sfunc (char *args, int from_tty, struct cmd_list_element *c)
288b725ae77Skettenis {
289b725ae77Skettenis }
290b725ae77Skettenis
291b725ae77Skettenis /* Add element named NAME to command list LIST (the list for set/show
292b725ae77Skettenis or some sublist thereof).
293b725ae77Skettenis TYPE is set_cmd or show_cmd.
294b725ae77Skettenis CLASS is as in add_cmd.
295b725ae77Skettenis VAR_TYPE is the kind of thing we are setting.
296b725ae77Skettenis VAR is address of the variable being controlled by this command.
297b725ae77Skettenis DOC is the documentation string. */
298b725ae77Skettenis
299b725ae77Skettenis static struct cmd_list_element *
add_set_or_show_cmd(char * name,enum cmd_types type,enum command_class class,var_types var_type,void * var,char * doc,struct cmd_list_element ** list)300b725ae77Skettenis add_set_or_show_cmd (char *name,
301b725ae77Skettenis enum cmd_types type,
302b725ae77Skettenis enum command_class class,
303b725ae77Skettenis var_types var_type,
304b725ae77Skettenis void *var,
305b725ae77Skettenis char *doc,
306b725ae77Skettenis struct cmd_list_element **list)
307b725ae77Skettenis {
308b725ae77Skettenis struct cmd_list_element *c = add_cmd (name, class, NULL, doc, list);
309b725ae77Skettenis gdb_assert (type == set_cmd || type == show_cmd);
310b725ae77Skettenis c->type = type;
311b725ae77Skettenis c->var_type = var_type;
312b725ae77Skettenis c->var = var;
313b725ae77Skettenis /* This needs to be something besides NULL so that this isn't
314b725ae77Skettenis treated as a help class. */
315b725ae77Skettenis set_cmd_sfunc (c, empty_sfunc);
316b725ae77Skettenis return c;
317b725ae77Skettenis }
318b725ae77Skettenis
319b725ae77Skettenis /* Add element named NAME to both the command SET_LIST and SHOW_LIST.
320b725ae77Skettenis CLASS is as in add_cmd. VAR_TYPE is the kind of thing we are
321b725ae77Skettenis setting. VAR is address of the variable being controlled by this
322b725ae77Skettenis command. SET_FUNC and SHOW_FUNC are the callback functions (if
32311efff7fSkettenis non-NULL). SET_DOC, SHOW_DOC and HELP_DOC are the documentation
32411efff7fSkettenis strings. PRINT the format string to print the value. SET_RESULT
32511efff7fSkettenis and SHOW_RESULT, if not NULL, are set to the resulting command
32611efff7fSkettenis structures. */
327b725ae77Skettenis
32811efff7fSkettenis static void
add_setshow_cmd_full(char * name,enum command_class class,var_types var_type,void * var,const char * set_doc,const char * show_doc,const char * help_doc,const char * print,cmd_sfunc_ftype * set_func,cmd_sfunc_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list,struct cmd_list_element ** set_result,struct cmd_list_element ** show_result)329b725ae77Skettenis add_setshow_cmd_full (char *name,
330b725ae77Skettenis enum command_class class,
331b725ae77Skettenis var_types var_type, void *var,
33211efff7fSkettenis const char *set_doc, const char *show_doc,
33311efff7fSkettenis const char *help_doc, const char *print,
33411efff7fSkettenis cmd_sfunc_ftype *set_func,
33511efff7fSkettenis cmd_sfunc_ftype *show_func,
336b725ae77Skettenis struct cmd_list_element **set_list,
337b725ae77Skettenis struct cmd_list_element **show_list,
338b725ae77Skettenis struct cmd_list_element **set_result,
339b725ae77Skettenis struct cmd_list_element **show_result)
340b725ae77Skettenis {
341b725ae77Skettenis struct cmd_list_element *set;
342b725ae77Skettenis struct cmd_list_element *show;
34311efff7fSkettenis char *full_set_doc;
34411efff7fSkettenis char *full_show_doc;
34511efff7fSkettenis
34611efff7fSkettenis if (help_doc != NULL)
34711efff7fSkettenis {
34811efff7fSkettenis full_set_doc = xstrprintf ("%s\n%s", set_doc, help_doc);
34911efff7fSkettenis full_show_doc = xstrprintf ("%s\n%s", show_doc, help_doc);
35011efff7fSkettenis }
35111efff7fSkettenis else
35211efff7fSkettenis {
35311efff7fSkettenis full_set_doc = xstrdup (set_doc);
35411efff7fSkettenis full_show_doc = xstrdup (show_doc);
35511efff7fSkettenis }
356b725ae77Skettenis set = add_set_or_show_cmd (name, set_cmd, class, var_type, var,
35711efff7fSkettenis full_set_doc, set_list);
358b725ae77Skettenis if (set_func != NULL)
359b725ae77Skettenis set_cmd_sfunc (set, set_func);
360b725ae77Skettenis show = add_set_or_show_cmd (name, show_cmd, class, var_type, var,
36111efff7fSkettenis full_show_doc, show_list);
362b725ae77Skettenis if (show_func != NULL)
363b725ae77Skettenis set_cmd_sfunc (show, show_func);
364b725ae77Skettenis
365b725ae77Skettenis if (set_result != NULL)
366b725ae77Skettenis *set_result = set;
367b725ae77Skettenis if (show_result != NULL)
368b725ae77Skettenis *show_result = show;
369b725ae77Skettenis }
370b725ae77Skettenis
371b725ae77Skettenis struct cmd_list_element *
add_set_cmd(char * name,enum command_class class,var_types var_type,void * var,char * doc,struct cmd_list_element ** list)372b725ae77Skettenis add_set_cmd (char *name,
373b725ae77Skettenis enum command_class class,
374b725ae77Skettenis var_types var_type,
375b725ae77Skettenis void *var,
376b725ae77Skettenis char *doc,
377b725ae77Skettenis struct cmd_list_element **list)
378b725ae77Skettenis {
379b725ae77Skettenis return add_set_or_show_cmd (name, set_cmd, class, var_type, var, doc, list);
380b725ae77Skettenis }
381b725ae77Skettenis
382b725ae77Skettenis /* Add element named NAME to command list LIST (the list for set
383b725ae77Skettenis or some sublist thereof).
384b725ae77Skettenis CLASS is as in add_cmd.
385b725ae77Skettenis ENUMLIST is a list of strings which may follow NAME.
386b725ae77Skettenis VAR is address of the variable which will contain the matching string
387b725ae77Skettenis (from ENUMLIST).
388b725ae77Skettenis DOC is the documentation string. */
389b725ae77Skettenis
390b725ae77Skettenis struct cmd_list_element *
add_set_enum_cmd(char * name,enum command_class class,const char * enumlist[],const char ** var,char * doc,struct cmd_list_element ** list)391b725ae77Skettenis add_set_enum_cmd (char *name,
392b725ae77Skettenis enum command_class class,
393b725ae77Skettenis const char *enumlist[],
394b725ae77Skettenis const char **var,
395b725ae77Skettenis char *doc,
396b725ae77Skettenis struct cmd_list_element **list)
397b725ae77Skettenis {
398b725ae77Skettenis struct cmd_list_element *c
399b725ae77Skettenis = add_set_cmd (name, class, var_enum, var, doc, list);
400b725ae77Skettenis c->enums = enumlist;
401b725ae77Skettenis
402b725ae77Skettenis return c;
403b725ae77Skettenis }
404b725ae77Skettenis
405*bb23a316Skettenis /* Add element named NAME to command list LIST (the list for set or
406*bb23a316Skettenis some sublist thereof). CLASS is as in add_cmd. ENUMLIST is a list
407*bb23a316Skettenis of strings which may follow NAME. VAR is address of the variable
408*bb23a316Skettenis which will contain the matching string (from ENUMLIST). */
409*bb23a316Skettenis
410*bb23a316Skettenis void
add_setshow_enum_cmd(char * name,enum command_class class,const char * enumlist[],const char ** var,const char * set_doc,const char * show_doc,const char * help_doc,const char * print,cmd_sfunc_ftype * set_func,cmd_sfunc_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)411*bb23a316Skettenis add_setshow_enum_cmd (char *name,
412*bb23a316Skettenis enum command_class class,
413*bb23a316Skettenis const char *enumlist[],
414*bb23a316Skettenis const char **var,
415*bb23a316Skettenis const char *set_doc,
416*bb23a316Skettenis const char *show_doc,
417*bb23a316Skettenis const char *help_doc,
418*bb23a316Skettenis const char *print,
419*bb23a316Skettenis cmd_sfunc_ftype *set_func,
420*bb23a316Skettenis cmd_sfunc_ftype *show_func,
421*bb23a316Skettenis struct cmd_list_element **set_list,
422*bb23a316Skettenis struct cmd_list_element **show_list)
423*bb23a316Skettenis {
424*bb23a316Skettenis struct cmd_list_element *c;
425*bb23a316Skettenis add_setshow_cmd_full (name, class, var_enum, var,
426*bb23a316Skettenis set_doc, show_doc, help_doc, print,
427*bb23a316Skettenis set_func, show_func,
428*bb23a316Skettenis set_list, show_list,
429*bb23a316Skettenis &c, NULL);
430*bb23a316Skettenis c->enums = enumlist;
431*bb23a316Skettenis }
432*bb23a316Skettenis
433b725ae77Skettenis /* Add an auto-boolean command named NAME to both the set and show
434b725ae77Skettenis command list lists. CLASS is as in add_cmd. VAR is address of the
435b725ae77Skettenis variable which will contain the value. DOC is the documentation
436b725ae77Skettenis string. FUNC is the corresponding callback. */
437b725ae77Skettenis void
add_setshow_auto_boolean_cmd(char * name,enum command_class class,enum auto_boolean * var,const char * set_doc,const char * show_doc,const char * help_doc,const char * print,cmd_sfunc_ftype * set_func,cmd_sfunc_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)438b725ae77Skettenis add_setshow_auto_boolean_cmd (char *name,
439b725ae77Skettenis enum command_class class,
440b725ae77Skettenis enum auto_boolean *var,
44111efff7fSkettenis const char *set_doc, const char *show_doc,
44211efff7fSkettenis const char *help_doc, const char *print,
443b725ae77Skettenis cmd_sfunc_ftype *set_func,
444b725ae77Skettenis cmd_sfunc_ftype *show_func,
445b725ae77Skettenis struct cmd_list_element **set_list,
446b725ae77Skettenis struct cmd_list_element **show_list)
447b725ae77Skettenis {
448b725ae77Skettenis static const char *auto_boolean_enums[] = { "on", "off", "auto", NULL };
449b725ae77Skettenis struct cmd_list_element *c;
450b725ae77Skettenis add_setshow_cmd_full (name, class, var_auto_boolean, var,
45111efff7fSkettenis set_doc, show_doc, help_doc, print,
45211efff7fSkettenis set_func, show_func,
453b725ae77Skettenis set_list, show_list,
454b725ae77Skettenis &c, NULL);
455b725ae77Skettenis c->enums = auto_boolean_enums;
456b725ae77Skettenis }
457b725ae77Skettenis
458b725ae77Skettenis /* Add element named NAME to both the set and show command LISTs (the
459b725ae77Skettenis list for set/show or some sublist thereof). CLASS is as in
460b725ae77Skettenis add_cmd. VAR is address of the variable which will contain the
46111efff7fSkettenis value. SET_DOC and SHOW_DOC are the documentation strings. */
462b725ae77Skettenis void
add_setshow_boolean_cmd(char * name,enum command_class class,int * var,const char * set_doc,const char * show_doc,const char * help_doc,const char * print,cmd_sfunc_ftype * set_func,cmd_sfunc_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)46311efff7fSkettenis add_setshow_boolean_cmd (char *name, enum command_class class, int *var,
46411efff7fSkettenis const char *set_doc, const char *show_doc,
46511efff7fSkettenis const char *help_doc, const char *print,
466b725ae77Skettenis cmd_sfunc_ftype *set_func,
467b725ae77Skettenis cmd_sfunc_ftype *show_func,
468b725ae77Skettenis struct cmd_list_element **set_list,
469b725ae77Skettenis struct cmd_list_element **show_list)
470b725ae77Skettenis {
471b725ae77Skettenis static const char *boolean_enums[] = { "on", "off", NULL };
472b725ae77Skettenis struct cmd_list_element *c;
473b725ae77Skettenis add_setshow_cmd_full (name, class, var_boolean, var,
47411efff7fSkettenis set_doc, show_doc, help_doc, print,
475b725ae77Skettenis set_func, show_func,
476b725ae77Skettenis set_list, show_list,
477b725ae77Skettenis &c, NULL);
478b725ae77Skettenis c->enums = boolean_enums;
479b725ae77Skettenis }
480b725ae77Skettenis
481b725ae77Skettenis /* Add element named NAME to both the set and show command LISTs (the
48211efff7fSkettenis list for set/show or some sublist thereof). */
48311efff7fSkettenis void
add_setshow_filename_cmd(char * name,enum command_class class,char ** var,const char * set_doc,const char * show_doc,const char * help_doc,const char * print,cmd_sfunc_ftype * set_func,cmd_sfunc_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)48411efff7fSkettenis add_setshow_filename_cmd (char *name, enum command_class class,
48511efff7fSkettenis char **var,
48611efff7fSkettenis const char *set_doc, const char *show_doc,
48711efff7fSkettenis const char *help_doc, const char *print,
48811efff7fSkettenis cmd_sfunc_ftype *set_func,
48911efff7fSkettenis cmd_sfunc_ftype *show_func,
49011efff7fSkettenis struct cmd_list_element **set_list,
49111efff7fSkettenis struct cmd_list_element **show_list)
49211efff7fSkettenis {
49311efff7fSkettenis add_setshow_cmd_full (name, class, var_filename, var,
49411efff7fSkettenis set_doc, show_doc, help_doc, print,
49511efff7fSkettenis set_func, show_func,
49611efff7fSkettenis set_list, show_list,
49711efff7fSkettenis NULL, NULL);
49811efff7fSkettenis }
49911efff7fSkettenis
50011efff7fSkettenis /* Add element named NAME to both the set and show command LISTs (the
50111efff7fSkettenis list for set/show or some sublist thereof). */
50211efff7fSkettenis void
add_setshow_string_cmd(char * name,enum command_class class,char ** var,const char * set_doc,const char * show_doc,const char * help_doc,const char * print,cmd_sfunc_ftype * set_func,cmd_sfunc_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)50311efff7fSkettenis add_setshow_string_cmd (char *name, enum command_class class,
50411efff7fSkettenis char **var,
50511efff7fSkettenis const char *set_doc, const char *show_doc,
50611efff7fSkettenis const char *help_doc, const char *print,
50711efff7fSkettenis cmd_sfunc_ftype *set_func,
50811efff7fSkettenis cmd_sfunc_ftype *show_func,
50911efff7fSkettenis struct cmd_list_element **set_list,
51011efff7fSkettenis struct cmd_list_element **show_list)
51111efff7fSkettenis {
51211efff7fSkettenis add_setshow_cmd_full (name, class, var_string, var,
51311efff7fSkettenis set_doc, show_doc, help_doc, print,
51411efff7fSkettenis set_func, show_func,
51511efff7fSkettenis set_list, show_list,
51611efff7fSkettenis NULL, NULL);
51711efff7fSkettenis }
51811efff7fSkettenis
51911efff7fSkettenis /* Add element named NAME to both the set and show command LISTs (the
520b725ae77Skettenis list for set/show or some sublist thereof). CLASS is as in
521b725ae77Skettenis add_cmd. VAR is address of the variable which will contain the
52211efff7fSkettenis value. SET_DOC and SHOW_DOC are the documentation strings. */
523b725ae77Skettenis void
add_setshow_uinteger_cmd(char * name,enum command_class class,unsigned int * var,const char * set_doc,const char * show_doc,const char * help_doc,const char * print,cmd_sfunc_ftype * set_func,cmd_sfunc_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)52411efff7fSkettenis add_setshow_uinteger_cmd (char *name, enum command_class class,
52511efff7fSkettenis unsigned int *var,
52611efff7fSkettenis const char *set_doc, const char *show_doc,
52711efff7fSkettenis const char *help_doc, const char *print,
528b725ae77Skettenis cmd_sfunc_ftype *set_func,
529b725ae77Skettenis cmd_sfunc_ftype *show_func,
530b725ae77Skettenis struct cmd_list_element **set_list,
531b725ae77Skettenis struct cmd_list_element **show_list)
532b725ae77Skettenis {
533b725ae77Skettenis add_setshow_cmd_full (name, class, var_uinteger, var,
53411efff7fSkettenis set_doc, show_doc, help_doc, print,
53511efff7fSkettenis set_func, show_func,
53611efff7fSkettenis set_list, show_list,
53711efff7fSkettenis NULL, NULL);
53811efff7fSkettenis }
53911efff7fSkettenis
54011efff7fSkettenis /* Add element named NAME to both the set and show command LISTs (the
54111efff7fSkettenis list for set/show or some sublist thereof). CLASS is as in
54211efff7fSkettenis add_cmd. VAR is address of the variable which will contain the
54311efff7fSkettenis value. SET_DOC and SHOW_DOC are the documentation strings. */
54411efff7fSkettenis void
add_setshow_zinteger_cmd(char * name,enum command_class class,int * var,const char * set_doc,const char * show_doc,const char * help_doc,const char * print,cmd_sfunc_ftype * set_func,cmd_sfunc_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)54511efff7fSkettenis add_setshow_zinteger_cmd (char *name, enum command_class class,
54611efff7fSkettenis int *var,
54711efff7fSkettenis const char *set_doc, const char *show_doc,
54811efff7fSkettenis const char *help_doc, const char *print,
54911efff7fSkettenis cmd_sfunc_ftype *set_func,
55011efff7fSkettenis cmd_sfunc_ftype *show_func,
55111efff7fSkettenis struct cmd_list_element **set_list,
55211efff7fSkettenis struct cmd_list_element **show_list)
55311efff7fSkettenis {
55411efff7fSkettenis add_setshow_cmd_full (name, class, var_zinteger, var,
55511efff7fSkettenis set_doc, show_doc, help_doc, print,
556b725ae77Skettenis set_func, show_func,
557b725ae77Skettenis set_list, show_list,
558b725ae77Skettenis NULL, NULL);
559b725ae77Skettenis }
560b725ae77Skettenis
561b725ae77Skettenis /* Where SETCMD has already been added, add the corresponding show
562b725ae77Skettenis command to LIST and return a pointer to the added command (not
563b725ae77Skettenis necessarily the head of LIST). */
56411efff7fSkettenis /* NOTE: cagney/2002-03-17: The original version of
56511efff7fSkettenis deprecated_add_show_from_set used memcpy() to clone `set' into
56611efff7fSkettenis `show'. This meant that in addition to all the needed fields (var,
56711efff7fSkettenis name, et.al.) some unnecessary fields were copied (namely the
56811efff7fSkettenis callback function). The function explictly copies relevant fields.
56911efff7fSkettenis For a `set' and `show' command to share the same callback, the
57011efff7fSkettenis caller must set both explicitly. */
571b725ae77Skettenis struct cmd_list_element *
deprecated_add_show_from_set(struct cmd_list_element * setcmd,struct cmd_list_element ** list)57211efff7fSkettenis deprecated_add_show_from_set (struct cmd_list_element *setcmd,
573b725ae77Skettenis struct cmd_list_element **list)
574b725ae77Skettenis {
575b725ae77Skettenis char *doc;
576b725ae77Skettenis const static char setstring[] = "Set ";
577b725ae77Skettenis
578b725ae77Skettenis /* Create a doc string by replacing "Set " at the start of the
579b725ae77Skettenis `set'' command's doco with "Show ". */
580b725ae77Skettenis gdb_assert (strncmp (setcmd->doc, setstring, sizeof (setstring) - 1) == 0);
581b725ae77Skettenis doc = concat ("Show ", setcmd->doc + sizeof (setstring) - 1, NULL);
582b725ae77Skettenis
583b725ae77Skettenis /* Insert the basic command. */
584b725ae77Skettenis return add_set_or_show_cmd (setcmd->name, show_cmd, setcmd->class,
585b725ae77Skettenis setcmd->var_type, setcmd->var, doc, list);
586b725ae77Skettenis }
587b725ae77Skettenis
588b725ae77Skettenis /* Remove the command named NAME from the command list. */
589b725ae77Skettenis
590b725ae77Skettenis void
delete_cmd(char * name,struct cmd_list_element ** list)591b725ae77Skettenis delete_cmd (char *name, struct cmd_list_element **list)
592b725ae77Skettenis {
593b725ae77Skettenis struct cmd_list_element *c;
594b725ae77Skettenis struct cmd_list_element *p;
595b725ae77Skettenis
596b725ae77Skettenis while (*list && strcmp ((*list)->name, name) == 0)
597b725ae77Skettenis {
598b725ae77Skettenis if ((*list)->hookee_pre)
599b725ae77Skettenis (*list)->hookee_pre->hook_pre = 0; /* Hook slips out of its mouth */
600b725ae77Skettenis if ((*list)->hookee_post)
601b725ae77Skettenis (*list)->hookee_post->hook_post = 0; /* Hook slips out of its bottom */
602b725ae77Skettenis p = (*list)->next;
603b725ae77Skettenis xfree (* list);
604b725ae77Skettenis *list = p;
605b725ae77Skettenis }
606b725ae77Skettenis
607b725ae77Skettenis if (*list)
608b725ae77Skettenis for (c = *list; c->next;)
609b725ae77Skettenis {
610b725ae77Skettenis if (strcmp (c->next->name, name) == 0)
611b725ae77Skettenis {
612b725ae77Skettenis if (c->next->hookee_pre)
613b725ae77Skettenis c->next->hookee_pre->hook_pre = 0; /* hooked cmd gets away. */
614b725ae77Skettenis if (c->next->hookee_post)
615b725ae77Skettenis c->next->hookee_post->hook_post = 0; /* remove post hook */
616b725ae77Skettenis /* :( no fishing metaphore */
617b725ae77Skettenis p = c->next->next;
618b725ae77Skettenis xfree (c->next);
619b725ae77Skettenis c->next = p;
620b725ae77Skettenis }
621b725ae77Skettenis else
622b725ae77Skettenis c = c->next;
623b725ae77Skettenis }
624b725ae77Skettenis }
625b725ae77Skettenis
626b725ae77Skettenis /* Shorthands to the commands above. */
627b725ae77Skettenis
628b725ae77Skettenis /* Add an element to the list of info subcommands. */
629b725ae77Skettenis
630b725ae77Skettenis struct cmd_list_element *
add_info(char * name,void (* fun)(char *,int),char * doc)631b725ae77Skettenis add_info (char *name, void (*fun) (char *, int), char *doc)
632b725ae77Skettenis {
633b725ae77Skettenis return add_cmd (name, no_class, fun, doc, &infolist);
634b725ae77Skettenis }
635b725ae77Skettenis
636b725ae77Skettenis /* Add an alias to the list of info subcommands. */
637b725ae77Skettenis
638b725ae77Skettenis struct cmd_list_element *
add_info_alias(char * name,char * oldname,int abbrev_flag)639b725ae77Skettenis add_info_alias (char *name, char *oldname, int abbrev_flag)
640b725ae77Skettenis {
641b725ae77Skettenis return add_alias_cmd (name, oldname, 0, abbrev_flag, &infolist);
642b725ae77Skettenis }
643b725ae77Skettenis
644b725ae77Skettenis /* Add an element to the list of commands. */
645b725ae77Skettenis
646b725ae77Skettenis struct cmd_list_element *
add_com(char * name,enum command_class class,void (* fun)(char *,int),char * doc)647b725ae77Skettenis add_com (char *name, enum command_class class, void (*fun) (char *, int),
648b725ae77Skettenis char *doc)
649b725ae77Skettenis {
650b725ae77Skettenis return add_cmd (name, class, fun, doc, &cmdlist);
651b725ae77Skettenis }
652b725ae77Skettenis
653b725ae77Skettenis /* Add an alias or abbreviation command to the list of commands. */
654b725ae77Skettenis
655b725ae77Skettenis struct cmd_list_element *
add_com_alias(char * name,char * oldname,enum command_class class,int abbrev_flag)656b725ae77Skettenis add_com_alias (char *name, char *oldname, enum command_class class,
657b725ae77Skettenis int abbrev_flag)
658b725ae77Skettenis {
659b725ae77Skettenis return add_alias_cmd (name, oldname, class, abbrev_flag, &cmdlist);
660b725ae77Skettenis }
661b725ae77Skettenis
662b725ae77Skettenis /* Recursively walk the commandlist structures, and print out the
663b725ae77Skettenis documentation of commands that match our regex in either their
664b725ae77Skettenis name, or their documentation.
665b725ae77Skettenis */
666b725ae77Skettenis void
apropos_cmd(struct ui_file * stream,struct cmd_list_element * commandlist,struct re_pattern_buffer * regex,char * prefix)667b725ae77Skettenis apropos_cmd (struct ui_file *stream, struct cmd_list_element *commandlist,
668b725ae77Skettenis struct re_pattern_buffer *regex, char *prefix)
669b725ae77Skettenis {
670b725ae77Skettenis struct cmd_list_element *c;
671b725ae77Skettenis int returnvalue=1; /*Needed to avoid double printing*/
672b725ae77Skettenis /* Walk through the commands */
673b725ae77Skettenis for (c=commandlist;c;c=c->next)
674b725ae77Skettenis {
675b725ae77Skettenis if (c->name != NULL)
676b725ae77Skettenis {
677b725ae77Skettenis /* Try to match against the name*/
678b725ae77Skettenis returnvalue=re_search(regex,c->name,strlen(c->name),0,strlen(c->name),NULL);
679b725ae77Skettenis if (returnvalue >= 0)
680b725ae77Skettenis {
681b725ae77Skettenis /* Stolen from help_cmd_list. We don't directly use
682b725ae77Skettenis * help_cmd_list because it doesn't let us print out
683b725ae77Skettenis * single commands
684b725ae77Skettenis */
685b725ae77Skettenis fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
686b725ae77Skettenis print_doc_line (stream, c->doc);
687b725ae77Skettenis fputs_filtered ("\n", stream);
688b725ae77Skettenis returnvalue=0; /*Set this so we don't print it again.*/
689b725ae77Skettenis }
690b725ae77Skettenis }
691b725ae77Skettenis if (c->doc != NULL && returnvalue != 0)
692b725ae77Skettenis {
693b725ae77Skettenis /* Try to match against documentation */
694b725ae77Skettenis if (re_search(regex,c->doc,strlen(c->doc),0,strlen(c->doc),NULL) >=0)
695b725ae77Skettenis {
696b725ae77Skettenis /* Stolen from help_cmd_list. We don't directly use
697b725ae77Skettenis * help_cmd_list because it doesn't let us print out
698b725ae77Skettenis * single commands
699b725ae77Skettenis */
700b725ae77Skettenis fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
701b725ae77Skettenis print_doc_line (stream, c->doc);
702b725ae77Skettenis fputs_filtered ("\n", stream);
703b725ae77Skettenis }
704b725ae77Skettenis }
705b725ae77Skettenis /* Check if this command has subcommands */
706b725ae77Skettenis if (c->prefixlist != NULL)
707b725ae77Skettenis {
708b725ae77Skettenis /* Recursively call ourselves on the subcommand list,
709b725ae77Skettenis passing the right prefix in.
710b725ae77Skettenis */
711b725ae77Skettenis apropos_cmd (stream,*c->prefixlist,regex,c->prefixname);
712b725ae77Skettenis }
713b725ae77Skettenis }
714b725ae77Skettenis }
715b725ae77Skettenis
716b725ae77Skettenis /* This command really has to deal with two things:
717b725ae77Skettenis * 1) I want documentation on *this string* (usually called by
718b725ae77Skettenis * "help commandname").
719b725ae77Skettenis * 2) I want documentation on *this list* (usually called by
720b725ae77Skettenis * giving a command that requires subcommands. Also called by saying
721b725ae77Skettenis * just "help".)
722b725ae77Skettenis *
723b725ae77Skettenis * I am going to split this into two seperate comamnds, help_cmd and
724b725ae77Skettenis * help_list.
725b725ae77Skettenis */
726b725ae77Skettenis
727b725ae77Skettenis void
help_cmd(char * command,struct ui_file * stream)728b725ae77Skettenis help_cmd (char *command, struct ui_file *stream)
729b725ae77Skettenis {
730b725ae77Skettenis struct cmd_list_element *c;
731b725ae77Skettenis extern struct cmd_list_element *cmdlist;
732b725ae77Skettenis
733b725ae77Skettenis if (!command)
734b725ae77Skettenis {
735b725ae77Skettenis help_list (cmdlist, "", all_classes, stream);
736b725ae77Skettenis return;
737b725ae77Skettenis }
738b725ae77Skettenis
739b725ae77Skettenis if (strcmp (command, "all") == 0)
740b725ae77Skettenis {
741b725ae77Skettenis help_all (stream);
742b725ae77Skettenis return;
743b725ae77Skettenis }
744b725ae77Skettenis
745b725ae77Skettenis c = lookup_cmd (&command, cmdlist, "", 0, 0);
746b725ae77Skettenis
747b725ae77Skettenis if (c == 0)
748b725ae77Skettenis return;
749b725ae77Skettenis
750b725ae77Skettenis /* There are three cases here.
751b725ae77Skettenis If c->prefixlist is nonzero, we have a prefix command.
752b725ae77Skettenis Print its documentation, then list its subcommands.
753b725ae77Skettenis
754b725ae77Skettenis If c->func is non NULL, we really have a command. Print its
755b725ae77Skettenis documentation and return.
756b725ae77Skettenis
757b725ae77Skettenis If c->func is NULL, we have a class name. Print its
758b725ae77Skettenis documentation (as if it were a command) and then set class to the
759b725ae77Skettenis number of this class so that the commands in the class will be
760b725ae77Skettenis listed. */
761b725ae77Skettenis
762b725ae77Skettenis fputs_filtered (c->doc, stream);
763b725ae77Skettenis fputs_filtered ("\n", stream);
764b725ae77Skettenis
765b725ae77Skettenis if (c->prefixlist == 0 && c->func != NULL)
766b725ae77Skettenis return;
767b725ae77Skettenis fprintf_filtered (stream, "\n");
768b725ae77Skettenis
769b725ae77Skettenis /* If this is a prefix command, print it's subcommands */
770b725ae77Skettenis if (c->prefixlist)
771b725ae77Skettenis help_list (*c->prefixlist, c->prefixname, all_commands, stream);
772b725ae77Skettenis
773b725ae77Skettenis /* If this is a class name, print all of the commands in the class */
774b725ae77Skettenis if (c->func == NULL)
775b725ae77Skettenis help_list (cmdlist, "", c->class, stream);
776b725ae77Skettenis
777b725ae77Skettenis if (c->hook_pre || c->hook_post)
778b725ae77Skettenis fprintf_filtered (stream,
779b725ae77Skettenis "\nThis command has a hook (or hooks) defined:\n");
780b725ae77Skettenis
781b725ae77Skettenis if (c->hook_pre)
782b725ae77Skettenis fprintf_filtered (stream,
783b725ae77Skettenis "\tThis command is run after : %s (pre hook)\n",
784b725ae77Skettenis c->hook_pre->name);
785b725ae77Skettenis if (c->hook_post)
786b725ae77Skettenis fprintf_filtered (stream,
787b725ae77Skettenis "\tThis command is run before : %s (post hook)\n",
788b725ae77Skettenis c->hook_post->name);
789b725ae77Skettenis }
790b725ae77Skettenis
791b725ae77Skettenis /*
792b725ae77Skettenis * Get a specific kind of help on a command list.
793b725ae77Skettenis *
794b725ae77Skettenis * LIST is the list.
795b725ae77Skettenis * CMDTYPE is the prefix to use in the title string.
796b725ae77Skettenis * CLASS is the class with which to list the nodes of this list (see
797b725ae77Skettenis * documentation for help_cmd_list below), As usual, ALL_COMMANDS for
798b725ae77Skettenis * everything, ALL_CLASSES for just classes, and non-negative for only things
799b725ae77Skettenis * in a specific class.
800b725ae77Skettenis * and STREAM is the output stream on which to print things.
801b725ae77Skettenis * If you call this routine with a class >= 0, it recurses.
802b725ae77Skettenis */
803b725ae77Skettenis void
help_list(struct cmd_list_element * list,char * cmdtype,enum command_class class,struct ui_file * stream)804b725ae77Skettenis help_list (struct cmd_list_element *list, char *cmdtype,
805b725ae77Skettenis enum command_class class, struct ui_file *stream)
806b725ae77Skettenis {
807b725ae77Skettenis int len;
808b725ae77Skettenis char *cmdtype1, *cmdtype2;
809b725ae77Skettenis
810b725ae77Skettenis /* If CMDTYPE is "foo ", CMDTYPE1 gets " foo" and CMDTYPE2 gets "foo sub" */
811b725ae77Skettenis len = strlen (cmdtype);
812b725ae77Skettenis cmdtype1 = (char *) alloca (len + 1);
813b725ae77Skettenis cmdtype1[0] = 0;
814b725ae77Skettenis cmdtype2 = (char *) alloca (len + 4);
815b725ae77Skettenis cmdtype2[0] = 0;
816b725ae77Skettenis if (len)
817b725ae77Skettenis {
818b725ae77Skettenis cmdtype1[0] = ' ';
819b725ae77Skettenis strncpy (cmdtype1 + 1, cmdtype, len - 1);
820b725ae77Skettenis cmdtype1[len] = 0;
821b725ae77Skettenis strncpy (cmdtype2, cmdtype, len - 1);
822b725ae77Skettenis strcpy (cmdtype2 + len - 1, " sub");
823b725ae77Skettenis }
824b725ae77Skettenis
825b725ae77Skettenis if (class == all_classes)
826b725ae77Skettenis fprintf_filtered (stream, "List of classes of %scommands:\n\n", cmdtype2);
827b725ae77Skettenis else
828b725ae77Skettenis fprintf_filtered (stream, "List of %scommands:\n\n", cmdtype2);
829b725ae77Skettenis
830b725ae77Skettenis help_cmd_list (list, class, cmdtype, (int) class >= 0, stream);
831b725ae77Skettenis
832b725ae77Skettenis if (class == all_classes)
833b725ae77Skettenis {
834b725ae77Skettenis fprintf_filtered (stream, "\n\
835b725ae77Skettenis Type \"help%s\" followed by a class name for a list of commands in ",
836b725ae77Skettenis cmdtype1);
837b725ae77Skettenis wrap_here ("");
838b725ae77Skettenis fprintf_filtered (stream, "that class.");
839b725ae77Skettenis }
840b725ae77Skettenis
841b725ae77Skettenis fprintf_filtered (stream, "\nType \"help%s\" followed by %scommand name ",
842b725ae77Skettenis cmdtype1, cmdtype2);
843b725ae77Skettenis wrap_here ("");
844b725ae77Skettenis fputs_filtered ("for ", stream);
845b725ae77Skettenis wrap_here ("");
846b725ae77Skettenis fputs_filtered ("full ", stream);
847b725ae77Skettenis wrap_here ("");
848b725ae77Skettenis fputs_filtered ("documentation.\n", stream);
849b725ae77Skettenis fputs_filtered ("Command name abbreviations are allowed if unambiguous.\n",
850b725ae77Skettenis stream);
851b725ae77Skettenis }
852b725ae77Skettenis
853b725ae77Skettenis static void
help_all(struct ui_file * stream)854b725ae77Skettenis help_all (struct ui_file *stream)
855b725ae77Skettenis {
856b725ae77Skettenis struct cmd_list_element *c;
857b725ae77Skettenis extern struct cmd_list_element *cmdlist;
858b725ae77Skettenis
859b725ae77Skettenis for (c = cmdlist; c; c = c->next)
860b725ae77Skettenis {
861b725ae77Skettenis if (c->abbrev_flag)
862b725ae77Skettenis continue;
863b725ae77Skettenis /* If this is a prefix command, print it's subcommands */
864b725ae77Skettenis if (c->prefixlist)
865b725ae77Skettenis help_cmd_list (*c->prefixlist, all_commands, c->prefixname, 0, stream);
866b725ae77Skettenis
867b725ae77Skettenis /* If this is a class name, print all of the commands in the class */
868b725ae77Skettenis else if (c->func == NULL)
869b725ae77Skettenis help_cmd_list (cmdlist, c->class, "", 0, stream);
870b725ae77Skettenis }
871b725ae77Skettenis }
872b725ae77Skettenis
873b725ae77Skettenis /* Print only the first line of STR on STREAM. */
874b725ae77Skettenis void
print_doc_line(struct ui_file * stream,char * str)875b725ae77Skettenis print_doc_line (struct ui_file *stream, char *str)
876b725ae77Skettenis {
877b725ae77Skettenis static char *line_buffer = 0;
878b725ae77Skettenis static int line_size;
879b725ae77Skettenis char *p;
880b725ae77Skettenis
881b725ae77Skettenis if (!line_buffer)
882b725ae77Skettenis {
883b725ae77Skettenis line_size = 80;
884b725ae77Skettenis line_buffer = (char *) xmalloc (line_size);
885b725ae77Skettenis }
886b725ae77Skettenis
887b725ae77Skettenis p = str;
888b725ae77Skettenis while (*p && *p != '\n' && *p != '.' && *p != ',')
889b725ae77Skettenis p++;
890b725ae77Skettenis if (p - str > line_size - 1)
891b725ae77Skettenis {
892b725ae77Skettenis line_size = p - str + 1;
893b725ae77Skettenis xfree (line_buffer);
894b725ae77Skettenis line_buffer = (char *) xmalloc (line_size);
895b725ae77Skettenis }
896b725ae77Skettenis strncpy (line_buffer, str, p - str);
897b725ae77Skettenis line_buffer[p - str] = '\0';
898b725ae77Skettenis if (islower (line_buffer[0]))
899b725ae77Skettenis line_buffer[0] = toupper (line_buffer[0]);
900b725ae77Skettenis ui_out_text (uiout, line_buffer);
901b725ae77Skettenis }
902b725ae77Skettenis
903b725ae77Skettenis /*
904b725ae77Skettenis * Implement a help command on command list LIST.
905b725ae77Skettenis * RECURSE should be non-zero if this should be done recursively on
906b725ae77Skettenis * all sublists of LIST.
907b725ae77Skettenis * PREFIX is the prefix to print before each command name.
908b725ae77Skettenis * STREAM is the stream upon which the output should be written.
909b725ae77Skettenis * CLASS should be:
910b725ae77Skettenis * A non-negative class number to list only commands in that
911b725ae77Skettenis * class.
912b725ae77Skettenis * ALL_COMMANDS to list all commands in list.
913b725ae77Skettenis * ALL_CLASSES to list all classes in list.
914b725ae77Skettenis *
915b725ae77Skettenis * Note that RECURSE will be active on *all* sublists, not just the
916b725ae77Skettenis * ones selected by the criteria above (ie. the selection mechanism
917b725ae77Skettenis * is at the low level, not the high-level).
918b725ae77Skettenis */
919b725ae77Skettenis void
help_cmd_list(struct cmd_list_element * list,enum command_class class,char * prefix,int recurse,struct ui_file * stream)920b725ae77Skettenis help_cmd_list (struct cmd_list_element *list, enum command_class class,
921b725ae77Skettenis char *prefix, int recurse, struct ui_file *stream)
922b725ae77Skettenis {
923b725ae77Skettenis struct cmd_list_element *c;
924b725ae77Skettenis
925b725ae77Skettenis for (c = list; c; c = c->next)
926b725ae77Skettenis {
927b725ae77Skettenis if (c->abbrev_flag == 0 &&
928b725ae77Skettenis (class == all_commands
929b725ae77Skettenis || (class == all_classes && c->func == NULL)
930b725ae77Skettenis || (class == c->class && c->func != NULL)))
931b725ae77Skettenis {
932b725ae77Skettenis fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
933b725ae77Skettenis print_doc_line (stream, c->doc);
934b725ae77Skettenis fputs_filtered ("\n", stream);
935b725ae77Skettenis }
936b725ae77Skettenis if (recurse
937b725ae77Skettenis && c->prefixlist != 0
938b725ae77Skettenis && c->abbrev_flag == 0)
939b725ae77Skettenis help_cmd_list (*c->prefixlist, class, c->prefixname, 1, stream);
940b725ae77Skettenis }
941b725ae77Skettenis }
942b725ae77Skettenis
943b725ae77Skettenis
944b725ae77Skettenis /* Search the input clist for 'command'. Return the command if
945b725ae77Skettenis found (or NULL if not), and return the number of commands
946b725ae77Skettenis found in nfound */
947b725ae77Skettenis
948b725ae77Skettenis static struct cmd_list_element *
find_cmd(char * command,int len,struct cmd_list_element * clist,int ignore_help_classes,int * nfound)949b725ae77Skettenis find_cmd (char *command, int len, struct cmd_list_element *clist,
950b725ae77Skettenis int ignore_help_classes, int *nfound)
951b725ae77Skettenis {
952b725ae77Skettenis struct cmd_list_element *found, *c;
953b725ae77Skettenis
954b725ae77Skettenis found = (struct cmd_list_element *) NULL;
955b725ae77Skettenis *nfound = 0;
956b725ae77Skettenis for (c = clist; c; c = c->next)
957b725ae77Skettenis if (!strncmp (command, c->name, len)
958b725ae77Skettenis && (!ignore_help_classes || c->func))
959b725ae77Skettenis {
960b725ae77Skettenis found = c;
961b725ae77Skettenis (*nfound)++;
962b725ae77Skettenis if (c->name[len] == '\0')
963b725ae77Skettenis {
964b725ae77Skettenis *nfound = 1;
965b725ae77Skettenis break;
966b725ae77Skettenis }
967b725ae77Skettenis }
968b725ae77Skettenis return found;
969b725ae77Skettenis }
970b725ae77Skettenis
971b725ae77Skettenis /* This routine takes a line of TEXT and a CLIST in which to start the
972b725ae77Skettenis lookup. When it returns it will have incremented the text pointer past
973b725ae77Skettenis the section of text it matched, set *RESULT_LIST to point to the list in
974b725ae77Skettenis which the last word was matched, and will return a pointer to the cmd
975b725ae77Skettenis list element which the text matches. It will return NULL if no match at
976b725ae77Skettenis all was possible. It will return -1 (cast appropriately, ick) if ambigous
977b725ae77Skettenis matches are possible; in this case *RESULT_LIST will be set to point to
978b725ae77Skettenis the list in which there are ambiguous choices (and *TEXT will be set to
979b725ae77Skettenis the ambiguous text string).
980b725ae77Skettenis
981b725ae77Skettenis If the located command was an abbreviation, this routine returns the base
982b725ae77Skettenis command of the abbreviation.
983b725ae77Skettenis
984b725ae77Skettenis It does no error reporting whatsoever; control will always return
985b725ae77Skettenis to the superior routine.
986b725ae77Skettenis
987b725ae77Skettenis In the case of an ambiguous return (-1), *RESULT_LIST will be set to point
988b725ae77Skettenis at the prefix_command (ie. the best match) *or* (special case) will be NULL
989b725ae77Skettenis if no prefix command was ever found. For example, in the case of "info a",
990b725ae77Skettenis "info" matches without ambiguity, but "a" could be "args" or "address", so
991b725ae77Skettenis *RESULT_LIST is set to the cmd_list_element for "info". So in this case
992b725ae77Skettenis RESULT_LIST should not be interpeted as a pointer to the beginning of a
993b725ae77Skettenis list; it simply points to a specific command. In the case of an ambiguous
994b725ae77Skettenis return *TEXT is advanced past the last non-ambiguous prefix (e.g.
995b725ae77Skettenis "info t" can be "info types" or "info target"; upon return *TEXT has been
996b725ae77Skettenis advanced past "info ").
997b725ae77Skettenis
998b725ae77Skettenis If RESULT_LIST is NULL, don't set *RESULT_LIST (but don't otherwise
999b725ae77Skettenis affect the operation).
1000b725ae77Skettenis
1001b725ae77Skettenis This routine does *not* modify the text pointed to by TEXT.
1002b725ae77Skettenis
1003b725ae77Skettenis If IGNORE_HELP_CLASSES is nonzero, ignore any command list elements which
1004b725ae77Skettenis are actually help classes rather than commands (i.e. the function field of
1005b725ae77Skettenis the struct cmd_list_element is NULL). */
1006b725ae77Skettenis
1007b725ae77Skettenis struct cmd_list_element *
lookup_cmd_1(char ** text,struct cmd_list_element * clist,struct cmd_list_element ** result_list,int ignore_help_classes)1008b725ae77Skettenis lookup_cmd_1 (char **text, struct cmd_list_element *clist,
1009b725ae77Skettenis struct cmd_list_element **result_list, int ignore_help_classes)
1010b725ae77Skettenis {
1011b725ae77Skettenis char *p, *command;
1012b725ae77Skettenis int len, tmp, nfound;
1013b725ae77Skettenis struct cmd_list_element *found, *c;
1014b725ae77Skettenis char *line = *text;
1015b725ae77Skettenis
1016b725ae77Skettenis while (**text == ' ' || **text == '\t')
1017b725ae77Skettenis (*text)++;
1018b725ae77Skettenis
1019b725ae77Skettenis /* Treating underscores as part of command words is important
1020b725ae77Skettenis so that "set args_foo()" doesn't get interpreted as
1021b725ae77Skettenis "set args _foo()". */
1022b725ae77Skettenis /* NOTE: cagney/2003-02-13 The `tui_active' was previously
1023b725ae77Skettenis `tui_version'. */
1024b725ae77Skettenis for (p = *text;
1025b725ae77Skettenis *p && (isalnum (*p) || *p == '-' || *p == '_' ||
1026b725ae77Skettenis #if defined(TUI)
1027b725ae77Skettenis (tui_active &&
1028b725ae77Skettenis (*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
1029b725ae77Skettenis #endif
1030b725ae77Skettenis (xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
1031b725ae77Skettenis p++)
1032b725ae77Skettenis ;
1033b725ae77Skettenis
1034b725ae77Skettenis /* If nothing but whitespace, return 0. */
1035b725ae77Skettenis if (p == *text)
1036b725ae77Skettenis return 0;
1037b725ae77Skettenis
1038b725ae77Skettenis len = p - *text;
1039b725ae77Skettenis
1040b725ae77Skettenis /* *text and p now bracket the first command word to lookup (and
1041b725ae77Skettenis it's length is len). We copy this into a local temporary */
1042b725ae77Skettenis
1043b725ae77Skettenis
1044b725ae77Skettenis command = (char *) alloca (len + 1);
1045b725ae77Skettenis for (tmp = 0; tmp < len; tmp++)
1046b725ae77Skettenis {
1047b725ae77Skettenis char x = (*text)[tmp];
1048b725ae77Skettenis command[tmp] = x;
1049b725ae77Skettenis }
1050b725ae77Skettenis command[len] = '\0';
1051b725ae77Skettenis
1052b725ae77Skettenis /* Look it up. */
1053b725ae77Skettenis found = 0;
1054b725ae77Skettenis nfound = 0;
1055b725ae77Skettenis found = find_cmd (command, len, clist, ignore_help_classes, &nfound);
1056b725ae77Skettenis
1057b725ae77Skettenis /*
1058b725ae77Skettenis ** We didn't find the command in the entered case, so lower case it
1059b725ae77Skettenis ** and search again.
1060b725ae77Skettenis */
1061b725ae77Skettenis if (!found || nfound == 0)
1062b725ae77Skettenis {
1063b725ae77Skettenis for (tmp = 0; tmp < len; tmp++)
1064b725ae77Skettenis {
1065b725ae77Skettenis char x = command[tmp];
1066b725ae77Skettenis command[tmp] = isupper (x) ? tolower (x) : x;
1067b725ae77Skettenis }
1068b725ae77Skettenis found = find_cmd (command, len, clist, ignore_help_classes, &nfound);
1069b725ae77Skettenis }
1070b725ae77Skettenis
1071b725ae77Skettenis /* If nothing matches, we have a simple failure. */
1072b725ae77Skettenis if (nfound == 0)
1073b725ae77Skettenis return 0;
1074b725ae77Skettenis
1075b725ae77Skettenis if (nfound > 1)
1076b725ae77Skettenis {
1077b725ae77Skettenis if (result_list != NULL)
1078b725ae77Skettenis /* Will be modified in calling routine
1079b725ae77Skettenis if we know what the prefix command is. */
1080b725ae77Skettenis *result_list = 0;
1081b725ae77Skettenis return (struct cmd_list_element *) -1; /* Ambiguous. */
1082b725ae77Skettenis }
1083b725ae77Skettenis
1084b725ae77Skettenis /* We've matched something on this list. Move text pointer forward. */
1085b725ae77Skettenis
1086b725ae77Skettenis *text = p;
1087b725ae77Skettenis
1088b725ae77Skettenis if (found->cmd_pointer)
1089b725ae77Skettenis {
1090b725ae77Skettenis /* We drop the alias (abbreviation) in favor of the command it is
1091b725ae77Skettenis pointing to. If the alias is deprecated, though, we need to
1092b725ae77Skettenis warn the user about it before we drop it. Note that while we
1093b725ae77Skettenis are warning about the alias, we may also warn about the command
1094b725ae77Skettenis itself and we will adjust the appropriate DEPRECATED_WARN_USER
1095b725ae77Skettenis flags */
1096b725ae77Skettenis
1097b725ae77Skettenis if (found->flags & DEPRECATED_WARN_USER)
1098b725ae77Skettenis deprecated_cmd_warning (&line);
1099b725ae77Skettenis found = found->cmd_pointer;
1100b725ae77Skettenis }
1101b725ae77Skettenis /* If we found a prefix command, keep looking. */
1102b725ae77Skettenis
1103b725ae77Skettenis if (found->prefixlist)
1104b725ae77Skettenis {
1105b725ae77Skettenis c = lookup_cmd_1 (text, *found->prefixlist, result_list,
1106b725ae77Skettenis ignore_help_classes);
1107b725ae77Skettenis if (!c)
1108b725ae77Skettenis {
1109b725ae77Skettenis /* Didn't find anything; this is as far as we got. */
1110b725ae77Skettenis if (result_list != NULL)
1111b725ae77Skettenis *result_list = clist;
1112b725ae77Skettenis return found;
1113b725ae77Skettenis }
1114b725ae77Skettenis else if (c == (struct cmd_list_element *) -1)
1115b725ae77Skettenis {
1116b725ae77Skettenis /* We've gotten this far properly, but the next step
1117b725ae77Skettenis is ambiguous. We need to set the result list to the best
1118b725ae77Skettenis we've found (if an inferior hasn't already set it). */
1119b725ae77Skettenis if (result_list != NULL)
1120b725ae77Skettenis if (!*result_list)
1121b725ae77Skettenis /* This used to say *result_list = *found->prefixlist
1122b725ae77Skettenis If that was correct, need to modify the documentation
1123b725ae77Skettenis at the top of this function to clarify what is supposed
1124b725ae77Skettenis to be going on. */
1125b725ae77Skettenis *result_list = found;
1126b725ae77Skettenis return c;
1127b725ae77Skettenis }
1128b725ae77Skettenis else
1129b725ae77Skettenis {
1130b725ae77Skettenis /* We matched! */
1131b725ae77Skettenis return c;
1132b725ae77Skettenis }
1133b725ae77Skettenis }
1134b725ae77Skettenis else
1135b725ae77Skettenis {
1136b725ae77Skettenis if (result_list != NULL)
1137b725ae77Skettenis *result_list = clist;
1138b725ae77Skettenis return found;
1139b725ae77Skettenis }
1140b725ae77Skettenis }
1141b725ae77Skettenis
1142b725ae77Skettenis /* All this hair to move the space to the front of cmdtype */
1143b725ae77Skettenis
1144b725ae77Skettenis static void
undef_cmd_error(char * cmdtype,char * q)1145b725ae77Skettenis undef_cmd_error (char *cmdtype, char *q)
1146b725ae77Skettenis {
1147b725ae77Skettenis error ("Undefined %scommand: \"%s\". Try \"help%s%.*s\".",
1148b725ae77Skettenis cmdtype,
1149b725ae77Skettenis q,
1150b725ae77Skettenis *cmdtype ? " " : "",
1151b725ae77Skettenis (int) strlen (cmdtype) - 1,
1152b725ae77Skettenis cmdtype);
1153b725ae77Skettenis }
1154b725ae77Skettenis
1155b725ae77Skettenis /* Look up the contents of *LINE as a command in the command list LIST.
1156b725ae77Skettenis LIST is a chain of struct cmd_list_element's.
1157b725ae77Skettenis If it is found, return the struct cmd_list_element for that command
1158b725ae77Skettenis and update *LINE to point after the command name, at the first argument.
1159b725ae77Skettenis If not found, call error if ALLOW_UNKNOWN is zero
1160b725ae77Skettenis otherwise (or if error returns) return zero.
1161b725ae77Skettenis Call error if specified command is ambiguous,
1162b725ae77Skettenis unless ALLOW_UNKNOWN is negative.
1163b725ae77Skettenis CMDTYPE precedes the word "command" in the error message.
1164b725ae77Skettenis
1165b725ae77Skettenis If INGNORE_HELP_CLASSES is nonzero, ignore any command list
1166b725ae77Skettenis elements which are actually help classes rather than commands (i.e.
1167b725ae77Skettenis the function field of the struct cmd_list_element is 0). */
1168b725ae77Skettenis
1169b725ae77Skettenis struct cmd_list_element *
lookup_cmd(char ** line,struct cmd_list_element * list,char * cmdtype,int allow_unknown,int ignore_help_classes)1170b725ae77Skettenis lookup_cmd (char **line, struct cmd_list_element *list, char *cmdtype,
1171b725ae77Skettenis int allow_unknown, int ignore_help_classes)
1172b725ae77Skettenis {
1173b725ae77Skettenis struct cmd_list_element *last_list = 0;
1174b725ae77Skettenis struct cmd_list_element *c =
1175b725ae77Skettenis lookup_cmd_1 (line, list, &last_list, ignore_help_classes);
1176b725ae77Skettenis
1177b725ae77Skettenis /* Note: Do not remove trailing whitespace here because this
1178b725ae77Skettenis would be wrong for complete_command. Jim Kingdon */
1179b725ae77Skettenis
1180b725ae77Skettenis if (!c)
1181b725ae77Skettenis {
1182b725ae77Skettenis if (!allow_unknown)
1183b725ae77Skettenis {
1184b725ae77Skettenis if (!*line)
1185b725ae77Skettenis error ("Lack of needed %scommand", cmdtype);
1186b725ae77Skettenis else
1187b725ae77Skettenis {
1188b725ae77Skettenis char *p = *line, *q;
1189b725ae77Skettenis
1190b725ae77Skettenis while (isalnum (*p) || *p == '-')
1191b725ae77Skettenis p++;
1192b725ae77Skettenis
1193b725ae77Skettenis q = (char *) alloca (p - *line + 1);
1194b725ae77Skettenis strncpy (q, *line, p - *line);
1195b725ae77Skettenis q[p - *line] = '\0';
1196b725ae77Skettenis undef_cmd_error (cmdtype, q);
1197b725ae77Skettenis }
1198b725ae77Skettenis }
1199b725ae77Skettenis else
1200b725ae77Skettenis return 0;
1201b725ae77Skettenis }
1202b725ae77Skettenis else if (c == (struct cmd_list_element *) -1)
1203b725ae77Skettenis {
1204b725ae77Skettenis /* Ambigous. Local values should be off prefixlist or called
1205b725ae77Skettenis values. */
1206b725ae77Skettenis int local_allow_unknown = (last_list ? last_list->allow_unknown :
1207b725ae77Skettenis allow_unknown);
1208b725ae77Skettenis char *local_cmdtype = last_list ? last_list->prefixname : cmdtype;
1209b725ae77Skettenis struct cmd_list_element *local_list =
1210b725ae77Skettenis (last_list ? *(last_list->prefixlist) : list);
1211b725ae77Skettenis
1212b725ae77Skettenis if (local_allow_unknown < 0)
1213b725ae77Skettenis {
1214b725ae77Skettenis if (last_list)
1215b725ae77Skettenis return last_list; /* Found something. */
1216b725ae77Skettenis else
1217b725ae77Skettenis return 0; /* Found nothing. */
1218b725ae77Skettenis }
1219b725ae77Skettenis else
1220b725ae77Skettenis {
1221b725ae77Skettenis /* Report as error. */
1222b725ae77Skettenis int amb_len;
1223b725ae77Skettenis char ambbuf[100];
1224b725ae77Skettenis
1225b725ae77Skettenis for (amb_len = 0;
1226b725ae77Skettenis ((*line)[amb_len] && (*line)[amb_len] != ' '
1227b725ae77Skettenis && (*line)[amb_len] != '\t');
1228b725ae77Skettenis amb_len++)
1229b725ae77Skettenis ;
1230b725ae77Skettenis
1231b725ae77Skettenis ambbuf[0] = 0;
1232b725ae77Skettenis for (c = local_list; c; c = c->next)
1233b725ae77Skettenis if (!strncmp (*line, c->name, amb_len))
1234b725ae77Skettenis {
1235b725ae77Skettenis if (strlen (ambbuf) + strlen (c->name) + 6 < (int) sizeof ambbuf)
1236b725ae77Skettenis {
1237b725ae77Skettenis if (strlen (ambbuf))
1238b725ae77Skettenis strcat (ambbuf, ", ");
1239b725ae77Skettenis strcat (ambbuf, c->name);
1240b725ae77Skettenis }
1241b725ae77Skettenis else
1242b725ae77Skettenis {
1243b725ae77Skettenis strcat (ambbuf, "..");
1244b725ae77Skettenis break;
1245b725ae77Skettenis }
1246b725ae77Skettenis }
1247b725ae77Skettenis error ("Ambiguous %scommand \"%s\": %s.", local_cmdtype,
1248b725ae77Skettenis *line, ambbuf);
1249b725ae77Skettenis return 0; /* lint */
1250b725ae77Skettenis }
1251b725ae77Skettenis }
1252b725ae77Skettenis else
1253b725ae77Skettenis {
1254b725ae77Skettenis /* We've got something. It may still not be what the caller
1255b725ae77Skettenis wants (if this command *needs* a subcommand). */
1256b725ae77Skettenis while (**line == ' ' || **line == '\t')
1257b725ae77Skettenis (*line)++;
1258b725ae77Skettenis
1259b725ae77Skettenis if (c->prefixlist && **line && !c->allow_unknown)
1260b725ae77Skettenis undef_cmd_error (c->prefixname, *line);
1261b725ae77Skettenis
1262b725ae77Skettenis /* Seems to be what he wants. Return it. */
1263b725ae77Skettenis return c;
1264b725ae77Skettenis }
1265b725ae77Skettenis return 0;
1266b725ae77Skettenis }
1267b725ae77Skettenis
1268b725ae77Skettenis /* We are here presumably because an alias or command in *TEXT is
1269b725ae77Skettenis deprecated and a warning message should be generated. This function
1270b725ae77Skettenis decodes *TEXT and potentially generates a warning message as outlined
1271b725ae77Skettenis below.
1272b725ae77Skettenis
1273b725ae77Skettenis Example for 'set endian big' which has a fictitious alias 'seb'.
1274b725ae77Skettenis
1275b725ae77Skettenis If alias wasn't used in *TEXT, and the command is deprecated:
1276b725ae77Skettenis "warning: 'set endian big' is deprecated."
1277b725ae77Skettenis
1278b725ae77Skettenis If alias was used, and only the alias is deprecated:
1279b725ae77Skettenis "warning: 'seb' an alias for the command 'set endian big' is deprecated."
1280b725ae77Skettenis
1281b725ae77Skettenis If alias was used and command is deprecated (regardless of whether the
1282b725ae77Skettenis alias itself is deprecated:
1283b725ae77Skettenis
1284b725ae77Skettenis "warning: 'set endian big' (seb) is deprecated."
1285b725ae77Skettenis
1286b725ae77Skettenis After the message has been sent, clear the appropriate flags in the
1287b725ae77Skettenis command and/or the alias so the user is no longer bothered.
1288b725ae77Skettenis
1289b725ae77Skettenis */
1290b725ae77Skettenis void
deprecated_cmd_warning(char ** text)1291b725ae77Skettenis deprecated_cmd_warning (char **text)
1292b725ae77Skettenis {
1293b725ae77Skettenis struct cmd_list_element *alias = NULL;
1294b725ae77Skettenis struct cmd_list_element *prefix_cmd = NULL;
1295b725ae77Skettenis struct cmd_list_element *cmd = NULL;
1296b725ae77Skettenis struct cmd_list_element *c;
1297b725ae77Skettenis char *type;
1298b725ae77Skettenis
1299b725ae77Skettenis if (!lookup_cmd_composition (*text, &alias, &prefix_cmd, &cmd))
1300b725ae77Skettenis /* return if text doesn't evaluate to a command */
1301b725ae77Skettenis return;
1302b725ae77Skettenis
1303b725ae77Skettenis if (!((alias ? (alias->flags & DEPRECATED_WARN_USER) : 0)
1304b725ae77Skettenis || (cmd->flags & DEPRECATED_WARN_USER) ) )
1305b725ae77Skettenis /* return if nothing is deprecated */
1306b725ae77Skettenis return;
1307b725ae77Skettenis
1308b725ae77Skettenis printf_filtered ("Warning:");
1309b725ae77Skettenis
1310b725ae77Skettenis if (alias && !(cmd->flags & CMD_DEPRECATED))
1311b725ae77Skettenis printf_filtered (" '%s', an alias for the", alias->name);
1312b725ae77Skettenis
1313b725ae77Skettenis printf_filtered (" command '");
1314b725ae77Skettenis
1315b725ae77Skettenis if (prefix_cmd)
1316b725ae77Skettenis printf_filtered ("%s", prefix_cmd->prefixname);
1317b725ae77Skettenis
1318b725ae77Skettenis printf_filtered ("%s", cmd->name);
1319b725ae77Skettenis
1320b725ae77Skettenis if (alias && (cmd->flags & CMD_DEPRECATED))
1321b725ae77Skettenis printf_filtered ("' (%s) is deprecated.\n", alias->name);
1322b725ae77Skettenis else
1323b725ae77Skettenis printf_filtered ("' is deprecated.\n");
1324b725ae77Skettenis
1325b725ae77Skettenis
1326b725ae77Skettenis /* if it is only the alias that is deprecated, we want to indicate the
1327b725ae77Skettenis new alias, otherwise we'll indicate the new command */
1328b725ae77Skettenis
1329b725ae77Skettenis if (alias && !(cmd->flags & CMD_DEPRECATED))
1330b725ae77Skettenis {
1331b725ae77Skettenis if (alias->replacement)
1332b725ae77Skettenis printf_filtered ("Use '%s'.\n\n", alias->replacement);
1333b725ae77Skettenis else
1334b725ae77Skettenis printf_filtered ("No alternative known.\n\n");
1335b725ae77Skettenis }
1336b725ae77Skettenis else
1337b725ae77Skettenis {
1338b725ae77Skettenis if (cmd->replacement)
1339b725ae77Skettenis printf_filtered ("Use '%s'.\n\n", cmd->replacement);
1340b725ae77Skettenis else
1341b725ae77Skettenis printf_filtered ("No alternative known.\n\n");
1342b725ae77Skettenis }
1343b725ae77Skettenis
1344b725ae77Skettenis /* We've warned you, now we'll keep quiet */
1345b725ae77Skettenis if (alias)
1346b725ae77Skettenis alias->flags &= ~DEPRECATED_WARN_USER;
1347b725ae77Skettenis
1348b725ae77Skettenis cmd->flags &= ~DEPRECATED_WARN_USER;
1349b725ae77Skettenis }
1350b725ae77Skettenis
1351b725ae77Skettenis
1352b725ae77Skettenis
1353b725ae77Skettenis /* Look up the contents of LINE as a command in the command list 'cmdlist'.
1354b725ae77Skettenis Return 1 on success, 0 on failure.
1355b725ae77Skettenis
1356b725ae77Skettenis If LINE refers to an alias, *alias will point to that alias.
1357b725ae77Skettenis
1358b725ae77Skettenis If LINE is a postfix command (i.e. one that is preceeded by a prefix
1359b725ae77Skettenis command) set *prefix_cmd.
1360b725ae77Skettenis
1361b725ae77Skettenis Set *cmd to point to the command LINE indicates.
1362b725ae77Skettenis
1363b725ae77Skettenis If any of *alias, *prefix_cmd, or *cmd cannot be determined or do not
1364b725ae77Skettenis exist, they are NULL when we return.
1365b725ae77Skettenis
1366b725ae77Skettenis */
1367b725ae77Skettenis int
lookup_cmd_composition(char * text,struct cmd_list_element ** alias,struct cmd_list_element ** prefix_cmd,struct cmd_list_element ** cmd)1368b725ae77Skettenis lookup_cmd_composition (char *text,
1369b725ae77Skettenis struct cmd_list_element **alias,
1370b725ae77Skettenis struct cmd_list_element **prefix_cmd,
1371b725ae77Skettenis struct cmd_list_element **cmd)
1372b725ae77Skettenis {
1373b725ae77Skettenis char *p, *command;
1374b725ae77Skettenis int len, tmp, nfound;
1375b725ae77Skettenis struct cmd_list_element *cur_list;
1376b725ae77Skettenis struct cmd_list_element *prev_cmd;
1377b725ae77Skettenis *alias = NULL;
1378b725ae77Skettenis *prefix_cmd = NULL;
1379b725ae77Skettenis *cmd = NULL;
1380b725ae77Skettenis
1381b725ae77Skettenis cur_list = cmdlist;
1382b725ae77Skettenis
1383b725ae77Skettenis while (1)
1384b725ae77Skettenis {
1385b725ae77Skettenis /* Go through as many command lists as we need to
1386b725ae77Skettenis to find the command TEXT refers to. */
1387b725ae77Skettenis
1388b725ae77Skettenis prev_cmd = *cmd;
1389b725ae77Skettenis
1390b725ae77Skettenis while (*text == ' ' || *text == '\t')
1391b725ae77Skettenis (text)++;
1392b725ae77Skettenis
1393b725ae77Skettenis /* Treating underscores as part of command words is important
1394b725ae77Skettenis so that "set args_foo()" doesn't get interpreted as
1395b725ae77Skettenis "set args _foo()". */
1396b725ae77Skettenis /* NOTE: cagney/2003-02-13 The `tui_active' was previously
1397b725ae77Skettenis `tui_version'. */
1398b725ae77Skettenis for (p = text;
1399b725ae77Skettenis *p && (isalnum (*p) || *p == '-' || *p == '_' ||
1400b725ae77Skettenis #if defined(TUI)
1401b725ae77Skettenis (tui_active &&
1402b725ae77Skettenis (*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
1403b725ae77Skettenis #endif
1404b725ae77Skettenis (xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
1405b725ae77Skettenis p++)
1406b725ae77Skettenis ;
1407b725ae77Skettenis
1408b725ae77Skettenis /* If nothing but whitespace, return. */
1409b725ae77Skettenis if (p == text)
1410b725ae77Skettenis return 0;
1411b725ae77Skettenis
1412b725ae77Skettenis len = p - text;
1413b725ae77Skettenis
1414b725ae77Skettenis /* text and p now bracket the first command word to lookup (and
1415b725ae77Skettenis it's length is len). We copy this into a local temporary */
1416b725ae77Skettenis
1417b725ae77Skettenis command = (char *) alloca (len + 1);
1418b725ae77Skettenis for (tmp = 0; tmp < len; tmp++)
1419b725ae77Skettenis {
1420b725ae77Skettenis char x = text[tmp];
1421b725ae77Skettenis command[tmp] = x;
1422b725ae77Skettenis }
1423b725ae77Skettenis command[len] = '\0';
1424b725ae77Skettenis
1425b725ae77Skettenis /* Look it up. */
1426b725ae77Skettenis *cmd = 0;
1427b725ae77Skettenis nfound = 0;
1428b725ae77Skettenis *cmd = find_cmd (command, len, cur_list, 1, &nfound);
1429b725ae77Skettenis
1430b725ae77Skettenis /* We didn't find the command in the entered case, so lower case it
1431b725ae77Skettenis and search again.
1432b725ae77Skettenis */
1433b725ae77Skettenis if (!*cmd || nfound == 0)
1434b725ae77Skettenis {
1435b725ae77Skettenis for (tmp = 0; tmp < len; tmp++)
1436b725ae77Skettenis {
1437b725ae77Skettenis char x = command[tmp];
1438b725ae77Skettenis command[tmp] = isupper (x) ? tolower (x) : x;
1439b725ae77Skettenis }
1440b725ae77Skettenis *cmd = find_cmd (command, len, cur_list, 1, &nfound);
1441b725ae77Skettenis }
1442b725ae77Skettenis
1443b725ae77Skettenis if (*cmd == (struct cmd_list_element *) -1)
1444b725ae77Skettenis {
1445b725ae77Skettenis return 0; /* ambiguous */
1446b725ae77Skettenis }
1447b725ae77Skettenis
1448b725ae77Skettenis if (*cmd == NULL)
1449b725ae77Skettenis return 0; /* nothing found */
1450b725ae77Skettenis else
1451b725ae77Skettenis {
1452b725ae77Skettenis if ((*cmd)->cmd_pointer)
1453b725ae77Skettenis {
1454b725ae77Skettenis /* cmd was actually an alias, we note that an alias was used
1455b725ae77Skettenis (by assigning *alais) and we set *cmd.
1456b725ae77Skettenis */
1457b725ae77Skettenis *alias = *cmd;
1458b725ae77Skettenis *cmd = (*cmd)->cmd_pointer;
1459b725ae77Skettenis }
1460b725ae77Skettenis *prefix_cmd = prev_cmd;
1461b725ae77Skettenis }
1462b725ae77Skettenis if ((*cmd)->prefixlist)
1463b725ae77Skettenis cur_list = *(*cmd)->prefixlist;
1464b725ae77Skettenis else
1465b725ae77Skettenis return 1;
1466b725ae77Skettenis
1467b725ae77Skettenis text = p;
1468b725ae77Skettenis }
1469b725ae77Skettenis }
1470b725ae77Skettenis
1471b725ae77Skettenis /* Helper function for SYMBOL_COMPLETION_FUNCTION. */
1472b725ae77Skettenis
1473b725ae77Skettenis /* Return a vector of char pointers which point to the different
1474b725ae77Skettenis possible completions in LIST of TEXT.
1475b725ae77Skettenis
1476b725ae77Skettenis WORD points in the same buffer as TEXT, and completions should be
1477b725ae77Skettenis returned relative to this position. For example, suppose TEXT is "foo"
1478b725ae77Skettenis and we want to complete to "foobar". If WORD is "oo", return
1479b725ae77Skettenis "oobar"; if WORD is "baz/foo", return "baz/foobar". */
1480b725ae77Skettenis
1481b725ae77Skettenis char **
complete_on_cmdlist(struct cmd_list_element * list,char * text,char * word)1482b725ae77Skettenis complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
1483b725ae77Skettenis {
1484b725ae77Skettenis struct cmd_list_element *ptr;
1485b725ae77Skettenis char **matchlist;
1486b725ae77Skettenis int sizeof_matchlist;
1487b725ae77Skettenis int matches;
1488b725ae77Skettenis int textlen = strlen (text);
1489b725ae77Skettenis
1490b725ae77Skettenis sizeof_matchlist = 10;
1491b725ae77Skettenis matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
1492b725ae77Skettenis matches = 0;
1493b725ae77Skettenis
1494b725ae77Skettenis for (ptr = list; ptr; ptr = ptr->next)
1495b725ae77Skettenis if (!strncmp (ptr->name, text, textlen)
1496b725ae77Skettenis && !ptr->abbrev_flag
1497b725ae77Skettenis && (ptr->func
1498b725ae77Skettenis || ptr->prefixlist))
1499b725ae77Skettenis {
1500b725ae77Skettenis if (matches == sizeof_matchlist)
1501b725ae77Skettenis {
1502b725ae77Skettenis sizeof_matchlist *= 2;
1503b725ae77Skettenis matchlist = (char **) xrealloc ((char *) matchlist,
1504b725ae77Skettenis (sizeof_matchlist
1505b725ae77Skettenis * sizeof (char *)));
1506b725ae77Skettenis }
1507b725ae77Skettenis
1508b725ae77Skettenis matchlist[matches] = (char *)
1509b725ae77Skettenis xmalloc (strlen (word) + strlen (ptr->name) + 1);
1510b725ae77Skettenis if (word == text)
1511b725ae77Skettenis strcpy (matchlist[matches], ptr->name);
1512b725ae77Skettenis else if (word > text)
1513b725ae77Skettenis {
1514b725ae77Skettenis /* Return some portion of ptr->name. */
1515b725ae77Skettenis strcpy (matchlist[matches], ptr->name + (word - text));
1516b725ae77Skettenis }
1517b725ae77Skettenis else
1518b725ae77Skettenis {
1519b725ae77Skettenis /* Return some of text plus ptr->name. */
1520b725ae77Skettenis strncpy (matchlist[matches], word, text - word);
1521b725ae77Skettenis matchlist[matches][text - word] = '\0';
1522b725ae77Skettenis strcat (matchlist[matches], ptr->name);
1523b725ae77Skettenis }
1524b725ae77Skettenis ++matches;
1525b725ae77Skettenis }
1526b725ae77Skettenis
1527b725ae77Skettenis if (matches == 0)
1528b725ae77Skettenis {
1529b725ae77Skettenis xfree (matchlist);
1530b725ae77Skettenis matchlist = 0;
1531b725ae77Skettenis }
1532b725ae77Skettenis else
1533b725ae77Skettenis {
1534b725ae77Skettenis matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
1535b725ae77Skettenis * sizeof (char *)));
1536b725ae77Skettenis matchlist[matches] = (char *) 0;
1537b725ae77Skettenis }
1538b725ae77Skettenis
1539b725ae77Skettenis return matchlist;
1540b725ae77Skettenis }
1541b725ae77Skettenis
1542b725ae77Skettenis /* Helper function for SYMBOL_COMPLETION_FUNCTION. */
1543b725ae77Skettenis
1544b725ae77Skettenis /* Return a vector of char pointers which point to the different
1545b725ae77Skettenis possible completions in CMD of TEXT.
1546b725ae77Skettenis
1547b725ae77Skettenis WORD points in the same buffer as TEXT, and completions should be
1548b725ae77Skettenis returned relative to this position. For example, suppose TEXT is "foo"
1549b725ae77Skettenis and we want to complete to "foobar". If WORD is "oo", return
1550b725ae77Skettenis "oobar"; if WORD is "baz/foo", return "baz/foobar". */
1551b725ae77Skettenis
1552b725ae77Skettenis char **
complete_on_enum(const char * enumlist[],char * text,char * word)1553b725ae77Skettenis complete_on_enum (const char *enumlist[],
1554b725ae77Skettenis char *text,
1555b725ae77Skettenis char *word)
1556b725ae77Skettenis {
1557b725ae77Skettenis char **matchlist;
1558b725ae77Skettenis int sizeof_matchlist;
1559b725ae77Skettenis int matches;
1560b725ae77Skettenis int textlen = strlen (text);
1561b725ae77Skettenis int i;
1562b725ae77Skettenis const char *name;
1563b725ae77Skettenis
1564b725ae77Skettenis sizeof_matchlist = 10;
1565b725ae77Skettenis matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
1566b725ae77Skettenis matches = 0;
1567b725ae77Skettenis
1568b725ae77Skettenis for (i = 0; (name = enumlist[i]) != NULL; i++)
1569b725ae77Skettenis if (strncmp (name, text, textlen) == 0)
1570b725ae77Skettenis {
1571b725ae77Skettenis if (matches == sizeof_matchlist)
1572b725ae77Skettenis {
1573b725ae77Skettenis sizeof_matchlist *= 2;
1574b725ae77Skettenis matchlist = (char **) xrealloc ((char *) matchlist,
1575b725ae77Skettenis (sizeof_matchlist
1576b725ae77Skettenis * sizeof (char *)));
1577b725ae77Skettenis }
1578b725ae77Skettenis
1579b725ae77Skettenis matchlist[matches] = (char *)
1580b725ae77Skettenis xmalloc (strlen (word) + strlen (name) + 1);
1581b725ae77Skettenis if (word == text)
1582b725ae77Skettenis strcpy (matchlist[matches], name);
1583b725ae77Skettenis else if (word > text)
1584b725ae77Skettenis {
1585b725ae77Skettenis /* Return some portion of name. */
1586b725ae77Skettenis strcpy (matchlist[matches], name + (word - text));
1587b725ae77Skettenis }
1588b725ae77Skettenis else
1589b725ae77Skettenis {
1590b725ae77Skettenis /* Return some of text plus name. */
1591b725ae77Skettenis strncpy (matchlist[matches], word, text - word);
1592b725ae77Skettenis matchlist[matches][text - word] = '\0';
1593b725ae77Skettenis strcat (matchlist[matches], name);
1594b725ae77Skettenis }
1595b725ae77Skettenis ++matches;
1596b725ae77Skettenis }
1597b725ae77Skettenis
1598b725ae77Skettenis if (matches == 0)
1599b725ae77Skettenis {
1600b725ae77Skettenis xfree (matchlist);
1601b725ae77Skettenis matchlist = 0;
1602b725ae77Skettenis }
1603b725ae77Skettenis else
1604b725ae77Skettenis {
1605b725ae77Skettenis matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
1606b725ae77Skettenis * sizeof (char *)));
1607b725ae77Skettenis matchlist[matches] = (char *) 0;
1608b725ae77Skettenis }
1609b725ae77Skettenis
1610b725ae77Skettenis return matchlist;
1611b725ae77Skettenis }
1612b725ae77Skettenis
1613b725ae77Skettenis
1614b725ae77Skettenis /* check function pointer */
1615b725ae77Skettenis int
cmd_func_p(struct cmd_list_element * cmd)1616b725ae77Skettenis cmd_func_p (struct cmd_list_element *cmd)
1617b725ae77Skettenis {
1618b725ae77Skettenis return (cmd->func != NULL);
1619b725ae77Skettenis }
1620b725ae77Skettenis
1621b725ae77Skettenis
1622b725ae77Skettenis /* call the command function */
1623b725ae77Skettenis void
cmd_func(struct cmd_list_element * cmd,char * args,int from_tty)1624b725ae77Skettenis cmd_func (struct cmd_list_element *cmd, char *args, int from_tty)
1625b725ae77Skettenis {
1626b725ae77Skettenis if (cmd_func_p (cmd))
1627b725ae77Skettenis (*cmd->func) (cmd, args, from_tty);
1628b725ae77Skettenis else
1629b725ae77Skettenis error ("Invalid command");
1630b725ae77Skettenis }
1631b725ae77Skettenis
1632b725ae77Skettenis
1633