/* Handle lists of commands, their decoding and documentation, for GDB.
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2022 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "defs.h"
#include "symtab.h"
#include <ctype.h>
-#include "gdb_regex.h"
+#include "gdbsupport/gdb_regex.h"
#include "completer.h"
#include "ui-out.h"
#include "cli/cli-cmds.h"
static void undef_cmd_error (const char *, const char *);
-static struct cmd_list_element *delete_cmd (const char *name,
- struct cmd_list_element **list,
- struct cmd_list_element **prehook,
- struct cmd_list_element **prehookee,
- struct cmd_list_element **posthook,
- struct cmd_list_element **posthookee);
+static cmd_list_element::aliases_list_type delete_cmd
+ (const char *name, cmd_list_element **list, cmd_list_element **prehook,
+ cmd_list_element **prehookee, cmd_list_element **posthook,
+ cmd_list_element **posthookee);
static struct cmd_list_element *find_cmd (const char *command,
int len,
static void help_all (struct ui_file *stream);
-/* Look up a command whose 'prefixlist' is KEY. Return the command if found,
- otherwise return NULL. */
+static int lookup_cmd_composition_1 (const char *text,
+ struct cmd_list_element **alias,
+ struct cmd_list_element **prefix_cmd,
+ struct cmd_list_element **cmd,
+ struct cmd_list_element *cur_list);
+
+/* Look up a command whose 'subcommands' field is SUBCOMMANDS. Return the
+ command if found, otherwise return NULL. */
static struct cmd_list_element *
-lookup_cmd_for_prefixlist (struct cmd_list_element **key,
- struct cmd_list_element *list)
+lookup_cmd_with_subcommands (cmd_list_element **subcommands,
+ cmd_list_element *list)
{
struct cmd_list_element *p = NULL;
{
struct cmd_list_element *q;
- if (p->prefixlist == NULL)
+ if (!p->is_prefix ())
continue;
- else if (p->prefixlist == key)
+
+ else if (p->subcommands == subcommands)
{
/* If we found an alias, we must return the aliased
command. */
- return p->cmd_pointer ? p->cmd_pointer : p;
+ return p->is_alias () ? p->alias_target : p;
}
- q = lookup_cmd_for_prefixlist (key, *(p->prefixlist));
+ q = lookup_cmd_with_subcommands (subcommands, *(p->subcommands));
if (q != NULL)
return q;
}
}
static void
-print_help_for_command (struct cmd_list_element *c,
+print_help_for_command (const cmd_list_element &c,
bool recurse, struct ui_file *stream);
-\f
-/* Set the callback function for the specified command. For each both
- the commands callback and func() are set. The latter set to a
- bounce function (unless cfunc / sfunc is NULL that is). */
-
static void
-do_const_cfunc (struct cmd_list_element *c, const char *args, int from_tty)
+do_simple_func (const char *args, int from_tty, cmd_list_element *c)
{
- c->function.const_cfunc (args, from_tty);
+ c->function.simple_func (args, from_tty);
}
static void
-set_cmd_cfunc (struct cmd_list_element *cmd, cmd_const_cfunc_ftype *cfunc)
+set_cmd_simple_func (struct cmd_list_element *cmd, cmd_simple_func_ftype *simple_func)
{
- if (cfunc == NULL)
+ if (simple_func == NULL)
cmd->func = NULL;
else
- cmd->func = do_const_cfunc;
- cmd->function.const_cfunc = cfunc;
+ cmd->func = do_simple_func;
+
+ cmd->function.simple_func = simple_func;
}
-static void
-do_sfunc (struct cmd_list_element *c, const char *args, int from_tty)
+int
+cmd_simple_func_eq (struct cmd_list_element *cmd, cmd_simple_func_ftype *simple_func)
{
- c->function.sfunc (args, from_tty, c);
+ return (cmd->func == do_simple_func
+ && cmd->function.simple_func == simple_func);
}
void
-set_cmd_sfunc (struct cmd_list_element *cmd, cmd_const_sfunc_ftype *sfunc)
+set_cmd_completer (struct cmd_list_element *cmd, completer_ftype *completer)
{
- if (sfunc == NULL)
- cmd->func = NULL;
- else
- cmd->func = do_sfunc;
- cmd->function.sfunc = sfunc;
+ cmd->completer = completer; /* Ok. */
}
-int
-cmd_cfunc_eq (struct cmd_list_element *cmd, cmd_const_cfunc_ftype *cfunc)
-{
- return cmd->func == do_const_cfunc && cmd->function.const_cfunc == cfunc;
-}
+/* See definition in commands.h. */
void
-set_cmd_context (struct cmd_list_element *cmd, void *context)
+set_cmd_completer_handle_brkchars (struct cmd_list_element *cmd,
+ completer_handle_brkchars_ftype *func)
{
- cmd->context = context;
+ cmd->completer_handle_brkchars = func;
}
-void *
-get_cmd_context (struct cmd_list_element *cmd)
+std::string
+cmd_list_element::prefixname () const
{
- return cmd->context;
-}
+ if (!this->is_prefix ())
+ /* Not a prefix command. */
+ return "";
-enum cmd_types
-cmd_type (struct cmd_list_element *cmd)
-{
- return cmd->type;
-}
+ std::string prefixname;
+ if (this->prefix != nullptr)
+ prefixname = this->prefix->prefixname ();
-void
-set_cmd_completer (struct cmd_list_element *cmd, completer_ftype *completer)
-{
- cmd->completer = completer; /* Ok. */
+ prefixname += this->name;
+ prefixname += " ";
+
+ return prefixname;
}
-/* See definition in commands.h. */
+/* See cli/cli-decode.h. */
-void
-set_cmd_completer_handle_brkchars (struct cmd_list_element *cmd,
- completer_handle_brkchars_ftype *func)
+std::vector<std::string>
+cmd_list_element::command_components () const
{
- cmd->completer_handle_brkchars = func;
+ std::vector<std::string> result;
+
+ if (this->prefix != nullptr)
+ result = this->prefix->command_components ();
+
+ result.emplace_back (std::string (this->name));
+ return result;
}
/* Add element named NAME.
{
struct cmd_list_element *c = new struct cmd_list_element (name, theclass,
doc);
- struct cmd_list_element *p, *iter;
/* Turn each alias of the old command into an alias of the new
command. */
c->aliases = delete_cmd (name, list, &c->hook_pre, &c->hookee_pre,
&c->hook_post, &c->hookee_post);
- for (iter = c->aliases; iter; iter = iter->alias_chain)
- iter->cmd_pointer = c;
+
+ for (cmd_list_element &alias : c->aliases)
+ alias.alias_target = c;
+
if (c->hook_pre)
c->hook_pre->hookee_pre = c;
+
if (c->hookee_pre)
c->hookee_pre->hook_pre = c;
+
if (c->hook_post)
c->hook_post->hookee_post = c;
+
if (c->hookee_post)
c->hookee_post->hook_post = c;
}
else
{
- p = *list;
+ cmd_list_element *p = *list;
while (p->next && strcmp (p->next->name, name) <= 0)
{
p = p->next;
/* Search the prefix cmd of C, and assigns it to C->prefix.
See also add_prefix_cmd and update_prefix_field_of_prefixed_commands. */
- struct cmd_list_element *prefixcmd = lookup_cmd_for_prefixlist (list,
- cmdlist);
+ cmd_list_element *prefixcmd = lookup_cmd_with_subcommands (list, cmdlist);
c->prefix = prefixcmd;
{
cmd_list_element *result = do_add_cmd (name, theclass, doc, list);
result->func = NULL;
- result->function.const_cfunc = NULL;
+ result->function.simple_func = NULL;
return result;
}
struct cmd_list_element *
add_cmd (const char *name, enum command_class theclass,
- cmd_const_cfunc_ftype *fun,
+ cmd_simple_func_ftype *fun,
const char *doc, struct cmd_list_element **list)
{
cmd_list_element *result = do_add_cmd (name, theclass, doc, list);
- set_cmd_cfunc (result, fun);
+ set_cmd_simple_func (result, fun);
return result;
}
struct cmd_list_element *
add_cmd_suppress_notification (const char *name, enum command_class theclass,
- cmd_const_cfunc_ftype *fun, const char *doc,
+ cmd_simple_func_ftype *fun, const char *doc,
struct cmd_list_element **list,
- int *suppress_notification)
+ bool *suppress_notification)
{
struct cmd_list_element *element;
}
struct cmd_list_element *
-add_alias_cmd (const char *name, cmd_list_element *old,
+add_alias_cmd (const char *name, cmd_list_element *target,
enum command_class theclass, int abbrev_flag,
struct cmd_list_element **list)
{
- if (old == 0)
- {
- struct cmd_list_element *prehook, *prehookee, *posthook, *posthookee;
- struct cmd_list_element *aliases = delete_cmd (name, list,
- &prehook, &prehookee,
- &posthook, &posthookee);
-
- /* If this happens, it means a programmer error somewhere. */
- gdb_assert (!aliases && !prehook && !prehookee
- && !posthook && ! posthookee);
- return 0;
- }
+ gdb_assert (target != nullptr);
- struct cmd_list_element *c = add_cmd (name, theclass, old->doc, list);
+ struct cmd_list_element *c = add_cmd (name, theclass, target->doc, list);
- /* If OLD->DOC can be freed, we should make another copy. */
- if (old->doc_allocated)
+ /* If TARGET->DOC can be freed, we should make another copy. */
+ if (target->doc_allocated)
{
- c->doc = xstrdup (old->doc);
+ c->doc = xstrdup (target->doc);
c->doc_allocated = 1;
}
/* NOTE: Both FUNC and all the FUNCTIONs need to be copied. */
- c->func = old->func;
- c->function = old->function;
- c->prefixlist = old->prefixlist;
- c->prefixname = old->prefixname;
- c->allow_unknown = old->allow_unknown;
+ c->func = target->func;
+ c->function = target->function;
+ c->subcommands = target->subcommands;
+ c->allow_unknown = target->allow_unknown;
c->abbrev_flag = abbrev_flag;
- c->cmd_pointer = old;
- c->alias_chain = old->aliases;
- old->aliases = c;
+ c->alias_target = target;
+ target->aliases.push_front (*c);
return c;
}
-struct cmd_list_element *
-add_alias_cmd (const char *name, const char *oldname,
- enum command_class theclass, int abbrev_flag,
- struct cmd_list_element **list)
-{
- const char *tmp;
- struct cmd_list_element *old;
-
- tmp = oldname;
- old = lookup_cmd (&tmp, *list, "", NULL, 1, 1);
-
- return add_alias_cmd (name, old, theclass, abbrev_flag, list);
-}
-
-
/* Update the prefix field of all sub-commands of the prefix command C.
We must do this when a prefix command is defined as the GDB init sequence
does not guarantee that a prefix command is created before its sub-commands.
static void
update_prefix_field_of_prefixed_commands (struct cmd_list_element *c)
{
- for (cmd_list_element *p = *c->prefixlist; p != NULL; p = p->next)
+ for (cmd_list_element *p = *c->subcommands; p != NULL; p = p->next)
{
p->prefix = c;
/* We must recursively update the prefix field to cover
e.g. 'info auto-load libthread-db' where the creation
order was:
- libthread-db
- auto-load
- info
+ libthread-db
+ auto-load
+ info
In such a case, when 'auto-load' was created by do_add_cmd,
- the 'libthread-db' prefix field could not be updated, as the
+ the 'libthread-db' prefix field could not be updated, as the
'auto-load' command was not yet reachable by
- lookup_cmd_for_prefixlist (list, cmdlist)
+ lookup_cmd_for_subcommands (list, cmdlist)
that searches from the top level 'cmdlist'. */
- if (p->prefixlist != nullptr)
+ if (p->is_prefix ())
update_prefix_field_of_prefixed_commands (p);
}
}
/* Like add_cmd but adds an element for a command prefix: a name that
should be followed by a subcommand to be looked up in another
- command list. PREFIXLIST should be the address of the variable
+ command list. SUBCOMMANDS should be the address of the variable
containing that list. */
struct cmd_list_element *
add_prefix_cmd (const char *name, enum command_class theclass,
- cmd_const_cfunc_ftype *fun,
- const char *doc, struct cmd_list_element **prefixlist,
- const char *prefixname, int allow_unknown,
- struct cmd_list_element **list)
+ cmd_simple_func_ftype *fun,
+ const char *doc, struct cmd_list_element **subcommands,
+ int allow_unknown, struct cmd_list_element **list)
{
struct cmd_list_element *c = add_cmd (name, theclass, fun, doc, list);
- c->prefixlist = prefixlist;
- c->prefixname = prefixname;
+ c->subcommands = subcommands;
c->allow_unknown = allow_unknown;
/* Now that prefix command C is defined, we need to set the prefix field
do_prefix_cmd (const char *args, int from_tty, struct cmd_list_element *c)
{
/* Look past all aliases. */
- while (c->cmd_pointer != nullptr)
- c = c->cmd_pointer;
+ while (c->is_alias ())
+ c = c->alias_target;
- help_list (*c->prefixlist, c->prefixname, all_commands, gdb_stdout);
+ help_list (*c->subcommands, c->prefixname ().c_str (),
+ all_commands, gdb_stdout);
}
/* See command.h. */
struct cmd_list_element *
add_basic_prefix_cmd (const char *name, enum command_class theclass,
- const char *doc, struct cmd_list_element **prefixlist,
- const char *prefixname, int allow_unknown,
- struct cmd_list_element **list)
+ const char *doc, struct cmd_list_element **subcommands,
+ int allow_unknown, struct cmd_list_element **list)
{
struct cmd_list_element *cmd = add_prefix_cmd (name, theclass, nullptr,
- doc, prefixlist, prefixname,
+ doc, subcommands,
allow_unknown, list);
- set_cmd_sfunc (cmd, do_prefix_cmd);
+ cmd->func = do_prefix_cmd;
return cmd;
}
static void
do_show_prefix_cmd (const char *args, int from_tty, struct cmd_list_element *c)
{
- cmd_show_list (*c->prefixlist, from_tty);
+ cmd_show_list (*c->subcommands, from_tty);
}
/* See command.h. */
struct cmd_list_element *
add_show_prefix_cmd (const char *name, enum command_class theclass,
- const char *doc, struct cmd_list_element **prefixlist,
- const char *prefixname, int allow_unknown,
- struct cmd_list_element **list)
+ const char *doc, struct cmd_list_element **subcommands,
+ int allow_unknown, struct cmd_list_element **list)
{
struct cmd_list_element *cmd = add_prefix_cmd (name, theclass, nullptr,
- doc, prefixlist, prefixname,
+ doc, subcommands,
allow_unknown, list);
- set_cmd_sfunc (cmd, do_show_prefix_cmd);
+ cmd->func = do_show_prefix_cmd;
return cmd;
}
+/* See command.h. */
+
+set_show_commands
+add_setshow_prefix_cmd (const char *name, command_class theclass,
+ const char *set_doc, const char *show_doc,
+ cmd_list_element **set_subcommands_list,
+ cmd_list_element **show_subcommands_list,
+ cmd_list_element **set_list,
+ cmd_list_element **show_list)
+{
+ set_show_commands cmds;
+
+ cmds.set = add_basic_prefix_cmd (name, theclass, set_doc,
+ set_subcommands_list, 0,
+ set_list);
+ cmds.show = add_show_prefix_cmd (name, theclass, show_doc,
+ show_subcommands_list, 0,
+ show_list);
+
+ return cmds;
+}
+
/* Like ADD_PREFIX_CMD but sets the suppress_notification pointer on the
new command list element. */
struct cmd_list_element *
add_prefix_cmd_suppress_notification
- (const char *name, enum command_class theclass,
- cmd_const_cfunc_ftype *fun,
- const char *doc, struct cmd_list_element **prefixlist,
- const char *prefixname, int allow_unknown,
- struct cmd_list_element **list,
- int *suppress_notification)
+ (const char *name, enum command_class theclass,
+ cmd_simple_func_ftype *fun,
+ const char *doc, struct cmd_list_element **subcommands,
+ int allow_unknown, struct cmd_list_element **list,
+ bool *suppress_notification)
{
struct cmd_list_element *element
- = add_prefix_cmd (name, theclass, fun, doc, prefixlist,
- prefixname, allow_unknown, list);
+ = add_prefix_cmd (name, theclass, fun, doc, subcommands,
+ allow_unknown, list);
element->suppress_notification = suppress_notification;
return element;
}
struct cmd_list_element *
add_abbrev_prefix_cmd (const char *name, enum command_class theclass,
- cmd_const_cfunc_ftype *fun, const char *doc,
- struct cmd_list_element **prefixlist,
- const char *prefixname,
+ cmd_simple_func_ftype *fun, const char *doc,
+ struct cmd_list_element **subcommands,
int allow_unknown, struct cmd_list_element **list)
{
struct cmd_list_element *c = add_cmd (name, theclass, fun, doc, list);
- c->prefixlist = prefixlist;
- c->prefixname = prefixname;
+ c->subcommands = subcommands;
c->allow_unknown = allow_unknown;
c->abbrev_flag = 1;
return c;
}
-/* This is an empty "cfunc". */
+/* This is an empty "simple func". */
void
not_just_help_class_command (const char *args, int from_tty)
{
}
-/* This is an empty "sfunc". */
+/* This is an empty cmd func. */
static void
-empty_sfunc (const char *args, int from_tty, struct cmd_list_element *c)
+empty_func (const char *args, int from_tty, cmd_list_element *c)
{
}
CLASS is as in add_cmd.
VAR_TYPE is the kind of thing we are setting.
VAR is address of the variable being controlled by this command.
+ SET_SETTING_FUNC is a pointer to an optional function callback used to set
+ the setting value.
+ GET_SETTING_FUNC is a pointer to an optional function callback used to get
+ the setting value.
DOC is the documentation string. */
static struct cmd_list_element *
enum cmd_types type,
enum command_class theclass,
var_types var_type,
- void *var,
+ const setting::erased_args &arg,
const char *doc,
struct cmd_list_element **list)
{
gdb_assert (type == set_cmd || type == show_cmd);
c->type = type;
- c->var_type = var_type;
- c->var = var;
+ c->var.emplace (var_type, arg);
+
/* This needs to be something besides NULL so that this isn't
treated as a help class. */
- set_cmd_sfunc (c, empty_sfunc);
+ c->func = empty_func;
return c;
}
/* Add element named NAME to both the command SET_LIST and SHOW_LIST.
CLASS is as in add_cmd. VAR_TYPE is the kind of thing we are
setting. VAR is address of the variable being controlled by this
- command. SET_FUNC and SHOW_FUNC are the callback functions (if
- non-NULL). SET_DOC, SHOW_DOC and HELP_DOC are the documentation
- strings. PRINT the format string to print the value. SET_RESULT
- and SHOW_RESULT, if not NULL, are set to the resulting command
- structures. */
-
-static void
-add_setshow_cmd_full (const char *name,
- enum command_class theclass,
- var_types var_type, void *var,
- const char *set_doc, const char *show_doc,
- const char *help_doc,
- cmd_const_sfunc_ftype *set_func,
- show_value_ftype *show_func,
- struct cmd_list_element **set_list,
- struct cmd_list_element **show_list,
- struct cmd_list_element **set_result,
- struct cmd_list_element **show_result)
+ command. If nullptr is given as VAR, then both SET_SETTING_FUNC and
+ GET_SETTING_FUNC must be provided. SET_SETTING_FUNC and GET_SETTING_FUNC are
+ callbacks used to access and modify the underlying property, whatever its
+ storage is. SET_FUNC and SHOW_FUNC are the callback functions (if non-NULL).
+ SET_DOC, SHOW_DOC and HELP_DOC are the documentation strings.
+
+ Return the newly created set and show commands. */
+
+static set_show_commands
+add_setshow_cmd_full_erased (const char *name,
+ enum command_class theclass,
+ var_types var_type,
+ const setting::erased_args &args,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ cmd_func_ftype *set_func,
+ show_value_ftype *show_func,
+ struct cmd_list_element **set_list,
+ struct cmd_list_element **show_list)
{
struct cmd_list_element *set;
struct cmd_list_element *show;
- char *full_set_doc;
- char *full_show_doc;
+ gdb::unique_xmalloc_ptr<char> full_set_doc;
+ gdb::unique_xmalloc_ptr<char> full_show_doc;
if (help_doc != NULL)
{
}
else
{
- full_set_doc = xstrdup (set_doc);
- full_show_doc = xstrdup (show_doc);
+ full_set_doc = make_unique_xstrdup (set_doc);
+ full_show_doc = make_unique_xstrdup (show_doc);
}
- set = add_set_or_show_cmd (name, set_cmd, theclass, var_type, var,
- full_set_doc, set_list);
+ set = add_set_or_show_cmd (name, set_cmd, theclass, var_type, args,
+ full_set_doc.release (), set_list);
set->doc_allocated = 1;
if (set_func != NULL)
- set_cmd_sfunc (set, set_func);
+ set->func = set_func;
- show = add_set_or_show_cmd (name, show_cmd, theclass, var_type, var,
- full_show_doc, show_list);
+ show = add_set_or_show_cmd (name, show_cmd, theclass, var_type, args,
+ full_show_doc.release (), show_list);
show->doc_allocated = 1;
show->show_value_func = show_func;
/* Disable the default symbol completer. Doesn't make much sense
for the "show" command to complete on anything. */
set_cmd_completer (show, nullptr);
- if (set_result != NULL)
- *set_result = set;
- if (show_result != NULL)
- *show_result = show;
+ return {set, show};
+}
+
+template<typename T>
+static set_show_commands
+add_setshow_cmd_full (const char *name,
+ enum command_class theclass,
+ var_types var_type, T *var,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ typename setting_func_types<T>::set set_setting_func,
+ typename setting_func_types<T>::get get_setting_func,
+ cmd_func_ftype *set_func,
+ show_value_ftype *show_func,
+ struct cmd_list_element **set_list,
+ struct cmd_list_element **show_list)
+{
+ auto erased_args
+ = setting::erase_args (var_type, var,
+ set_setting_func, get_setting_func);
+
+ return add_setshow_cmd_full_erased (name,
+ theclass,
+ var_type, erased_args,
+ set_doc, show_doc,
+ help_doc,
+ set_func,
+ show_func,
+ set_list,
+ show_list);
}
/* Add element named NAME to command list LIST (the list for set or
of strings which may follow NAME. VAR is address of the variable
which will contain the matching string (from ENUMLIST). */
-void
+set_show_commands
add_setshow_enum_cmd (const char *name,
enum command_class theclass,
const char *const *enumlist,
const char *set_doc,
const char *show_doc,
const char *help_doc,
- cmd_const_sfunc_ftype *set_func,
+ cmd_func_ftype *set_func,
show_value_ftype *show_func,
struct cmd_list_element **set_list,
- struct cmd_list_element **show_list,
- void *context)
+ struct cmd_list_element **show_list)
{
- struct cmd_list_element *c, *show;
+ /* We require *VAR to be initialized before this call, and
+ furthermore it must be == to one of the values in ENUMLIST. */
+ gdb_assert (var != nullptr && *var != nullptr);
+ for (int i = 0; ; ++i)
+ {
+ gdb_assert (enumlist[i] != nullptr);
+ if (*var == enumlist[i])
+ break;
+ }
+
+ set_show_commands commands
+ = add_setshow_cmd_full<const char *> (name, theclass, var_enum, var,
+ set_doc, show_doc, help_doc,
+ nullptr, nullptr, set_func,
+ show_func, set_list, show_list);
+ commands.set->enums = enumlist;
+ return commands;
+}
- add_setshow_cmd_full (name, theclass, var_enum, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list,
- &c, &show);
- c->enums = enumlist;
+/* Same as above but using a getter and a setter function instead of a pointer
+ to a global storage buffer. */
- set_cmd_context (c, context);
- set_cmd_context (show, context);
+set_show_commands
+add_setshow_enum_cmd (const char *name, command_class theclass,
+ const char *const *enumlist, const char *set_doc,
+ const char *show_doc, const char *help_doc,
+ setting_func_types<const char *>::set set_func,
+ setting_func_types<const char *>::get get_func,
+ show_value_ftype *show_func,
+ cmd_list_element **set_list,
+ cmd_list_element **show_list)
+{
+ auto cmds = add_setshow_cmd_full<const char *> (name, theclass, var_enum,
+ nullptr, set_doc, show_doc,
+ help_doc, set_func, get_func,
+ nullptr, show_func, set_list,
+ show_list);
+
+ cmds.set->enums = enumlist;
+
+ return cmds;
}
/* See cli-decode.h. */
command list lists. CLASS is as in add_cmd. VAR is address of the
variable which will contain the value. DOC is the documentation
string. FUNC is the corresponding callback. */
-void
+
+set_show_commands
add_setshow_auto_boolean_cmd (const char *name,
enum command_class theclass,
enum auto_boolean *var,
const char *set_doc, const char *show_doc,
const char *help_doc,
- cmd_const_sfunc_ftype *set_func,
+ cmd_func_ftype *set_func,
show_value_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
- struct cmd_list_element *c;
+ set_show_commands commands
+ = add_setshow_cmd_full<enum auto_boolean> (name, theclass, var_auto_boolean,
+ var, set_doc, show_doc, help_doc,
+ nullptr, nullptr, set_func,
+ show_func, set_list, show_list);
+
+ commands.set->enums = auto_boolean_enums;
- add_setshow_cmd_full (name, theclass, var_auto_boolean, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list,
- &c, NULL);
- c->enums = auto_boolean_enums;
+ return commands;
+}
+
+/* Same as above but using a getter and a setter function instead of a pointer
+ to a global storage buffer. */
+
+set_show_commands
+add_setshow_auto_boolean_cmd (const char *name, command_class theclass,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ setting_func_types<enum auto_boolean>::set set_func,
+ setting_func_types<enum auto_boolean>::get get_func,
+ show_value_ftype *show_func,
+ cmd_list_element **set_list,
+ cmd_list_element **show_list)
+{
+ auto cmds = add_setshow_cmd_full<enum auto_boolean> (name, theclass,
+ var_auto_boolean,
+ nullptr, set_doc,
+ show_doc, help_doc,
+ set_func, get_func,
+ nullptr, show_func,
+ set_list, show_list);
+
+ cmds.set->enums = auto_boolean_enums;
+
+ return cmds;
}
/* See cli-decode.h. */
value. SET_DOC and SHOW_DOC are the documentation strings.
Returns the new command element. */
-cmd_list_element *
+set_show_commands
add_setshow_boolean_cmd (const char *name, enum command_class theclass, bool *var,
const char *set_doc, const char *show_doc,
const char *help_doc,
- cmd_const_sfunc_ftype *set_func,
+ cmd_func_ftype *set_func,
show_value_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
- struct cmd_list_element *c;
+ set_show_commands commands
+ = add_setshow_cmd_full<bool> (name, theclass, var_boolean, var,
+ set_doc, show_doc, help_doc,
+ nullptr, nullptr, set_func, show_func,
+ set_list, show_list);
- add_setshow_cmd_full (name, theclass, var_boolean, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list,
- &c, NULL);
- c->enums = boolean_enums;
+ commands.set->enums = boolean_enums;
- return c;
+ return commands;
+}
+
+/* Same as above but using a getter and a setter function instead of a pointer
+ to a global storage buffer. */
+
+set_show_commands
+add_setshow_boolean_cmd (const char *name, command_class theclass,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ setting_func_types<bool>::set set_func,
+ setting_func_types<bool>::get get_func,
+ show_value_ftype *show_func,
+ cmd_list_element **set_list,
+ cmd_list_element **show_list)
+{
+ auto cmds = add_setshow_cmd_full<bool> (name, theclass, var_boolean, nullptr,
+ set_doc, show_doc, help_doc,
+ set_func, get_func, nullptr,
+ show_func, set_list, show_list);
+
+ cmds.set->enums = boolean_enums;
+
+ return cmds;
}
/* Add element named NAME to both the set and show command LISTs (the
list for set/show or some sublist thereof). */
-void
+
+set_show_commands
add_setshow_filename_cmd (const char *name, enum command_class theclass,
- char **var,
+ std::string *var,
const char *set_doc, const char *show_doc,
const char *help_doc,
- cmd_const_sfunc_ftype *set_func,
+ cmd_func_ftype *set_func,
show_value_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
- struct cmd_list_element *set_result;
+ set_show_commands commands
+ = add_setshow_cmd_full<std::string> (name, theclass, var_filename, var,
+ set_doc, show_doc, help_doc,
+ nullptr, nullptr, set_func,
+ show_func, set_list, show_list);
+
+ set_cmd_completer (commands.set, filename_completer);
- add_setshow_cmd_full (name, theclass, var_filename, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list,
- &set_result, NULL);
- set_cmd_completer (set_result, filename_completer);
+ return commands;
+}
+
+/* Same as above but using a getter and a setter function instead of a pointer
+ to a global storage buffer. */
+
+set_show_commands
+add_setshow_filename_cmd (const char *name, command_class theclass,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ setting_func_types<std::string>::set set_func,
+ setting_func_types<std::string>::get get_func,
+ show_value_ftype *show_func,
+ cmd_list_element **set_list,
+ cmd_list_element **show_list)
+{
+ auto cmds = add_setshow_cmd_full<std::string> (name, theclass, var_filename,
+ nullptr, set_doc, show_doc,
+ help_doc, set_func, get_func,
+ nullptr, show_func, set_list,
+ show_list);
+
+ set_cmd_completer (cmds.set, filename_completer);
+
+ return cmds;
}
/* Add element named NAME to both the set and show command LISTs (the
list for set/show or some sublist thereof). */
-void
+
+set_show_commands
add_setshow_string_cmd (const char *name, enum command_class theclass,
- char **var,
+ std::string *var,
const char *set_doc, const char *show_doc,
const char *help_doc,
- cmd_const_sfunc_ftype *set_func,
+ cmd_func_ftype *set_func,
show_value_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
- cmd_list_element *set_cmd;
+ set_show_commands commands
+ = add_setshow_cmd_full<std::string> (name, theclass, var_string, var,
+ set_doc, show_doc, help_doc,
+ nullptr, nullptr, set_func,
+ show_func, set_list, show_list);
+
+ /* Disable the default symbol completer. */
+ set_cmd_completer (commands.set, nullptr);
- add_setshow_cmd_full (name, theclass, var_string, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list,
- &set_cmd, NULL);
+ return commands;
+}
+
+/* Same as above but using a getter and a setter function instead of a pointer
+ to a global storage buffer. */
+
+set_show_commands
+add_setshow_string_cmd (const char *name, command_class theclass,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ setting_func_types<std::string>::set set_func,
+ setting_func_types<std::string>::get get_func,
+ show_value_ftype *show_func,
+ cmd_list_element **set_list,
+ cmd_list_element **show_list)
+{
+ auto cmds = add_setshow_cmd_full<std::string> (name, theclass, var_string,
+ nullptr, set_doc, show_doc,
+ help_doc, set_func, get_func,
+ nullptr, show_func, set_list,
+ show_list);
/* Disable the default symbol completer. */
- set_cmd_completer (set_cmd, nullptr);
+ set_cmd_completer (cmds.set, nullptr);
+
+ return cmds;
}
/* Add element named NAME to both the set and show command LISTs (the
list for set/show or some sublist thereof). */
-struct cmd_list_element *
+
+set_show_commands
add_setshow_string_noescape_cmd (const char *name, enum command_class theclass,
- char **var,
+ std::string *var,
const char *set_doc, const char *show_doc,
const char *help_doc,
- cmd_const_sfunc_ftype *set_func,
+ cmd_func_ftype *set_func,
show_value_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
- struct cmd_list_element *set_cmd;
+ set_show_commands commands
+ = add_setshow_cmd_full<std::string> (name, theclass, var_string_noescape,
+ var, set_doc, show_doc, help_doc,
+ nullptr, nullptr, set_func, show_func,
+ set_list, show_list);
+
+ /* Disable the default symbol completer. */
+ set_cmd_completer (commands.set, nullptr);
+
+ return commands;
+}
- add_setshow_cmd_full (name, theclass, var_string_noescape, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list,
- &set_cmd, NULL);
+/* Same as above but using a getter and a setter function instead of a pointer
+ to a global storage buffer. */
+
+set_show_commands
+add_setshow_string_noescape_cmd (const char *name, command_class theclass,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ setting_func_types<std::string>::set set_func,
+ setting_func_types<std::string>::get get_func,
+ show_value_ftype *show_func,
+ cmd_list_element **set_list,
+ cmd_list_element **show_list)
+{
+ auto cmds = add_setshow_cmd_full<std::string> (name, theclass,
+ var_string_noescape, nullptr,
+ set_doc, show_doc, help_doc,
+ set_func, get_func,
+ nullptr, show_func, set_list,
+ show_list);
/* Disable the default symbol completer. */
- set_cmd_completer (set_cmd, nullptr);
+ set_cmd_completer (cmds.set, nullptr);
- return set_cmd;
+ return cmds;
}
/* Add element named NAME to both the set and show command LISTs (the
list for set/show or some sublist thereof). */
-void
+
+set_show_commands
add_setshow_optional_filename_cmd (const char *name, enum command_class theclass,
- char **var,
+ std::string *var,
const char *set_doc, const char *show_doc,
const char *help_doc,
- cmd_const_sfunc_ftype *set_func,
+ cmd_func_ftype *set_func,
show_value_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
- struct cmd_list_element *set_result;
-
- add_setshow_cmd_full (name, theclass, var_optional_filename, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list,
- &set_result, NULL);
-
- set_cmd_completer (set_result, filename_completer);
+ set_show_commands commands
+ = add_setshow_cmd_full<std::string> (name, theclass, var_optional_filename,
+ var, set_doc, show_doc, help_doc,
+ nullptr, nullptr, set_func, show_func,
+ set_list, show_list);
+
+ set_cmd_completer (commands.set, filename_completer);
+
+ return commands;
+}
+
+/* Same as above but using a getter and a setter function instead of a pointer
+ to a global storage buffer. */
+
+set_show_commands
+add_setshow_optional_filename_cmd (const char *name, command_class theclass,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ setting_func_types<std::string>::set set_func,
+ setting_func_types<std::string>::get get_func,
+ show_value_ftype *show_func,
+ cmd_list_element **set_list,
+ cmd_list_element **show_list)
+{
+ auto cmds =
+ add_setshow_cmd_full<std::string> (name, theclass, var_optional_filename,
+ nullptr, set_doc, show_doc, help_doc,
+ set_func, get_func, nullptr, show_func,
+ set_list,show_list);
+
+ set_cmd_completer (cmds.set, filename_completer);
+ return cmds;
}
/* Completes on literal "unlimited". Used by integer commands that
NULL,
};
+ if (*text == '\0')
+ tracker.add_completion (make_unique_xstrdup ("NUMBER"));
complete_on_enum (tracker, keywords, text, word);
}
add_cmd. VAR is address of the variable which will contain the
value. SET_DOC and SHOW_DOC are the documentation strings. This
function is only used in Python API. Please don't use it elsewhere. */
-void
+
+set_show_commands
add_setshow_integer_cmd (const char *name, enum command_class theclass,
int *var,
const char *set_doc, const char *show_doc,
const char *help_doc,
- cmd_const_sfunc_ftype *set_func,
+ cmd_func_ftype *set_func,
show_value_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
- struct cmd_list_element *set;
+ set_show_commands commands
+ = add_setshow_cmd_full<int> (name, theclass, var_integer, var,
+ set_doc, show_doc, help_doc,
+ nullptr, nullptr, set_func,
+ show_func, set_list, show_list);
+
+ set_cmd_completer (commands.set, integer_unlimited_completer);
+
+ return commands;
+}
+
+/* Same as above but using a getter and a setter function instead of a pointer
+ to a global storage buffer. */
- add_setshow_cmd_full (name, theclass, var_integer, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list,
- &set, NULL);
+set_show_commands
+add_setshow_integer_cmd (const char *name, command_class theclass,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ setting_func_types<int>::set set_func,
+ setting_func_types<int>::get get_func,
+ show_value_ftype *show_func,
+ cmd_list_element **set_list,
+ cmd_list_element **show_list)
+{
+ auto cmds = add_setshow_cmd_full<int> (name, theclass, var_integer, nullptr,
+ set_doc, show_doc, help_doc, set_func,
+ get_func, nullptr, show_func, set_list,
+ show_list);
+
+ set_cmd_completer (cmds.set, integer_unlimited_completer);
- set_cmd_completer (set, integer_unlimited_completer);
+ return cmds;
}
/* Add element named NAME to both the set and show command LISTs (the
list for set/show or some sublist thereof). CLASS is as in
add_cmd. VAR is address of the variable which will contain the
value. SET_DOC and SHOW_DOC are the documentation strings. */
-void
+
+set_show_commands
add_setshow_uinteger_cmd (const char *name, enum command_class theclass,
unsigned int *var,
const char *set_doc, const char *show_doc,
const char *help_doc,
- cmd_const_sfunc_ftype *set_func,
+ cmd_func_ftype *set_func,
show_value_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
- struct cmd_list_element *set;
+ set_show_commands commands
+ = add_setshow_cmd_full<unsigned int> (name, theclass, var_uinteger, var,
+ set_doc, show_doc, help_doc,
+ nullptr, nullptr, set_func,
+ show_func, set_list, show_list);
- add_setshow_cmd_full (name, theclass, var_uinteger, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list,
- &set, NULL);
+ set_cmd_completer (commands.set, integer_unlimited_completer);
- set_cmd_completer (set, integer_unlimited_completer);
+ return commands;
+}
+
+/* Same as above but using a getter and a setter function instead of a pointer
+ to a global storage buffer. */
+
+set_show_commands
+add_setshow_uinteger_cmd (const char *name, command_class theclass,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ setting_func_types<unsigned int>::set set_func,
+ setting_func_types<unsigned int>::get get_func,
+ show_value_ftype *show_func,
+ cmd_list_element **set_list,
+ cmd_list_element **show_list)
+{
+ auto cmds = add_setshow_cmd_full<unsigned int> (name, theclass, var_uinteger,
+ nullptr, set_doc, show_doc,
+ help_doc, set_func, get_func,
+ nullptr, show_func, set_list,
+ show_list);
+
+ set_cmd_completer (cmds.set, integer_unlimited_completer);
+
+ return cmds;
}
/* Add element named NAME to both the set and show command LISTs (the
list for set/show or some sublist thereof). CLASS is as in
add_cmd. VAR is address of the variable which will contain the
value. SET_DOC and SHOW_DOC are the documentation strings. */
-void
+
+set_show_commands
add_setshow_zinteger_cmd (const char *name, enum command_class theclass,
int *var,
const char *set_doc, const char *show_doc,
const char *help_doc,
- cmd_const_sfunc_ftype *set_func,
+ cmd_func_ftype *set_func,
show_value_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
- add_setshow_cmd_full (name, theclass, var_zinteger, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list,
- NULL, NULL);
+ return add_setshow_cmd_full<int> (name, theclass, var_zinteger, var,
+ set_doc, show_doc, help_doc,
+ nullptr, nullptr, set_func,
+ show_func, set_list, show_list);
}
-void
+/* Same as above but using a getter and a setter function instead of a pointer
+ to a global storage buffer. */
+
+set_show_commands
+add_setshow_zinteger_cmd (const char *name, command_class theclass,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ setting_func_types<int>::set set_func,
+ setting_func_types<int>::get get_func,
+ show_value_ftype *show_func,
+ cmd_list_element **set_list,
+ cmd_list_element **show_list)
+{
+ return add_setshow_cmd_full<int> (name, theclass, var_zinteger, nullptr,
+ set_doc, show_doc, help_doc, set_func,
+ get_func, nullptr, show_func, set_list,
+ show_list);
+}
+
+set_show_commands
add_setshow_zuinteger_unlimited_cmd (const char *name,
enum command_class theclass,
int *var,
const char *set_doc,
const char *show_doc,
const char *help_doc,
- cmd_const_sfunc_ftype *set_func,
+ cmd_func_ftype *set_func,
show_value_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
- struct cmd_list_element *set;
+ set_show_commands commands
+ = add_setshow_cmd_full<int> (name, theclass, var_zuinteger_unlimited, var,
+ set_doc, show_doc, help_doc, nullptr,
+ nullptr, set_func, show_func, set_list,
+ show_list);
- add_setshow_cmd_full (name, theclass, var_zuinteger_unlimited, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list,
- &set, NULL);
+ set_cmd_completer (commands.set, integer_unlimited_completer);
- set_cmd_completer (set, integer_unlimited_completer);
+ return commands;
+}
+
+/* Same as above but using a getter and a setter function instead of a pointer
+ to a global storage buffer. */
+
+set_show_commands
+add_setshow_zuinteger_unlimited_cmd (const char *name, command_class theclass,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ setting_func_types<int>::set set_func,
+ setting_func_types<int>::get get_func,
+ show_value_ftype *show_func,
+ cmd_list_element **set_list,
+ cmd_list_element **show_list)
+{
+ auto cmds
+ = add_setshow_cmd_full<int> (name, theclass, var_zuinteger_unlimited,
+ nullptr, set_doc, show_doc, help_doc, set_func,
+ get_func, nullptr, show_func, set_list,
+ show_list);
+
+ set_cmd_completer (cmds.set, integer_unlimited_completer);
+
+ return cmds;
}
/* Add element named NAME to both the set and show command LISTs (the
list for set/show or some sublist thereof). CLASS is as in
add_cmd. VAR is address of the variable which will contain the
value. SET_DOC and SHOW_DOC are the documentation strings. */
-void
+
+set_show_commands
add_setshow_zuinteger_cmd (const char *name, enum command_class theclass,
unsigned int *var,
const char *set_doc, const char *show_doc,
const char *help_doc,
- cmd_const_sfunc_ftype *set_func,
+ cmd_func_ftype *set_func,
show_value_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
- add_setshow_cmd_full (name, theclass, var_zuinteger, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list,
- NULL, NULL);
+ return add_setshow_cmd_full<unsigned int> (name, theclass, var_zuinteger,
+ var, set_doc, show_doc, help_doc,
+ nullptr, nullptr, set_func,
+ show_func, set_list, show_list);
}
-/* Remove the command named NAME from the command list. Return the
- list commands which were aliased to the deleted command. If the
- command had no aliases, return NULL. The various *HOOKs are set to
- the pre- and post-hook commands for the deleted command. If the
- command does not have a hook, the corresponding out parameter is
- set to NULL. */
+/* Same as above but using a getter and a setter function instead of a pointer
+ to a global storage buffer. */
-static struct cmd_list_element *
+set_show_commands
+add_setshow_zuinteger_cmd (const char *name, command_class theclass,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ setting_func_types<unsigned int>::set set_func,
+ setting_func_types<unsigned int>::get get_func,
+ show_value_ftype *show_func,
+ cmd_list_element **set_list,
+ cmd_list_element **show_list)
+{
+ return add_setshow_cmd_full<unsigned int> (name, theclass, var_zuinteger,
+ nullptr, set_doc, show_doc,
+ help_doc, set_func, get_func,
+ nullptr, show_func, set_list,
+ show_list);
+}
+
+/* Remove the command named NAME from the command list. Return the list
+ commands which were aliased to the deleted command. The various *HOOKs are
+ set to the pre- and post-hook commands for the deleted command. If the
+ command does not have a hook, the corresponding out parameter is set to
+ NULL. */
+
+static cmd_list_element::aliases_list_type
delete_cmd (const char *name, struct cmd_list_element **list,
struct cmd_list_element **prehook,
struct cmd_list_element **prehookee,
{
struct cmd_list_element *iter;
struct cmd_list_element **previous_chain_ptr;
- struct cmd_list_element *aliases = NULL;
+ cmd_list_element::aliases_list_type aliases;
*prehook = NULL;
*prehookee = NULL;
if (strcmp (iter->name, name) == 0)
{
if (iter->destroyer)
- iter->destroyer (iter, iter->context);
+ iter->destroyer (iter, iter->context ());
+
if (iter->hookee_pre)
iter->hookee_pre->hook_pre = 0;
*prehook = iter->hook_pre;
/* Update the link. */
*previous_chain_ptr = iter->next;
- aliases = iter->aliases;
+ aliases = std::move (iter->aliases);
/* If this command was an alias, remove it from the list of
aliases. */
- if (iter->cmd_pointer)
+ if (iter->is_alias ())
{
- struct cmd_list_element **prevp = &iter->cmd_pointer->aliases;
- struct cmd_list_element *a = *prevp;
-
- while (a != iter)
- {
- prevp = &a->alias_chain;
- a = *prevp;
- }
- *prevp = iter->alias_chain;
+ auto it = iter->alias_target->aliases.iterator_to (*iter);
+ iter->alias_target->aliases.erase (it);
}
delete iter;
/* Add an element to the list of info subcommands. */
struct cmd_list_element *
-add_info (const char *name, cmd_const_cfunc_ftype *fun, const char *doc)
+add_info (const char *name, cmd_simple_func_ftype *fun, const char *doc)
{
return add_cmd (name, class_info, fun, doc, &infolist);
}
/* Add an alias to the list of info subcommands. */
-struct cmd_list_element *
-add_info_alias (const char *name, const char *oldname, int abbrev_flag)
+cmd_list_element *
+add_info_alias (const char *name, cmd_list_element *target, int abbrev_flag)
{
- return add_alias_cmd (name, oldname, class_run, abbrev_flag, &infolist);
+ return add_alias_cmd (name, target, class_run, abbrev_flag, &infolist);
}
/* Add an element to the list of commands. */
struct cmd_list_element *
add_com (const char *name, enum command_class theclass,
- cmd_const_cfunc_ftype *fun,
+ cmd_simple_func_ftype *fun,
const char *doc)
{
return add_cmd (name, theclass, fun, doc, &cmdlist);
different of class_alias, as class_alias is used to identify
user defined aliases. */
-struct cmd_list_element *
-add_com_alias (const char *name, const char *oldname, enum command_class theclass,
- int abbrev_flag)
+cmd_list_element *
+add_com_alias (const char *name, cmd_list_element *target,
+ command_class theclass, int abbrev_flag)
{
- return add_alias_cmd (name, oldname, theclass, abbrev_flag, &cmdlist);
+ return add_alias_cmd (name, target, theclass, abbrev_flag, &cmdlist);
}
/* Add an element with a suppress notification to the list of commands. */
struct cmd_list_element *
add_com_suppress_notification (const char *name, enum command_class theclass,
- cmd_const_cfunc_ftype *fun, const char *doc,
- int *suppress_notification)
+ cmd_simple_func_ftype *fun, const char *doc,
+ bool *suppress_notification)
{
return add_cmd_suppress_notification (name, theclass, fun, doc,
&cmdlist, suppress_notification);
/* Print the prefix of C followed by name of C in title style. */
static void
-fput_command_name_styled (struct cmd_list_element *c, struct ui_file *stream)
+fput_command_name_styled (const cmd_list_element &c, struct ui_file *stream)
{
- const char *prefixname
- = c->prefix == nullptr ? "" : c->prefix->prefixname;
+ std::string prefixname
+ = c.prefix == nullptr ? "" : c.prefix->prefixname ();
+
+ fprintf_styled (stream, title_style.style (), "%s%s",
+ prefixname.c_str (), c.name);
+}
- fprintf_styled (stream, title_style.style (), "%s%s", prefixname, c->name);
+/* True if ALIAS has a user-defined documentation. */
+
+static bool
+user_documented_alias (const cmd_list_element &alias)
+{
+ gdb_assert (alias.is_alias ());
+ /* Alias is user documented if it has an allocated documentation
+ that differs from the aliased command. */
+ return (alias.doc_allocated
+ && strcmp (alias.doc, alias.alias_target->doc) != 0);
}
/* Print the definition of alias C using title style for alias
and aliased command. */
static void
-fput_alias_definition_styled (struct cmd_list_element *c,
+fput_alias_definition_styled (const cmd_list_element &c,
struct ui_file *stream)
{
- gdb_assert (c->cmd_pointer != nullptr);
- fputs_filtered (" alias ", stream);
+ gdb_assert (c.is_alias ());
+ gdb_puts (" alias ", stream);
fput_command_name_styled (c, stream);
- fprintf_filtered (stream, " = ");
- fput_command_name_styled (c->cmd_pointer, stream);
- fprintf_filtered (stream, " %s\n", c->default_args.c_str ());
+ gdb_printf (stream, " = ");
+ fput_command_name_styled (*c.alias_target, stream);
+ gdb_printf (stream, " %s\n", c.default_args.c_str ());
}
-/* Print the definition of the aliases of CMD that have default args. */
+/* Print the definition of CMD aliases not deprecated and having default args
+ and not specifically documented by the user. */
static void
-fput_aliases_definition_styled (struct cmd_list_element *cmd,
+fput_aliases_definition_styled (const cmd_list_element &cmd,
struct ui_file *stream)
{
- if (cmd->aliases != nullptr)
- {
- for (cmd_list_element *iter = cmd->aliases;
- iter;
- iter = iter->alias_chain)
- {
- if (!iter->default_args.empty ())
- fput_alias_definition_styled (iter, stream);
- }
- }
+ for (const cmd_list_element &alias : cmd.aliases)
+ if (!alias.cmd_deprecated
+ && !user_documented_alias (alias)
+ && !alias.default_args.empty ())
+ fput_alias_definition_styled (alias, stream);
}
-
-/* If C has one or more aliases, style print the name of C and
- the name of its aliases, separated by commas.
+/* If C has one or more aliases, style print the name of C and the name of its
+ aliases not documented specifically by the user, separated by commas.
If ALWAYS_FPUT_C_NAME, print the name of C even if it has no aliases.
If one or more names are printed, POSTFIX is printed after the last name.
*/
static void
-fput_command_names_styled (struct cmd_list_element *c,
+fput_command_names_styled (const cmd_list_element &c,
bool always_fput_c_name, const char *postfix,
struct ui_file *stream)
{
- if (always_fput_c_name || c->aliases != nullptr)
+ /* First, check if we are going to print something. That is, either if
+ ALWAYS_FPUT_C_NAME is true or if there exists at least one non-deprecated
+ alias not documented specifically by the user. */
+
+ auto print_alias = [] (const cmd_list_element &alias)
+ {
+ return !alias.cmd_deprecated && !user_documented_alias (alias);
+ };
+
+ bool print_something = always_fput_c_name;
+ if (!print_something)
+ for (const cmd_list_element &alias : c.aliases)
+ {
+ if (!print_alias (alias))
+ continue;
+
+ print_something = true;
+ break;
+ }
+
+ if (print_something)
fput_command_name_styled (c, stream);
- if (c->aliases != nullptr)
+
+ for (const cmd_list_element &alias : c.aliases)
{
- for (cmd_list_element *iter = c->aliases; iter; iter = iter->alias_chain)
- {
- fputs_filtered (", ", stream);
- wrap_here (" ");
- fput_command_name_styled (iter, stream);
- }
+ if (!print_alias (alias))
+ continue;
+
+ gdb_puts (", ", stream);
+ stream->wrap_here (3);
+ fput_command_name_styled (alias, stream);
}
- if (always_fput_c_name || c->aliases != nullptr)
- fputs_filtered (postfix, stream);
+
+ if (print_something)
+ gdb_puts (postfix, stream);
}
/* If VERBOSE, print the full help for command C and highlight the
otherwise print only one-line help for command C. */
static void
-print_doc_of_command (struct cmd_list_element *c, const char *prefix,
+print_doc_of_command (const cmd_list_element &c, const char *prefix,
bool verbose, compiled_regex &highlight,
struct ui_file *stream)
{
this documentation from the previous command help, in the likely
case that apropos finds several commands. */
if (verbose)
- fputs_filtered ("\n", stream);
+ gdb_puts ("\n", stream);
fput_command_names_styled (c, true,
verbose ? "" : " -- ", stream);
if (verbose)
{
- fputs_filtered ("\n", stream);
+ gdb_puts ("\n", stream);
fput_aliases_definition_styled (c, stream);
- fputs_highlighted (c->doc, highlight, stream);
- fputs_filtered ("\n", stream);
+ fputs_highlighted (c.doc, highlight, stream);
+ gdb_puts ("\n", stream);
}
else
{
- print_doc_line (stream, c->doc, false);
- fputs_filtered ("\n", stream);
+ print_doc_line (stream, c.doc, false);
+ gdb_puts ("\n", stream);
fput_aliases_definition_styled (c, stream);
}
}
/* Walk through the commands. */
for (c=commandlist;c;c=c->next)
{
- if (c->cmd_pointer != nullptr)
+ if (c->is_alias () && !user_documented_alias (*c))
{
- /* Command aliases/abbreviations are skipped to ensure we print the
- doc of a command only once, when encountering the aliased
- command. */
+ /* Command aliases/abbreviations not specifically documented by the
+ user are skipped to ensure we print the doc of a command only once,
+ when encountering the aliased command. */
continue;
}
/* Try to match against the name. */
returnvalue = regex.search (c->name, name_len, 0, name_len, NULL);
if (returnvalue >= 0)
- print_doc_of_command (c, prefix, verbose, regex, stream);
+ print_doc_of_command (*c, prefix, verbose, regex, stream);
/* Try to match against the name of the aliases. */
- for (cmd_list_element *iter = c->aliases;
- returnvalue < 0 && iter;
- iter = iter->alias_chain)
+ for (const cmd_list_element &alias : c->aliases)
{
- name_len = strlen (iter->name);
- returnvalue = regex.search (iter->name, name_len, 0, name_len, NULL);
+ name_len = strlen (alias.name);
+ returnvalue = regex.search (alias.name, name_len, 0, name_len, NULL);
if (returnvalue >= 0)
- print_doc_of_command (c, prefix, verbose, regex, stream);
+ {
+ print_doc_of_command (*c, prefix, verbose, regex, stream);
+ break;
+ }
}
}
if (c->doc != NULL && returnvalue < 0)
/* Try to match against documentation. */
if (regex.search (c->doc, doc_len, 0, doc_len, NULL) >= 0)
- print_doc_of_command (c, prefix, verbose, regex, stream);
+ print_doc_of_command (*c, prefix, verbose, regex, stream);
}
/* Check if this command has subcommands. */
- if (c->prefixlist != NULL)
+ if (c->is_prefix ())
{
/* Recursively call ourselves on the subcommand list,
passing the right prefix in. */
- apropos_cmd (stream, *c->prefixlist, verbose, regex, c->prefixname);
+ apropos_cmd (stream, *c->subcommands, verbose, regex,
+ c->prefixname ().c_str ());
}
}
}
lookup_cmd_composition (orig_command, &alias, &prefix_cmd, &c_cmd);
/* There are three cases here.
- If c->prefixlist is nonzero, we have a prefix command.
+ If c->subcommands is nonzero, we have a prefix command.
Print its documentation, then list its subcommands.
If c->func is non NULL, we really have a command. Print its
number of this class so that the commands in the class will be
listed. */
- /* If the user asked 'help somecommand' and there is no alias,
- the false indicates to not output the (single) command name. */
- fput_command_names_styled (c, false, "\n", stream);
- fput_aliases_definition_styled (c, stream);
- fputs_filtered (c->doc, stream);
- fputs_filtered ("\n", stream);
+ if (alias == nullptr || !user_documented_alias (*alias))
+ {
+ /* Case of a normal command, or an alias not explictly
+ documented by the user. */
+ /* If the user asked 'help somecommand' and there is no alias,
+ the false indicates to not output the (single) command name. */
+ fput_command_names_styled (*c, false, "\n", stream);
+ fput_aliases_definition_styled (*c, stream);
+ gdb_puts (c->doc, stream);
+ }
+ else
+ {
+ /* Case of an alias explictly documented by the user.
+ Only output the alias definition and its explicit documentation. */
+ fput_alias_definition_styled (*alias, stream);
+ fput_command_names_styled (*alias, false, "\n", stream);
+ gdb_puts (alias->doc, stream);
+ }
+ gdb_puts ("\n", stream);
- if (c->prefixlist == 0 && c->func != NULL)
+ if (!c->is_prefix () && !c->is_command_class_help ())
return;
- fprintf_filtered (stream, "\n");
+
+ gdb_printf (stream, "\n");
/* If this is a prefix command, print it's subcommands. */
- if (c->prefixlist)
- help_list (*c->prefixlist, c->prefixname, all_commands, stream);
+ if (c->is_prefix ())
+ help_list (*c->subcommands, c->prefixname ().c_str (),
+ all_commands, stream);
/* If this is a class name, print all of the commands in the class. */
- if (c->func == NULL)
+ if (c->is_command_class_help ())
help_list (cmdlist, "", c->theclass, stream);
if (c->hook_pre || c->hook_post)
- fprintf_filtered (stream,
- "\nThis command has a hook (or hooks) defined:\n");
+ gdb_printf (stream,
+ "\nThis command has a hook (or hooks) defined:\n");
if (c->hook_pre)
- fprintf_filtered (stream,
- "\tThis command is run after : %s (pre hook)\n",
- c->hook_pre->name);
+ gdb_printf (stream,
+ "\tThis command is run after : %s (pre hook)\n",
+ c->hook_pre->name);
if (c->hook_post)
- fprintf_filtered (stream,
- "\tThis command is run before : %s (post hook)\n",
- c->hook_post->name);
+ gdb_printf (stream,
+ "\tThis command is run before : %s (post hook)\n",
+ c->hook_post->name);
}
/*
}
if (theclass == all_classes)
- fprintf_filtered (stream, "List of classes of %scommands:\n\n", cmdtype2);
+ gdb_printf (stream, "List of classes of %scommands:\n\n", cmdtype2);
else
- fprintf_filtered (stream, "List of %scommands:\n\n", cmdtype2);
+ gdb_printf (stream, "List of %scommands:\n\n", cmdtype2);
help_cmd_list (list, theclass, theclass >= 0, stream);
if (theclass == all_classes)
{
- fprintf_filtered (stream, "\n\
+ gdb_printf (stream, "\n\
Type \"help%s\" followed by a class name for a list of commands in ",
- cmdtype1);
- wrap_here ("");
- fprintf_filtered (stream, "that class.");
+ cmdtype1);
+ stream->wrap_here (0);
+ gdb_printf (stream, "that class.");
- fprintf_filtered (stream, "\n\
+ gdb_printf (stream, "\n\
Type \"help all\" for the list of all commands.");
}
- fprintf_filtered (stream, "\nType \"help%s\" followed by %scommand name ",
- cmdtype1, cmdtype2);
- wrap_here ("");
- fputs_filtered ("for ", stream);
- wrap_here ("");
- fputs_filtered ("full ", stream);
- wrap_here ("");
- fputs_filtered ("documentation.\n", stream);
- fputs_filtered ("Type \"apropos word\" to search "
- "for commands related to \"word\".\n", stream);
- fputs_filtered ("Type \"apropos -v word\" for full documentation", stream);
- wrap_here ("");
- fputs_filtered (" of commands related to \"word\".\n", stream);
- fputs_filtered ("Command name abbreviations are allowed if unambiguous.\n",
- stream);
+ gdb_printf (stream, "\nType \"help%s\" followed by %scommand name ",
+ cmdtype1, cmdtype2);
+ stream->wrap_here (0);
+ gdb_puts ("for ", stream);
+ stream->wrap_here (0);
+ gdb_puts ("full ", stream);
+ stream->wrap_here (0);
+ gdb_puts ("documentation.\n", stream);
+ gdb_puts ("Type \"apropos word\" to search "
+ "for commands related to \"word\".\n", stream);
+ gdb_puts ("Type \"apropos -v word\" for full documentation", stream);
+ stream->wrap_here (0);
+ gdb_puts (" of commands related to \"word\".\n", stream);
+ gdb_puts ("Command name abbreviations are allowed if unambiguous.\n",
+ stream);
}
static void
for (c = cmdlist; c; c = c->next)
{
if (c->abbrev_flag)
- continue;
+ continue;
/* If this is a class name, print all of the commands in the
class. */
- if (c->func == NULL)
+ if (c->is_command_class_help ())
{
- fprintf_filtered (stream, "\nCommand class: %s\n\n", c->name);
+ gdb_printf (stream, "\nCommand class: %s\n\n", c->name);
help_cmd_list (cmdlist, c->theclass, true, stream);
}
}
for (c = cmdlist; c; c = c->next)
{
if (c->abbrev_flag)
- continue;
+ continue;
if (c->theclass == no_class)
{
if (!seen_unclassified)
{
- fprintf_filtered (stream, "\nUnclassified commands\n\n");
+ gdb_printf (stream, "\nUnclassified commands\n\n");
seen_unclassified = 1;
}
- print_help_for_command (c, true, stream);
+ print_help_for_command (*c, true, stream);
}
}
}
else
line_buffer[p - str] = '\0';
- fputs_filtered (line_buffer, stream);
+ gdb_puts (line_buffer, stream);
}
/* Print one-line help for command C.
If RECURSE is non-zero, also print one-line descriptions
of all prefixed subcommands. */
static void
-print_help_for_command (struct cmd_list_element *c,
+print_help_for_command (const cmd_list_element &c,
bool recurse, struct ui_file *stream)
{
fput_command_names_styled (c, true, " -- ", stream);
- print_doc_line (stream, c->doc, false);
- fputs_filtered ("\n", stream);
- if (!c->default_args.empty ())
+ print_doc_line (stream, c.doc, false);
+ gdb_puts ("\n", stream);
+ if (!c.default_args.empty ())
fput_alias_definition_styled (c, stream);
fput_aliases_definition_styled (c, stream);
if (recurse
- && c->prefixlist != 0
- && c->abbrev_flag == 0)
+ && c.is_prefix ()
+ && c.abbrev_flag == 0)
/* Subcommands of a prefix command typically have 'all_commands'
as class. If we pass CLASS to recursive invocation,
most often we won't see anything. */
- help_cmd_list (*c->prefixlist, all_commands, true, stream);
+ help_cmd_list (*c.subcommands, all_commands, true, stream);
}
/*
continue;
}
- if (c->cmd_pointer != nullptr && theclass != class_alias)
+ if (c->is_alias () && theclass != class_alias)
{
/* Do not show an alias, unless specifically showing the
list of aliases: for all other classes, an alias is
}
if (theclass == all_commands
- || (theclass == all_classes && c->func == NULL)
- || (theclass == c->theclass && c->func != NULL))
+ || (theclass == all_classes && c->is_command_class_help ())
+ || (theclass == c->theclass && !c->is_command_class_help ()))
{
/* show C when
- - showing all commands
+ - showing all commands
- showing all classes and C is a help class
- showing commands of THECLASS and C is not the help class */
as this would show the (possibly very long) not very useful
list of sub-commands of the aliased command. */
print_help_for_command
- (c,
- recurse && (theclass != class_alias || c->cmd_pointer == nullptr),
+ (*c,
+ recurse && (theclass != class_alias || !c->is_alias ()),
stream);
continue;
}
if (recurse
&& (theclass == class_user || theclass == class_alias)
- && c->prefixlist != NULL)
+ && c->is_prefix ())
{
/* User-defined commands or aliases may be subcommands. */
- help_cmd_list (*c->prefixlist, theclass, recurse, stream);
+ help_cmd_list (*c->subcommands, theclass, recurse, stream);
continue;
}
*nfound = 0;
for (c = clist; c; c = c->next)
if (!strncmp (command, c->name, len)
- && (!ignore_help_classes || c->func))
+ && (!ignore_help_classes || !c->is_command_class_help ()))
{
found = c;
(*nfound)++;
return true;
}
-/* This routine takes a line of TEXT and a CLIST in which to start the
- lookup. When it returns it will have incremented the text pointer past
- the section of text it matched, set *RESULT_LIST to point to the list in
- which the last word was matched, and will return a pointer to the cmd
- list element which the text matches. It will return NULL if no match at
- all was possible. It will return -1 (cast appropriately, ick) if ambigous
- matches are possible; in this case *RESULT_LIST will be set to point to
- the list in which there are ambiguous choices (and *TEXT will be set to
- the ambiguous text string).
-
- if DEFAULT_ARGS is not null, *DEFAULT_ARGS is set to the found command
- default args (possibly empty).
-
- If the located command was an abbreviation, this routine returns the base
- command of the abbreviation. Note that *DEFAULT_ARGS will contain the
- default args defined for the alias.
-
- It does no error reporting whatsoever; control will always return
- to the superior routine.
-
- In the case of an ambiguous return (-1), *RESULT_LIST will be set to point
- at the prefix_command (ie. the best match) *or* (special case) will be NULL
- if no prefix command was ever found. For example, in the case of "info a",
- "info" matches without ambiguity, but "a" could be "args" or "address", so
- *RESULT_LIST is set to the cmd_list_element for "info". So in this case
- RESULT_LIST should not be interpreted as a pointer to the beginning of a
- list; it simply points to a specific command. In the case of an ambiguous
- return *TEXT is advanced past the last non-ambiguous prefix (e.g.
- "info t" can be "info types" or "info target"; upon return *TEXT has been
- advanced past "info ").
-
- If RESULT_LIST is NULL, don't set *RESULT_LIST (but don't otherwise
- affect the operation).
-
- This routine does *not* modify the text pointed to by TEXT.
-
- If IGNORE_HELP_CLASSES is nonzero, ignore any command list elements which
- are actually help classes rather than commands (i.e. the function field of
- the struct cmd_list_element is NULL). */
+/* See command.h. */
struct cmd_list_element *
lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
struct cmd_list_element **result_list, std::string *default_args,
- int ignore_help_classes)
+ int ignore_help_classes, bool lookup_for_completion_p)
{
char *command;
int len, nfound;
*text += len;
- if (found->cmd_pointer)
+ if (found->is_alias ())
{
/* We drop the alias (abbreviation) in favor of the command it
is pointing to. If the alias is deprecated, though, we need to
itself and we will adjust the appropriate DEPRECATED_WARN_USER
flags. */
- if (found->deprecated_warn_user)
- deprecated_cmd_warning (line);
+ if (found->deprecated_warn_user && !lookup_for_completion_p)
+ deprecated_cmd_warning (line, clist);
+
/* Return the default_args of the alias, not the default_args
of the command it is pointing to. */
if (default_args != nullptr)
*default_args = found->default_args;
- found = found->cmd_pointer;
+ found = found->alias_target;
found_alias = true;
}
/* If we found a prefix command, keep looking. */
- if (found->prefixlist)
+ if (found->is_prefix ())
{
- c = lookup_cmd_1 (text, *found->prefixlist, result_list,
- default_args, ignore_help_classes);
+ c = lookup_cmd_1 (text, *found->subcommands, result_list, default_args,
+ ignore_help_classes, lookup_for_completion_p);
if (!c)
{
/* Didn't find anything; this is as far as we got. */
we've found (if an inferior hasn't already set it). */
if (result_list != nullptr)
if (!*result_list)
- /* This used to say *result_list = *found->prefixlist.
- If that was correct, need to modify the documentation
- at the top of this function to clarify what is
- supposed to be going on. */
+ /* This used to say *result_list = *found->subcommands.
+ If that was correct, need to modify the documentation
+ at the top of this function to clarify what is
+ supposed to be going on. */
*result_list = found;
/* For ambiguous commands, do not return any default_args args. */
if (default_args != nullptr)
}
else if (c == CMD_LIST_AMBIGUOUS)
{
- /* Ambigous. Local values should be off prefixlist or called
- values. */
+ /* Ambigous. Local values should be off subcommands or called
+ values. */
int local_allow_unknown = (last_list ? last_list->allow_unknown :
allow_unknown);
- const char *local_cmdtype = last_list ? last_list->prefixname : cmdtype;
+ std::string local_cmdtype
+ = last_list ? last_list->prefixname () : cmdtype;
struct cmd_list_element *local_list =
- (last_list ? *(last_list->prefixlist) : list);
+ (last_list ? *(last_list->subcommands) : list);
if (local_allow_unknown < 0)
{
break;
}
}
- error (_("Ambiguous %scommand \"%s\": %s."), local_cmdtype,
- *line, ambbuf);
+ error (_("Ambiguous %scommand \"%s\": %s."),
+ local_cmdtype.c_str (), *line, ambbuf);
}
}
else
{
if (c->type == set_cmd && **line != '\0' && !isspace (**line))
- error (_("Argument must be preceded by space."));
+ error (_("Argument must be preceded by space."));
/* We've got something. It may still not be what the caller
- wants (if this command *needs* a subcommand). */
+ wants (if this command *needs* a subcommand). */
while (**line == ' ' || **line == '\t')
(*line)++;
- if (c->prefixlist && **line && !c->allow_unknown)
- undef_cmd_error (c->prefixname, *line);
+ if (c->is_prefix () && **line && !c->allow_unknown)
+ undef_cmd_error (c->prefixname ().c_str (), *line);
/* Seems to be what he wants. Return it. */
return c;
return 0;
}
+/* See command.h. */
+
+struct cmd_list_element *
+lookup_cmd_exact (const char *name,
+ struct cmd_list_element *list,
+ bool ignore_help_classes)
+{
+ const char *tem = name;
+ struct cmd_list_element *cmd = lookup_cmd (&tem, list, "", NULL, -1,
+ ignore_help_classes);
+ if (cmd != nullptr && strcmp (name, cmd->name) != 0)
+ cmd = nullptr;
+ return cmd;
+}
+
/* We are here presumably because an alias or command in TEXT is
deprecated and a warning message should be generated. This
function decodes TEXT and potentially generates a warning message
*/
void
-deprecated_cmd_warning (const char *text)
-{
- struct cmd_list_element *alias = NULL;
- struct cmd_list_element *prefix_cmd = NULL;
- struct cmd_list_element *cmd = NULL;
-
- if (!lookup_cmd_composition (text, &alias, &prefix_cmd, &cmd))
- /* Return if text doesn't evaluate to a command. */
- return;
+deprecated_cmd_warning (const char *text, struct cmd_list_element *list)
+{
+ struct cmd_list_element *alias = nullptr;
+ struct cmd_list_element *cmd = nullptr;
+
+ /* Return if text doesn't evaluate to a command. We place this lookup
+ within its own scope so that the PREFIX_CMD local is not visible
+ later in this function. The value returned in PREFIX_CMD is based on
+ the prefix found in TEXT, and is our case this prefix can be missing
+ in some situations (when LIST is not the global CMDLIST).
+
+ It is better for our purposes to use the prefix commands directly from
+ the ALIAS and CMD results. */
+ {
+ struct cmd_list_element *prefix_cmd = nullptr;
+ if (!lookup_cmd_composition_1 (text, &alias, &prefix_cmd, &cmd, list))
+ return;
+ }
- if (!((alias ? alias->deprecated_warn_user : 0)
- || cmd->deprecated_warn_user) )
- /* Return if nothing is deprecated. */
+ /* Return if nothing is deprecated. */
+ if (!((alias != nullptr ? alias->deprecated_warn_user : 0)
+ || cmd->deprecated_warn_user))
return;
-
- printf_filtered ("Warning:");
-
- if (alias && !cmd->cmd_deprecated)
- printf_filtered (" '%s', an alias for the", alias->name);
-
- printf_filtered (" command '");
-
- if (prefix_cmd)
- printf_filtered ("%s", prefix_cmd->prefixname);
-
- printf_filtered ("%s", cmd->name);
-
- if (alias && cmd->cmd_deprecated)
- printf_filtered ("' (%s) is deprecated.\n", alias->name);
- else
- printf_filtered ("' is deprecated.\n");
-
- /* If it is only the alias that is deprecated, we want to indicate
- the new alias, otherwise we'll indicate the new command. */
+ /* Join command prefix (if any) and the command name. */
+ std::string tmp_cmd_str;
+ if (cmd->prefix != nullptr)
+ tmp_cmd_str += cmd->prefix->prefixname ();
+ tmp_cmd_str += std::string (cmd->name);
- if (alias && !cmd->cmd_deprecated)
+ /* Display the appropriate first line, this warns that the thing the user
+ entered is deprecated. */
+ if (alias != nullptr)
{
- if (alias->replacement)
- printf_filtered ("Use '%s'.\n\n", alias->replacement);
+ /* Join the alias prefix (if any) and the alias name. */
+ std::string tmp_alias_str;
+ if (alias->prefix != nullptr)
+ tmp_alias_str += alias->prefix->prefixname ();
+ tmp_alias_str += std::string (alias->name);
+
+ if (cmd->cmd_deprecated)
+ gdb_printf (_("Warning: command '%ps' (%ps) is deprecated.\n"),
+ styled_string (title_style.style (),
+ tmp_cmd_str.c_str ()),
+ styled_string (title_style.style (),
+ tmp_alias_str.c_str ()));
else
- printf_filtered ("No alternative known.\n\n");
- }
- else
- {
- if (cmd->replacement)
- printf_filtered ("Use '%s'.\n\n", cmd->replacement);
- else
- printf_filtered ("No alternative known.\n\n");
+ gdb_printf (_("Warning: '%ps', an alias for the command '%ps', "
+ "is deprecated.\n"),
+ styled_string (title_style.style (),
+ tmp_alias_str.c_str ()),
+ styled_string (title_style.style (),
+ tmp_cmd_str.c_str ()));
}
+ else
+ gdb_printf (_("Warning: command '%ps' is deprecated.\n"),
+ styled_string (title_style.style (),
+ tmp_cmd_str.c_str ()));
+
+ /* Now display a second line indicating what the user should use instead.
+ If it is only the alias that is deprecated, we want to indicate the
+ new alias, otherwise we'll indicate the new command. */
+ const char *replacement;
+ if (alias != nullptr && !cmd->cmd_deprecated)
+ replacement = alias->replacement;
+ else
+ replacement = cmd->replacement;
+ if (replacement != nullptr)
+ gdb_printf (_("Use '%ps'.\n\n"),
+ styled_string (title_style.style (),
+ replacement));
+ else
+ gdb_printf (_("No alternative known.\n\n"));
/* We've warned you, now we'll keep quiet. */
- if (alias)
+ if (alias != nullptr)
alias->deprecated_warn_user = 0;
-
cmd->deprecated_warn_user = 0;
}
-
-/* Look up the contents of TEXT as a command in the command list 'cmdlist'.
+/* Look up the contents of TEXT as a command in the command list CUR_LIST.
Return 1 on success, 0 on failure.
If TEXT refers to an alias, *ALIAS will point to that alias.
exist, they are NULL when we return.
*/
-int
-lookup_cmd_composition (const char *text,
- struct cmd_list_element **alias,
- struct cmd_list_element **prefix_cmd,
- struct cmd_list_element **cmd)
-{
- char *command;
- int len, nfound;
- struct cmd_list_element *cur_list;
- struct cmd_list_element *prev_cmd;
-
- *alias = NULL;
- *prefix_cmd = NULL;
- *cmd = NULL;
- cur_list = cmdlist;
+static int
+lookup_cmd_composition_1 (const char *text,
+ struct cmd_list_element **alias,
+ struct cmd_list_element **prefix_cmd,
+ struct cmd_list_element **cmd,
+ struct cmd_list_element *cur_list)
+{
+ *alias = nullptr;
+ *prefix_cmd = cur_list->prefix;
+ *cmd = nullptr;
text = skip_spaces (text);
+ /* Go through as many command lists as we need to, to find the command
+ TEXT refers to. */
while (1)
{
- /* Go through as many command lists as we need to,
- to find the command TEXT refers to. */
-
- prev_cmd = *cmd;
-
/* Identify the name of the command. */
- len = find_command_name_length (text);
+ int len = find_command_name_length (text);
/* If nothing but whitespace, return. */
if (len == 0)
/* TEXT is the start of the first command word to lookup (and
it's length is LEN). We copy this into a local temporary. */
-
- command = (char *) alloca (len + 1);
- memcpy (command, text, len);
- command[len] = '\0';
+ std::string command (text, len);
/* Look it up. */
- *cmd = 0;
- nfound = 0;
- *cmd = find_cmd (command, len, cur_list, 1, &nfound);
+ int nfound = 0;
+ *cmd = find_cmd (command.c_str (), len, cur_list, 1, &nfound);
- if (*cmd == CMD_LIST_AMBIGUOUS)
- {
- return 0; /* ambiguous */
- }
-
- if (*cmd == NULL)
- return 0; /* nothing found */
+ /* We only handle the case where a single command was found. */
+ if (*cmd == CMD_LIST_AMBIGUOUS || *cmd == nullptr)
+ return 0;
else
{
- if ((*cmd)->cmd_pointer)
+ if ((*cmd)->is_alias ())
{
- /* cmd was actually an alias, we note that an alias was
- used (by assigning *ALIAS) and we set *CMD. */
+ /* If the command was actually an alias, we note that an
+ alias was used (by assigning *ALIAS) and we set *CMD. */
*alias = *cmd;
- *cmd = (*cmd)->cmd_pointer;
+ *cmd = (*cmd)->alias_target;
}
- *prefix_cmd = prev_cmd;
}
text += len;
text = skip_spaces (text);
- if ((*cmd)->prefixlist && *text != '\0')
- cur_list = *(*cmd)->prefixlist;
+ if ((*cmd)->is_prefix () && *text != '\0')
+ {
+ cur_list = *(*cmd)->subcommands;
+ *prefix_cmd = *cmd;
+ }
else
return 1;
}
}
+/* Look up the contents of TEXT as a command in the command list 'cmdlist'.
+ Return 1 on success, 0 on failure.
+
+ If TEXT refers to an alias, *ALIAS will point to that alias.
+
+ If TEXT is a subcommand (i.e. one that is preceded by a prefix
+ command) set *PREFIX_CMD.
+
+ Set *CMD to point to the command TEXT indicates.
+
+ If any of *ALIAS, *PREFIX_CMD, or *CMD cannot be determined or do not
+ exist, they are NULL when we return.
+
+*/
+
+int
+lookup_cmd_composition (const char *text,
+ struct cmd_list_element **alias,
+ struct cmd_list_element **prefix_cmd,
+ struct cmd_list_element **cmd)
+{
+ return lookup_cmd_composition_1 (text, alias, prefix_cmd, cmd, cmdlist);
+}
+
/* Helper function for SYMBOL_COMPLETION_FUNCTION. */
/* Return a vector of char pointers which point to the different
for (ptr = list; ptr; ptr = ptr->next)
if (!strncmp (ptr->name, text, textlen)
&& !ptr->abbrev_flag
- && (!ignore_help_classes || ptr->func
- || ptr->prefixlist))
+ && (!ignore_help_classes || !ptr->is_command_class_help ()
+ || ptr->is_prefix ()))
{
if (pass == 0)
{
tracker.add_completion (make_completion_match_str (name, text, word));
}
-
-/* Check function pointer. */
-int
-cmd_func_p (struct cmd_list_element *cmd)
-{
- return (cmd->func != NULL);
-}
-
-
/* Call the command function. */
void
cmd_func (struct cmd_list_element *cmd, const char *args, int from_tty)
{
- if (cmd_func_p (cmd))
+ if (!cmd->is_command_class_help ())
{
- gdb::optional<scoped_restore_tmpl<int>> restore_suppress;
+ gdb::optional<scoped_restore_tmpl<bool>> restore_suppress;
if (cmd->suppress_notification != NULL)
- restore_suppress.emplace (cmd->suppress_notification, 1);
+ restore_suppress.emplace (cmd->suppress_notification, true);
- (*cmd->func) (cmd, args, from_tty);
+ cmd->func (args, from_tty, cmd);
}
else
error (_("Invalid command"));
int
cli_user_command_p (struct cmd_list_element *cmd)
{
- return (cmd->theclass == class_user
- && (cmd->func == do_const_cfunc || cmd->func == do_sfunc));
+ return cmd->theclass == class_user && cmd->func == do_simple_func;
}