/* GDB CLI commands.
- Copyright (C) 2000-2019 Free Software Foundation, Inc.
+ Copyright (C) 2000-2021 Free Software Foundation, Inc.
This file is part of GDB.
#include "cli/cli-cmds.h"
#include "cli/cli-style.h"
#include "cli/cli-utils.h"
+#include "cli/cli-style.h"
#include "extension.h"
#include "gdbsupport/pathstuff.h"
struct cmd_list_element *maintenancechecklist;
+/* Chain containing all defined "maintenance flush" subcommands. */
+
+struct cmd_list_element *maintenanceflushlist;
+
struct cmd_list_element *setprintlist;
struct cmd_list_element *showprintlist;
error (_("Argument required (%s)."), why);
}
-/* The "info" command is defined as a prefix, with allow_unknown = 0.
- Therefore, its own definition is called only for "info" with no
- args. */
+/* This implements the "info" prefix command. Normally such commands
+ are automatically handled by add_basic_prefix_cmd, but in this case
+ a separate command is used so that it can be hooked into by
+ gdb-gdb.gdb. */
static void
info_command (const char *arg, int from_tty)
{
- printf_unfiltered (_("\"info\" must be followed by "
- "the name of an info command.\n"));
help_list (infolist, "info ", all_commands, gdb_stdout);
}
-/* The "show" command with no arguments shows all the settings. */
-
-static void
-show_command (const char *arg, int from_tty)
-{
- cmd_show_list (showlist, from_tty, "");
-}
-
/* See cli/cli-cmds.h. */
void
nested_cmd = repeat_previous ();
cmd_list_element *set_cmd = lookup_cmd (&args, setlist, set_cmd_prefix,
+ nullptr,
/*allow_unknown=*/ 0,
/*ignore_help_classes=*/ 1);
gdb_assert (set_cmd != nullptr);
with_command_completer_1 ("set ", tracker, text);
}
-\f
+/* Look up the contents of TEXT as a command usable with default args.
+ Throws an error if no such command is found.
+ Return the found command and advances TEXT past the found command.
+ If the found command is a postfix command, set *PREFIX_CMD to its
+ prefix command. */
+
+static struct cmd_list_element *
+lookup_cmd_for_default_args (const char **text,
+ struct cmd_list_element **prefix_cmd)
+{
+ const char *orig_text = *text;
+ struct cmd_list_element *lcmd;
+
+ if (*text == nullptr || skip_spaces (*text) == nullptr)
+ error (_("ALIAS missing."));
+
+ /* We first use lookup_cmd to verify TEXT unambiguously identifies
+ a command. */
+ lcmd = lookup_cmd (text, cmdlist, "", NULL,
+ /*allow_unknown=*/ 0,
+ /*ignore_help_classes=*/ 1);
+
+ /* Note that we accept default args for prefix commands,
+ as a prefix command can also be a valid usable
+ command accepting some arguments.
+ For example, "thread apply" applies a command to a
+ list of thread ids, and is also the prefix command for
+ thread apply all. */
+
+ /* We have an unambiguous command for which default args
+ can be specified. What remains after having found LCMD
+ is either spaces, or the default args character. */
+
+ /* We then use lookup_cmd_composition to detect if the user
+ has specified an alias, and find the possible prefix_cmd
+ of cmd. */
+ struct cmd_list_element *alias, *cmd;
+ lookup_cmd_composition
+ (std::string (orig_text, *text - orig_text).c_str (),
+ &alias, prefix_cmd, &cmd);
+ gdb_assert (cmd != nullptr);
+ gdb_assert (cmd == lcmd);
+ if (alias != nullptr)
+ cmd = alias;
+
+ return cmd;
+}
+
/* Provide documentation on command or list given by COMMAND. FROM_TTY
is ignored. */
if (cwd == NULL)
error (_("Error finding name of working directory: %s"),
- safe_strerror (errno));
+ safe_strerror (errno));
if (strcmp (cwd.get (), current_directory) != 0)
printf_unfiltered (_("Working directory %ps\n (canonically %ps).\n"),
if (IS_DIR_SEPARATOR (dir[len - 1]))
{
/* Remove the trailing slash unless this is a root directory
- (including a drive letter on non-Unix systems). */
+ (including a drive letter on non-Unix systems). */
if (!(len == 1) /* "/" */
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
&& !(len == 3 && dir[1] == ':') /* "d:/" */
if (found_real_path)
{
/* Search backwards for the directory just before the "/.."
- and obliterate it and the "/..". */
+ and obliterate it and the "/..". */
char *q = p;
while (q != current_directory && !IS_DIR_SEPARATOR (q[-1]))
if (!opened)
{
/* The script wasn't found, or was otherwise inaccessible.
- If the source command was invoked interactively, throw an
+ If the source command was invoked interactively, throw an
error. Otherwise (e.g. if it was invoked by a script),
just emit a warning, rather than cause an error. */
if (from_tty)
clear_internalvar (var_signal);
if (WIFEXITED (exit_status))
set_internalvar_integer (var_code, WEXITSTATUS (exit_status));
+#ifdef __MINGW32__
+ else if (WIFSIGNALED (exit_status) && WTERMSIG (exit_status) == -1)
+ {
+ /* The -1 condition can happen on MinGW, if we don't recognize
+ the fatal exception code encoded in the exit status; see
+ gdbsupport/gdb_wait.c. We don't want to lose information in
+ the exit status in that case. Record it as a normal exit
+ with the full exit status, including the higher 0xC0000000
+ bits. */
+ set_internalvar_integer (var_code, exit_status);
+ }
+#endif
else if (WIFSIGNALED (exit_status))
set_internalvar_integer (var_signal, WTERMSIG (exit_status));
else
/* Make sure to return to the directory GDB thinks it is, in case
the shell command we just ran changed it. */
chdir (current_directory);
- exit_status_set_internal_vars (rc);
#endif
+ exit_status_set_internal_vars (rc);
#else /* Can fork. */
int status, pid;
sal = sals[0];
if (*arg1)
- error (_("Junk at end of line specification."));
+ error (_("Junk at end of line specification."));
/* If line was specified by address, first print exactly which
- line, and which file. In this case, sal.symtab == 0 means
- address is outside of all known source files, not that user
- failed to give a filename. */
+ line, and which file. In this case, sal.symtab == 0 means
+ address is outside of all known source files, not that user
+ failed to give a filename. */
if (*arg == '*')
- {
+ {
struct gdbarch *gdbarch;
- if (sal.symtab == 0)
+ if (sal.symtab == 0)
error (_("No source file for address %s."),
paddress (get_current_arch (), sal.pc));
- gdbarch = get_objfile_arch (SYMTAB_OBJFILE (sal.symtab));
- sym = find_pc_function (sal.pc);
- if (sym)
+ gdbarch = SYMTAB_OBJFILE (sal.symtab)->arch ();
+ sym = find_pc_function (sal.pc);
+ if (sym)
printf_filtered ("%s is in %s (%s:%d).\n",
paddress (gdbarch, sal.pc),
sym->print_name (),
symtab_to_filename_for_display (sal.symtab),
sal.line);
- else
+ else
printf_filtered ("%s is at %s:%d.\n",
paddress (gdbarch, sal.pc),
symtab_to_filename_for_display (sal.symtab),
sal.line);
- }
+ }
/* If what was given does not imply a symtab, it must be an
- undebuggable symbol which means no source code. */
+ undebuggable symbol which means no source code. */
if (sal.symtab == 0)
- error (_("No line number known for %s."), arg);
+ error (_("No line number known for %s."), arg);
}
if ((editor = getenv ("EDITOR")) == NULL)
if (exit_status < 0)
error (_("shell command \"%s\" failed: %s"), shell_command,
- safe_strerror (errno));
+ safe_strerror (errno));
exit_status_set_internal_vars (exit_status);
}
error (_("No source file for address %s."),
paddress (get_current_arch (), sal.pc));
- gdbarch = get_objfile_arch (SYMTAB_OBJFILE (sal.symtab));
+ gdbarch = SYMTAB_OBJFILE (sal.symtab)->arch ();
sym = find_pc_function (sal.pc);
if (sym)
printf_filtered ("%s is in %s (%s:%d).\n",
gdb_disassembly_flags flags)
{
#if defined(TUI)
- if (!tui_is_window_visible (DISASSEM_WIN))
+ if (tui_is_window_visible (DISASSEM_WIN))
+ tui_show_assembly (gdbarch, low);
+ else
#endif
{
- printf_filtered ("Dump of assembler code ");
+ printf_filtered (_("Dump of assembler code "));
if (name != NULL)
- printf_filtered ("for function %s:\n", name);
+ printf_filtered (_("for function %ps:\n"),
+ styled_string (function_name_style.style (), name));
if (block == nullptr || BLOCK_CONTIGUOUS_P (block))
- {
+ {
if (name == NULL)
- printf_filtered ("from %s to %s:\n",
- paddress (gdbarch, low), paddress (gdbarch, high));
+ printf_filtered (_("from %ps to %ps:\n"),
+ styled_string (address_style.style (),
+ paddress (gdbarch, low)),
+ styled_string (address_style.style (),
+ paddress (gdbarch, high)));
/* Dump the specified range. */
gdb_disassembly (gdbarch, current_uiout, flags, -1, low, high);
}
else
- {
+ {
for (int i = 0; i < BLOCK_NRANGES (block); i++)
{
CORE_ADDR range_low = BLOCK_RANGE_START (block, i);
CORE_ADDR range_high = BLOCK_RANGE_END (block, i);
- printf_filtered (_("Address range %s to %s:\n"),
- paddress (gdbarch, range_low),
- paddress (gdbarch, range_high));
+ printf_filtered (_("Address range %ps to %ps:\n"),
+ styled_string (address_style.style (),
+ paddress (gdbarch, range_low)),
+ styled_string (address_style.style (),
+ paddress (gdbarch, range_high)));
gdb_disassembly (gdbarch, current_uiout, flags, -1,
range_low, range_high);
}
}
- printf_filtered ("End of assembler dump.\n");
- }
-#if defined(TUI)
- else
- {
- tui_show_assembly (gdbarch, low);
+ printf_filtered (_("End of assembler dump.\n"));
}
-#endif
}
/* Subroutine of disassemble_command to simplify it.
{
struct gdbarch *gdbarch = get_current_arch ();
CORE_ADDR low, high;
+ const general_symbol_info *symbol = nullptr;
const char *name;
CORE_ADDR pc;
gdb_disassembly_flags flags;
if (p[0] == '\0')
{
/* One argument. */
- if (find_pc_partial_function (pc, &name, &low, &high, &block) == 0)
+ if (!find_pc_partial_function_sym (pc, &symbol, &low, &high, &block))
error (_("No function contains specified address."));
+
+ if (asm_demangle)
+ name = symbol->print_name ();
+ else
+ name = symbol->linkage_name ();
+
#if defined(TUI)
/* NOTE: cagney/2003-02-13 The `tui_active' was previously
`tui_version'. */
{
const char *comname = args;
- c = lookup_cmd (&comname, cmdlist, "", 0, 1);
+ c = lookup_cmd (&comname, cmdlist, "", NULL, 0, 1);
if (!cli_user_command_p (c))
error (_("Not a user command."));
show_user_1 (c, "", args, gdb_stdout);
apropos_cmd (gdb_stdout, cmdlist, verbose, pattern, "");
}
+/* The options for the "alias" command. */
+
+struct alias_opts
+{
+ /* For "-a". */
+ bool abbrev_flag = false;
+};
+
+static const gdb::option::option_def alias_option_defs[] = {
+
+ gdb::option::flag_option_def<alias_opts> {
+ "a",
+ [] (alias_opts *opts) { return &opts->abbrev_flag; },
+ N_("Specify that ALIAS is an abbreviation of COMMAND.\n\
+Abbreviations are not used in command completion."),
+ },
+
+};
+
+/* Create an option_def_group for the "alias" options, with
+ A_OPTS as context. */
+
+static gdb::option::option_def_group
+make_alias_options_def_group (alias_opts *a_opts)
+{
+ return {{alias_option_defs}, a_opts};
+}
+
+/* Completer for the "alias_command". */
+
+static void
+alias_command_completer (struct cmd_list_element *ignore,
+ completion_tracker &tracker,
+ const char *text, const char *word)
+{
+ const auto grp = make_alias_options_def_group (nullptr);
+
+ tracker.set_use_custom_word_point (true);
+
+ if (gdb::option::complete_options
+ (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp))
+ return;
+
+ const char *delim = strchr (text, '=');
+
+ /* If we're past the "=" delimiter, complete the
+ "alias ALIAS = COMMAND [DEFAULT-ARGS...]" as if the user is
+ typing COMMAND DEFAULT-ARGS... */
+ if (delim != text
+ && delim != nullptr
+ && isspace (delim[-1])
+ && (isspace (delim[1]) || delim[1] == '\0'))
+ {
+ std::string new_text = std::string (delim + 1);
+
+ tracker.advance_custom_word_point_by (delim + 1 - text);
+ complete_nested_command_line (tracker, new_text.c_str ());
+ return;
+ }
+
+ /* We're not yet past the "=" delimiter. Complete a command, as
+ the user might type an alias following a prefix command. */
+ complete_nested_command_line (tracker, text);
+}
+
/* Subroutine of alias_command to simplify it.
Return the first N elements of ARGV flattened back to a string
with a space separating each element.
}
/* Subroutine of alias_command to simplify it.
- Return true if COMMAND exists, unambiguously. Otherwise false. */
+ Verifies that COMMAND can have an alias:
+ COMMAND must exist.
+ COMMAND must not have default args.
+ This last condition is to avoid the following:
+ alias aaa = backtrace -full
+ alias bbb = aaa -past-main
+ as (at least currently), alias default args are not cumulative
+ and the user would expect bbb to execute 'backtrace -full -past-main'
+ while it will execute 'backtrace -past-main'. */
-static bool
-valid_command_p (const char *command)
+static void
+validate_aliased_command (const char *command)
{
struct cmd_list_element *c;
+ std::string default_args;
- c = lookup_cmd_1 (& command, cmdlist, NULL, 1);
+ c = lookup_cmd_1 (& command, cmdlist, NULL, &default_args, 1);
if (c == NULL || c == (struct cmd_list_element *) -1)
- return false;
-
- /* This is the slightly tricky part.
- lookup_cmd_1 will return a pointer to the last part of COMMAND
- to match, leaving COMMAND pointing at the remainder. */
- while (*command == ' ' || *command == '\t')
- ++command;
- return *command == '\0';
+ error (_("Invalid command to alias to: %s"), command);
+
+ if (!default_args.empty ())
+ error (_("Cannot define an alias of an alias that has default args"));
}
/* Called when "alias" was incorrectly used. */
static void
alias_usage_error (void)
{
- error (_("Usage: alias [-a] [--] ALIAS = COMMAND"));
+ error (_("Usage: alias [-a] [--] ALIAS = COMMAND [DEFAULT-ARGS...]"));
}
/* Make an alias of an existing command. */
static void
alias_command (const char *args, int from_tty)
{
+ alias_opts a_opts;
+
+ auto grp = make_alias_options_def_group (&a_opts);
+ gdb::option::process_options
+ (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp);
+
int i, alias_argc, command_argc;
- int abbrev_flag = 0;
const char *equals;
const char *alias, *command;
std::string args2 (args, equals - args);
gdb_argv built_alias_argv (args2.c_str ());
- gdb_argv command_argv (equals + 1);
+
+ const char *default_args = equals + 1;
+ struct cmd_list_element *c_command_prefix;
+
+ lookup_cmd_for_default_args (&default_args, &c_command_prefix);
+ std::string command_argv_str (equals + 1,
+ default_args == nullptr
+ ? strlen (equals + 1)
+ : default_args - equals - 1);
+ gdb_argv command_argv (command_argv_str.c_str ());
char **alias_argv = built_alias_argv.get ();
- while (alias_argv[0] != NULL)
- {
- if (strcmp (alias_argv[0], "-a") == 0)
- {
- ++alias_argv;
- abbrev_flag = 1;
- }
- else if (strcmp (alias_argv[0], "--") == 0)
- {
- ++alias_argv;
- break;
- }
- else
- break;
- }
if (alias_argv[0] == NULL || command_argv[0] == NULL
|| *alias_argv[0] == '\0' || *command_argv[0] == '\0')
alias_argc = countargv (alias_argv);
command_argc = command_argv.count ();
- /* COMMAND must exist.
+ /* COMMAND must exist, and cannot have default args.
Reconstruct the command to remove any extraneous spaces,
for better error messages. */
std::string command_string (argv_to_string (command_argv.get (),
command_argc));
command = command_string.c_str ();
- if (! valid_command_p (command))
- error (_("Invalid command to alias to: %s"), command);
+ validate_aliased_command (command);
/* ALIAS must not exist. */
std::string alias_string (argv_to_string (alias_argv, alias_argc));
alias = alias_string.c_str ();
- if (valid_command_p (alias))
- error (_("Alias already exists: %s"), alias);
+ {
+ cmd_list_element *alias_cmd, *prefix_cmd, *cmd;
+
+ if (lookup_cmd_composition (alias, &alias_cmd, &prefix_cmd, &cmd))
+ {
+ const char *alias_name = alias_argv[alias_argc-1];
+
+ /* If we found an existing ALIAS_CMD, check that the prefix differ or
+ the name differ. */
+
+ if (alias_cmd != nullptr
+ && alias_cmd->prefix == prefix_cmd
+ && strcmp (alias_name, alias_cmd->name) == 0)
+ error (_("Alias already exists: %s"), alias);
+
+ /* Check ALIAS differs from the found CMD. */
+
+ if (cmd->prefix == prefix_cmd
+ && strcmp (alias_name, cmd->name) == 0)
+ error (_("Alias %s is the name of an existing command"), alias);
+ }
+ }
+
+
+ struct cmd_list_element *alias_cmd;
/* If ALIAS is one word, it is an alias for the entire COMMAND.
Example: alias spe = set print elements
if (alias_argc == 1)
{
/* add_cmd requires *we* allocate space for name, hence the xstrdup. */
- add_com_alias (xstrdup (alias_argv[0]), command, class_alias,
- abbrev_flag);
+ alias_cmd = add_com_alias (xstrdup (alias_argv[0]), command, class_alias,
+ a_opts.abbrev_flag);
}
else
{
alias_prefix = alias_prefix_string.c_str ();
command_prefix = command_prefix_string.c_str ();
- c_command = lookup_cmd_1 (& command_prefix, cmdlist, NULL, 1);
+ c_command = lookup_cmd_1 (& command_prefix, cmdlist, NULL, NULL, 1);
/* We've already tried to look up COMMAND. */
gdb_assert (c_command != NULL
&& c_command != (struct cmd_list_element *) -1);
gdb_assert (c_command->prefixlist != NULL);
- c_alias = lookup_cmd_1 (& alias_prefix, cmdlist, NULL, 1);
+ c_alias = lookup_cmd_1 (& alias_prefix, cmdlist, NULL, NULL, 1);
if (c_alias != c_command)
error (_("ALIAS and COMMAND prefixes do not match."));
/* add_cmd requires *we* allocate space for name, hence the xstrdup. */
- add_alias_cmd (xstrdup (alias_argv[alias_argc - 1]),
- command_argv[command_argc - 1],
- class_alias, abbrev_flag, c_command->prefixlist);
+ alias_cmd = add_alias_cmd (xstrdup (alias_argv[alias_argc - 1]),
+ command_argv[command_argc - 1],
+ class_alias, a_opts.abbrev_flag,
+ c_command->prefixlist);
+ }
+
+ gdb_assert (alias_cmd != nullptr);
+ gdb_assert (alias_cmd->default_args.empty ());
+ if (default_args != nullptr)
+ {
+ default_args = skip_spaces (default_args);
+
+ alias_cmd->default_args = default_args;
}
}
\f
sals.erase (from, sals.end ());
}
-static void
-set_debug (const char *arg, int from_tty)
-{
- printf_unfiltered (_("\"set debug\" must be followed by "
- "the name of a debug subcommand.\n"));
- help_list (setdebuglist, "set debug ", all_commands, gdb_stdout);
-}
-
-static void
-show_debug (const char *args, int from_tty)
-{
- cmd_show_list (showdebuglist, from_tty, "");
-}
-
void
init_cmd_lists (void)
{
value);
}
-static void
-show_remote_debug (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
-{
- fprintf_filtered (file, _("Debugging of remote protocol is %s.\n"),
- value);
-}
-
-static void
-show_remote_timeout (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
-{
- fprintf_filtered (file,
- _("Timeout limit to wait for target to respond is %s.\n"),
- value);
-}
-
static void
show_max_user_call_depth (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
struct type *type0 = check_typedef (value_type (argv[0]));
- if (TYPE_CODE (type0) != TYPE_CODE_ARRAY
- && TYPE_CODE (type0) != TYPE_CODE_STRING)
+ if (type0->code () != TYPE_CODE_ARRAY
+ && type0->code () != TYPE_CODE_STRING)
error (_("First argument of %s must be a string."), fnname);
const char *a0 = (const char *) value_contents (argv[0]);
- cmd_list_element *cmd = lookup_cmd (&a0, showlist, "", -1, 0);
+ cmd_list_element *cmd = lookup_cmd (&a0, showlist, "", NULL, -1, 0);
- if (cmd == nullptr || cmd_type (cmd) != show_cmd)
+ if (cmd == nullptr || cmd->type != show_cmd)
error (_("First argument of %s must be a "
"valid setting of the 'show' command."), fnname);
gdbarch);
}
+void _initialize_cli_cmds ();
void
-_initialize_cli_cmds (void)
+_initialize_cli_cmds ()
{
struct cmd_list_element *c;
&cmdlist);
add_cmd ("obscure", class_obscure, _("Obscure features."), &cmdlist);
add_cmd ("aliases", class_alias,
- _("Aliases of other commands."), &cmdlist);
+ _("User-defined aliases of other commands."), &cmdlist);
add_cmd ("user-defined", class_user, _("\
User-defined commands.\n\
The commands in this class are those defined by the user.\n\
When the program being debugged stops, gdb selects the innermost frame.\n\
The commands below can be used to select other frames by number or address."),
&cmdlist);
+#ifdef TUI
+ add_cmd ("text-user-interface", class_tui,
+ _("TUI is the GDB text based interface.\n\
+In TUI mode, GDB can display several text windows showing\n\
+the source file, the processor registers, the program disassembly, ..."), &cmdlist);
+#endif
add_cmd ("running", class_run, _("Running the program."), &cmdlist);
/* Define general commands. */
show_info_verbose,
&setlist, &showlist);
- add_prefix_cmd ("history", class_support, set_history,
- _("Generic command for setting command history parameters."),
- &sethistlist, "set history ", 0, &setlist);
- add_prefix_cmd ("history", class_support, show_history,
- _("Generic command for showing command history parameters."),
- &showhistlist, "show history ", 0, &showlist);
+ add_basic_prefix_cmd ("history", class_support, _("\
+Generic command for setting command history parameters."),
+ &sethistlist, "set history ", 0, &setlist);
+ add_show_prefix_cmd ("history", class_support, _("\
+Generic command for showing command history parameters."),
+ &showhistlist, "show history ", 0, &showlist);
add_setshow_boolean_cmd ("expansion", no_class, &history_expansion_p, _("\
Set history expansion on command input."), _("\
add_com ("complete", class_obscure, complete_command,
_("List the completions for the rest of the line as a command."));
- add_prefix_cmd ("show", class_info, show_command, _("\
+ c = add_show_prefix_cmd ("show", class_info, _("\
Generic command for showing things about the debugger."),
- &showlist, "show ", 0, &cmdlist);
+ &showlist, "show ", 0, &cmdlist);
/* Another way to get at the same thing. */
- add_info ("set", show_command, _("Show all GDB settings."));
+ add_alias_cmd ("set", c, class_info, 0, &infolist);
c = add_com ("with", class_vars, with_command, _("\
Temporarily set SETTING to VALUE, run COMMAND, and restore SETTING.\n\
add_cmd ("configuration", no_set_class, show_configuration,
_("Show how GDB was configured at build time."), &showlist);
- add_setshow_zinteger_cmd ("remote", no_class, &remote_debug, _("\
-Set debugging of remote protocol."), _("\
-Show debugging of remote protocol."), _("\
-When enabled, each packet sent or received with the remote target\n\
-is displayed."),
- NULL,
- show_remote_debug,
- &setdebuglist, &showdebuglist);
-
- add_setshow_zuinteger_unlimited_cmd ("remotetimeout", no_class,
- &remote_timeout, _("\
-Set timeout limit to wait for target to respond."), _("\
-Show timeout limit to wait for target to respond."), _("\
-This value is used to set the time limit for gdb to wait for a response\n\
-from the target."),
- NULL,
- show_remote_timeout,
- &setlist, &showlist);
-
- add_prefix_cmd ("debug", no_class, set_debug,
- _("Generic command for setting gdb debugging flags."),
- &setdebuglist, "set debug ", 0, &setlist);
-
- add_prefix_cmd ("debug", no_class, show_debug,
- _("Generic command for showing gdb debugging flags."),
- &showdebuglist, "show debug ", 0, &showlist);
+ add_basic_prefix_cmd ("debug", no_class,
+ _("Generic command for setting gdb debugging flags."),
+ &setdebuglist, "set debug ", 0, &setlist);
+
+ add_show_prefix_cmd ("debug", no_class,
+ _("Generic command for showing gdb debugging flags."),
+ &showdebuglist, "show debug ", 0, &showlist);
c = add_com ("shell", class_support, shell_command, _("\
Execute the rest of the line as a shell command.\n\
c = add_com ("disassemble", class_vars, disassemble_command, _("\
Disassemble a specified section of memory.\n\
+Usage: disassemble[/m|/r|/s] START [, END]\n\
Default is the function surrounding the pc of the selected frame.\n\
\n\
+With a /s modifier, source lines are included (if available).\n\
+In this mode, the output is displayed in PC address order, and\n\
+file names and contents for all relevant source files are displayed.\n\
+\n\
With a /m modifier, source lines are included (if available).\n\
This view is \"source centric\": the output is in source line order,\n\
regardless of any optimization that is present. Only the main source file\n\
This modifier hasn't proved useful in practice and is deprecated\n\
in favor of /s.\n\
\n\
-With a /s modifier, source lines are included (if available).\n\
-This differs from /m in two important respects:\n\
-- the output is still in pc address order, and\n\
-- file names and contents for all relevant source files are displayed.\n\
-\n\
With a /r modifier, raw instructions in hex are included.\n\
\n\
With a single argument, the function surrounding that address is dumped.\n\
NULL,
&setlist, &showlist);
- c = add_com ("alias", class_support, alias_command, _("\
+ const auto alias_opts = make_alias_options_def_group (nullptr);
+
+ static std::string alias_help
+ = gdb::option::build_help (_("\
Define a new command that is an alias of an existing command.\n\
-Usage: alias [-a] [--] ALIAS = COMMAND\n\
+Usage: alias [-a] [--] ALIAS = COMMAND [DEFAULT-ARGS...]\n\
ALIAS is the name of the alias command to create.\n\
COMMAND is the command being aliased to.\n\
-If \"-a\" is specified, the command is an abbreviation,\n\
-and will not appear in help command list output.\n\
+\n\
+Options:\n\
+%OPTIONS%\n\
+\n\
+GDB will automatically prepend the provided DEFAULT-ARGS to the list\n\
+of arguments explicitly provided when using ALIAS.\n\
+Use \"help aliases\" to list all user defined aliases and their default args.\n\
\n\
Examples:\n\
Make \"spe\" an alias of \"set print elements\":\n\
alias spe = set print elements\n\
Make \"elms\" an alias of \"elements\" in the \"set print\" command:\n\
- alias -a set print elms = set print elements"));
+ alias -a set print elms = set print elements\n\
+Make \"btf\" an alias of \"backtrace -full -past-entry -past-main\" :\n\
+ alias btf = backtrace -full -past-entry -past-main\n\
+Make \"wLapPeu\" an alias of 2 nested \"with\":\n\
+ alias wLapPeu = with language pascal -- with print elements unlimited --"),
+ alias_opts);
+
+ c = add_com ("alias", class_support, alias_command,
+ alias_help.c_str ());
+
+ set_cmd_completer_handle_brkchars (c, alias_command_completer);
const char *source_help_text = xstrprintf (_("\
Read commands from a file named FILE.\n\