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