/* GDB CLI commands.
- Copyright (C) 2000-2020 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"
+#include "gdbsupport/gdb_tilde_expand.h"
#ifdef TUI
#include "tui/tui.h" /* For tui_active et.al. */
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;
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)
anyway so that error messages show the actual file used. But only do
this if we (may have) used search_path, as printing the full path in
errors for the non-search case can be more noise than signal. */
- source_script_from_stream (opened->stream.get (), file,
- search_path ? opened->full_path.get () : file);
+ const char *file_to_open;
+ gdb::unique_xmalloc_ptr<char> tilde_expanded_file;
+ if (search_path)
+ file_to_open = opened->full_path.get ();
+ else
+ {
+ tilde_expanded_file = gdb_tilde_expand_up (file);
+ file_to_open = tilde_expanded_file.get ();
+ }
+ source_script_from_stream (opened->stream.get (), file, file_to_open);
}
/* Wrapper around source_script_with_search to export it to main.c
/* 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 = SYMTAB_OBJFILE (sal.symtab)->arch ();
- sym = find_pc_function (sal.pc);
- if (sym)
+ 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);
}
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");
+ printf_filtered (_("End of assembler dump.\n"));
}
}
{
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);
{
for (c = cmdlist; c; c = c->next)
{
- if (cli_user_command_p (c) || c->prefixlist != NULL)
+ if (cli_user_command_p (c) || c->is_prefix ())
show_user_1 (c, "", c->name, 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);
+ gdb_assert (c_command->is_prefix ());
+ 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->subcommands);
+ }
+
+ 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
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)
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);
&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. */
add_basic_prefix_cmd ("history", class_support, _("\
Generic command for setting command history parameters."),
- &sethistlist, "set history ", 0, &setlist);
+ &sethistlist, 0, &setlist);
add_show_prefix_cmd ("history", class_support, _("\
Generic command for showing command history parameters."),
- &showhistlist, "show history ", 0, &showlist);
+ &showhistlist, 0, &showlist);
add_setshow_boolean_cmd ("expansion", no_class, &history_expansion_p, _("\
Set history expansion on command input."), _("\
add_prefix_cmd ("info", class_info, info_command, _("\
Generic command for showing things about the program being debugged."),
- &infolist, "info ", 0, &cmdlist);
+ &infolist, 0, &cmdlist);
add_com_alias ("i", "info", class_info, 1);
add_com_alias ("inf", "info", class_info, 1);
add_com ("complete", class_obscure, complete_command,
_("List the completions for the rest of the line as a command."));
- add_show_prefix_cmd ("show", class_info, _("\
+ c = add_show_prefix_cmd ("show", class_info, _("\
Generic command for showing things about the debugger."),
- &showlist, "show ", 0, &cmdlist);
+ &showlist, 0, &cmdlist);
/* Another way to get at the same thing. */
- add_show_prefix_cmd ("set", class_info, _("Show all GDB settings."),
- &showlist, "info set ", 0, &infolist);
+ 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_basic_prefix_cmd ("debug", no_class,
_("Generic command for setting gdb debugging flags."),
- &setdebuglist, "set debug ", 0, &setlist);
+ &setdebuglist, 0, &setlist);
add_show_prefix_cmd ("debug", no_class,
_("Generic command for showing gdb debugging flags."),
- &showdebuglist, "show debug ", 0, &showlist);
+ &showdebuglist, 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\