This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFAv2 1/3] leading-args: allow to define default command/alias arguments


Hi Philippe,

Just a few comments below of things that I spotted on a
quick initial skim.  I'm not sure I'll have more time for
review today.

Design comment off hand:

 did you consider storing the default arguments on a separate
 map instead of recording them in the commands themselves?

On 8/5/19 9:51 PM, Philippe Waroquiers wrote:
> Currently, a user can define an alias, but cannot have default
> arguments for this alias.
> 
> This patch provides the following:
> 
> * A new command 'set leading-args' that can define default leading args
>   to preprend to the command or alias arguments before executing it.

preprend -> prepend

>   Note that leading args can be used for an alias and can nicely
>   combine nested "with" (see below the changes for the alias command).
> 
>       (gdb) help set leading-args
>       Set or clear leading args automatically preprended to a command or alias.
>       Usage: set leading-args COMMAND [LEADING-ARGS...]
>       Set or clear the leading arguments automatically prepended
>       to the arguments the user provides when COMMAND is run.
>       Note that COMMAND can be an alias.  Commands and their aliases
>       do not share their leading arguments, so you can specify different
>       leading arguments for a command and for each of its aliases.
>       Without the [LEADING-ARGS...], clears COMMAND leading arguments.
> 
>   Note that 'set leading-args' command has a completer to help typing
>   COMMAND and its leading-args.
> 

Nice, I like having completers.  :-)

> * A new command 'show leading-args'.
> 
>         (gdb) help show leading-args
>         Show the leading args of a command, or of all commands.
>         Usage: show leading-args [COMMAND]
>         Show the leading args of COMMAND.  Without COMMAND, show the leading args
>         of all commands.
> 
> * The 'alias' command is modified so as to directly accepts leading-args.

"directly accepts" -> "directly accept"

>   Note that the help alias assumes this patch will be pushed after the
>   'with command' is pushed.

You can remove this sentence now.

> 
>         (gdb) help alias
>         Define a new command that is an alias of an existing command.
>         Usage: alias [-a] [--] ALIAS = COMMAND [LEADING-ARGS...]
>         ALIAS is the name of the alias command to create.
>         COMMAND is the command being aliased to.
>         If "-a" is specified, the command is an abbreviation,
>         and will not appear in help command list output.
> 
>         You can optionally provide LEADING-ARGS to define at the same time
>         ALIAS and its leading args.  This is the equivalent of:
>           alias ALIAS = COMMAND
>           set leading-args ALIAS LEADING-ARGS...
> 
>         Examples:
>         Make "spe" an alias of "set print elements":
>           alias spe = set print elements
>         Make "elms" an alias of "elements" in the "set print" command:
>           alias -a set print elms = set print elements
>         Make "btf" an alias of "backtrace -full -past-entry -past-main" :
>           alias btf = backtrace -full -past-entry -past-main
>         Make "wLapPeu" an alias of 2 nested "with":
>           alias wLapPeu = with language pascal -- with print elements unlimited --
> 
> * 'alias' command now has a completer that helps to complete:
>    ALIAS (if the user defines an alias after a prefix),
>    the aliased COMMAND
>    the possible options for the aliased COMMAND.
> 
> * A new setting 'set enable-leading-args'.  This can be used if the
>   user wants to temporarily disable the usage of leading args.
>   'show enable-leading-args' shows the value of 'enable-leading-args'.
>   The main intended usage of this setting is to use it in the "with"
>   command: as set leading-args can add arguments to standard GDB commands,
>   it is useful (e.g. in user defined commands) to be able to go back
>   to the 'standard' behaviour of a command.
> 
> gdb/ChangeLog
> 2019-08-04  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
> 
> 	* cli/cli-cmds.c (leading_args_cmd_completer,
> 	lookup_cmd_for_leading_args, set_leading_args_command,
> 	show_leading_args, show_leading_args_command_1,
> 	show_leading_args_command, alias_command_completer,
>         make_alias_options_def_group): New functions.

Tabs vs spaces.

Also, when you need to break between multiple lines, close parens, and
reopen on next line, like:

 	* cli/cli-cmds.c (leading_args_cmd_completer)
 	(lookup_cmd_for_leading_args, set_leading_args_command)
 	(show_leading_args, show_leading_args_command_1)
 	(show_leading_args_command, alias_command_completer)
 	(make_alias_options_def_group): New functions.

> 	(alias_opts, alias_option_defs): New struct and array.
> 	(alias_usage_error): Update usage.
> 	(alias_command): Handles optional LEADING-ARGS... arguments.
> 	Use option framework.
> 	(_initialize_cli_cmds): Install 'set|show leading-args' commands.
> 	Update alias command help.
> 	(show_user, valid_command_p):
> 	Add NULL for new leading_args lookup_cmd argument.
> 	* cli/cli-decode.c (help_cmd): Show leading args if command has
> 	some.
> 	(lookup_cmd_1, lookup_cmd): New argument leading_args.
> 	(add_alias_cmd):
> 	Add NULL for new leading_args lookup_cmd argument.
> 	(print_help_for_command): Show leading args.
> 	* cli/cli-decode.h (struct cmd_list_element): New member leading_args.
> 	xfree leading_args in destructor.
> 	* cli/cli-script.c (process_next_line, do_define_command):
> 	Add NULL for new leading_args lookup_cmd argument.
> 	* command.h: Declare new leading_args argument in lookup_cmd
> 	and lookup_cmd_1.
> 	* completer.c (complete_line_internal_1):
> 	Add NULL for new leading_args lookup_cmd or lookup_cmd_1 argument.
> 	* guile/scm-cmd.c (gdbscm_parse_command_name): Likewise.
> 	* guile/scm-param.c (add_setshow_generic, pascm_parameter_defined_p):
> 	 Likewise.

Spurious extra space.

> 	* infcmd.c (_initialize_infcmd): Likewise.
> 	* python/py-auto-load.c (gdbpy_initialize_auto_load): Likewise.
> 	* python/py-cmd.c (gdbpy_parse_command_name): Likewise.
> 	* python/py-param.c (add_setshow_generic): Likewise.
> 	* remote.c (_initialize_remote): Likewise.
> 	* top.c (enable_leading_args_var): New flag.
> 	(execute_command): Prepend leading_args if command has some.
> 	(set_verbose):
> 	Add NULL for new leading_args lookup_cmd or  lookup_cmd_1 argument.

Spurious extra space.

> 	(init_main): Install 'set|show enable-leading-args.
> 	* tracepoint.c (validate_actionline, encode_actions_1):
> 	Add NULL for new leading_args lookup_cmd or lookup_cmd_1 argument.
> ---
>  gdb/cli/cli-cmds.c        | 326 ++++++++++++++++++++++++++++++++++----
>  gdb/cli/cli-decode.c      |  95 +++++++++--
>  gdb/cli/cli-decode.h      |   6 +
>  gdb/cli/cli-script.c      |  10 +-
>  gdb/command.h             |   2 +
>  gdb/completer.c           |   2 +-
>  gdb/guile/scm-cmd.c       |   2 +-
>  gdb/guile/scm-param.c     |   6 +-
>  gdb/infcmd.c              |   6 +-
>  gdb/python/py-auto-load.c |   4 +-
>  gdb/python/py-cmd.c       |   2 +-
>  gdb/python/py-param.c     |   4 +-
>  gdb/remote.c              |   4 +-
>  gdb/top.c                 |  41 ++++-
>  gdb/tracepoint.c          |   6 +-
>  15 files changed, 446 insertions(+), 70 deletions(-)
> 
> diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
> index 0b62622e88..b33527b360 100644
> --- a/gdb/cli/cli-cmds.c
> +++ b/gdb/cli/cli-cmds.c
> @@ -50,6 +50,7 @@
>  #include "cli/cli-setshow.h"
>  #include "cli/cli-cmds.h"
>  #include "cli/cli-utils.h"
> +#include "cli/cli-style.h"
>  
>  #include "extension.h"
>  #include "gdbsupport/pathstuff.h"
> @@ -227,6 +228,7 @@ with_command_1 (const char *set_cmd_prefix,
>      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);
> @@ -321,6 +323,149 @@ with_command_completer (struct cmd_list_element *ignore,
>    with_command_completer_1 ("set ", tracker,  text);
>  }
>  
> +/* Completer for the "set|show leading-args" commands.  */
> +
> +static void
> +leading_args_cmd_completer (struct cmd_list_element *ignore,
> +			    completion_tracker &tracker,
> +			    const char *text, const char *word)
> +{
> +  tracker.set_use_custom_word_point (true);
> +
> +  complete_nested_command_line (tracker, text);
> +}
> +
> +/* Look up the contents of TEXT as a command usable with leading 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_leading_args (const char **text,
> +			     struct cmd_list_element **prefix_cmd)
> +{
> +  const char *orig_text = *text;
> +  struct cmd_list_element *lcmd, *alias, *cmd;
> +
> +  if (*text == nullptr || skip_spaces (*text) == nullptr)
> +    error (_("COMMAND 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 leading 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 id, and is also the prefix command for

"list of thread id" -> "list of thread ids"

> +     thread apply all.  */
> +
> +  /* We have an unambiguous command for which leading args
> +     can be specified.  What remains after having found LCMD
> +     is either spaces, or the the leading args character.  */

"the the" -> "the"

> +
> +  /* We then use lookup_cmd_composition to detect if the user
> +     has specified an alias, and find the possible prefix_cmd
> +     of cmd.  */
> +  (void) lookup_cmd_composition
> +    (std::string (orig_text, *text - orig_text).c_str (),
> +     &alias, prefix_cmd, &cmd);

We don't generally use "(void)" to "suppress" the return value.
You'll only find it in really old code.

> +  gdb_assert (cmd != nullptr);
> +  gdb_assert (cmd == lcmd);
> +  if (alias != nullptr)
> +    cmd = alias;
> +
> +  return cmd;
> +}
> +
> +/* Implementation of the "set leading-args" command.  */
> +
> +static void
> +set_leading_args_command (const char *arg, int from_tty)
> +{
> +  struct cmd_list_element *prefix_cmd;
> +  struct cmd_list_element *cmd = lookup_cmd_for_leading_args (&arg, &prefix_cmd);
> +
> +  const char *leading_args = skip_spaces (arg);
> +
> +  if (*leading_args == '\0')
> +    leading_args = nullptr;
> +
> +  if (cmd->leading_args)
> +    xfree ((char *) cmd->leading_args);
> +  if (leading_args == nullptr)
> +    cmd->leading_args = nullptr;
> +  else
> +    cmd->leading_args = xstrdup (leading_args);
> +}
> +
> +/* Print a message showing C name and its leading args or <no leading args>

"showing C name" -> "showing C's name"

> +   if C has no leading args.
> +   If SILENT_FOR_NO_LEADING_ARGS, does nothing if C has no leading args.  */
> +
> +static void
> +show_leading_args (struct cmd_list_element *c,
> +		   const char *prefix,
> +		   bool silent_for_no_leading_args)
> +{
> +  if (c->leading_args != nullptr || !silent_for_no_leading_args)
> +    {
> +      fputs_filtered ("leading-args ", gdb_stdout);
> +      fprintf_styled (gdb_stdout, title_style.style (),
> +		      "%s%s",
> +		      prefix == nullptr ? "" : prefix, c->name);
> +      fprintf_filtered (gdb_stdout, " = %s\n",
> +			c->leading_args == nullptr ?

? goes on next line.

> +			"<no leading args>" : c->leading_args);
> +    }
> +}
> +
> +/* Recursively traverse COMMANDLIST and prints a message showing
> +   the leading-args of the commands have have non-null leading args.

"have have" -> "that have"

> +   PREFIX is the prefix that led to COMMANDLIST.  */
> +
> +static void
> +show_leading_args_command_1 (struct cmd_list_element *commandlist,
> +			     const char *prefix)
> +{
> +  struct cmd_list_element *c;
> +
> +  /* Walk through the commands.  */
> +  for (c = commandlist; c; c = c->next)

Declare the var in the loop, and might as well drop struct while at it:

  /* Walk through the commands.  */
  for (cmd_list_element *c = commandlist; c; c = c->next)


> +    {
> +      show_leading_args (c, prefix, true);
> +      /* If C has subcommands, recursively search if its subcommands
> +	 have leading args.
> +	 Do not recurse for abbreviations to avoid duplicates
> +	 in the output.  */
> +      if (c->prefixlist != NULL && !c->abbrev_flag)
> +	show_leading_args_command_1 (*c->prefixlist, c->prefixname);
> +    }
> +}
> +
> +/* Implementation of the "show leading-args" command.  */
> +
> +static void
> +show_leading_args_command (const char *arg, int from_tty)
> +{
> +  if (arg != nullptr && skip_spaces (arg) != nullptr)

You can just write:

  if (skip_spaces (arg) != nullptr)

since skip_spaces already handles nullptr.  (Saw the same thing
in other spots in the patch.)


> +    {
> +      struct cmd_list_element *prefix_cmd;
> +      struct cmd_list_element *c = lookup_cmd_for_leading_args (&arg,
> +								&prefix_cmd);
> +
> +      show_leading_args (c,
> +			 prefix_cmd == nullptr ?

? on next line.  Or merge both lines into one assuming it fits.

> +			 "" : prefix_cmd->prefixname,
> +			 false);
> +    }
> +  else
> +    show_leading_args_command_1 (cmdlist, "");
> +}
> +
>  
>  /* Provide documentation on command or list given by COMMAND.  FROM_TTY
>     is ignored.  */
> @@ -1536,7 +1681,7 @@ show_user (const char *args, int from_tty)
>      {
>        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);
> @@ -1568,6 +1713,71 @@ apropos_command (const char *arg, int from_tty)
>    apropos_cmd (gdb_stdout, cmdlist, verbose, pattern, "");
>  }
>  
> +/* The options for the "alias" command.  */
> +
> +struct alias_opts
> +{
> +  /* For "-a".  */
> +  int abbrev_flag = 0;
> +};
> +
> +static const gdb::option::option_def alias_option_defs[] = {
> +
> +  gdb::option::flag_option_def<alias_opts> {
> +    "a",

Given we accept abbreviations, should that be "abbrev" or "abbreviation"
instead of "a" ?

> +    [] (alias_opts *opts) { return &opts->abbrev_flag; },
> +    N_("Specify that ALIAS is an abbreviation of COMMAND.\n\
> +Abbreviations are not shown in command lists displayed by the 'help' command."),
> +  },
> +
> +};
> +
> +/* Create an option_def_group for the "alias" options, with
> +   IT_OPTS as context.  */

IT_OPTS -> A_OPTS

> +
> +static inline 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 = strstr (text, "=");
> +
> +  /* If we're past the "=" delimiter, complete the
> +     "alias ALIAS = COMMAND [LEADING-ARGS...]" as if the user is
> +     typing COMMAND LEADING-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.
> @@ -1602,7 +1812,7 @@ valid_command_p (const char *command)
>  {
>    struct cmd_list_element *c;
>  
> -  c = lookup_cmd_1 (& command, cmdlist, NULL, 1);
> +  c = lookup_cmd_1 (& command, cmdlist, NULL, NULL, 1);
>  
>    if (c == NULL || c == (struct cmd_list_element *) -1)
>      return false;
> @@ -1620,7 +1830,7 @@ valid_command_p (const char *command)
>  static void
>  alias_usage_error (void)
>  {
> -  error (_("Usage: alias [-a] [--] ALIAS = COMMAND"));
> +  error (_("Usage: alias [-a] [--] ALIAS = COMMAND [LEADING-ARGS...]"));

For this alias use case, I wonder whether talking about "leading" is really
useful.  I'd find this totally natural and intuitive:

   error (_("Usage: alias [-a] [--] ALIAS = COMMAND [ARGS...]"));

>  }
>  
>  /* Make an alias of an existing command.  */
> @@ -1628,8 +1838,13 @@ alias_usage_error (void)
>  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;
>  
> @@ -1640,24 +1855,18 @@ alias_command (const char *args, int from_tty)
>    std::string args2 (args, equals - args);
>  
>    gdb_argv built_alias_argv (args2.c_str ());
> -  gdb_argv command_argv (equals + 1);
> +
> +  const char *leading_args = equals + 1;
> +  struct cmd_list_element *c_command_prefix;
> +
> +  lookup_cmd_for_leading_args (&leading_args, &c_command_prefix);
> +  std::string command_argv_str (equals + 1,
> +				leading_args == nullptr ?
> +				strlen (equals + 1)
> +				: leading_args - equals - 1);

				(leading_args == nullptr
				 ? strlen (equals + 1)
				 : leading_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')
> @@ -1692,6 +1901,8 @@ alias_command (const char *args, int from_tty)
>    if (valid_command_p (alias))
>      error (_("Alias already exists: %s"), 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
>  
> @@ -1704,8 +1915,8 @@ alias_command (const char *args, int from_tty)
>    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
>      {
> @@ -1725,19 +1936,30 @@ alias_command (const char *args, int from_tty)
>        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);
> +  gdb_assert (alias_cmd->leading_args == nullptr);
> +  if (leading_args != nullptr)
> +    {
> +      leading_args = skip_spaces (leading_args);
> +
> +      if (*leading_args != '\0')
> +	alias_cmd->leading_args = xstrdup (leading_args);
>      }
>  }
>  
> @@ -2051,6 +2273,26 @@ You can supply a command number to start with, or a `+' to start after\n\
>  the previous command number shown."),
>  	   &showlist);
>  
> +  c = add_cmd ("leading-args", class_support, set_leading_args_command, _("\
> +Set or clear leading args automatically preprended to a command or alias.\n\

"preprended" -> "prepended"

> +Usage: set leading-args COMMAND [LEADING-ARGS...]\n\
> +Set or clear the leading arguments automatically prepended\n\
> +to the arguments the user provides when COMMAND is run.\n\
> +Note that COMMAND can be an alias.  Commands and their aliases\n\
> +do not share their leading arguments, so you can specify different\n\
> +leading arguments for a command and for each of its aliases.\n\
> +Without the [= LEADING-ARGS...], clears COMMAND leading arguments."),
> +	   &setlist);
> +  set_cmd_completer_handle_brkchars (c, leading_args_cmd_completer);
> +
> +  c = add_cmd ("leading-args", class_support, show_leading_args_command, _("\
> +Show the leading args of a command, or of all commands.\n\
> +Usage: show leading-args [COMMAND]\n\
> +Show the leading args of COMMAND.  Without COMMAND, show the leading args\n\
> +of all commands."),
> +	   &showlist);
> +  set_cmd_completer_handle_brkchars (c, leading_args_cmd_completer);
> +
>    add_cmd ("version", no_set_class, show_version,
>  	   _("Show what version of GDB this is."), &showlist);
>  
> @@ -2202,19 +2444,37 @@ When 'on', each command is displayed as it is executed."),
>  			   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 [LEADING-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%\
> +You can optionally provide LEADING-ARGS to define at the same time\n\
> +ALIAS and its leading args.  This is the equivalent of:\n\
> +  alias ALIAS = COMMAND\n\
> +  set leading-args ALIAS LEADING-ARGS...\n\
>  \n\
>  Examples:\n\
>  Make \"spe\" an alias of \"set print elements\":\n\
> -  alias spe = 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\
> diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
> index edea3ad021..cc93b9ac6c 100644
> --- a/gdb/cli/cli-decode.c
> +++ b/gdb/cli/cli-decode.c
> @@ -343,7 +343,7 @@ add_alias_cmd (const char *name, const char *oldname,
>    struct cmd_list_element *old;
>  
>    tmp = oldname;
> -  old = lookup_cmd (&tmp, *list, "", 1, 1);
> +  old = lookup_cmd (&tmp, *list, "", NULL, 1, 1);
>  
>    return add_alias_cmd (name, old, theclass, abbrev_flag, list);
>  }
> @@ -1045,6 +1045,7 @@ void
>  help_cmd (const char *command, struct ui_file *stream)
>  {
>    struct cmd_list_element *c;
> +  const char *initial_command = command;
>  
>    if (!command)
>      {
> @@ -1058,7 +1059,7 @@ help_cmd (const char *command, struct ui_file *stream)
>        return;
>      }
>  
> -  c = lookup_cmd (&command, cmdlist, "", 0, 0);
> +  c = lookup_cmd (&command, cmdlist, "", NULL, 0, 0);
>  
>    if (c == 0)
>      return;
> @@ -1078,6 +1079,41 @@ help_cmd (const char *command, struct ui_file *stream)
>    fputs_filtered (c->doc, stream);
>    fputs_filtered ("\n", stream);
>  
> +  if (c->func != nullptr)
> +    {
> +      /* Print the leading args of the command if it has some.
> +	 Use lookup_cmd_composition to find if help was requested for
> +	 an alias.  In this case, rather print the alias leading_args.  */
> +
> +      struct cmd_list_element *alias, *prefix_cmd, *cmd;
> +      const char *name, *leading_args;
> +
> +      (void) lookup_cmd_composition (initial_command,
> +				     &alias, &prefix_cmd, &cmd);

Drop the (void).

> +      gdb_assert (cmd != nullptr);
> +      gdb_assert (cmd == c);
> +
> +      if (alias == nullptr)
> +	{
> +	  name = c->name;
> +	  leading_args = c->leading_args;
> +	}
> +      else
> +	{
> +	  name = alias->name;
> +	  leading_args = alias->leading_args;
> +	}
> +      if (leading_args != nullptr)
> +	{
> +	  fputs_filtered ("leading-args ", stream);
> +	  fprintf_styled (stream, title_style.style (),
> +			  "%s%s",
> +			  prefix_cmd == nullptr ? "" : prefix_cmd->prefixname,
> +			  name);
> +	  fprintf_filtered (stream, " = %s\n", leading_args);
> +	}
> +    }
> +
>    if (c->prefixlist == 0 && c->func != NULL)
>      return;
>    fprintf_filtered (stream, "\n");
> @@ -1262,6 +1298,13 @@ print_help_for_command (struct cmd_list_element *c, const char *prefix,
>    fputs_filtered (" -- ", stream);
>    print_doc_line (stream, c->doc);
>    fputs_filtered ("\n", stream);
> +  if (c->leading_args != nullptr)
> +    {
> +      fputs_filtered ("  leading-args ", stream);
> +      fprintf_styled (stream, title_style.style (),
> +		      "%s%s", prefix, c->name);
> +      fprintf_filtered (stream, " = %s\n", c->leading_args);
> +    }
>  
>    if (recurse
>        && c->prefixlist != 0
> @@ -1409,8 +1452,12 @@ valid_user_defined_cmd_name_p (const char *name)
>     the list in which there are ambiguous choices (and *TEXT will be set to
>     the ambiguous text string).
>  
> +   if LEADING_ARGS is not null and the found command has leading args defined,
> +   then *LEADING_ARGS points at these leading args.
> +
>     If the located command was an abbreviation, this routine returns the base
> -   command of the abbreviation.
> +   command of the abbreviation.  Note that *LEADING_ARGS will point at the
> +   leading args defined for the alias.
>  
>     It does no error reporting whatsoever; control will always return
>     to the superior routine.
> @@ -1437,11 +1484,13 @@ valid_user_defined_cmd_name_p (const char *name)
>  
>  struct cmd_list_element *
>  lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
> -	      struct cmd_list_element **result_list, int ignore_help_classes)
> +	      struct cmd_list_element **result_list, const char **leading_args,
> +	      int ignore_help_classes)
>  {
>    char *command;
>    int len, nfound;
>    struct cmd_list_element *found, *c;
> +  bool found_alias = false;
>    const char *line = *text;
>  
>    while (**text == ' ' || **text == '\t')
> @@ -1477,6 +1526,8 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
>  	/* Will be modified in calling routine
>  	   if we know what the prefix command is.  */
>  	*result_list = 0;
> +      if (leading_args != NULL)
> +	*leading_args = nullptr;
>        return CMD_LIST_AMBIGUOUS;	/* Ambiguous.  */
>      }
>  
> @@ -1492,22 +1543,30 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
>         are warning about the alias, we may also warn about the command
>         itself and we will adjust the appropriate DEPRECATED_WARN_USER
>         flags.  */
> -      
> +
>        if (found->deprecated_warn_user)
>  	deprecated_cmd_warning (line);
> +
> +      /* Return the leading_args of the alias, not the leading_args
> +	 of the command it is pointing to.  */
> +      if (leading_args != NULL)
> +	*leading_args = found->leading_args;
>        found = found->cmd_pointer;
> +      found_alias = true;
>      }
>    /* If we found a prefix command, keep looking.  */
>  
>    if (found->prefixlist)
>      {
>        c = lookup_cmd_1 (text, *found->prefixlist, result_list,
> -			ignore_help_classes);
> +			leading_args, ignore_help_classes);
>        if (!c)
>  	{
>  	  /* Didn't find anything; this is as far as we got.  */
>  	  if (result_list != NULL)
>  	    *result_list = clist;
> +	  if (!found_alias && leading_args != NULL)
> +	    *leading_args = found->leading_args;
>  	  return found;
>  	}
>        else if (c == CMD_LIST_AMBIGUOUS)
> @@ -1522,11 +1581,18 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
>  	         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 leading_args args.  */
> +	  if (leading_args != nullptr)
> +	    *leading_args = nullptr;
>  	  return c;
>  	}
>        else
>  	{
>  	  /* We matched!  */
> +	  /*
> +	  if (leading_args != NULL && *leading_args == nullptr)
> +	    *leading_args = c->leading_args;
> +	    */

Leftover?

>  	  return c;
>  	}
>      }
> @@ -1534,6 +1600,8 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
>      {
>        if (result_list != NULL)
>  	*result_list = clist;
> +      if (!found_alias && leading_args != NULL)
> +	*leading_args = found->leading_args;
>        return found;
>      }
>  }
> @@ -1553,21 +1621,28 @@ undef_cmd_error (const char *cmdtype, const char *q)
>  
>  /* Look up the contents of *LINE as a command in the command list LIST.
>     LIST is a chain of struct cmd_list_element's.
> -   If it is found, return the struct cmd_list_element for that command
> -   and update *LINE to point after the command name, at the first argument.
> +   If it is found, return the struct cmd_list_element for that command,
> +   update *LINE to point after the command name, at the first argument
> +   and update *LEADING_ARGS (if LEADING_ARGS is not null) to point at
> +   the leading args to prepend to the user provided args when running
> +   the command.
> +   Note that if the found cmd_list_element is found via an alias,
> +   the leading args of the alias are returned.
> +
>     If not found, call error if ALLOW_UNKNOWN is zero
>     otherwise (or if error returns) return zero.
>     Call error if specified command is ambiguous,
>     unless ALLOW_UNKNOWN is negative.
>     CMDTYPE precedes the word "command" in the error message.
>  
> -   If INGNORE_HELP_CLASSES is nonzero, ignore any command list
> +   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 0).  */
>  
>  struct cmd_list_element *
>  lookup_cmd (const char **line, struct cmd_list_element *list,
>  	    const char *cmdtype,
> +	    const char **leading_args,
>  	    int allow_unknown, int ignore_help_classes)
>  {
>    struct cmd_list_element *last_list = 0;
> @@ -1579,7 +1654,7 @@ lookup_cmd (const char **line, struct cmd_list_element *list,
>    if (!*line)
>      error (_("Lack of needed %scommand"), cmdtype);
>  
> -  c = lookup_cmd_1 (line, list, &last_list, ignore_help_classes);
> +  c = lookup_cmd_1 (line, list, &last_list, leading_args, ignore_help_classes);
>  
>    if (!c)
>      {
> diff --git a/gdb/cli/cli-decode.h b/gdb/cli/cli-decode.h
> index 16a6ce9f66..52089022b5 100644
> --- a/gdb/cli/cli-decode.h
> +++ b/gdb/cli/cli-decode.h
> @@ -69,6 +69,8 @@ struct cmd_list_element
>      {
>        if (doc && doc_allocated)
>  	xfree ((char *) doc);
> +      if (leading_args)
> +	xfree ((char *) leading_args);
>      }
>  
>      DISABLE_COPY_AND_ASSIGN (cmd_list_element);
> @@ -176,6 +178,10 @@ struct cmd_list_element
>      /* Hook for another command to be executed after this command.  */
>      struct cmd_list_element *hook_post = nullptr;
>  
> +    /* Leading arguments to automatically prepend to the user
> +       provided arguments when running this command or alias.  */
> +    const char *leading_args = nullptr;
> +
>      /* Nonzero identifies a prefix command.  For them, the address
>         of the variable containing the list of subcommands.  */
>      struct cmd_list_element **prefixlist = nullptr;
> diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
> index 4fc9c70259..e5f944f0bd 100644
> --- a/gdb/cli/cli-script.c
> +++ b/gdb/cli/cli-script.c
> @@ -971,7 +971,7 @@ process_next_line (const char *p, struct command_line **command,
>        /* Resolve command abbreviations (e.g. 'ws' for 'while-stepping').  */
>        const char *cmd_name = p;
>        struct cmd_list_element *cmd
> -	= lookup_cmd_1 (&cmd_name, cmdlist, NULL, 1);
> +	= lookup_cmd_1 (&cmd_name, cmdlist, NULL, NULL, 1);
>        cmd_name = skip_spaces (cmd_name);
>        bool inline_cmd = *cmd_name != '\0';
>  
> @@ -1328,7 +1328,7 @@ validate_comname (const char **comname)
>        std::string prefix (*comname, last_word - 1);
>        const char *tem = prefix.c_str ();
>  
> -      c = lookup_cmd (&tem, cmdlist, "", 0, 1);
> +      c = lookup_cmd (&tem, cmdlist, "", NULL, 0, 1);
>        if (c->prefixlist == NULL)
>  	error (_("\"%s\" is not a prefix command."), prefix.c_str ());
>  
> @@ -1384,7 +1384,7 @@ do_define_command (const char *comname, int from_tty,
>  
>    /* Look it up, and verify that we got an exact match.  */
>    tem = comname;
> -  c = lookup_cmd (&tem, *list, "", -1, 1);
> +  c = lookup_cmd (&tem, *list, "", NULL, -1, 1);
>    if (c && strcmp (comname, c->name) != 0)
>      c = 0;
>  
> @@ -1419,7 +1419,7 @@ do_define_command (const char *comname, int from_tty,
>      {
>        /* Look up cmd it hooks, and verify that we got an exact match.  */
>        tem = comname + hook_name_size;
> -      hookc = lookup_cmd (&tem, *list, "", -1, 0);
> +      hookc = lookup_cmd (&tem, *list, "", NULL, -1, 0);
>        if (hookc && strcmp (comname + hook_name_size, hookc->name) != 0)
>  	hookc = 0;
>        if (!hookc && commands == nullptr)
> @@ -1488,7 +1488,7 @@ document_command (const char *comname, int from_tty)
>    list = validate_comname (&comname);
>  
>    tem = comname;
> -  c = lookup_cmd (&tem, *list, "", 0, 1);
> +  c = lookup_cmd (&tem, *list, "", NULL, 0, 1);
>  
>    if (c->theclass != class_user)
>      error (_("Command \"%s\" is built-in."), comfull);
> diff --git a/gdb/command.h b/gdb/command.h
> index 2c608048d5..1df4d7fb57 100644
> --- a/gdb/command.h
> +++ b/gdb/command.h
> @@ -244,11 +244,13 @@ extern enum cmd_types cmd_type (struct cmd_list_element *cmd);
>  extern struct cmd_list_element *lookup_cmd (const char **,
>  					    struct cmd_list_element *,
>  					    const char *,
> +					    const char **,
>  					    int, int);
>  
>  extern struct cmd_list_element *lookup_cmd_1 (const char **,
>  					      struct cmd_list_element *,
>  					      struct cmd_list_element **,
> +					      const char **,
>  					      int);
>  
>  extern struct cmd_list_element *deprecate_cmd (struct cmd_list_element *,
> diff --git a/gdb/completer.c b/gdb/completer.c
> index 07facfb012..b88bdbdeca 100644
> --- a/gdb/completer.c
> +++ b/gdb/completer.c
> @@ -1341,7 +1341,7 @@ complete_line_internal_1 (completion_tracker &tracker,
>      }
>    else
>      {
> -      c = lookup_cmd_1 (&p, cmdlist, &result_list, ignore_help_classes);
> +      c = lookup_cmd_1 (&p, cmdlist, &result_list, NULL, ignore_help_classes);
>      }
>  
>    /* Move p up to the next interesting thing.  */
> diff --git a/gdb/guile/scm-cmd.c b/gdb/guile/scm-cmd.c
> index f2fa40e453..8cf70f6e52 100644
> --- a/gdb/guile/scm-cmd.c
> +++ b/gdb/guile/scm-cmd.c
> @@ -515,7 +515,7 @@ gdbscm_parse_command_name (const char *name,
>    prefix_text[i + 1] = '\0';
>  
>    prefix_text2 = prefix_text;
> -  elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, 1);
> +  elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, NULL, 1);
>    if (elt == NULL || elt == CMD_LIST_AMBIGUOUS)
>      {
>        msg = xstrprintf (_("could not find command prefix '%s'"), prefix_text);
> diff --git a/gdb/guile/scm-param.c b/gdb/guile/scm-param.c
> index 53120cb23e..4d3ce6770a 100644
> --- a/gdb/guile/scm-param.c
> +++ b/gdb/guile/scm-param.c
> @@ -463,13 +463,13 @@ add_setshow_generic (enum var_types param_type, enum command_class cmd_class,
>    /* Lookup created parameter, and register Scheme object against the
>       parameter context.  Perform this task against both lists.  */
>    tmp_name = cmd_name;
> -  param = lookup_cmd (&tmp_name, *show_list, "", 0, 1);
> +  param = lookup_cmd (&tmp_name, *show_list, "", NULL, 0, 1);
>    gdb_assert (param != NULL);
>    set_cmd_context (param, self);
>    *set_cmd = param;
>  
>    tmp_name = cmd_name;
> -  param = lookup_cmd (&tmp_name, *set_list, "", 0, 1);
> +  param = lookup_cmd (&tmp_name, *set_list, "", NULL, 0, 1);
>    gdb_assert (param != NULL);
>    set_cmd_context (param, self);
>    *show_cmd = param;
> @@ -966,7 +966,7 @@ pascm_parameter_defined_p (const char *name, struct cmd_list_element *list)
>  {
>    struct cmd_list_element *c;
>  
> -  c = lookup_cmd_1 (&name, list, NULL, 1);
> +  c = lookup_cmd_1 (&name, list, NULL, NULL, 1);
>  
>    /* If the name is ambiguous that's ok, it's a new parameter still.  */
>    return c != NULL && c != CMD_LIST_AMBIGUOUS;
> diff --git a/gdb/infcmd.c b/gdb/infcmd.c
> index 0ad9b91677..cc711a524a 100644
> --- a/gdb/infcmd.c
> +++ b/gdb/infcmd.c
> @@ -3148,7 +3148,7 @@ is restored."),
>  				     show_inferior_tty_command,
>  				     &setlist, &showlist);
>    cmd_name = "inferior-tty";
> -  c = lookup_cmd (&cmd_name, setlist, "", -1, 1);
> +  c = lookup_cmd (&cmd_name, setlist, "", NULL, -1, 1);
>    gdb_assert (c != NULL);
>    add_alias_cmd ("tty", c, class_alias, 0, &cmdlist);
>  
> @@ -3161,7 +3161,7 @@ Follow this command with any number of args, to be passed to the program."),
>  				   set_args_command,
>  				   show_args_command,
>  				   &setlist, &showlist);
> -  c = lookup_cmd (&cmd_name, setlist, "", -1, 1);
> +  c = lookup_cmd (&cmd_name, setlist, "", NULL, -1, 1);
>    gdb_assert (c != NULL);
>    set_cmd_completer (c, filename_completer);
>  
> @@ -3180,7 +3180,7 @@ working directory."),
>  				   set_cwd_command,
>  				   show_cwd_command,
>  				   &setlist, &showlist);
> -  c = lookup_cmd (&cmd_name, setlist, "", -1, 1);
> +  c = lookup_cmd (&cmd_name, setlist, "", NULL, -1, 1);
>    gdb_assert (c != NULL);
>    set_cmd_completer (c, filename_completer);
>  
> diff --git a/gdb/python/py-auto-load.c b/gdb/python/py-auto-load.c
> index c7b9afdb11..559652de93 100644
> --- a/gdb/python/py-auto-load.c
> +++ b/gdb/python/py-auto-load.c
> @@ -84,12 +84,12 @@ Show the debugger's behaviour regarding auto-loaded Python scripts, "
>  			   NULL, NULL, show_auto_load_python_scripts,
>  			   &setlist, &showlist);
>    cmd_name = "auto-load-scripts";
> -  cmd = lookup_cmd (&cmd_name, setlist, "", -1, 1);
> +  cmd = lookup_cmd (&cmd_name, setlist, "", NULL, -1, 1);
>    deprecate_cmd (cmd, "set auto-load python-scripts");
>  
>    /* It is needed because lookup_cmd updates the CMD_NAME pointer.  */
>    cmd_name = "auto-load-scripts";
> -  cmd = lookup_cmd (&cmd_name, showlist, "", -1, 1);
> +  cmd = lookup_cmd (&cmd_name, showlist, "", NULL, -1, 1);
>    deprecate_cmd (cmd, "show auto-load python-scripts");
>  
>    add_cmd ("python-scripts", class_info, info_auto_load_python_scripts,
> diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
> index 87d1888c52..70e328080c 100644
> --- a/gdb/python/py-cmd.c
> +++ b/gdb/python/py-cmd.c
> @@ -396,7 +396,7 @@ gdbpy_parse_command_name (const char *name,
>    std::string prefix_text (name, i + 1);
>  
>    prefix_text2 = prefix_text.c_str ();
> -  elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, 1);
> +  elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, NULL, 1);
>    if (elt == NULL || elt == CMD_LIST_AMBIGUOUS)
>      {
>        PyErr_Format (PyExc_RuntimeError, _("Could not find command prefix %s."),
> diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c
> index afeff581ee..87af351051 100644
> --- a/gdb/python/py-param.c
> +++ b/gdb/python/py-param.c
> @@ -566,12 +566,12 @@ add_setshow_generic (int parmclass, enum command_class cmdclass,
>    /* Lookup created parameter, and register Python object against the
>       parameter context.  Perform this task against both lists.  */
>    tmp_name = cmd_name;
> -  param = lookup_cmd (&tmp_name, *show_list, "", 0, 1);
> +  param = lookup_cmd (&tmp_name, *show_list, "", NULL, 0, 1);
>    if (param)
>      set_cmd_context (param, self);
>  
>    tmp_name = cmd_name;
> -  param = lookup_cmd (&tmp_name, *set_list, "", 0, 1);
> +  param = lookup_cmd (&tmp_name, *set_list, "", NULL, 0, 1);
>    if (param)
>      set_cmd_context (param, self);
>  }
> diff --git a/gdb/remote.c b/gdb/remote.c
> index 42c730e48f..249725a263 100644
> --- a/gdb/remote.c
> +++ b/gdb/remote.c
> @@ -14312,10 +14312,10 @@ If set, a break, instead of a cntrl-c, is sent to the remote target."),
>  			   set_remotebreak, show_remotebreak,
>  			   &setlist, &showlist);
>    cmd_name = "remotebreak";
> -  cmd = lookup_cmd (&cmd_name, setlist, "", -1, 1);
> +  cmd = lookup_cmd (&cmd_name, setlist, "", NULL, -1, 1);
>    deprecate_cmd (cmd, "set remote interrupt-sequence");
>    cmd_name = "remotebreak"; /* needed because lookup_cmd updates the pointer */
> -  cmd = lookup_cmd (&cmd_name, showlist, "", -1, 1);
> +  cmd = lookup_cmd (&cmd_name, showlist, "", NULL, -1, 1);
>    deprecate_cmd (cmd, "show remote interrupt-sequence");
>  
>    add_setshow_enum_cmd ("interrupt-sequence", class_support,
> diff --git a/gdb/top.c b/gdb/top.c
> index 60f81b3bf8..7faac35cc7 100644
> --- a/gdb/top.c
> +++ b/gdb/top.c
> @@ -535,6 +535,11 @@ set_repeat_arguments (const char *args)
>    repeat_arguments = args;
>  }
>  
> +/* Flag for whether we want to use the configured leading args.
> +   Default is yes.  */
> +
> +static int enable_leading_args_var = 1;
> +
>  /* Execute the line P as a command, in the current user context.
>     Pass FROM_TTY as second argument to the defining function.  */
>  
> @@ -563,6 +568,8 @@ execute_command (const char *p, int from_tty)
>      {
>        const char *cmd = p;
>        const char *arg;
> +      const char *leading_args;
> +      std::string leading_args_and_arg;
>        int was_sync = current_ui->prompt_state == PROMPT_BLOCKED;
>  
>        line = p;
> @@ -570,15 +577,28 @@ execute_command (const char *p, int from_tty)
>        /* If trace-commands is set then this will print this command.  */
>        print_command_trace ("%s", p);
>  
> -      c = lookup_cmd (&cmd, cmdlist, "", 0, 1);
> +      c = lookup_cmd (&cmd, cmdlist, "", &leading_args, 0, 1);
>        p = cmd;
>  
>        scoped_restore save_repeat_args
>  	= make_scoped_restore (&repeat_arguments, nullptr);
>        const char *args_pointer = p;
>  
> -      /* Pass null arg rather than an empty one.  */
> -      arg = *p ? p : 0;
> +      if (leading_args != nullptr && enable_leading_args_var)
> +	{
> +	  leading_args_and_arg = std::string (leading_args);

This statement seems unnecessary, since both branches below
overwrite leading_args_and_arg again.

> +	  if (*p)
> +	    leading_args_and_arg = std::string (leading_args)
> +	      + ' ' + std::string (p);
> +	  else
> +	    leading_args_and_arg = std::string (leading_args);
> +	  arg = leading_args_and_arg.c_str ();
> +	}
> +      else
> +	{
> +	  /* Pass null arg rather than an empty one.  */
> +	  arg = *p ? p : 0;
> +	}

Thanks,
Pedro Alves


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]