1 /* Handle lists of commands, their decoding and documentation, for GDB.
2 
3    Copyright (C) 1986-2024 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 3 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, see <http://www.gnu.org/licenses/>.  */
17 
18 #include "symtab.h"
19 #include <ctype.h>
20 #include "gdbsupport/gdb_regex.h"
21 #include "completer.h"
22 #include "ui-out.h"
23 #include "cli/cli-cmds.h"
24 #include "cli/cli-decode.h"
25 #include "cli/cli-style.h"
26 #include <optional>
27 
28 /* Prototypes for local functions.  */
29 
30 static void undef_cmd_error (const char *, const char *);
31 
32 static cmd_list_element::aliases_list_type delete_cmd
33   (const char *name, cmd_list_element **list, cmd_list_element **prehook,
34    cmd_list_element **prehookee, cmd_list_element **posthook,
35    cmd_list_element **posthookee);
36 
37 static struct cmd_list_element *find_cmd (const char *command,
38                                                     int len,
39                                                     struct cmd_list_element *clist,
40                                                     int ignore_help_classes,
41                                                     int *nfound);
42 
43 static void help_cmd_list (struct cmd_list_element *list,
44                                  enum command_class theclass,
45                                  bool recurse,
46                                  struct ui_file *stream);
47 
48 static void help_all (struct ui_file *stream);
49 
50 static int lookup_cmd_composition_1 (const char *text,
51                                              struct cmd_list_element **alias,
52                                              struct cmd_list_element **prefix_cmd,
53                                              struct cmd_list_element **cmd,
54                                              struct cmd_list_element *cur_list);
55 
56 /* Look up a command whose 'subcommands' field is SUBCOMMANDS.  Return the
57    command if found, otherwise return NULL.  */
58 
59 static struct cmd_list_element *
lookup_cmd_with_subcommands(cmd_list_element ** subcommands,cmd_list_element * list)60 lookup_cmd_with_subcommands (cmd_list_element **subcommands,
61                                    cmd_list_element *list)
62 {
63   struct cmd_list_element *p = NULL;
64 
65   for (p = list; p != NULL; p = p->next)
66     {
67       struct cmd_list_element *q;
68 
69       if (!p->is_prefix ())
70           continue;
71 
72       else if (p->subcommands == subcommands)
73           {
74             /* If we found an alias, we must return the aliased
75                command.  */
76             return p->is_alias () ? p->alias_target : p;
77           }
78 
79       q = lookup_cmd_with_subcommands (subcommands, *(p->subcommands));
80       if (q != NULL)
81           return q;
82     }
83 
84   return NULL;
85 }
86 
87 static void
88 print_help_for_command (const cmd_list_element &c,
89                               bool recurse, struct ui_file *stream);
90 
91 static void
do_simple_func(const char * args,int from_tty,cmd_list_element * c)92 do_simple_func (const char *args, int from_tty, cmd_list_element *c)
93 {
94   c->function.simple_func (args, from_tty);
95 }
96 
97 static void
set_cmd_simple_func(struct cmd_list_element * cmd,cmd_simple_func_ftype * simple_func)98 set_cmd_simple_func (struct cmd_list_element *cmd, cmd_simple_func_ftype *simple_func)
99 {
100   if (simple_func == NULL)
101     cmd->func = NULL;
102   else
103     cmd->func = do_simple_func;
104 
105   cmd->function.simple_func = simple_func;
106 }
107 
108 int
cmd_simple_func_eq(struct cmd_list_element * cmd,cmd_simple_func_ftype * simple_func)109 cmd_simple_func_eq (struct cmd_list_element *cmd, cmd_simple_func_ftype *simple_func)
110 {
111   return (cmd->func == do_simple_func
112             && cmd->function.simple_func == simple_func);
113 }
114 
115 void
set_cmd_completer(struct cmd_list_element * cmd,completer_ftype * completer)116 set_cmd_completer (struct cmd_list_element *cmd, completer_ftype *completer)
117 {
118   cmd->completer = completer; /* Ok.  */
119 }
120 
121 /* See definition in commands.h.  */
122 
123 void
set_cmd_completer_handle_brkchars(struct cmd_list_element * cmd,completer_handle_brkchars_ftype * func)124 set_cmd_completer_handle_brkchars (struct cmd_list_element *cmd,
125                                            completer_handle_brkchars_ftype *func)
126 {
127   cmd->completer_handle_brkchars = func;
128 }
129 
130 std::string
prefixname()131 cmd_list_element::prefixname () const
132 {
133   if (!this->is_prefix ())
134     /* Not a prefix command.  */
135     return "";
136 
137   std::string prefixname;
138   if (this->prefix != nullptr)
139     prefixname = this->prefix->prefixname ();
140 
141   prefixname += this->name;
142   prefixname += " ";
143 
144   return prefixname;
145 }
146 
147 /* See cli/cli-decode.h.  */
148 
149 std::vector<std::string>
command_components()150 cmd_list_element::command_components () const
151 {
152   std::vector<std::string> result;
153 
154   if (this->prefix != nullptr)
155     result = this->prefix->command_components ();
156 
157   result.emplace_back (this->name);
158   return result;
159 }
160 
161 /* Add element named NAME.
162    Space for NAME and DOC must be allocated by the caller.
163    THECLASS is the top level category into which commands are broken down
164    for "help" purposes.
165    FUN should be the function to execute the command;
166    it will get a character string as argument, with leading
167    and trailing blanks already eliminated.
168 
169    DOC is a documentation string for the command.
170    Its first line should be a complete sentence.
171    It should start with ? for a command that is an abbreviation
172    or with * for a command that most users don't need to know about.
173 
174    Add this command to command list *LIST.
175 
176    Returns a pointer to the added command (not necessarily the head
177    of *LIST).  */
178 
179 static struct cmd_list_element *
do_add_cmd(const char * name,enum command_class theclass,const char * doc,struct cmd_list_element ** list)180 do_add_cmd (const char *name, enum command_class theclass,
181               const char *doc, struct cmd_list_element **list)
182 {
183   struct cmd_list_element *c = new struct cmd_list_element (name, theclass,
184                                                                           doc);
185 
186   /* Turn each alias of the old command into an alias of the new
187      command.  */
188   c->aliases = delete_cmd (name, list, &c->hook_pre, &c->hookee_pre,
189                                  &c->hook_post, &c->hookee_post);
190 
191   for (cmd_list_element &alias : c->aliases)
192     alias.alias_target = c;
193 
194   if (c->hook_pre)
195     c->hook_pre->hookee_pre = c;
196 
197   if (c->hookee_pre)
198     c->hookee_pre->hook_pre = c;
199 
200   if (c->hook_post)
201     c->hook_post->hookee_post = c;
202 
203   if (c->hookee_post)
204     c->hookee_post->hook_post = c;
205 
206   if (*list == NULL || strcmp ((*list)->name, name) >= 0)
207     {
208       c->next = *list;
209       *list = c;
210     }
211   else
212     {
213       cmd_list_element *p = *list;
214       while (p->next && strcmp (p->next->name, name) <= 0)
215           {
216             p = p->next;
217           }
218       c->next = p->next;
219       p->next = c;
220     }
221 
222   /* Search the prefix cmd of C, and assigns it to C->prefix.
223      See also add_prefix_cmd and update_prefix_field_of_prefixed_commands.  */
224   cmd_list_element *prefixcmd = lookup_cmd_with_subcommands (list, cmdlist);
225   c->prefix = prefixcmd;
226 
227 
228   return c;
229 }
230 
231 struct cmd_list_element *
add_cmd(const char * name,enum command_class theclass,const char * doc,struct cmd_list_element ** list)232 add_cmd (const char *name, enum command_class theclass,
233            const char *doc, struct cmd_list_element **list)
234 {
235   cmd_list_element *result = do_add_cmd (name, theclass, doc, list);
236   result->func = NULL;
237   result->function.simple_func = NULL;
238   return result;
239 }
240 
241 struct cmd_list_element *
add_cmd(const char * name,enum command_class theclass,cmd_simple_func_ftype * fun,const char * doc,struct cmd_list_element ** list)242 add_cmd (const char *name, enum command_class theclass,
243            cmd_simple_func_ftype *fun,
244            const char *doc, struct cmd_list_element **list)
245 {
246   cmd_list_element *result = do_add_cmd (name, theclass, doc, list);
247   set_cmd_simple_func (result, fun);
248   return result;
249 }
250 
251 /* Add an element with a suppress notification to the LIST of commands.  */
252 
253 struct cmd_list_element *
add_cmd_suppress_notification(const char * name,enum command_class theclass,cmd_simple_func_ftype * fun,const char * doc,struct cmd_list_element ** list,bool * suppress_notification)254 add_cmd_suppress_notification (const char *name, enum command_class theclass,
255                                      cmd_simple_func_ftype *fun, const char *doc,
256                                      struct cmd_list_element **list,
257                                      bool *suppress_notification)
258 {
259   struct cmd_list_element *element;
260 
261   element = add_cmd (name, theclass, fun, doc, list);
262   element->suppress_notification = suppress_notification;
263 
264   return element;
265 }
266 
267 
268 /* Deprecates a command CMD.
269    REPLACEMENT is the name of the command which should be used in
270    place of this command, or NULL if no such command exists.
271 
272    This function does not check to see if command REPLACEMENT exists
273    since gdb may not have gotten around to adding REPLACEMENT when
274    this function is called.
275 
276    Returns a pointer to the deprecated command.  */
277 
278 struct cmd_list_element *
deprecate_cmd(struct cmd_list_element * cmd,const char * replacement)279 deprecate_cmd (struct cmd_list_element *cmd, const char *replacement)
280 {
281   cmd->cmd_deprecated = 1;
282   cmd->deprecated_warn_user = 1;
283 
284   if (replacement != NULL)
285     cmd->replacement = replacement;
286   else
287     cmd->replacement = NULL;
288 
289   return cmd;
290 }
291 
292 struct cmd_list_element *
add_alias_cmd(const char * name,cmd_list_element * target,enum command_class theclass,int abbrev_flag,struct cmd_list_element ** list)293 add_alias_cmd (const char *name, cmd_list_element *target,
294                  enum command_class theclass, int abbrev_flag,
295                  struct cmd_list_element **list)
296 {
297   gdb_assert (target != nullptr);
298 
299   struct cmd_list_element *c = add_cmd (name, theclass, target->doc, list);
300 
301   /* If TARGET->DOC can be freed, we should make another copy.  */
302   if (target->doc_allocated)
303     {
304       c->doc = xstrdup (target->doc);
305       c->doc_allocated = 1;
306     }
307   /* NOTE: Both FUNC and all the FUNCTIONs need to be copied.  */
308   c->func = target->func;
309   c->function = target->function;
310   c->subcommands = target->subcommands;
311   c->allow_unknown = target->allow_unknown;
312   c->abbrev_flag = abbrev_flag;
313   c->alias_target = target;
314   target->aliases.push_front (*c);
315 
316   return c;
317 }
318 
319 /* Update the prefix field of all sub-commands of the prefix command C.
320    We must do this when a prefix command is defined as the GDB init sequence
321    does not guarantee that a prefix command is created before its sub-commands.
322    For example, break-catch-sig.c initialization runs before breakpoint.c
323    initialization, but it is breakpoint.c that creates the "catch" command used
324    by the "catch signal" command created by break-catch-sig.c.  */
325 
326 static void
update_prefix_field_of_prefixed_commands(struct cmd_list_element * c)327 update_prefix_field_of_prefixed_commands (struct cmd_list_element *c)
328 {
329   for (cmd_list_element *p = *c->subcommands; p != NULL; p = p->next)
330     {
331       p->prefix = c;
332 
333       /* We must recursively update the prefix field to cover
334            e.g.  'info auto-load libthread-db' where the creation
335            order was:
336              libthread-db
337              auto-load
338              info
339            In such a case, when 'auto-load' was created by do_add_cmd,
340            the 'libthread-db' prefix field could not be updated, as the
341            'auto-load' command was not yet reachable by
342               lookup_cmd_for_subcommands (list, cmdlist)
343               that searches from the top level 'cmdlist'.  */
344       if (p->is_prefix ())
345           update_prefix_field_of_prefixed_commands (p);
346     }
347 }
348 
349 
350 /* Like add_cmd but adds an element for a command prefix: a name that
351    should be followed by a subcommand to be looked up in another
352    command list.  SUBCOMMANDS should be the address of the variable
353    containing that list.  */
354 
355 struct cmd_list_element *
add_prefix_cmd(const char * name,enum command_class theclass,cmd_simple_func_ftype * fun,const char * doc,struct cmd_list_element ** subcommands,int allow_unknown,struct cmd_list_element ** list)356 add_prefix_cmd (const char *name, enum command_class theclass,
357                     cmd_simple_func_ftype *fun,
358                     const char *doc, struct cmd_list_element **subcommands,
359                     int allow_unknown, struct cmd_list_element **list)
360 {
361   struct cmd_list_element *c = add_cmd (name, theclass, fun, doc, list);
362 
363   c->subcommands = subcommands;
364   c->allow_unknown = allow_unknown;
365 
366   /* Now that prefix command C is defined, we need to set the prefix field
367      of all prefixed commands that were defined before C itself was defined.  */
368   update_prefix_field_of_prefixed_commands (c);
369 
370   return c;
371 }
372 
373 /* A helper function for add_basic_prefix_cmd.  This is a command
374    function that just forwards to help_list.  */
375 
376 static void
do_prefix_cmd(const char * args,int from_tty,struct cmd_list_element * c)377 do_prefix_cmd (const char *args, int from_tty, struct cmd_list_element *c)
378 {
379   /* Look past all aliases.  */
380   while (c->is_alias ())
381     c = c->alias_target;
382 
383   help_list (*c->subcommands, c->prefixname ().c_str (),
384                all_commands, gdb_stdout);
385 }
386 
387 /* See command.h.  */
388 
389 struct cmd_list_element *
add_basic_prefix_cmd(const char * name,enum command_class theclass,const char * doc,struct cmd_list_element ** subcommands,int allow_unknown,struct cmd_list_element ** list)390 add_basic_prefix_cmd (const char *name, enum command_class theclass,
391                           const char *doc, struct cmd_list_element **subcommands,
392                           int allow_unknown, struct cmd_list_element **list)
393 {
394   struct cmd_list_element *cmd = add_prefix_cmd (name, theclass, nullptr,
395                                                              doc, subcommands,
396                                                              allow_unknown, list);
397   cmd->func = do_prefix_cmd;
398   return cmd;
399 }
400 
401 /* A helper function for add_show_prefix_cmd.  This is a command
402    function that just forwards to cmd_show_list.  */
403 
404 static void
do_show_prefix_cmd(const char * args,int from_tty,struct cmd_list_element * c)405 do_show_prefix_cmd (const char *args, int from_tty, struct cmd_list_element *c)
406 {
407   cmd_show_list (*c->subcommands, from_tty);
408 }
409 
410 /* See command.h.  */
411 
412 struct cmd_list_element *
add_show_prefix_cmd(const char * name,enum command_class theclass,const char * doc,struct cmd_list_element ** subcommands,int allow_unknown,struct cmd_list_element ** list)413 add_show_prefix_cmd (const char *name, enum command_class theclass,
414                          const char *doc, struct cmd_list_element **subcommands,
415                          int allow_unknown, struct cmd_list_element **list)
416 {
417   struct cmd_list_element *cmd = add_prefix_cmd (name, theclass, nullptr,
418                                                              doc, subcommands,
419                                                              allow_unknown, list);
420   cmd->func = do_show_prefix_cmd;
421   return cmd;
422 }
423 
424 /* See command.h.  */
425 
426 set_show_commands
add_setshow_prefix_cmd(const char * name,command_class theclass,const char * set_doc,const char * show_doc,cmd_list_element ** set_subcommands_list,cmd_list_element ** show_subcommands_list,cmd_list_element ** set_list,cmd_list_element ** show_list)427 add_setshow_prefix_cmd (const char *name, command_class theclass,
428                               const char *set_doc, const char *show_doc,
429                               cmd_list_element **set_subcommands_list,
430                               cmd_list_element **show_subcommands_list,
431                               cmd_list_element **set_list,
432                               cmd_list_element **show_list)
433 {
434   set_show_commands cmds;
435 
436   cmds.set = add_basic_prefix_cmd (name, theclass, set_doc,
437                                            set_subcommands_list, 0,
438                                            set_list);
439   cmds.show = add_show_prefix_cmd (name, theclass, show_doc,
440                                            show_subcommands_list, 0,
441                                            show_list);
442 
443   return cmds;
444 }
445 
446 /* Like ADD_PREFIX_CMD but sets the suppress_notification pointer on the
447    new command list element.  */
448 
449 struct cmd_list_element *
add_prefix_cmd_suppress_notification(const char * name,enum command_class theclass,cmd_simple_func_ftype * fun,const char * doc,struct cmd_list_element ** subcommands,int allow_unknown,struct cmd_list_element ** list,bool * suppress_notification)450 add_prefix_cmd_suppress_notification
451                  (const char *name, enum command_class theclass,
452                     cmd_simple_func_ftype *fun,
453                     const char *doc, struct cmd_list_element **subcommands,
454                     int allow_unknown, struct cmd_list_element **list,
455                     bool *suppress_notification)
456 {
457   struct cmd_list_element *element
458     = add_prefix_cmd (name, theclass, fun, doc, subcommands,
459                           allow_unknown, list);
460   element->suppress_notification = suppress_notification;
461   return element;
462 }
463 
464 /* Like add_prefix_cmd but sets the abbrev_flag on the new command.  */
465 
466 struct cmd_list_element *
add_abbrev_prefix_cmd(const char * name,enum command_class theclass,cmd_simple_func_ftype * fun,const char * doc,struct cmd_list_element ** subcommands,int allow_unknown,struct cmd_list_element ** list)467 add_abbrev_prefix_cmd (const char *name, enum command_class theclass,
468                            cmd_simple_func_ftype *fun, const char *doc,
469                            struct cmd_list_element **subcommands,
470                            int allow_unknown, struct cmd_list_element **list)
471 {
472   struct cmd_list_element *c = add_cmd (name, theclass, fun, doc, list);
473 
474   c->subcommands = subcommands;
475   c->allow_unknown = allow_unknown;
476   c->abbrev_flag = 1;
477   return c;
478 }
479 
480 /* This is an empty "simple func".  */
481 void
not_just_help_class_command(const char * args,int from_tty)482 not_just_help_class_command (const char *args, int from_tty)
483 {
484 }
485 
486 /* This is an empty cmd func.  */
487 
488 static void
empty_func(const char * args,int from_tty,cmd_list_element * c)489 empty_func (const char *args, int from_tty, cmd_list_element *c)
490 {
491 }
492 
493 /* Add element named NAME to command list LIST (the list for set/show
494    or some sublist thereof).
495    TYPE is set_cmd or show_cmd.
496    THECLASS is as in add_cmd.
497    VAR_TYPE is the kind of thing we are setting.
498    EXTRA_LITERALS if non-NULL define extra literals to be accepted in lieu of
499    a number for integer variables.
500    ARGS is a pre-validated type-erased reference to the variable being
501    controlled by this command.
502    DOC is the documentation string.  */
503 
504 static struct cmd_list_element *
add_set_or_show_cmd(const char * name,enum cmd_types type,enum command_class theclass,var_types var_type,const literal_def * extra_literals,const setting::erased_args & arg,const char * doc,struct cmd_list_element ** list)505 add_set_or_show_cmd (const char *name,
506                          enum cmd_types type,
507                          enum command_class theclass,
508                          var_types var_type,
509                          const literal_def *extra_literals,
510                          const setting::erased_args &arg,
511                          const char *doc,
512                          struct cmd_list_element **list)
513 {
514   struct cmd_list_element *c = add_cmd (name, theclass, doc, list);
515 
516   gdb_assert (type == set_cmd || type == show_cmd);
517   c->type = type;
518   c->var.emplace (var_type, extra_literals, arg);
519 
520   /* This needs to be something besides NULL so that this isn't
521      treated as a help class.  */
522   c->func = empty_func;
523   return c;
524 }
525 
526 /* Add element named NAME to both command lists SET_LIST and SHOW_LIST.
527    THECLASS is as in add_cmd.  VAR_TYPE is the kind of thing we are
528    setting.  EXTRA_LITERALS if non-NULL define extra literals to be
529    accepted in lieu of a number for integer variables.  ARGS is a
530    pre-validated type-erased reference to the variable being controlled
531    by this command.  SET_FUNC and SHOW_FUNC are the callback functions
532    (if non-NULL).  SET_DOC, SHOW_DOC and HELP_DOC are the documentation
533    strings.
534 
535    Return the newly created set and show commands.  */
536 
537 static set_show_commands
add_setshow_cmd_full_erased(const char * name,enum command_class theclass,var_types var_type,const literal_def * extra_literals,const setting::erased_args & args,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)538 add_setshow_cmd_full_erased (const char *name,
539                                    enum command_class theclass,
540                                    var_types var_type,
541                                    const literal_def *extra_literals,
542                                    const setting::erased_args &args,
543                                    const char *set_doc, const char *show_doc,
544                                    const char *help_doc,
545                                    cmd_func_ftype *set_func,
546                                    show_value_ftype *show_func,
547                                    struct cmd_list_element **set_list,
548                                    struct cmd_list_element **show_list)
549 {
550   struct cmd_list_element *set;
551   struct cmd_list_element *show;
552   gdb::unique_xmalloc_ptr<char> full_set_doc;
553   gdb::unique_xmalloc_ptr<char> full_show_doc;
554 
555   if (help_doc != NULL)
556     {
557       full_set_doc = xstrprintf ("%s\n%s", set_doc, help_doc);
558       full_show_doc = xstrprintf ("%s\n%s", show_doc, help_doc);
559     }
560   else
561     {
562       full_set_doc = make_unique_xstrdup (set_doc);
563       full_show_doc = make_unique_xstrdup (show_doc);
564     }
565   set = add_set_or_show_cmd (name, set_cmd, theclass, var_type,
566                                    extra_literals, args,
567                                    full_set_doc.release (), set_list);
568   set->doc_allocated = 1;
569 
570   if (set_func != NULL)
571     set->func = set_func;
572 
573   show = add_set_or_show_cmd (name, show_cmd, theclass, var_type,
574                                     extra_literals, args,
575                                     full_show_doc.release (), show_list);
576   show->doc_allocated = 1;
577   show->show_value_func = show_func;
578   /* Disable the default symbol completer.  Doesn't make much sense
579      for the "show" command to complete on anything.  */
580   set_cmd_completer (show, nullptr);
581 
582   return {set, show};
583 }
584 
585 /* Completes on integer commands that support extra literals.  */
586 
587 static void
integer_literals_completer(struct cmd_list_element * c,completion_tracker & tracker,const char * text,const char * word)588 integer_literals_completer (struct cmd_list_element *c,
589                                   completion_tracker &tracker,
590                                   const char *text, const char *word)
591 {
592   const literal_def *extra_literals = c->var->extra_literals ();
593 
594   if (*text == '\0')
595     {
596       tracker.add_completion (make_unique_xstrdup ("NUMBER"));
597       for (const literal_def *l = extra_literals;
598              l->literal != nullptr;
599              l++)
600           tracker.add_completion (make_unique_xstrdup (l->literal));
601     }
602   else
603     for (const literal_def *l = extra_literals;
604            l->literal != nullptr;
605            l++)
606       if (startswith (l->literal, text))
607           tracker.add_completion (make_unique_xstrdup (l->literal));
608 }
609 
610 /* Add element named NAME to both command lists SET_LIST and SHOW_LIST.
611    THECLASS is as in add_cmd.  VAR_TYPE is the kind of thing we are
612    setting.  VAR is address of the variable being controlled by this
613    command.  EXTRA_LITERALS if non-NULL define extra literals to be
614    accepted in lieu of a number for integer variables.  If nullptr is
615    given as VAR, then both SET_SETTING_FUNC and GET_SETTING_FUNC must
616    be provided.  SET_SETTING_FUNC and GET_SETTING_FUNC are callbacks
617    used to access and modify the underlying property, whatever its
618    storage is.  SET_FUNC and SHOW_FUNC are the callback functions
619    (if non-NULL).  SET_DOC, SHOW_DOC and HELP_DOC are the
620    documentation strings.
621 
622    Return the newly created set and show commands.  */
623 
624 template<typename T>
625 static set_show_commands
add_setshow_cmd_full(const char * name,enum command_class theclass,var_types var_type,T * var,const literal_def * extra_literals,const char * set_doc,const char * show_doc,const char * help_doc,typename setting_func_types<T>::set set_setting_func,typename setting_func_types<T>::get get_setting_func,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)626 add_setshow_cmd_full (const char *name,
627                           enum command_class theclass,
628                           var_types var_type, T *var,
629                           const literal_def *extra_literals,
630                           const char *set_doc, const char *show_doc,
631                           const char *help_doc,
632                           typename setting_func_types<T>::set set_setting_func,
633                           typename setting_func_types<T>::get get_setting_func,
634                           cmd_func_ftype *set_func,
635                           show_value_ftype *show_func,
636                           struct cmd_list_element **set_list,
637                           struct cmd_list_element **show_list)
638 {
639   auto erased_args
640     = setting::erase_args (var_type, var,
641                                  set_setting_func, get_setting_func);
642   auto cmds = add_setshow_cmd_full_erased (name,
643                                                      theclass,
644                                                      var_type, extra_literals,
645                                                      erased_args,
646                                                      set_doc, show_doc,
647                                                      help_doc,
648                                                      set_func,
649                                                      show_func,
650                                                      set_list,
651                                                      show_list);
652 
653   if (extra_literals != nullptr)
654     set_cmd_completer (cmds.set, integer_literals_completer);
655 
656   return cmds;
657 }
658 
659 /* Same as above but omitting EXTRA_LITERALS.  */
660 
661 template<typename T>
662 static set_show_commands
add_setshow_cmd_full(const char * name,enum command_class theclass,var_types var_type,T * var,const char * set_doc,const char * show_doc,const char * help_doc,typename setting_func_types<T>::set set_setting_func,typename setting_func_types<T>::get get_setting_func,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)663 add_setshow_cmd_full (const char *name,
664                           enum command_class theclass,
665                           var_types var_type, T *var,
666                           const char *set_doc, const char *show_doc,
667                           const char *help_doc,
668                           typename setting_func_types<T>::set set_setting_func,
669                           typename setting_func_types<T>::get get_setting_func,
670                           cmd_func_ftype *set_func,
671                           show_value_ftype *show_func,
672                           struct cmd_list_element **set_list,
673                           struct cmd_list_element **show_list)
674 {
675   return add_setshow_cmd_full (name, theclass, var_type, var, nullptr,
676                                      set_doc, show_doc, help_doc,
677                                      set_setting_func, get_setting_func,
678                                      set_func, show_func, set_list, show_list);
679 }
680 
681 /* Add element named NAME to command list LIST (the list for set or
682    some sublist thereof).  THECLASS is as in add_cmd.  ENUMLIST is a list
683    of strings which may follow NAME.  VAR is address of the variable
684    which will contain the matching string (from ENUMLIST).  */
685 
686 set_show_commands
add_setshow_enum_cmd(const char * name,enum command_class theclass,const char * const * enumlist,const char ** var,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)687 add_setshow_enum_cmd (const char *name,
688                           enum command_class theclass,
689                           const char *const *enumlist,
690                           const char **var,
691                           const char *set_doc,
692                           const char *show_doc,
693                           const char *help_doc,
694                           cmd_func_ftype *set_func,
695                           show_value_ftype *show_func,
696                           struct cmd_list_element **set_list,
697                           struct cmd_list_element **show_list)
698 {
699   /* We require *VAR to be initialized before this call, and
700      furthermore it must be == to one of the values in ENUMLIST.  */
701   gdb_assert (var != nullptr && *var != nullptr);
702   for (int i = 0; ; ++i)
703     {
704       gdb_assert (enumlist[i] != nullptr);
705       if (*var == enumlist[i])
706           break;
707     }
708 
709   set_show_commands commands
710     =  add_setshow_cmd_full<const char *> (name, theclass, var_enum, var,
711                                                      set_doc, show_doc, help_doc,
712                                                      nullptr, nullptr, set_func,
713                                                      show_func, set_list, show_list);
714   commands.set->enums = enumlist;
715   return commands;
716 }
717 
718 /* Same as above but using a getter and a setter function instead of a pointer
719    to a global storage buffer.  */
720 
721 set_show_commands
add_setshow_enum_cmd(const char * name,command_class theclass,const char * const * enumlist,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<const char * >::set set_func,setting_func_types<const char * >::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)722 add_setshow_enum_cmd (const char *name, command_class theclass,
723                           const char *const *enumlist, const char *set_doc,
724                           const char *show_doc, const char *help_doc,
725                           setting_func_types<const char *>::set set_func,
726                           setting_func_types<const char *>::get get_func,
727                           show_value_ftype *show_func,
728                           cmd_list_element **set_list,
729                           cmd_list_element **show_list)
730 {
731   auto cmds = add_setshow_cmd_full<const char *> (name, theclass, var_enum,
732                                                               nullptr, set_doc, show_doc,
733                                                               help_doc, set_func, get_func,
734                                                               nullptr, show_func, set_list,
735                                                               show_list);
736 
737   cmds.set->enums = enumlist;
738 
739   return cmds;
740 }
741 
742 /* See cli-decode.h.  */
743 const char * const auto_boolean_enums[] = { "on", "off", "auto", NULL };
744 
745 /* Add an auto-boolean command named NAME to both the set and show
746    command list lists.  THECLASS is as in add_cmd.  VAR is address of the
747    variable which will contain the value.  DOC is the documentation
748    string.  FUNC is the corresponding callback.  */
749 
750 set_show_commands
add_setshow_auto_boolean_cmd(const char * name,enum command_class theclass,enum auto_boolean * var,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)751 add_setshow_auto_boolean_cmd (const char *name,
752                                     enum command_class theclass,
753                                     enum auto_boolean *var,
754                                     const char *set_doc, const char *show_doc,
755                                     const char *help_doc,
756                                     cmd_func_ftype *set_func,
757                                     show_value_ftype *show_func,
758                                     struct cmd_list_element **set_list,
759                                     struct cmd_list_element **show_list)
760 {
761   set_show_commands commands
762     = add_setshow_cmd_full<enum auto_boolean> (name, theclass, var_auto_boolean,
763                                                          var, set_doc, show_doc, help_doc,
764                                                          nullptr, nullptr, set_func,
765                                                          show_func, set_list, show_list);
766 
767   commands.set->enums = auto_boolean_enums;
768 
769   return commands;
770 }
771 
772 /* Same as above but using a getter and a setter function instead of a pointer
773    to a global storage buffer.  */
774 
775 set_show_commands
add_setshow_auto_boolean_cmd(const char * name,command_class theclass,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<enum auto_boolean>::set set_func,setting_func_types<enum auto_boolean>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)776 add_setshow_auto_boolean_cmd (const char *name, command_class theclass,
777                                     const char *set_doc, const char *show_doc,
778                                     const char *help_doc,
779                                     setting_func_types<enum auto_boolean>::set set_func,
780                                     setting_func_types<enum auto_boolean>::get get_func,
781                                     show_value_ftype *show_func,
782                                     cmd_list_element **set_list,
783                                     cmd_list_element **show_list)
784 {
785   auto cmds = add_setshow_cmd_full<enum auto_boolean> (name, theclass,
786                                                                    var_auto_boolean,
787                                                                    nullptr, set_doc,
788                                                                    show_doc, help_doc,
789                                                                    set_func, get_func,
790                                                                    nullptr, show_func,
791                                                                    set_list, show_list);
792 
793   cmds.set->enums = auto_boolean_enums;
794 
795   return cmds;
796 }
797 
798 /* See cli-decode.h.  */
799 const char * const boolean_enums[] = { "on", "off", NULL };
800 
801 /* Add element named NAME to both the set and show command LISTs (the
802    list for set/show or some sublist thereof).  THECLASS is as in
803    add_cmd.  VAR is address of the variable which will contain the
804    value.  SET_DOC and SHOW_DOC are the documentation strings.
805    Returns the new command element.  */
806 
807 set_show_commands
add_setshow_boolean_cmd(const char * name,enum command_class theclass,bool * var,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)808 add_setshow_boolean_cmd (const char *name, enum command_class theclass, bool *var,
809                                const char *set_doc, const char *show_doc,
810                                const char *help_doc,
811                                cmd_func_ftype *set_func,
812                                show_value_ftype *show_func,
813                                struct cmd_list_element **set_list,
814                                struct cmd_list_element **show_list)
815 {
816   set_show_commands commands
817     = add_setshow_cmd_full<bool> (name, theclass, var_boolean, var,
818                                           set_doc, show_doc, help_doc,
819                                           nullptr, nullptr, set_func, show_func,
820                                           set_list, show_list);
821 
822   commands.set->enums = boolean_enums;
823 
824   return commands;
825 }
826 
827 /* Same as above but using a getter and a setter function instead of a pointer
828    to a global storage buffer.  */
829 
830 set_show_commands
add_setshow_boolean_cmd(const char * name,command_class theclass,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<bool>::set set_func,setting_func_types<bool>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)831 add_setshow_boolean_cmd (const char *name, command_class theclass,
832                                const char *set_doc, const char *show_doc,
833                                const char *help_doc,
834                                setting_func_types<bool>::set set_func,
835                                setting_func_types<bool>::get get_func,
836                                show_value_ftype *show_func,
837                                cmd_list_element **set_list,
838                                cmd_list_element **show_list)
839 {
840   auto cmds = add_setshow_cmd_full<bool> (name, theclass, var_boolean, nullptr,
841                                                     set_doc, show_doc, help_doc,
842                                                     set_func, get_func, nullptr,
843                                                     show_func, set_list, show_list);
844 
845   cmds.set->enums = boolean_enums;
846 
847   return cmds;
848 }
849 
850 /* Add element named NAME to both the set and show command LISTs (the
851    list for set/show or some sublist thereof).  */
852 
853 set_show_commands
add_setshow_filename_cmd(const char * name,enum command_class theclass,std::string * var,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)854 add_setshow_filename_cmd (const char *name, enum command_class theclass,
855                                 std::string *var,
856                                 const char *set_doc, const char *show_doc,
857                                 const char *help_doc,
858                                 cmd_func_ftype *set_func,
859                                 show_value_ftype *show_func,
860                                 struct cmd_list_element **set_list,
861                                 struct cmd_list_element **show_list)
862 {
863   set_show_commands commands
864     = add_setshow_cmd_full<std::string> (name, theclass, var_filename, var,
865                                                    set_doc, show_doc, help_doc,
866                                                    nullptr, nullptr, set_func,
867                                                    show_func, set_list, show_list);
868 
869   set_cmd_completer (commands.set, filename_completer);
870 
871   return commands;
872 }
873 
874 /* Same as above but using a getter and a setter function instead of a pointer
875    to a global storage buffer.  */
876 
877 set_show_commands
add_setshow_filename_cmd(const char * name,command_class theclass,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<std::string>::set set_func,setting_func_types<std::string>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)878 add_setshow_filename_cmd (const char *name, command_class theclass,
879                                 const char *set_doc, const char *show_doc,
880                                 const char *help_doc,
881                                 setting_func_types<std::string>::set set_func,
882                                 setting_func_types<std::string>::get get_func,
883                                 show_value_ftype *show_func,
884                                 cmd_list_element **set_list,
885                                 cmd_list_element **show_list)
886 {
887   auto cmds = add_setshow_cmd_full<std::string> (name, theclass, var_filename,
888                                                              nullptr, set_doc, show_doc,
889                                                              help_doc, set_func, get_func,
890                                                              nullptr, show_func, set_list,
891                                                              show_list);
892 
893   set_cmd_completer (cmds.set, filename_completer);
894 
895   return cmds;
896 }
897 
898 /* Add element named NAME to both the set and show command LISTs (the
899    list for set/show or some sublist thereof).  */
900 
901 set_show_commands
add_setshow_string_cmd(const char * name,enum command_class theclass,std::string * var,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)902 add_setshow_string_cmd (const char *name, enum command_class theclass,
903                               std::string *var,
904                               const char *set_doc, const char *show_doc,
905                               const char *help_doc,
906                               cmd_func_ftype *set_func,
907                               show_value_ftype *show_func,
908                               struct cmd_list_element **set_list,
909                               struct cmd_list_element **show_list)
910 {
911   set_show_commands commands
912     = add_setshow_cmd_full<std::string> (name, theclass, var_string, var,
913                                                   set_doc, show_doc, help_doc,
914                                                   nullptr, nullptr, set_func,
915                                                   show_func, set_list, show_list);
916 
917   /* Disable the default symbol completer.  */
918   set_cmd_completer (commands.set, nullptr);
919 
920   return commands;
921 }
922 
923 /* Same as above but using a getter and a setter function instead of a pointer
924    to a global storage buffer.  */
925 
926 set_show_commands
add_setshow_string_cmd(const char * name,command_class theclass,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<std::string>::set set_func,setting_func_types<std::string>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)927 add_setshow_string_cmd (const char *name, command_class theclass,
928                               const char *set_doc, const char *show_doc,
929                               const char *help_doc,
930                               setting_func_types<std::string>::set set_func,
931                               setting_func_types<std::string>::get get_func,
932                               show_value_ftype *show_func,
933                               cmd_list_element **set_list,
934                               cmd_list_element **show_list)
935 {
936   auto cmds = add_setshow_cmd_full<std::string> (name, theclass, var_string,
937                                                              nullptr, set_doc, show_doc,
938                                                              help_doc, set_func, get_func,
939                                                              nullptr, show_func, set_list,
940                                                              show_list);
941 
942   /* Disable the default symbol completer.  */
943   set_cmd_completer (cmds.set, nullptr);
944 
945   return cmds;
946 }
947 
948 /* Add element named NAME to both the set and show command LISTs (the
949    list for set/show or some sublist thereof).  */
950 
951 set_show_commands
add_setshow_string_noescape_cmd(const char * name,enum command_class theclass,std::string * var,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)952 add_setshow_string_noescape_cmd (const char *name, enum command_class theclass,
953                                          std::string *var,
954                                          const char *set_doc, const char *show_doc,
955                                          const char *help_doc,
956                                          cmd_func_ftype *set_func,
957                                          show_value_ftype *show_func,
958                                          struct cmd_list_element **set_list,
959                                          struct cmd_list_element **show_list)
960 {
961   set_show_commands commands
962     = add_setshow_cmd_full<std::string> (name, theclass, var_string_noescape,
963                                                    var, set_doc, show_doc, help_doc,
964                                                    nullptr, nullptr, set_func, show_func,
965                                                    set_list, show_list);
966 
967   /* Disable the default symbol completer.  */
968   set_cmd_completer (commands.set, nullptr);
969 
970   return commands;
971 }
972 
973 /* Same as above but using a getter and a setter function instead of a pointer
974    to a global storage buffer.  */
975 
976 set_show_commands
add_setshow_string_noescape_cmd(const char * name,command_class theclass,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<std::string>::set set_func,setting_func_types<std::string>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)977 add_setshow_string_noescape_cmd (const char *name, command_class theclass,
978                                          const char *set_doc, const char *show_doc,
979                                          const char *help_doc,
980                                          setting_func_types<std::string>::set set_func,
981                                          setting_func_types<std::string>::get get_func,
982                                          show_value_ftype *show_func,
983                                          cmd_list_element **set_list,
984                                          cmd_list_element **show_list)
985 {
986   auto cmds = add_setshow_cmd_full<std::string> (name, theclass,
987                                                              var_string_noescape, nullptr,
988                                                              set_doc, show_doc, help_doc,
989                                                              set_func, get_func,
990                                                              nullptr, show_func, set_list,
991                                                              show_list);
992 
993   /* Disable the default symbol completer.  */
994   set_cmd_completer (cmds.set, nullptr);
995 
996   return cmds;
997 }
998 
999 /* Add element named NAME to both the set and show command LISTs (the
1000    list for set/show or some sublist thereof).  */
1001 
1002 set_show_commands
add_setshow_optional_filename_cmd(const char * name,enum command_class theclass,std::string * var,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)1003 add_setshow_optional_filename_cmd (const char *name, enum command_class theclass,
1004                                            std::string *var,
1005                                            const char *set_doc, const char *show_doc,
1006                                            const char *help_doc,
1007                                            cmd_func_ftype *set_func,
1008                                            show_value_ftype *show_func,
1009                                            struct cmd_list_element **set_list,
1010                                            struct cmd_list_element **show_list)
1011 {
1012   set_show_commands commands
1013     = add_setshow_cmd_full<std::string> (name, theclass, var_optional_filename,
1014                                                    var, set_doc, show_doc, help_doc,
1015                                                    nullptr, nullptr, set_func, show_func,
1016                                                    set_list, show_list);
1017 
1018   set_cmd_completer (commands.set, filename_completer);
1019 
1020   return commands;
1021 }
1022 
1023 /* Same as above but using a getter and a setter function instead of a pointer
1024    to a global storage buffer.  */
1025 
1026 set_show_commands
add_setshow_optional_filename_cmd(const char * name,command_class theclass,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<std::string>::set set_func,setting_func_types<std::string>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)1027 add_setshow_optional_filename_cmd (const char *name, command_class theclass,
1028                                            const char *set_doc, const char *show_doc,
1029                                            const char *help_doc,
1030                                            setting_func_types<std::string>::set set_func,
1031                                            setting_func_types<std::string>::get get_func,
1032                                            show_value_ftype *show_func,
1033                                            cmd_list_element **set_list,
1034                                            cmd_list_element **show_list)
1035 {
1036   auto cmds =
1037     add_setshow_cmd_full<std::string> (name, theclass, var_optional_filename,
1038                                                nullptr, set_doc, show_doc, help_doc,
1039                                                set_func, get_func, nullptr, show_func,
1040                                                set_list,show_list);
1041 
1042   set_cmd_completer (cmds.set, filename_completer);
1043 
1044   return cmds;
1045 }
1046 
1047 /* Add element named NAME to both the set and show command LISTs (the
1048    list for set/show or some sublist thereof).  THECLASS is as in
1049    add_cmd.  VAR is address of the variable which will contain the
1050    value.  SET_DOC and SHOW_DOC are the documentation strings.  This
1051    function is only used in Python API.  Please don't use it elsewhere.  */
1052 
1053 set_show_commands
add_setshow_integer_cmd(const char * name,enum command_class theclass,int * var,const literal_def * extra_literals,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)1054 add_setshow_integer_cmd (const char *name, enum command_class theclass,
1055                                int *var, const literal_def *extra_literals,
1056                                const char *set_doc, const char *show_doc,
1057                                const char *help_doc,
1058                                cmd_func_ftype *set_func,
1059                                show_value_ftype *show_func,
1060                                struct cmd_list_element **set_list,
1061                                struct cmd_list_element **show_list)
1062 {
1063   set_show_commands commands
1064     = add_setshow_cmd_full<int> (name, theclass, var_integer, var,
1065                                          extra_literals, set_doc, show_doc,
1066                                          help_doc, nullptr, nullptr, set_func,
1067                                          show_func, set_list, show_list);
1068   return commands;
1069 }
1070 
1071 /* Same as above but using a getter and a setter function instead of a pointer
1072    to a global storage buffer.  */
1073 
1074 set_show_commands
add_setshow_integer_cmd(const char * name,command_class theclass,const literal_def * extra_literals,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<int>::set set_func,setting_func_types<int>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)1075 add_setshow_integer_cmd (const char *name, command_class theclass,
1076                                const literal_def *extra_literals,
1077                                const char *set_doc, const char *show_doc,
1078                                const char *help_doc,
1079                                setting_func_types<int>::set set_func,
1080                                setting_func_types<int>::get get_func,
1081                                show_value_ftype *show_func,
1082                                cmd_list_element **set_list,
1083                                cmd_list_element **show_list)
1084 {
1085   auto cmds = add_setshow_cmd_full<int> (name, theclass, var_integer, nullptr,
1086                                                    extra_literals, set_doc, show_doc,
1087                                                    help_doc, set_func, get_func, nullptr,
1088                                                    show_func, set_list, show_list);
1089   return cmds;
1090 }
1091 
1092 /* Accept `unlimited' or 0, translated internally to INT_MAX.  */
1093 const literal_def integer_unlimited_literals[] =
1094   {
1095     { "unlimited", INT_MAX, 0 },
1096     { nullptr }
1097   };
1098 
1099 /* Same as above but using `integer_unlimited_literals', with a pointer
1100    to a global storage buffer.  */
1101 
1102 set_show_commands
add_setshow_integer_cmd(const char * name,enum command_class theclass,int * var,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)1103 add_setshow_integer_cmd (const char *name, enum command_class theclass,
1104                                int *var,
1105                                const char *set_doc, const char *show_doc,
1106                                const char *help_doc,
1107                                cmd_func_ftype *set_func,
1108                                show_value_ftype *show_func,
1109                                struct cmd_list_element **set_list,
1110                                struct cmd_list_element **show_list)
1111 {
1112   set_show_commands commands
1113     = add_setshow_cmd_full<int> (name, theclass, var_integer, var,
1114                                          integer_unlimited_literals,
1115                                          set_doc, show_doc, help_doc,
1116                                          nullptr, nullptr, set_func,
1117                                          show_func, set_list, show_list);
1118   return commands;
1119 }
1120 
1121 /* Same as above but using a getter and a setter function instead of a pointer
1122    to a global storage buffer.  */
1123 
1124 set_show_commands
add_setshow_integer_cmd(const char * name,command_class theclass,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<int>::set set_func,setting_func_types<int>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)1125 add_setshow_integer_cmd (const char *name, command_class theclass,
1126                                const char *set_doc, const char *show_doc,
1127                                const char *help_doc,
1128                                setting_func_types<int>::set set_func,
1129                                setting_func_types<int>::get get_func,
1130                                show_value_ftype *show_func,
1131                                cmd_list_element **set_list,
1132                                cmd_list_element **show_list)
1133 {
1134   auto cmds = add_setshow_cmd_full<int> (name, theclass, var_integer, nullptr,
1135                                                    integer_unlimited_literals,
1136                                                    set_doc, show_doc, help_doc, set_func,
1137                                                    get_func, nullptr, show_func, set_list,
1138                                                    show_list);
1139   return cmds;
1140 }
1141 
1142 /* Add element named NAME to both the set and show command LISTs (the
1143    list for set/show or some sublist thereof).  CLASS is as in
1144    add_cmd.  VAR is address of the variable which will contain the
1145    value.  SET_DOC and SHOW_DOC are the documentation strings.  */
1146 
1147 set_show_commands
add_setshow_pinteger_cmd(const char * name,enum command_class theclass,int * var,const literal_def * extra_literals,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)1148 add_setshow_pinteger_cmd (const char *name, enum command_class theclass,
1149                                 int *var, const literal_def *extra_literals,
1150                                 const char *set_doc, const char *show_doc,
1151                                 const char *help_doc,
1152                                 cmd_func_ftype *set_func,
1153                                 show_value_ftype *show_func,
1154                                 struct cmd_list_element **set_list,
1155                                 struct cmd_list_element **show_list)
1156 {
1157   set_show_commands commands
1158     = add_setshow_cmd_full<int> (name, theclass, var_pinteger, var,
1159                                          extra_literals, set_doc, show_doc,
1160                                          help_doc, nullptr, nullptr, set_func,
1161                                          show_func, set_list, show_list);
1162   return commands;
1163 }
1164 
1165 /* Same as above but using a getter and a setter function instead of a pointer
1166    to a global storage buffer.  */
1167 
1168 set_show_commands
add_setshow_pinteger_cmd(const char * name,command_class theclass,const literal_def * extra_literals,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<int>::set set_func,setting_func_types<int>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)1169 add_setshow_pinteger_cmd (const char *name, command_class theclass,
1170                                 const literal_def *extra_literals,
1171                                 const char *set_doc, const char *show_doc,
1172                                 const char *help_doc,
1173                                 setting_func_types<int>::set set_func,
1174                                 setting_func_types<int>::get get_func,
1175                                 show_value_ftype *show_func,
1176                                 cmd_list_element **set_list,
1177                                 cmd_list_element **show_list)
1178 {
1179   auto cmds = add_setshow_cmd_full<int> (name, theclass, var_pinteger, nullptr,
1180                                                    extra_literals, set_doc, show_doc,
1181                                                    help_doc, set_func, get_func, nullptr,
1182                                                    show_func, set_list, show_list);
1183   return cmds;
1184 }
1185 
1186 /* Add element named NAME to both the set and show command LISTs (the
1187    list for set/show or some sublist thereof).  THECLASS is as in
1188    add_cmd.  VAR is address of the variable which will contain the
1189    value.  SET_DOC and SHOW_DOC are the documentation strings.  */
1190 
1191 set_show_commands
add_setshow_uinteger_cmd(const char * name,enum command_class theclass,unsigned int * var,const literal_def * extra_literals,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)1192 add_setshow_uinteger_cmd (const char *name, enum command_class theclass,
1193                                 unsigned int *var, const literal_def *extra_literals,
1194                                 const char *set_doc, const char *show_doc,
1195                                 const char *help_doc,
1196                                 cmd_func_ftype *set_func,
1197                                 show_value_ftype *show_func,
1198                                 struct cmd_list_element **set_list,
1199                                 struct cmd_list_element **show_list)
1200 {
1201   set_show_commands commands
1202     = add_setshow_cmd_full<unsigned int> (name, theclass, var_uinteger, var,
1203                                                     extra_literals, set_doc, show_doc,
1204                                                     help_doc, nullptr, nullptr, set_func,
1205                                                     show_func, set_list, show_list);
1206   return commands;
1207 }
1208 
1209 /* Same as above but using a getter and a setter function instead of a pointer
1210    to a global storage buffer.  */
1211 
1212 set_show_commands
add_setshow_uinteger_cmd(const char * name,command_class theclass,const literal_def * extra_literals,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<unsigned int>::set set_func,setting_func_types<unsigned int>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)1213 add_setshow_uinteger_cmd (const char *name, command_class theclass,
1214                                 const literal_def *extra_literals,
1215                                 const char *set_doc, const char *show_doc,
1216                                 const char *help_doc,
1217                                 setting_func_types<unsigned int>::set set_func,
1218                                 setting_func_types<unsigned int>::get get_func,
1219                                 show_value_ftype *show_func,
1220                                 cmd_list_element **set_list,
1221                                 cmd_list_element **show_list)
1222 {
1223   auto cmds = add_setshow_cmd_full<unsigned int> (name, theclass, var_uinteger,
1224                                                               nullptr, extra_literals,
1225                                                               set_doc, show_doc, help_doc,
1226                                                               set_func, get_func, nullptr,
1227                                                               show_func, set_list,
1228                                                               show_list);
1229   return cmds;
1230 }
1231 
1232 /* Accept `unlimited' or 0, translated internally to UINT_MAX.  */
1233 const literal_def uinteger_unlimited_literals[] =
1234   {
1235     { "unlimited", UINT_MAX, 0 },
1236     { nullptr }
1237   };
1238 
1239 /* Same as above but using `uinteger_unlimited_literals', with a pointer
1240    to a global storage buffer.  */
1241 
1242 set_show_commands
add_setshow_uinteger_cmd(const char * name,enum command_class theclass,unsigned int * var,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)1243 add_setshow_uinteger_cmd (const char *name, enum command_class theclass,
1244                                 unsigned int *var,
1245                                 const char *set_doc, const char *show_doc,
1246                                 const char *help_doc,
1247                                 cmd_func_ftype *set_func,
1248                                 show_value_ftype *show_func,
1249                                 struct cmd_list_element **set_list,
1250                                 struct cmd_list_element **show_list)
1251 {
1252   set_show_commands commands
1253     = add_setshow_cmd_full<unsigned int> (name, theclass, var_uinteger, var,
1254                                                     uinteger_unlimited_literals,
1255                                                     set_doc, show_doc, help_doc, nullptr,
1256                                                     nullptr, set_func, show_func,
1257                                                     set_list, show_list);
1258   return commands;
1259 }
1260 
1261 /* Same as above but using a getter and a setter function instead of a pointer
1262    to a global storage buffer.  */
1263 
1264 set_show_commands
add_setshow_uinteger_cmd(const char * name,command_class theclass,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<unsigned int>::set set_func,setting_func_types<unsigned int>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)1265 add_setshow_uinteger_cmd (const char *name, command_class theclass,
1266                                 const char *set_doc, const char *show_doc,
1267                                 const char *help_doc,
1268                                 setting_func_types<unsigned int>::set set_func,
1269                                 setting_func_types<unsigned int>::get get_func,
1270                                 show_value_ftype *show_func,
1271                                 cmd_list_element **set_list,
1272                                 cmd_list_element **show_list)
1273 {
1274   auto cmds = add_setshow_cmd_full<unsigned int> (name, theclass, var_uinteger,
1275                                                               nullptr,
1276                                                               uinteger_unlimited_literals,
1277                                                               set_doc, show_doc, help_doc,
1278                                                               set_func, get_func, nullptr,
1279                                                               show_func, set_list,
1280                                                               show_list);
1281   return cmds;
1282 }
1283 
1284 /* Add element named NAME to both the set and show command LISTs (the
1285    list for set/show or some sublist thereof).  THECLASS is as in
1286    add_cmd.  VAR is address of the variable which will contain the
1287    value.  SET_DOC and SHOW_DOC are the documentation strings.  */
1288 
1289 set_show_commands
add_setshow_zinteger_cmd(const char * name,enum command_class theclass,int * var,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)1290 add_setshow_zinteger_cmd (const char *name, enum command_class theclass,
1291                                 int *var,
1292                                 const char *set_doc, const char *show_doc,
1293                                 const char *help_doc,
1294                                 cmd_func_ftype *set_func,
1295                                 show_value_ftype *show_func,
1296                                 struct cmd_list_element **set_list,
1297                                 struct cmd_list_element **show_list)
1298 {
1299   return add_setshow_cmd_full<int> (name, theclass, var_integer, var,
1300                                             set_doc, show_doc, help_doc,
1301                                             nullptr, nullptr, set_func,
1302                                             show_func, set_list, show_list);
1303 }
1304 
1305 /* Same as above but using a getter and a setter function instead of a pointer
1306    to a global storage buffer.  */
1307 
1308 set_show_commands
add_setshow_zinteger_cmd(const char * name,command_class theclass,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<int>::set set_func,setting_func_types<int>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)1309 add_setshow_zinteger_cmd (const char *name, command_class theclass,
1310                                 const char *set_doc, const char *show_doc,
1311                                 const char *help_doc,
1312                                 setting_func_types<int>::set set_func,
1313                                 setting_func_types<int>::get get_func,
1314                                 show_value_ftype *show_func,
1315                                 cmd_list_element **set_list,
1316                                 cmd_list_element **show_list)
1317 {
1318   return add_setshow_cmd_full<int> (name, theclass, var_integer, nullptr,
1319                                             set_doc, show_doc, help_doc, set_func,
1320                                             get_func, nullptr, show_func, set_list,
1321                                             show_list);
1322 }
1323 
1324 /* Accept `unlimited' or -1, using -1 internally.  */
1325 const literal_def pinteger_unlimited_literals[] =
1326   {
1327     { "unlimited", -1, -1 },
1328     { nullptr }
1329   };
1330 
1331 /* Same as above but using `pinteger_unlimited_literals', with a pointer
1332    to a global storage buffer.  */
1333 
1334 set_show_commands
add_setshow_zuinteger_unlimited_cmd(const char * name,enum command_class theclass,int * var,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)1335 add_setshow_zuinteger_unlimited_cmd (const char *name,
1336                                              enum command_class theclass,
1337                                              int *var,
1338                                              const char *set_doc,
1339                                              const char *show_doc,
1340                                              const char *help_doc,
1341                                              cmd_func_ftype *set_func,
1342                                              show_value_ftype *show_func,
1343                                              struct cmd_list_element **set_list,
1344                                              struct cmd_list_element **show_list)
1345 {
1346   set_show_commands commands
1347     = add_setshow_cmd_full<int> (name, theclass, var_pinteger, var,
1348                                          pinteger_unlimited_literals,
1349                                          set_doc, show_doc, help_doc, nullptr,
1350                                          nullptr, set_func, show_func, set_list,
1351                                          show_list);
1352   return commands;
1353 }
1354 
1355 /* Same as above but using a getter and a setter function instead of a pointer
1356    to a global storage buffer.  */
1357 
1358 set_show_commands
add_setshow_zuinteger_unlimited_cmd(const char * name,command_class theclass,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<int>::set set_func,setting_func_types<int>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)1359 add_setshow_zuinteger_unlimited_cmd (const char *name, command_class theclass,
1360                                              const char *set_doc, const char *show_doc,
1361                                              const char *help_doc,
1362                                              setting_func_types<int>::set set_func,
1363                                              setting_func_types<int>::get get_func,
1364                                              show_value_ftype *show_func,
1365                                              cmd_list_element **set_list,
1366                                              cmd_list_element **show_list)
1367 {
1368   auto cmds
1369     = add_setshow_cmd_full<int> (name, theclass, var_pinteger, nullptr,
1370                                          pinteger_unlimited_literals,
1371                                          set_doc, show_doc, help_doc, set_func,
1372                                          get_func, nullptr, show_func, set_list,
1373                                          show_list);
1374   return cmds;
1375 }
1376 
1377 /* Add element named NAME to both the set and show command LISTs (the
1378    list for set/show or some sublist thereof).  THECLASS is as in
1379    add_cmd.  VAR is address of the variable which will contain the
1380    value.  SET_DOC and SHOW_DOC are the documentation strings.  */
1381 
1382 set_show_commands
add_setshow_zuinteger_cmd(const char * name,enum command_class theclass,unsigned int * var,const char * set_doc,const char * show_doc,const char * help_doc,cmd_func_ftype * set_func,show_value_ftype * show_func,struct cmd_list_element ** set_list,struct cmd_list_element ** show_list)1383 add_setshow_zuinteger_cmd (const char *name, enum command_class theclass,
1384                                  unsigned int *var,
1385                                  const char *set_doc, const char *show_doc,
1386                                  const char *help_doc,
1387                                  cmd_func_ftype *set_func,
1388                                  show_value_ftype *show_func,
1389                                  struct cmd_list_element **set_list,
1390                                  struct cmd_list_element **show_list)
1391 {
1392   return add_setshow_cmd_full<unsigned int> (name, theclass, var_uinteger,
1393                                                        var, set_doc, show_doc, help_doc,
1394                                                        nullptr, nullptr, set_func,
1395                                                        show_func, set_list, show_list);
1396 }
1397 
1398 /* Same as above but using a getter and a setter function instead of a pointer
1399    to a global storage buffer.  */
1400 
1401 set_show_commands
add_setshow_zuinteger_cmd(const char * name,command_class theclass,const char * set_doc,const char * show_doc,const char * help_doc,setting_func_types<unsigned int>::set set_func,setting_func_types<unsigned int>::get get_func,show_value_ftype * show_func,cmd_list_element ** set_list,cmd_list_element ** show_list)1402 add_setshow_zuinteger_cmd (const char *name, command_class theclass,
1403                                  const char *set_doc, const char *show_doc,
1404                                  const char *help_doc,
1405                                  setting_func_types<unsigned int>::set set_func,
1406                                  setting_func_types<unsigned int>::get get_func,
1407                                  show_value_ftype *show_func,
1408                                  cmd_list_element **set_list,
1409                                  cmd_list_element **show_list)
1410 {
1411   return add_setshow_cmd_full<unsigned int> (name, theclass, var_uinteger,
1412                                                        nullptr, set_doc, show_doc,
1413                                                        help_doc, set_func, get_func,
1414                                                        nullptr, show_func, set_list,
1415                                                        show_list);
1416 }
1417 
1418 /* Remove the command named NAME from the command list.  Return the list
1419    commands which were aliased to the deleted command.  The various *HOOKs are
1420    set to the pre- and post-hook commands for the deleted command.  If the
1421    command does not have a hook, the corresponding out parameter is set to
1422    NULL.  */
1423 
1424 static cmd_list_element::aliases_list_type
delete_cmd(const char * name,struct cmd_list_element ** list,struct cmd_list_element ** prehook,struct cmd_list_element ** prehookee,struct cmd_list_element ** posthook,struct cmd_list_element ** posthookee)1425 delete_cmd (const char *name, struct cmd_list_element **list,
1426               struct cmd_list_element **prehook,
1427               struct cmd_list_element **prehookee,
1428               struct cmd_list_element **posthook,
1429               struct cmd_list_element **posthookee)
1430 {
1431   struct cmd_list_element *iter;
1432   struct cmd_list_element **previous_chain_ptr;
1433   cmd_list_element::aliases_list_type aliases;
1434 
1435   *prehook = NULL;
1436   *prehookee = NULL;
1437   *posthook = NULL;
1438   *posthookee = NULL;
1439   previous_chain_ptr = list;
1440 
1441   for (iter = *previous_chain_ptr; iter; iter = *previous_chain_ptr)
1442     {
1443       if (strcmp (iter->name, name) == 0)
1444           {
1445             if (iter->destroyer)
1446               iter->destroyer (iter, iter->context ());
1447 
1448             if (iter->hookee_pre)
1449               iter->hookee_pre->hook_pre = 0;
1450             *prehook = iter->hook_pre;
1451             *prehookee = iter->hookee_pre;
1452             if (iter->hookee_post)
1453               iter->hookee_post->hook_post = 0;
1454             *posthook = iter->hook_post;
1455             *posthookee = iter->hookee_post;
1456 
1457             /* Update the link.  */
1458             *previous_chain_ptr = iter->next;
1459 
1460             aliases = std::move (iter->aliases);
1461 
1462             /* If this command was an alias, remove it from the list of
1463                aliases.  */
1464             if (iter->is_alias ())
1465               {
1466                 auto it = iter->alias_target->aliases.iterator_to (*iter);
1467                 iter->alias_target->aliases.erase (it);
1468               }
1469 
1470             delete iter;
1471 
1472             /* We won't see another command with the same name.  */
1473             break;
1474           }
1475       else
1476           previous_chain_ptr = &iter->next;
1477     }
1478 
1479   return aliases;
1480 }
1481 
1482 /* Shorthands to the commands above.  */
1483 
1484 /* Add an element to the list of info subcommands.  */
1485 
1486 struct cmd_list_element *
add_info(const char * name,cmd_simple_func_ftype * fun,const char * doc)1487 add_info (const char *name, cmd_simple_func_ftype *fun, const char *doc)
1488 {
1489   return add_cmd (name, class_info, fun, doc, &infolist);
1490 }
1491 
1492 /* Add an alias to the list of info subcommands.  */
1493 
1494 cmd_list_element *
add_info_alias(const char * name,cmd_list_element * target,int abbrev_flag)1495 add_info_alias (const char *name, cmd_list_element *target, int abbrev_flag)
1496 {
1497   return add_alias_cmd (name, target, class_run, abbrev_flag, &infolist);
1498 }
1499 
1500 /* Add an element to the list of commands.  */
1501 
1502 struct cmd_list_element *
add_com(const char * name,enum command_class theclass,cmd_simple_func_ftype * fun,const char * doc)1503 add_com (const char *name, enum command_class theclass,
1504            cmd_simple_func_ftype *fun,
1505            const char *doc)
1506 {
1507   return add_cmd (name, theclass, fun, doc, &cmdlist);
1508 }
1509 
1510 /* Add an alias or abbreviation command to the list of commands.
1511    For aliases predefined by GDB (such as bt), THECLASS must be
1512    different of class_alias, as class_alias is used to identify
1513    user defined aliases.  */
1514 
1515 cmd_list_element *
add_com_alias(const char * name,cmd_list_element * target,command_class theclass,int abbrev_flag)1516 add_com_alias (const char *name, cmd_list_element *target,
1517                  command_class theclass, int abbrev_flag)
1518 {
1519   return add_alias_cmd (name, target, theclass, abbrev_flag, &cmdlist);
1520 }
1521 
1522 /* Add an element with a suppress notification to the list of commands.  */
1523 
1524 struct cmd_list_element *
add_com_suppress_notification(const char * name,enum command_class theclass,cmd_simple_func_ftype * fun,const char * doc,bool * suppress_notification)1525 add_com_suppress_notification (const char *name, enum command_class theclass,
1526                                      cmd_simple_func_ftype *fun, const char *doc,
1527                                      bool *suppress_notification)
1528 {
1529   return add_cmd_suppress_notification (name, theclass, fun, doc,
1530                                                   &cmdlist, suppress_notification);
1531 }
1532 
1533 /* Print the prefix of C followed by name of C in title style.  */
1534 
1535 static void
fput_command_name_styled(const cmd_list_element & c,struct ui_file * stream)1536 fput_command_name_styled (const cmd_list_element &c, struct ui_file *stream)
1537 {
1538   std::string prefixname
1539     = c.prefix == nullptr ? "" : c.prefix->prefixname ();
1540 
1541   fprintf_styled (stream, title_style.style (), "%s%s",
1542                       prefixname.c_str (), c.name);
1543 }
1544 
1545 /* True if ALIAS has a user-defined documentation.  */
1546 
1547 static bool
user_documented_alias(const cmd_list_element & alias)1548 user_documented_alias (const cmd_list_element &alias)
1549 {
1550   gdb_assert (alias.is_alias ());
1551   /* Alias is user documented if it has an allocated documentation
1552      that differs from the aliased command.  */
1553   return (alias.doc_allocated
1554             && strcmp (alias.doc, alias.alias_target->doc) != 0);
1555 }
1556 
1557 /* Print the definition of alias C using title style for alias
1558    and aliased command.  */
1559 
1560 static void
fput_alias_definition_styled(const cmd_list_element & c,struct ui_file * stream)1561 fput_alias_definition_styled (const cmd_list_element &c,
1562                                     struct ui_file *stream)
1563 {
1564   gdb_assert (c.is_alias ());
1565   gdb_puts ("  alias ", stream);
1566   fput_command_name_styled (c, stream);
1567   gdb_printf (stream, " = ");
1568   fput_command_name_styled (*c.alias_target, stream);
1569   gdb_printf (stream, " %s\n", c.default_args.c_str ());
1570 }
1571 
1572 /* Print the definition of CMD aliases not deprecated and having default args
1573    and not specifically documented by the user.  */
1574 
1575 static void
fput_aliases_definition_styled(const cmd_list_element & cmd,struct ui_file * stream)1576 fput_aliases_definition_styled (const cmd_list_element &cmd,
1577                                         struct ui_file *stream)
1578 {
1579   for (const cmd_list_element &alias : cmd.aliases)
1580     if (!alias.cmd_deprecated
1581           && !user_documented_alias (alias)
1582           && !alias.default_args.empty ())
1583       fput_alias_definition_styled (alias, stream);
1584 }
1585 
1586 /* If C has one or more aliases, style print the name of C and the name of its
1587    aliases not documented specifically by the user, separated by commas.
1588    If ALWAYS_FPUT_C_NAME, print the name of C even if it has no aliases.
1589    If one or more names are printed, POSTFIX is printed after the last name.
1590 */
1591 
1592 static void
fput_command_names_styled(const cmd_list_element & c,bool always_fput_c_name,const char * postfix,struct ui_file * stream)1593 fput_command_names_styled (const cmd_list_element &c,
1594                                  bool always_fput_c_name, const char *postfix,
1595                                  struct ui_file *stream)
1596 {
1597   /* First, check if we are going to print something.  That is, either if
1598      ALWAYS_FPUT_C_NAME is true or if there exists at least one non-deprecated
1599      alias not documented specifically by the user.  */
1600 
1601   auto print_alias = [] (const cmd_list_element &alias)
1602     {
1603       return !alias.cmd_deprecated && !user_documented_alias (alias);
1604     };
1605 
1606   bool print_something = always_fput_c_name;
1607   if (!print_something)
1608     for (const cmd_list_element &alias : c.aliases)
1609       {
1610           if (!print_alias (alias))
1611             continue;
1612 
1613           print_something = true;
1614           break;
1615       }
1616 
1617   if (print_something)
1618     fput_command_name_styled (c, stream);
1619 
1620   for (const cmd_list_element &alias : c.aliases)
1621     {
1622       if (!print_alias (alias))
1623           continue;
1624 
1625       gdb_puts (", ", stream);
1626       stream->wrap_here (3);
1627       fput_command_name_styled (alias, stream);
1628     }
1629 
1630   if (print_something)
1631     gdb_puts (postfix, stream);
1632 }
1633 
1634 /* If VERBOSE, print the full help for command C and highlight the
1635    documentation parts matching HIGHLIGHT,
1636    otherwise print only one-line help for command C.  */
1637 
1638 static void
print_doc_of_command(const cmd_list_element & c,bool verbose,compiled_regex & highlight,struct ui_file * stream)1639 print_doc_of_command (const cmd_list_element &c, bool verbose,
1640                           compiled_regex &highlight, struct ui_file *stream)
1641 {
1642   /* When printing the full documentation, add a line to separate
1643      this documentation from the previous command help, in the likely
1644      case that apropos finds several commands.  */
1645   if (verbose)
1646     gdb_puts ("\n", stream);
1647 
1648   fput_command_names_styled (c, true,
1649                                    verbose ? "" : " -- ", stream);
1650   if (verbose)
1651     {
1652       gdb_puts ("\n", stream);
1653       fput_aliases_definition_styled (c, stream);
1654       fputs_highlighted (c.doc, highlight, stream);
1655       gdb_puts ("\n", stream);
1656     }
1657   else
1658     {
1659       print_doc_line (stream, c.doc, false);
1660       gdb_puts ("\n", stream);
1661       fput_aliases_definition_styled (c, stream);
1662     }
1663 }
1664 
1665 /* Recursively walk the commandlist structures, and print out the
1666    documentation of commands that match our regex in either their
1667    name, or their documentation.
1668    If VERBOSE, prints the complete documentation and highlight the
1669    documentation parts matching REGEX, otherwise prints only
1670    the first line.
1671 */
1672 void
apropos_cmd(struct ui_file * stream,struct cmd_list_element * commandlist,bool verbose,compiled_regex & regex)1673 apropos_cmd (struct ui_file *stream,
1674                struct cmd_list_element *commandlist,
1675                bool verbose, compiled_regex &regex)
1676 {
1677   struct cmd_list_element *c;
1678   int returnvalue;
1679 
1680   /* Walk through the commands.  */
1681   for (c=commandlist;c;c=c->next)
1682     {
1683       if (c->is_alias () && !user_documented_alias (*c))
1684           {
1685             /* Command aliases/abbreviations not specifically documented by the
1686                user are skipped to ensure we print the doc of a command only once,
1687                when encountering the aliased command.  */
1688             continue;
1689           }
1690 
1691       returnvalue = -1; /* Needed to avoid double printing.  */
1692       if (c->name != NULL)
1693           {
1694             size_t name_len = strlen (c->name);
1695 
1696             /* Try to match against the name.  */
1697             returnvalue = regex.search (c->name, name_len, 0, name_len, NULL);
1698             if (returnvalue >= 0)
1699               print_doc_of_command (*c, verbose, regex, stream);
1700 
1701             /* Try to match against the name of the aliases.  */
1702             for (const cmd_list_element &alias : c->aliases)
1703               {
1704                 name_len = strlen (alias.name);
1705                 returnvalue = regex.search (alias.name, name_len, 0, name_len, NULL);
1706                 if (returnvalue >= 0)
1707                     {
1708                       print_doc_of_command (*c, verbose, regex, stream);
1709                       break;
1710                     }
1711               }
1712           }
1713       if (c->doc != NULL && returnvalue < 0)
1714           {
1715             size_t doc_len = strlen (c->doc);
1716 
1717             /* Try to match against documentation.  */
1718             if (regex.search (c->doc, doc_len, 0, doc_len, NULL) >= 0)
1719               print_doc_of_command (*c, verbose, regex, stream);
1720           }
1721       /* Check if this command has subcommands.  */
1722       if (c->is_prefix ())
1723           {
1724             /* Recursively call ourselves on the subcommand list,
1725                passing the right prefix in.  */
1726             apropos_cmd (stream, *c->subcommands, verbose, regex);
1727           }
1728     }
1729 }
1730 
1731 /* This command really has to deal with two things:
1732    1) I want documentation on *this string* (usually called by
1733       "help commandname").
1734 
1735    2) I want documentation on *this list* (usually called by giving a
1736       command that requires subcommands.  Also called by saying just
1737       "help".)
1738 
1739    I am going to split this into two separate commands, help_cmd and
1740    help_list.  */
1741 
1742 void
help_cmd(const char * command,struct ui_file * stream)1743 help_cmd (const char *command, struct ui_file *stream)
1744 {
1745   struct cmd_list_element *c, *alias, *prefix_cmd, *c_cmd;
1746 
1747   if (!command)
1748     {
1749       help_list (cmdlist, "", all_classes, stream);
1750       return;
1751     }
1752 
1753   if (strcmp (command, "all") == 0)
1754     {
1755       help_all (stream);
1756       return;
1757     }
1758 
1759   const char *orig_command = command;
1760   c = lookup_cmd (&command, cmdlist, "", NULL, 0, 0);
1761 
1762   if (c == 0)
1763     return;
1764 
1765   lookup_cmd_composition (orig_command, &alias, &prefix_cmd, &c_cmd);
1766 
1767   /* There are three cases here.
1768      If c->subcommands is nonzero, we have a prefix command.
1769      Print its documentation, then list its subcommands.
1770 
1771      If c->func is non NULL, we really have a command.  Print its
1772      documentation and return.
1773 
1774      If c->func is NULL, we have a class name.  Print its
1775      documentation (as if it were a command) and then set class to the
1776      number of this class so that the commands in the class will be
1777      listed.  */
1778 
1779   if (alias == nullptr || !user_documented_alias (*alias))
1780     {
1781       /* Case of a normal command, or an alias not explicitly
1782            documented by the user.  */
1783       /* If the user asked 'help somecommand' and there is no alias,
1784            the false indicates to not output the (single) command name.  */
1785       fput_command_names_styled (*c, false, "\n", stream);
1786       fput_aliases_definition_styled (*c, stream);
1787       gdb_puts (c->doc, stream);
1788     }
1789   else
1790     {
1791       /* Case of an alias explicitly documented by the user.
1792            Only output the alias definition and its explicit documentation.  */
1793       fput_alias_definition_styled (*alias, stream);
1794       fput_command_names_styled (*alias, false, "\n", stream);
1795       gdb_puts (alias->doc, stream);
1796     }
1797   gdb_puts ("\n", stream);
1798 
1799   if (!c->is_prefix () && !c->is_command_class_help ())
1800     return;
1801 
1802   gdb_printf (stream, "\n");
1803 
1804   /* If this is a prefix command, print it's subcommands.  */
1805   if (c->is_prefix ())
1806     help_list (*c->subcommands, c->prefixname ().c_str (),
1807                  all_commands, stream);
1808 
1809   /* If this is a class name, print all of the commands in the class.  */
1810   if (c->is_command_class_help ())
1811     help_list (cmdlist, "", c->theclass, stream);
1812 
1813   if (c->hook_pre || c->hook_post)
1814     gdb_printf (stream,
1815                     "\nThis command has a hook (or hooks) defined:\n");
1816 
1817   if (c->hook_pre)
1818     gdb_printf (stream,
1819                     "\tThis command is run after  : %s (pre hook)\n",
1820                     c->hook_pre->name);
1821   if (c->hook_post)
1822     gdb_printf (stream,
1823                     "\tThis command is run before : %s (post hook)\n",
1824                     c->hook_post->name);
1825 }
1826 
1827 /*
1828  * Get a specific kind of help on a command list.
1829  *
1830  * LIST is the list.
1831  * CMDTYPE is the prefix to use in the title string.
1832  * THECLASS is the class with which to list the nodes of this list (see
1833  * documentation for help_cmd_list below),  As usual, ALL_COMMANDS for
1834  * everything, ALL_CLASSES for just classes, and non-negative for only things
1835  * in a specific class.
1836  * and STREAM is the output stream on which to print things.
1837  * If you call this routine with a class >= 0, it recurses.
1838  */
1839 void
help_list(struct cmd_list_element * list,const char * cmdtype,enum command_class theclass,struct ui_file * stream)1840 help_list (struct cmd_list_element *list, const char *cmdtype,
1841              enum command_class theclass, struct ui_file *stream)
1842 {
1843   int len;
1844   char *cmdtype1, *cmdtype2;
1845 
1846   /* If CMDTYPE is "foo ", CMDTYPE1 gets " foo" and CMDTYPE2 gets "foo sub".
1847    */
1848   len = strlen (cmdtype);
1849   cmdtype1 = (char *) alloca (len + 1);
1850   cmdtype1[0] = 0;
1851   cmdtype2 = (char *) alloca (len + 4);
1852   cmdtype2[0] = 0;
1853   if (len)
1854     {
1855       cmdtype1[0] = ' ';
1856       memcpy (cmdtype1 + 1, cmdtype, len - 1);
1857       cmdtype1[len] = 0;
1858       memcpy (cmdtype2, cmdtype, len - 1);
1859       strcpy (cmdtype2 + len - 1, " sub");
1860     }
1861 
1862   if (theclass == all_classes)
1863     gdb_printf (stream, "List of classes of %scommands:\n\n", cmdtype2);
1864   else
1865     gdb_printf (stream, "List of %scommands:\n\n", cmdtype2);
1866 
1867   help_cmd_list (list, theclass, theclass >= 0, stream);
1868 
1869   if (theclass == all_classes)
1870     {
1871       gdb_printf (stream, "\n\
1872 Type \"help%s\" followed by a class name for a list of commands in ",
1873                       cmdtype1);
1874       stream->wrap_here (0);
1875       gdb_printf (stream, "that class.");
1876 
1877       gdb_printf (stream, "\n\
1878 Type \"help all\" for the list of all commands.");
1879     }
1880 
1881   gdb_printf (stream, "\nType \"help%s\" followed by %scommand name ",
1882                 cmdtype1, cmdtype2);
1883   stream->wrap_here (0);
1884   gdb_puts ("for ", stream);
1885   stream->wrap_here (0);
1886   gdb_puts ("full ", stream);
1887   stream->wrap_here (0);
1888   gdb_puts ("documentation.\n", stream);
1889   gdb_puts ("Type \"apropos word\" to search "
1890               "for commands related to \"word\".\n", stream);
1891   gdb_puts ("Type \"apropos -v word\" for full documentation", stream);
1892   stream->wrap_here (0);
1893   gdb_puts (" of commands related to \"word\".\n", stream);
1894   gdb_puts ("Command name abbreviations are allowed if unambiguous.\n",
1895               stream);
1896 }
1897 
1898 static void
help_all(struct ui_file * stream)1899 help_all (struct ui_file *stream)
1900 {
1901   struct cmd_list_element *c;
1902   int seen_unclassified = 0;
1903 
1904   for (c = cmdlist; c; c = c->next)
1905     {
1906       if (c->abbrev_flag)
1907           continue;
1908       /* If this is a class name, print all of the commands in the
1909            class.  */
1910 
1911       if (c->is_command_class_help ())
1912           {
1913             gdb_printf (stream, "\nCommand class: %s\n\n", c->name);
1914             help_cmd_list (cmdlist, c->theclass, true, stream);
1915           }
1916     }
1917 
1918   /* While it's expected that all commands are in some class,
1919      as a safety measure, we'll print commands outside of any
1920      class at the end.  */
1921 
1922   for (c = cmdlist; c; c = c->next)
1923     {
1924       if (c->abbrev_flag)
1925           continue;
1926 
1927       if (c->theclass == no_class)
1928           {
1929             if (!seen_unclassified)
1930               {
1931                 gdb_printf (stream, "\nUnclassified commands\n\n");
1932                 seen_unclassified = 1;
1933               }
1934             print_help_for_command (*c, true, stream);
1935           }
1936     }
1937 
1938 }
1939 
1940 /* See cli-decode.h.  */
1941 
1942 void
print_doc_line(struct ui_file * stream,const char * str,bool for_value_prefix)1943 print_doc_line (struct ui_file *stream, const char *str,
1944                     bool for_value_prefix)
1945 {
1946   static char *line_buffer = 0;
1947   static int line_size;
1948   const char *p;
1949 
1950   if (!line_buffer)
1951     {
1952       line_size = 80;
1953       line_buffer = (char *) xmalloc (line_size);
1954     }
1955 
1956   /* Searches for the first end of line or the end of STR.  */
1957   p = str;
1958   while (*p && *p != '\n')
1959     p++;
1960   if (p - str > line_size - 1)
1961     {
1962       line_size = p - str + 1;
1963       xfree (line_buffer);
1964       line_buffer = (char *) xmalloc (line_size);
1965     }
1966   strncpy (line_buffer, str, p - str);
1967   if (for_value_prefix)
1968     {
1969       if (islower (line_buffer[0]))
1970           line_buffer[0] = toupper (line_buffer[0]);
1971       gdb_assert (p > str);
1972       if (line_buffer[p - str - 1] == '.')
1973           line_buffer[p - str - 1] = '\0';
1974       else
1975           line_buffer[p - str] = '\0';
1976     }
1977   else
1978     line_buffer[p - str] = '\0';
1979   gdb_puts (line_buffer, stream);
1980 }
1981 
1982 /* Print one-line help for command C.
1983    If RECURSE is non-zero, also print one-line descriptions
1984    of all prefixed subcommands.  */
1985 static void
print_help_for_command(const cmd_list_element & c,bool recurse,struct ui_file * stream)1986 print_help_for_command (const cmd_list_element &c,
1987                               bool recurse, struct ui_file *stream)
1988 {
1989   fput_command_names_styled (c, true, " -- ", stream);
1990   print_doc_line (stream, c.doc, false);
1991   gdb_puts ("\n", stream);
1992   if (!c.default_args.empty ())
1993     fput_alias_definition_styled (c, stream);
1994   fput_aliases_definition_styled (c, stream);
1995 
1996   if (recurse
1997       && c.is_prefix ()
1998       && c.abbrev_flag == 0)
1999     /* Subcommands of a prefix command typically have 'all_commands'
2000        as class.  If we pass CLASS to recursive invocation,
2001        most often we won't see anything.  */
2002     help_cmd_list (*c.subcommands, all_commands, true, stream);
2003 }
2004 
2005 /*
2006  * Implement a help command on command list LIST.
2007  * RECURSE should be non-zero if this should be done recursively on
2008  * all sublists of LIST.
2009  * STREAM is the stream upon which the output should be written.
2010  * THECLASS should be:
2011  *      A non-negative class number to list only commands in that
2012  *      ALL_COMMANDS to list all commands in list.
2013  *      ALL_CLASSES  to list all classes in list.
2014  *
2015  *   Note that aliases are only shown when THECLASS is class_alias.
2016  *   In the other cases, the aliases will be shown together with their
2017  *   aliased command.
2018  *
2019  *   Note that RECURSE will be active on *all* sublists, not just the
2020  * ones selected by the criteria above (ie. the selection mechanism
2021  * is at the low level, not the high-level).
2022  */
2023 
2024 static void
help_cmd_list(struct cmd_list_element * list,enum command_class theclass,bool recurse,struct ui_file * stream)2025 help_cmd_list (struct cmd_list_element *list, enum command_class theclass,
2026                  bool recurse, struct ui_file *stream)
2027 {
2028   struct cmd_list_element *c;
2029 
2030   for (c = list; c; c = c->next)
2031     {
2032       if (c->abbrev_flag == 1 || c->cmd_deprecated)
2033           {
2034             /* Do not show abbreviations or deprecated commands.  */
2035             continue;
2036           }
2037 
2038       if (c->is_alias () && theclass != class_alias)
2039           {
2040             /* Do not show an alias, unless specifically showing the
2041                list of aliases:  for all other classes, an alias is
2042                shown (if needed) together with its aliased command.  */
2043             continue;
2044           }
2045 
2046       if (theclass == all_commands
2047             || (theclass == all_classes && c->is_command_class_help ())
2048             || (theclass == c->theclass && !c->is_command_class_help ()))
2049           {
2050             /* show C when
2051                - showing all commands
2052                - showing all classes and C is a help class
2053                - showing commands of THECLASS and C is not the help class  */
2054 
2055             /* If we show the class_alias and C is an alias, do not recurse,
2056                as this would show the (possibly very long) not very useful
2057                list of sub-commands of the aliased command.  */
2058             print_help_for_command
2059               (*c,
2060                recurse && (theclass != class_alias || !c->is_alias ()),
2061                stream);
2062             continue;
2063           }
2064 
2065       if (recurse
2066             && (theclass == class_user || theclass == class_alias)
2067             && c->is_prefix ())
2068           {
2069             /* User-defined commands or aliases may be subcommands.  */
2070             help_cmd_list (*c->subcommands, theclass, recurse, stream);
2071             continue;
2072           }
2073 
2074       /* Do not show C or recurse on C, e.g. because C does not belong to
2075            THECLASS or because C is a help class.  */
2076     }
2077 }
2078 
2079 
2080 /* Search the input clist for 'command'.  Return the command if
2081    found (or NULL if not), and return the number of commands
2082    found in nfound.  */
2083 
2084 static struct cmd_list_element *
find_cmd(const char * command,int len,struct cmd_list_element * clist,int ignore_help_classes,int * nfound)2085 find_cmd (const char *command, int len, struct cmd_list_element *clist,
2086             int ignore_help_classes, int *nfound)
2087 {
2088   struct cmd_list_element *found, *c;
2089 
2090   found = NULL;
2091   *nfound = 0;
2092   for (c = clist; c; c = c->next)
2093     if (!strncmp (command, c->name, len)
2094           && (!ignore_help_classes || !c->is_command_class_help ()))
2095       {
2096           found = c;
2097           (*nfound)++;
2098           if (c->name[len] == '\0')
2099             {
2100               *nfound = 1;
2101               break;
2102             }
2103       }
2104   return found;
2105 }
2106 
2107 /* Return the length of command name in TEXT.  */
2108 
2109 int
find_command_name_length(const char * text)2110 find_command_name_length (const char *text)
2111 {
2112   const char *p = text;
2113 
2114   /* Treating underscores as part of command words is important
2115      so that "set args_foo()" doesn't get interpreted as
2116      "set args _foo()".  */
2117   /* Some characters are only used for TUI specific commands.
2118      However, they are always allowed for the sake of consistency.
2119 
2120      Note that this is larger than the character set allowed when
2121      creating user-defined commands.  */
2122 
2123   /* Recognize the single character commands so that, e.g., "!ls"
2124      works as expected.  */
2125   if (*p == '!' || *p == '|')
2126     return 1;
2127 
2128   while (valid_cmd_char_p (*p)
2129            /* Characters used by TUI specific commands.  */
2130            || *p == '+' || *p == '<' || *p == '>' || *p == '$')
2131     p++;
2132 
2133   return p - text;
2134 }
2135 
2136 /* See command.h.  */
2137 
2138 bool
valid_cmd_char_p(int c)2139 valid_cmd_char_p (int c)
2140 {
2141   /* Alas "42" is a legitimate user-defined command.
2142      In the interests of not breaking anything we preserve that.  */
2143 
2144   return isalnum (c) || c == '-' || c == '_' || c == '.';
2145 }
2146 
2147 /* See command.h.  */
2148 
2149 bool
valid_user_defined_cmd_name_p(const char * name)2150 valid_user_defined_cmd_name_p (const char *name)
2151 {
2152   const char *p;
2153 
2154   if (*name == '\0')
2155     return false;
2156 
2157   for (p = name; *p != '\0'; ++p)
2158     {
2159       if (valid_cmd_char_p (*p))
2160           ; /* Ok.  */
2161       else
2162           return false;
2163     }
2164 
2165   return true;
2166 }
2167 
2168 /* See command.h.  */
2169 
2170 struct cmd_list_element *
lookup_cmd_1(const char ** text,struct cmd_list_element * clist,struct cmd_list_element ** result_list,std::string * default_args,int ignore_help_classes,bool lookup_for_completion_p)2171 lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
2172                 struct cmd_list_element **result_list, std::string *default_args,
2173                 int ignore_help_classes, bool lookup_for_completion_p)
2174 {
2175   char *command;
2176   int len, nfound;
2177   struct cmd_list_element *found, *c;
2178   bool found_alias = false;
2179   const char *line = *text;
2180 
2181   while (**text == ' ' || **text == '\t')
2182     (*text)++;
2183 
2184   /* Identify the name of the command.  */
2185   len = find_command_name_length (*text);
2186 
2187   /* If nothing but whitespace, return 0.  */
2188   if (len == 0)
2189     return 0;
2190 
2191   /* *text and p now bracket the first command word to lookup (and
2192      it's length is len).  We copy this into a local temporary.  */
2193 
2194 
2195   command = (char *) alloca (len + 1);
2196   memcpy (command, *text, len);
2197   command[len] = '\0';
2198 
2199   /* Look it up.  */
2200   found = 0;
2201   nfound = 0;
2202   found = find_cmd (command, len, clist, ignore_help_classes, &nfound);
2203 
2204   /* If nothing matches, we have a simple failure.  */
2205   if (nfound == 0)
2206     return 0;
2207 
2208   if (nfound > 1)
2209     {
2210       if (result_list != nullptr)
2211           /* Will be modified in calling routine
2212              if we know what the prefix command is.  */
2213           *result_list = 0;
2214       if (default_args != nullptr)
2215           *default_args = std::string ();
2216       return CMD_LIST_AMBIGUOUS;        /* Ambiguous.  */
2217     }
2218 
2219   /* We've matched something on this list.  Move text pointer forward.  */
2220 
2221   *text += len;
2222 
2223   if (found->is_alias ())
2224     {
2225       /* We drop the alias (abbreviation) in favor of the command it
2226        is pointing to.  If the alias is deprecated, though, we need to
2227        warn the user about it before we drop it.  Note that while we
2228        are warning about the alias, we may also warn about the command
2229        itself and we will adjust the appropriate DEPRECATED_WARN_USER
2230        flags.  */
2231 
2232       if (found->deprecated_warn_user && !lookup_for_completion_p)
2233           deprecated_cmd_warning (line, clist);
2234 
2235 
2236       /* Return the default_args of the alias, not the default_args
2237            of the command it is pointing to.  */
2238       if (default_args != nullptr)
2239           *default_args = found->default_args;
2240       found = found->alias_target;
2241       found_alias = true;
2242     }
2243   /* If we found a prefix command, keep looking.  */
2244 
2245   if (found->is_prefix ())
2246     {
2247       c = lookup_cmd_1 (text, *found->subcommands, result_list, default_args,
2248                               ignore_help_classes, lookup_for_completion_p);
2249       if (!c)
2250           {
2251             /* Didn't find anything; this is as far as we got.  */
2252             if (result_list != nullptr)
2253               *result_list = clist;
2254             if (!found_alias && default_args != nullptr)
2255               *default_args = found->default_args;
2256             return found;
2257           }
2258       else if (c == CMD_LIST_AMBIGUOUS)
2259           {
2260             /* We've gotten this far properly, but the next step is
2261                ambiguous.  We need to set the result list to the best
2262                we've found (if an inferior hasn't already set it).  */
2263             if (result_list != nullptr)
2264               if (!*result_list)
2265                 /* This used to say *result_list = *found->subcommands.
2266                      If that was correct, need to modify the documentation
2267                      at the top of this function to clarify what is
2268                      supposed to be going on.  */
2269                 *result_list = found;
2270             /* For ambiguous commands, do not return any default_args args.  */
2271             if (default_args != nullptr)
2272               *default_args = std::string ();
2273             return c;
2274           }
2275       else
2276           {
2277             /* We matched!  */
2278             return c;
2279           }
2280     }
2281   else
2282     {
2283       if (result_list != nullptr)
2284           *result_list = clist;
2285       if (!found_alias && default_args != nullptr)
2286           *default_args = found->default_args;
2287       return found;
2288     }
2289 }
2290 
2291 /* All this hair to move the space to the front of cmdtype */
2292 
2293 static void
undef_cmd_error(const char * cmdtype,const char * q)2294 undef_cmd_error (const char *cmdtype, const char *q)
2295 {
2296   error (_("Undefined %scommand: \"%s\".  Try \"help%s%.*s\"."),
2297            cmdtype,
2298            q,
2299            *cmdtype ? " " : "",
2300            (int) strlen (cmdtype) - 1,
2301            cmdtype);
2302 }
2303 
2304 /* Look up the contents of *LINE as a command in the command list LIST.
2305    LIST is a chain of struct cmd_list_element's.
2306    If it is found, return the struct cmd_list_element for that command,
2307    update *LINE to point after the command name, at the first argument
2308    and update *DEFAULT_ARGS (if DEFAULT_ARGS is not null) to the default
2309    args to prepend to the user provided args when running the command.
2310    Note that if the found cmd_list_element is found via an alias,
2311    the default args of the alias are returned.
2312 
2313    If not found, call error if ALLOW_UNKNOWN is zero
2314    otherwise (or if error returns) return zero.
2315    Call error if specified command is ambiguous,
2316    unless ALLOW_UNKNOWN is negative.
2317    CMDTYPE precedes the word "command" in the error message.
2318 
2319    If IGNORE_HELP_CLASSES is nonzero, ignore any command list
2320    elements which are actually help classes rather than commands (i.e.
2321    the function field of the struct cmd_list_element is 0).  */
2322 
2323 struct cmd_list_element *
lookup_cmd(const char ** line,struct cmd_list_element * list,const char * cmdtype,std::string * default_args,int allow_unknown,int ignore_help_classes)2324 lookup_cmd (const char **line, struct cmd_list_element *list,
2325               const char *cmdtype,
2326               std::string *default_args,
2327               int allow_unknown, int ignore_help_classes)
2328 {
2329   struct cmd_list_element *last_list = 0;
2330   struct cmd_list_element *c;
2331 
2332   /* Note: Do not remove trailing whitespace here because this
2333      would be wrong for complete_command.  Jim Kingdon  */
2334 
2335   if (!*line)
2336     error (_("Lack of needed %scommand"), cmdtype);
2337 
2338   c = lookup_cmd_1 (line, list, &last_list, default_args, ignore_help_classes);
2339 
2340   if (!c)
2341     {
2342       if (!allow_unknown)
2343           {
2344             char *q;
2345             int len = find_command_name_length (*line);
2346 
2347             q = (char *) alloca (len + 1);
2348             strncpy (q, *line, len);
2349             q[len] = '\0';
2350             undef_cmd_error (cmdtype, q);
2351           }
2352       else
2353           return 0;
2354     }
2355   else if (c == CMD_LIST_AMBIGUOUS)
2356     {
2357       /* Ambigous.  Local values should be off subcommands or called
2358            values.  */
2359       int local_allow_unknown = (last_list ? last_list->allow_unknown :
2360                                          allow_unknown);
2361       std::string local_cmdtype
2362           = last_list ? last_list->prefixname () : cmdtype;
2363       struct cmd_list_element *local_list =
2364           (last_list ? *(last_list->subcommands) : list);
2365 
2366       if (local_allow_unknown < 0)
2367           {
2368             if (last_list)
2369               return last_list;         /* Found something.  */
2370             else
2371               return 0;                 /* Found nothing.  */
2372           }
2373       else
2374           {
2375             /* Report as error.  */
2376             int amb_len;
2377             char ambbuf[100];
2378 
2379             for (amb_len = 0;
2380                  ((*line)[amb_len] && (*line)[amb_len] != ' '
2381                     && (*line)[amb_len] != '\t');
2382                  amb_len++)
2383               ;
2384 
2385             ambbuf[0] = 0;
2386             for (c = local_list; c; c = c->next)
2387               if (!strncmp (*line, c->name, amb_len))
2388                 {
2389                     if (strlen (ambbuf) + strlen (c->name) + 6
2390                         < (int) sizeof ambbuf)
2391                       {
2392                         if (strlen (ambbuf))
2393                           strcat (ambbuf, ", ");
2394                         strcat (ambbuf, c->name);
2395                       }
2396                     else
2397                       {
2398                         strcat (ambbuf, "..");
2399                         break;
2400                       }
2401                 }
2402             error (_("Ambiguous %scommand \"%s\": %s."),
2403                      local_cmdtype.c_str (), *line, ambbuf);
2404           }
2405     }
2406   else
2407     {
2408       if (c->type == set_cmd && **line != '\0' && !isspace (**line))
2409           error (_("Argument must be preceded by space."));
2410 
2411       /* We've got something.  It may still not be what the caller
2412            wants (if this command *needs* a subcommand).  */
2413       while (**line == ' ' || **line == '\t')
2414           (*line)++;
2415 
2416       if (c->is_prefix () && **line && !c->allow_unknown)
2417           undef_cmd_error (c->prefixname ().c_str (), *line);
2418 
2419       /* Seems to be what he wants.  Return it.  */
2420       return c;
2421     }
2422   return 0;
2423 }
2424 
2425 /* See command.h.  */
2426 
2427 struct cmd_list_element *
lookup_cmd_exact(const char * name,struct cmd_list_element * list,bool ignore_help_classes)2428 lookup_cmd_exact (const char *name,
2429                       struct cmd_list_element *list,
2430                       bool ignore_help_classes)
2431 {
2432   const char *tem = name;
2433   struct cmd_list_element *cmd = lookup_cmd (&tem, list, "", NULL, -1,
2434                                                        ignore_help_classes);
2435   if (cmd != nullptr && strcmp (name, cmd->name) != 0)
2436     cmd = nullptr;
2437   return cmd;
2438 }
2439 
2440 /* We are here presumably because an alias or command in TEXT is
2441    deprecated and a warning message should be generated.  This
2442    function decodes TEXT and potentially generates a warning message
2443    as outlined below.
2444 
2445    Example for 'set endian big' which has a fictitious alias 'seb'.
2446 
2447    If alias wasn't used in TEXT, and the command is deprecated:
2448    "warning: 'set endian big' is deprecated."
2449 
2450    If alias was used, and only the alias is deprecated:
2451    "warning: 'seb' an alias for the command 'set endian big' is deprecated."
2452 
2453    If alias was used and command is deprecated (regardless of whether
2454    the alias itself is deprecated:
2455 
2456    "warning: 'set endian big' (seb) is deprecated."
2457 
2458    After the message has been sent, clear the appropriate flags in the
2459    command and/or the alias so the user is no longer bothered.
2460 
2461 */
2462 void
deprecated_cmd_warning(const char * text,struct cmd_list_element * list)2463 deprecated_cmd_warning (const char *text, struct cmd_list_element *list)
2464 {
2465   struct cmd_list_element *alias = nullptr;
2466   struct cmd_list_element *cmd = nullptr;
2467 
2468   /* Return if text doesn't evaluate to a command.  We place this lookup
2469      within its own scope so that the PREFIX_CMD local is not visible
2470      later in this function.  The value returned in PREFIX_CMD is based on
2471      the prefix found in TEXT, and is our case this prefix can be missing
2472      in some situations (when LIST is not the global CMDLIST).
2473 
2474      It is better for our purposes to use the prefix commands directly from
2475      the ALIAS and CMD results.  */
2476   {
2477     struct cmd_list_element *prefix_cmd = nullptr;
2478     if (!lookup_cmd_composition_1 (text, &alias, &prefix_cmd, &cmd, list))
2479       return;
2480   }
2481 
2482   /* Return if nothing is deprecated.  */
2483   if (!((alias != nullptr ? alias->deprecated_warn_user : 0)
2484           || cmd->deprecated_warn_user))
2485     return;
2486 
2487   /* Join command prefix (if any) and the command name.  */
2488   std::string tmp_cmd_str;
2489   if (cmd->prefix != nullptr)
2490     tmp_cmd_str += cmd->prefix->prefixname ();
2491   tmp_cmd_str += std::string (cmd->name);
2492 
2493   /* Display the appropriate first line, this warns that the thing the user
2494      entered is deprecated.  */
2495   if (alias != nullptr)
2496     {
2497       /* Join the alias prefix (if any) and the alias name.  */
2498       std::string tmp_alias_str;
2499       if (alias->prefix != nullptr)
2500           tmp_alias_str += alias->prefix->prefixname ();
2501       tmp_alias_str += std::string (alias->name);
2502 
2503       if (cmd->cmd_deprecated)
2504           gdb_printf (_("Warning: command '%ps' (%ps) is deprecated.\n"),
2505                         styled_string (title_style.style (),
2506                                            tmp_cmd_str.c_str ()),
2507                         styled_string (title_style.style (),
2508                                            tmp_alias_str.c_str ()));
2509       else
2510           gdb_printf (_("Warning: '%ps', an alias for the command '%ps', "
2511                           "is deprecated.\n"),
2512                         styled_string (title_style.style (),
2513                                            tmp_alias_str.c_str ()),
2514                         styled_string (title_style.style (),
2515                                            tmp_cmd_str.c_str ()));
2516     }
2517   else
2518     gdb_printf (_("Warning: command '%ps' is deprecated.\n"),
2519                     styled_string (title_style.style (),
2520                                      tmp_cmd_str.c_str ()));
2521 
2522   /* Now display a second line indicating what the user should use instead.
2523      If it is only the alias that is deprecated, we want to indicate the
2524      new alias, otherwise we'll indicate the new command.  */
2525   const char *replacement;
2526   if (alias != nullptr && !cmd->cmd_deprecated)
2527     replacement = alias->replacement;
2528   else
2529     replacement = cmd->replacement;
2530   if (replacement != nullptr)
2531     gdb_printf (_("Use '%ps'.\n\n"),
2532                     styled_string (title_style.style (),
2533                                      replacement));
2534   else
2535     gdb_printf (_("No alternative known.\n\n"));
2536 
2537   /* We've warned you, now we'll keep quiet.  */
2538   if (alias != nullptr)
2539     alias->deprecated_warn_user = 0;
2540   cmd->deprecated_warn_user = 0;
2541 }
2542 
2543 /* Look up the contents of TEXT as a command in the command list CUR_LIST.
2544    Return 1 on success, 0 on failure.
2545 
2546    If TEXT refers to an alias, *ALIAS will point to that alias.
2547 
2548    If TEXT is a subcommand (i.e. one that is preceded by a prefix
2549    command) set *PREFIX_CMD.
2550 
2551    Set *CMD to point to the command TEXT indicates, or to
2552    CMD_LIST_AMBIGUOUS if there are multiple possible matches.
2553 
2554    If any of *ALIAS, *PREFIX_CMD, or *CMD cannot be determined or do not
2555    exist, they are NULL when we return.
2556 
2557 */
2558 
2559 static int
lookup_cmd_composition_1(const char * text,struct cmd_list_element ** alias,struct cmd_list_element ** prefix_cmd,struct cmd_list_element ** cmd,struct cmd_list_element * cur_list)2560 lookup_cmd_composition_1 (const char *text,
2561                                 struct cmd_list_element **alias,
2562                                 struct cmd_list_element **prefix_cmd,
2563                                 struct cmd_list_element **cmd,
2564                                 struct cmd_list_element *cur_list)
2565 {
2566   *alias = nullptr;
2567   *prefix_cmd = cur_list->prefix;
2568   *cmd = nullptr;
2569 
2570   text = skip_spaces (text);
2571 
2572   /* Go through as many command lists as we need to, to find the command
2573      TEXT refers to.  */
2574   while (1)
2575     {
2576       /* Identify the name of the command.  */
2577       int len = find_command_name_length (text);
2578 
2579       /* If nothing but whitespace, return.  */
2580       if (len == 0)
2581           return 0;
2582 
2583       /* TEXT is the start of the first command word to lookup (and
2584            it's length is LEN).  We copy this into a local temporary.  */
2585       std::string command (text, len);
2586 
2587       /* Look it up.  */
2588       int nfound = 0;
2589       *cmd = find_cmd (command.c_str (), len, cur_list, 1, &nfound);
2590 
2591       /* We only handle the case where a single command was found.  */
2592       if (nfound > 1)
2593           {
2594             *cmd = CMD_LIST_AMBIGUOUS;
2595             return 0;
2596           }
2597       else if (*cmd == nullptr)
2598           return 0;
2599       else
2600           {
2601             if ((*cmd)->is_alias ())
2602               {
2603                 /* If the command was actually an alias, we note that an
2604                      alias was used (by assigning *ALIAS) and we set *CMD.  */
2605                 *alias = *cmd;
2606                 *cmd = (*cmd)->alias_target;
2607               }
2608           }
2609 
2610       text += len;
2611       text = skip_spaces (text);
2612 
2613       if ((*cmd)->is_prefix () && *text != '\0')
2614           {
2615             cur_list = *(*cmd)->subcommands;
2616             *prefix_cmd = *cmd;
2617           }
2618       else
2619           return 1;
2620     }
2621 }
2622 
2623 /* Look up the contents of TEXT as a command in the command list 'cmdlist'.
2624    Return 1 on success, 0 on failure.
2625 
2626    If TEXT refers to an alias, *ALIAS will point to that alias.
2627 
2628    If TEXT is a subcommand (i.e. one that is preceded by a prefix
2629    command) set *PREFIX_CMD.
2630 
2631    Set *CMD to point to the command TEXT indicates, or to
2632    CMD_LIST_AMBIGUOUS if there are multiple possible matches.
2633 
2634    If any of *ALIAS, *PREFIX_CMD, or *CMD cannot be determined or do not
2635    exist, they are NULL when we return.
2636 
2637 */
2638 
2639 int
lookup_cmd_composition(const char * text,struct cmd_list_element ** alias,struct cmd_list_element ** prefix_cmd,struct cmd_list_element ** cmd)2640 lookup_cmd_composition (const char *text,
2641                               struct cmd_list_element **alias,
2642                               struct cmd_list_element **prefix_cmd,
2643                               struct cmd_list_element **cmd)
2644 {
2645   return lookup_cmd_composition_1 (text, alias, prefix_cmd, cmd, cmdlist);
2646 }
2647 
2648 /* Helper function for SYMBOL_COMPLETION_FUNCTION.  */
2649 
2650 /* Return a vector of char pointers which point to the different
2651    possible completions in LIST of TEXT.
2652 
2653    WORD points in the same buffer as TEXT, and completions should be
2654    returned relative to this position.  For example, suppose TEXT is
2655    "foo" and we want to complete to "foobar".  If WORD is "oo", return
2656    "oobar"; if WORD is "baz/foo", return "baz/foobar".  */
2657 
2658 void
complete_on_cmdlist(struct cmd_list_element * list,completion_tracker & tracker,const char * text,const char * word,int ignore_help_classes)2659 complete_on_cmdlist (struct cmd_list_element *list,
2660                          completion_tracker &tracker,
2661                          const char *text, const char *word,
2662                          int ignore_help_classes)
2663 {
2664   struct cmd_list_element *ptr;
2665   int textlen = strlen (text);
2666   int pass;
2667   int saw_deprecated_match = 0;
2668 
2669   /* We do one or two passes.  In the first pass, we skip deprecated
2670      commands.  If we see no matching commands in the first pass, and
2671      if we did happen to see a matching deprecated command, we do
2672      another loop to collect those.  */
2673   for (pass = 0; pass < 2; ++pass)
2674     {
2675       bool got_matches = false;
2676 
2677       for (ptr = list; ptr; ptr = ptr->next)
2678           if (!strncmp (ptr->name, text, textlen)
2679               && !ptr->abbrev_flag
2680               && (!ignore_help_classes || !ptr->is_command_class_help ()
2681                     || ptr->is_prefix ()))
2682             {
2683               if (pass == 0)
2684                 {
2685                     if (ptr->cmd_deprecated)
2686                       {
2687                         saw_deprecated_match = 1;
2688                         continue;
2689                       }
2690                 }
2691 
2692               tracker.add_completion
2693                 (make_completion_match_str (ptr->name, text, word));
2694               got_matches = true;
2695             }
2696 
2697       if (got_matches)
2698           break;
2699 
2700       /* If we saw no matching deprecated commands in the first pass,
2701            just bail out.  */
2702       if (!saw_deprecated_match)
2703           break;
2704     }
2705 }
2706 
2707 /* Helper function for SYMBOL_COMPLETION_FUNCTION.  */
2708 
2709 /* Add the different possible completions in ENUMLIST of TEXT.
2710 
2711    WORD points in the same buffer as TEXT, and completions should be
2712    returned relative to this position.  For example, suppose TEXT is "foo"
2713    and we want to complete to "foobar".  If WORD is "oo", return
2714    "oobar"; if WORD is "baz/foo", return "baz/foobar".  */
2715 
2716 void
complete_on_enum(completion_tracker & tracker,const char * const * enumlist,const char * text,const char * word)2717 complete_on_enum (completion_tracker &tracker,
2718                       const char *const *enumlist,
2719                       const char *text, const char *word)
2720 {
2721   int textlen = strlen (text);
2722   int i;
2723   const char *name;
2724 
2725   for (i = 0; (name = enumlist[i]) != NULL; i++)
2726     if (strncmp (name, text, textlen) == 0)
2727       tracker.add_completion (make_completion_match_str (name, text, word));
2728 }
2729 
2730 /* Call the command function.  */
2731 void
cmd_func(struct cmd_list_element * cmd,const char * args,int from_tty)2732 cmd_func (struct cmd_list_element *cmd, const char *args, int from_tty)
2733 {
2734   if (!cmd->is_command_class_help ())
2735     {
2736       std::optional<scoped_restore_tmpl<bool>> restore_suppress;
2737 
2738       if (cmd->suppress_notification != NULL)
2739           restore_suppress.emplace (cmd->suppress_notification, true);
2740 
2741       cmd->func (args, from_tty, cmd);
2742     }
2743   else
2744     error (_("Invalid command"));
2745 }
2746 
2747 int
cli_user_command_p(struct cmd_list_element * cmd)2748 cli_user_command_p (struct cmd_list_element *cmd)
2749 {
2750   return cmd->theclass == class_user && cmd->func == do_simple_func;
2751 }
2752