public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFAv8 0/3] Allow the user to define default args for aliases
@ 2020-06-21 18:31 Philippe Waroquiers
  2020-06-21 18:31 ` [RFAv8 1/3] default-args: allow to define default arguments " Philippe Waroquiers
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Philippe Waroquiers @ 2020-06-21 18:31 UTC (permalink / raw)
  To: gdb-patches

Allow the user to define default args for user-defined aliases.

This is version 8 of the patch series.
The documentation (NEWS and gdb.texinfo) should be re-reviewed,
as default-args are now only provided by the 'alias' command.

Compared to version 7 and 6:
It removes the commands 'set|show default-args' as these could introduce
a future backward incompatibility if alias expansion would be done
dynamically by GDB when executing the alias.
For the same reason, it implements the prevention of defining an alias
of an alias having default args, as suggested by Simon.
This prevention is implemented in cli-cmds.c validate_aliased_command
(which is valid_command_p renamed and modified).

The default-args.exp test was enhanced to test this prevention.
When relevant, the 'set/show default-args' have been converted to
use the 'alias' command or 'help aliases'.

The version 6 of the patch series did the following changes,
compared to the previous version:
  * it handles the comment of Simon that default args should only
    be available for user-defined aliases and not for GDB commands
    and GDB pre-defined aliases.
    As default args are now only for user-defined aliases,
    the 'show/set enable-default-args [on|off]' commands have been
    removed.
  * documentation changed accordingly.
  * help and apropos now shows the full definition of the aliases having
    default args.

Previous versions handled the comments of Christian/Eli/Pedro/Tom/Simon.

This patch series changes the alias command to be:
  alias [-a] [--] ALIAS = COMMAND [DEFAULT-ARGS...]


Using the above default-args, you can define powerful aliases.

For example:

  alias bt_ALL = backtrace -entry-values both -frame-arg all -past-main -past-entry -full

defines the alias bt_ALL that will give as much information as possible
in a backtrace.

Default args can usefully be combined with the 'with' command, such as:

Make "wLapPeu" an alias of 2 nested "with":
  alias wLapPeu = with language pascal -- with print elements unlimited --

or have an alias pp10 to pretty print an expression with a maximum of
10 elements:

  alias pp10 = with print pretty -- with print elem 10 -- print

This patch series also adds a completer for 'alias'.



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [RFAv8 1/3] default-args: allow to define default arguments for aliases
  2020-06-21 18:31 [RFAv8 0/3] Allow the user to define default args for aliases Philippe Waroquiers
@ 2020-06-21 18:31 ` Philippe Waroquiers
  2020-06-22 14:09   ` Simon Marchi
  2020-06-21 18:31 ` [RFAv8 2/3] Add tests for new alias default-args related commands and arguments Philippe Waroquiers
  2020-06-21 18:31 ` [RFAv8 3/3] NEWS and documentation for alias default-args related concept and commands Philippe Waroquiers
  2 siblings, 1 reply; 9+ messages in thread
From: Philippe Waroquiers @ 2020-06-21 18:31 UTC (permalink / raw)
  To: gdb-patches

Currently, a user can define an alias, but cannot have default
arguments for this alias.

This patch modifies the 'alias' command so that default args can
be provided.
    (gdb) h alias
    Define a new command that is an alias of an existing command.
    Usage: alias [-a] [--] ALIAS = COMMAND [DEFAULT-ARGS...]
    ALIAS is the name of the alias command to create.
    COMMAND is the command being aliased to.

    Options:
      -a
        Specify that ALIAS is an abbreviation of COMMAND.
        Abbreviations are not used in command completion..

    GDB will automatically prepend the provided DEFAULT-ARGS to the list
    of arguments explicitly provided when using ALIAS.
    Use "help aliases" to list all user defined aliases and their default 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 --
    (gdb)

The way 'default-args' is implemented makes it trivial to set default
args also for GDB commands (such as "backtrace") and for GDB pre-defined
aliases (such as "bt").  It was however deemed better to not allow to
define default arguments for pre-defined commands and aliases, to avoid
users believing that e.g. default args for "backtrace" would apply to "bt".

If needed, default-args could be allowed for GDB predefined commands
and aliases by adding a command
'set default-args GDB_COMMAND_OR_PREDEFINED_ALIAS [DEFAULT-ARGS...]'.

* '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.

* Help and apropos commands show the definitions of the aliases
  that have default arguments, e.g.
        (gdb) help backtrace
        backtrace, btf, where, bt
          alias btf = backtrace -full -past-entry -past-main
        Print backtrace of all stack frames, or innermost COUNT frames.
        Usage: backtrace [OPTION]... [QUALIFIER]... [COUNT | -COUNT]

        Options:
          -entry-values no|only|preferred|if-needed|both|compact|default
            Set printing of function arguments at function entry.
        ...

gdb/ChangeLog
YYYY-MM-DD  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* cli/cli-cmds.c (lookup_cmd_for_default_args)
	(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 DEFAULT-ARGS... arguments.
	Use option framework.
	(_initialize_cli_cmds): Update alias command help.
	Update aliases command help.
	(show_user):
	Add NULL for new default_args lookup_cmd argument.
	(valid_command_p): Rename to validate_aliased_command.
	Add NULL for new default_args lookup_cmd argument.  Verify that the
	aliased_command has no default args.
	* cli/cli-decode.c (help_cmd): Show aliases definitions.
	(lookup_cmd_1, lookup_cmd): New argument default_args.
	(add_alias_cmd):
	Add NULL for new default_args lookup_cmd argument.
	(print_help_for_command): Show default args under the layout
	 alias some_alias = some_aliased_cmd some_alias_default_arg.
	* cli/cli-decode.h (struct cmd_list_element): New member default_args.
	xfree default_args in destructor.
	* cli/cli-script.c (process_next_line, do_define_command):
	Add NULL for new default_args lookup_cmd argument.
	* command.h: Declare new default_args argument in lookup_cmd
	and lookup_cmd_1.
	* completer.c (complete_line_internal_1):
	Add NULL for new default_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.
	* 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 (execute_command): Prepend default_args if command has some.
	(set_verbose):
	Add NULL for new default_args lookup_cmd or lookup_cmd_1 argument.
	* tracepoint.c (validate_actionline, encode_actions_1):
	Add NULL for new default_args lookup_cmd or lookup_cmd_1 argument.
---
 gdb/cli/cli-cmds.c        | 247 ++++++++++++++++++++++++++++++--------
 gdb/cli/cli-decode.c      | 110 ++++++++++++++---
 gdb/cli/cli-decode.h      |   4 +
 gdb/cli/cli-script.c      |  12 +-
 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                 |  21 +++-
 gdb/tracepoint.c          |   6 +-
 15 files changed, 336 insertions(+), 96 deletions(-)

diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index cd6f785659..2ff515ace7 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -50,6 +50,7 @@
 #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"
@@ -221,6 +222,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);
@@ -315,7 +317,54 @@ with_command_completer (struct cmd_list_element *ignore,
   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.  */
 
@@ -1541,7 +1590,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);
@@ -1573,6 +1622,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".  */
+  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.
@@ -1600,24 +1714,29 @@ argv_to_string (char **argv, int n)
 }
 
 /* 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.  */
@@ -1625,7 +1744,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 [DEFAULT-ARGS...]"));
 }
 
 /* Make an alias of an existing command.  */
@@ -1633,8 +1752,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;
 
@@ -1645,24 +1769,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 *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')
@@ -1682,14 +1800,13 @@ alias_command (const char *args, int from_tty)
   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));
@@ -1718,6 +1835,8 @@ alias_command (const char *args, int from_tty)
   }
 
 
+  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
 
@@ -1730,8 +1849,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
     {
@@ -1751,19 +1870,29 @@ 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 != 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
@@ -1938,7 +2067,7 @@ setting_cmd (const char *fnname, struct cmd_list_element *showlist,
     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)
     error (_("First argument of %s must be a "
@@ -2128,7 +2257,7 @@ well documented as user commands."),
 	   &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\
@@ -2454,19 +2583,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 [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 be used in command completion.\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\
+  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 a4ef93c62b..85f50aa8e4 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -337,7 +337,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);
 }
@@ -1040,6 +1040,40 @@ fput_command_name_styled (struct cmd_list_element *c, struct ui_file *stream)
   fprintf_styled (stream, title_style.style (), "%s%s", prefixname, c->name);
 }
 
+/* Print the definition of alias C using title style for alias
+   and aliased command.  */
+
+static void
+fput_alias_definition_styled (struct cmd_list_element *c,
+			      struct ui_file *stream)
+{
+  gdb_assert (c->cmd_pointer != nullptr);
+  fputs_filtered ("  alias ", stream);
+  fput_command_name_styled (c, stream);
+  fprintf_filtered (stream, " = ");
+  fput_command_name_styled (c->cmd_pointer, stream);
+  fprintf_filtered (stream, " %s\n", c->default_args.c_str ());
+}
+
+/* Print the definition of the aliases of CMD that have default args.  */
+
+static void
+fput_aliases_definition_styled (struct cmd_list_element *cmd,
+				struct ui_file *stream)
+{
+  if (cmd->aliases != nullptr)
+    {
+      for (cmd_list_element *iter = cmd->aliases;
+	   iter;
+	   iter = iter->alias_chain)
+	{
+	  if (!iter->default_args.empty ())
+	    fput_alias_definition_styled (iter, stream);
+	}
+    }
+}
+
+
 /* If C has one or more aliases, style print the name of C and
    the name of its aliases, separated by commas.
    If ALWAYS_FPUT_C_NAME, print the name of C even if it has no aliases.
@@ -1081,12 +1115,21 @@ print_doc_of_command (struct cmd_list_element *c, const char *prefix,
   if (verbose)
     fputs_filtered ("\n", stream);
 
-  fput_command_names_styled (c, true, " -- ", stream);
+  fput_command_names_styled (c, true,
+			     verbose ? "" : " -- ", stream);
   if (verbose)
-    fputs_highlighted (c->doc, highlight, stream);
+    {
+      fputs_filtered ("\n", stream);
+      fput_aliases_definition_styled (c, stream);
+      fputs_highlighted (c->doc, highlight, stream);
+      fputs_filtered ("\n", stream);
+    }
   else
-    print_doc_line (stream, c->doc, false);
-  fputs_filtered ("\n", stream);
+    {
+      print_doc_line (stream, c->doc, false);
+      fputs_filtered ("\n", stream);
+      fput_aliases_definition_styled (c, stream);
+    }
 }
 
 /* Recursively walk the commandlist structures, and print out the
@@ -1183,7 +1226,7 @@ help_cmd (const char *command, struct ui_file *stream)
     }
 
   const char *orig_command = command;
-  c = lookup_cmd (&command, cmdlist, "", 0, 0);
+  c = lookup_cmd (&command, cmdlist, "", NULL, 0, 0);
 
   if (c == 0)
     return;
@@ -1205,6 +1248,7 @@ help_cmd (const char *command, struct ui_file *stream)
   /* If the user asked 'help somecommand' and there is no alias,
      the false indicates to not output the (single) command name.  */
   fput_command_names_styled (c, false, "\n", stream);
+  fput_aliases_definition_styled (c, stream);
   fputs_filtered (c->doc, stream);
   fputs_filtered ("\n", stream);
 
@@ -1341,7 +1385,7 @@ help_all (struct ui_file *stream)
 	      fprintf_filtered (stream, "\nUnclassified commands\n\n");
 	      seen_unclassified = 1;
 	    }
-	  print_help_for_command (c, 1, stream);
+	  print_help_for_command (c, true, stream);
 	}
     }
 
@@ -1399,6 +1443,9 @@ print_help_for_command (struct cmd_list_element *c,
   fput_command_names_styled (c, true, " -- ", stream);
   print_doc_line (stream, c->doc, false);
   fputs_filtered ("\n", stream);
+  if (!c->default_args.empty ())
+    fput_alias_definition_styled (c, stream);
+  fput_aliases_definition_styled (c, stream);
 
   if (recurse
       && c->prefixlist != 0
@@ -1582,8 +1629,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 DEFAULT_ARGS is not null, *DEFAULT_ARGS is set to the found command
+   default args (possibly empty).
+
    If the located command was an abbreviation, this routine returns the base
-   command of the abbreviation.
+   command of the abbreviation.  Note that *DEFAULT_ARGS will contain the
+   default args defined for the alias.
 
    It does no error reporting whatsoever; control will always return
    to the superior routine.
@@ -1610,11 +1661,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, std::string *default_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')
@@ -1646,10 +1699,12 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
 
   if (nfound > 1)
     {
-      if (result_list != NULL)
+      if (result_list != nullptr)
 	/* Will be modified in calling routine
 	   if we know what the prefix command is.  */
 	*result_list = 0;
+      if (default_args != nullptr)
+	*default_args = std::string ();
       return CMD_LIST_AMBIGUOUS;	/* Ambiguous.  */
     }
 
@@ -1665,22 +1720,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 default_args of the alias, not the default_args
+	 of the command it is pointing to.  */
+      if (default_args != nullptr)
+	*default_args = found->default_args;
       found = found->cmd_pointer;
+      found_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);
+			default_args, ignore_help_classes);
       if (!c)
 	{
 	  /* Didn't find anything; this is as far as we got.  */
-	  if (result_list != NULL)
+	  if (result_list != nullptr)
 	    *result_list = clist;
+	  if (!found_alias && default_args != nullptr)
+	    *default_args = found->default_args;
 	  return found;
 	}
       else if (c == CMD_LIST_AMBIGUOUS)
@@ -1688,13 +1751,16 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
 	  /* We've gotten this far properly, but the next step is
 	     ambiguous.  We need to set the result list to the best
 	     we've found (if an inferior hasn't already set it).  */
-	  if (result_list != NULL)
+	  if (result_list != nullptr)
 	    if (!*result_list)
 	      /* This used to say *result_list = *found->prefixlist.
 	         If that was correct, need to modify the documentation
 	         at the top of this function to clarify what is
 	         supposed to be going on.  */
 	      *result_list = found;
+	  /* For ambiguous commands, do not return any default_args args.  */
+	  if (default_args != nullptr)
+	    *default_args = std::string ();
 	  return c;
 	}
       else
@@ -1705,8 +1771,10 @@ lookup_cmd_1 (const char **text, struct cmd_list_element *clist,
     }
   else
     {
-      if (result_list != NULL)
+      if (result_list != nullptr)
 	*result_list = clist;
+      if (!found_alias && default_args != nullptr)
+	*default_args = found->default_args;
       return found;
     }
 }
@@ -1726,8 +1794,13 @@ 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 *DEFAULT_ARGS (if DEFAULT_ARGS is not null) to the default
+   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 default 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,
@@ -1741,6 +1814,7 @@ undef_cmd_error (const char *cmdtype, const char *q)
 struct cmd_list_element *
 lookup_cmd (const char **line, struct cmd_list_element *list,
 	    const char *cmdtype,
+	    std::string *default_args,
 	    int allow_unknown, int ignore_help_classes)
 {
   struct cmd_list_element *last_list = 0;
@@ -1752,7 +1826,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, default_args, ignore_help_classes);
 
   if (!c)
     {
diff --git a/gdb/cli/cli-decode.h b/gdb/cli/cli-decode.h
index f4719bfac4..f855ee5724 100644
--- a/gdb/cli/cli-decode.h
+++ b/gdb/cli/cli-decode.h
@@ -183,6 +183,10 @@ struct cmd_list_element
     /* Hook for another command to be executed after this command.  */
     struct cmd_list_element *hook_post = nullptr;
 
+    /* Default arguments to automatically prepend to the user
+       provided arguments when running this command or alias.  */
+    std::string default_args;
+
     /* 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 90ee67a5f3..da4a41023a 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -974,7 +974,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';
 
@@ -1331,7 +1331,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 ());
 
@@ -1387,7 +1387,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;
 
@@ -1432,7 +1432,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)
@@ -1518,7 +1518,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);
@@ -1566,7 +1566,7 @@ define_prefix_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 != nullptr && strcmp (comname, c->name) != 0)
     c = nullptr;
 
diff --git a/gdb/command.h b/gdb/command.h
index 32b5b35b0c..2cac5c8ced 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -291,11 +291,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 *,
+					    std::string *,
 					    int, int);
 
 extern struct cmd_list_element *lookup_cmd_1 (const char **,
 					      struct cmd_list_element *,
 					      struct cmd_list_element **,
+					      std::string *,
 					      int);
 
 extern struct cmd_list_element *deprecate_cmd (struct cmd_list_element *,
diff --git a/gdb/completer.c b/gdb/completer.c
index ea07096210..7d26774e85 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -1385,7 +1385,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 ec1adffa25..8fd2772df4 100644
--- a/gdb/guile/scm-cmd.c
+++ b/gdb/guile/scm-cmd.c
@@ -512,7 +512,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 b72766523a..62e2108740 100644
--- a/gdb/guile/scm-param.c
+++ b/gdb/guile/scm-param.c
@@ -466,13 +466,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;
@@ -969,7 +969,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 891da91c80..42b050d3c4 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -3052,7 +3052,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_run, 0, &cmdlist);
 
@@ -3065,7 +3065,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);
 
@@ -3084,7 +3084,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 2084fc43ff..56db946463 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 3c1c566b0a..760208f52b 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -390,7 +390,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 7b183cfa55..fb39187b18 100644
--- a/gdb/python/py-param.c
+++ b/gdb/python/py-param.c
@@ -569,12 +569,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 fd89f2c084..d560c69eca 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -14424,10 +14424,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 c62eb57695..da9b805b47 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -579,6 +579,8 @@ execute_command (const char *p, int from_tty)
     {
       const char *cmd = p;
       const char *arg;
+      std::string default_args;
+      std::string default_args_and_arg;
       int was_sync = current_ui->prompt_state == PROMPT_BLOCKED;
 
       line = p;
@@ -586,15 +588,26 @@ 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, "", &default_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 (!default_args.empty ())
+	{
+	  if (*p != '\0')
+	    default_args_and_arg = default_args + ' ' + p;
+	  else
+	    default_args_and_arg = default_args;
+	  arg = default_args_and_arg.c_str ();
+	}
+      else
+	{
+	  /* Pass null arg rather than an empty one.  */
+	  arg = *p == '\0' ? nullptr : p;
+	}
 
       /* FIXME: cagney/2002-02-02: The c->type test is pretty dodgy
          while the is_complete_command(cfunc) test is just plain
@@ -1957,7 +1970,7 @@ set_verbose (const char *args, int from_tty, struct cmd_list_element *c)
   const char *cmdname = "verbose";
   struct cmd_list_element *showcmd;
 
-  showcmd = lookup_cmd_1 (&cmdname, showlist, NULL, 1);
+  showcmd = lookup_cmd_1 (&cmdname, showlist, NULL, NULL, 1);
   gdb_assert (showcmd != NULL && showcmd != CMD_LIST_AMBIGUOUS);
 
   if (c->doc && c->doc_allocated)
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index f4a208f616..00b7059be5 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -651,7 +651,7 @@ validate_actionline (const char *line, struct breakpoint *b)
   if (*p == '#')		/* comment line */
     return;
 
-  c = lookup_cmd (&p, cmdlist, "", -1, 1);
+  c = lookup_cmd (&p, cmdlist, "", NULL, -1, 1);
   if (c == 0)
     error (_("`%s' is not a tracepoint action, or is ambiguous."), p);
 
@@ -1303,7 +1303,7 @@ encode_actions_1 (struct command_line *action,
       action_exp = action->line;
       action_exp = skip_spaces (action_exp);
 
-      cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
+      cmd = lookup_cmd (&action_exp, cmdlist, "", NULL, -1, 1);
       if (cmd == 0)
 	error (_("Bad action list item: %s"), action_exp);
 
@@ -2673,7 +2673,7 @@ trace_dump_actions (struct command_line *action,
       if (*action_exp == '#')	/* comment line */
 	continue;
 
-      cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
+      cmd = lookup_cmd (&action_exp, cmdlist, "", NULL, -1, 1);
       if (cmd == 0)
 	error (_("Bad action list item: %s"), action_exp);
 
-- 
2.20.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [RFAv8 2/3] Add tests for new alias default-args related commands and arguments.
  2020-06-21 18:31 [RFAv8 0/3] Allow the user to define default args for aliases Philippe Waroquiers
  2020-06-21 18:31 ` [RFAv8 1/3] default-args: allow to define default arguments " Philippe Waroquiers
@ 2020-06-21 18:31 ` Philippe Waroquiers
  2020-06-22 14:18   ` Simon Marchi
  2020-06-21 18:31 ` [RFAv8 3/3] NEWS and documentation for alias default-args related concept and commands Philippe Waroquiers
  2 siblings, 1 reply; 9+ messages in thread
From: Philippe Waroquiers @ 2020-06-21 18:31 UTC (permalink / raw)
  To: gdb-patches

Test the new default-args behaviour and completion for the alias command.
Note that gdb.base/default-args.exp is somewhat copied from
with.exp (the test of the with command), while default-exp.c
is a plain copy of with.c.

gdb/testsuite/ChangeLog
YYYY-MM-DD  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* gdb.base/default-args.exp: New test.
	* gdb.base/default-args.c: New file.
	* gdb.base/alias.exp: Update expected error msg for alias foo=bar.
	* gdb.base/default.exp: Update to new help text and
	make test names unique.
	* gdb.base/help.exp: Likewise.
	* gdb.base/page.exp: Likewise.
	* gdb.base/style.exp: Likewise.
	* gdb.guile/guile.exp: Likewise.
	* gdb.python/python.exp: Likewise.
---
 gdb/testsuite/gdb.base/alias.exp        |   2 +-
 gdb/testsuite/gdb.base/default-args.c   |  41 ++++++++
 gdb/testsuite/gdb.base/default-args.exp | 124 ++++++++++++++++++++++++
 gdb/testsuite/gdb.base/default.exp      |   4 +-
 gdb/testsuite/gdb.base/help.exp         |   2 +-
 gdb/testsuite/gdb.base/page.exp         |   4 +-
 gdb/testsuite/gdb.base/style.exp        |   8 +-
 gdb/testsuite/gdb.guile/guile.exp       |   5 +-
 gdb/testsuite/gdb.python/python.exp     |  37 +++----
 9 files changed, 198 insertions(+), 29 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/default-args.c
 create mode 100644 gdb/testsuite/gdb.base/default-args.exp

diff --git a/gdb/testsuite/gdb.base/alias.exp b/gdb/testsuite/gdb.base/alias.exp
index 6993d42648..03c440dfd7 100644
--- a/gdb/testsuite/gdb.base/alias.exp
+++ b/gdb/testsuite/gdb.base/alias.exp
@@ -56,7 +56,7 @@ test_abbrev_alias set6 "alias -a -- set6 = set" 46
 test_abbrev_alias -a "alias -a -- -a = set" 47
 
 gdb_test "alias set2=set" "already exists: set2"
-gdb_test "alias foo=bar" "Invalid command to alias to: bar"
+gdb_test "alias foo=bar" "Undefined command: \"bar\".  Try \"help\"."
 
 gdb_test_no_output "alias spe = set p elem"
 gdb_test_no_output "spe 50"
diff --git a/gdb/testsuite/gdb.base/default-args.c b/gdb/testsuite/gdb.base/default-args.c
new file mode 100644
index 0000000000..c6426625d4
--- /dev/null
+++ b/gdb/testsuite/gdb.base/default-args.c
@@ -0,0 +1,41 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2019 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int xxx1 = 123;
+
+struct S
+{
+  int a;
+  int b;
+  int c;
+};
+
+struct S g_s = {1, 2, 3};
+
+static void
+inc ()
+{
+  g_s.a++;;
+}
+
+int
+main ()
+{
+  inc ();
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/default-args.exp b/gdb/testsuite/gdb.base/default-args.exp
new file mode 100644
index 0000000000..1caa45c620
--- /dev/null
+++ b/gdb/testsuite/gdb.base/default-args.exp
@@ -0,0 +1,124 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2019 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test the "default-args" arguments and completion of alias command.
+
+load_lib completion-support.exp
+
+standard_testfile .c
+
+if {[build_executable "failed to prepare" $testfile $srcfile debug]} {
+    return -1
+}
+
+clean_restart $binfile
+
+# Basic/core tests using user-visible commands.
+with_test_prefix "basics" {
+    # Define an alias to pretty print something.
+    gdb_test "print g_s" " = {a = 1, b = 2, c = 3}" "simple print"
+    gdb_test_no_output "alias PP = print -pretty --" "alias PP"
+    gdb_test "help PP" "print, PP, inspect, p\r\n  alias PP = print -pretty --\r\n.*"
+    gdb_test "PP g_s" \
+	[multi_line  \
+	     " = {" \
+	     "  a = 1," \
+	     "  b = 2," \
+	     "  c = 3" \
+	     "}"]
+
+    # Define an alias of frame apply all with some default args.
+    gdb_test_no_output "alias frame apply tout = frame apply all -past-entry -past-main" \
+	"alias frame apply tout"
+    gdb_test "help frame apply tout" \
+	"frame apply all, frame apply tout\r\n  alias frame apply tout = frame apply all -past-entry -past-main\r\n.*"
+
+    # Show all aliases.
+    gdb_test "help aliases" \
+	[multi_line  \
+	     "User-defined aliases of other commands." \
+	     "" \
+	     "List of commands:" \
+	     "" \
+	     "PP -- Print value of expression EXP." \
+	     "  alias PP = print -pretty --" \
+	     "frame apply tout -- Apply a command to all frames." \
+	     "  alias frame apply tout = frame apply all -past-entry -past-main" \
+	     ".*" ] \
+	"help aliases"
+}
+
+# Check errors.
+with_test_prefix "errors" {
+    # Try an unknown root setting.
+    gdb_test "alias wrong = xxxx yyyy -someoption" \
+	"Undefined command: \"xxxx\".  Try \"help\"\\."
+
+    # Try ambiguous command.
+    gdb_test "alias wrong = a" \
+	"Ambiguous command \"a\":.*" "ambiguous a"
+    gdb_test "alias wrong = frame a" \
+	"Ambiguous frame command \"a\":.*" "ambiguous frame a"
+}
+
+
+# Check completion.
+with_test_prefix "completion" {
+    test_gdb_complete_unique \
+	"alias set pri" \
+	"alias set print"
+
+    test_gdb_complete_unique \
+	"alias set print items = set pri" \
+	"alias set print items = set print"
+
+    test_gdb_complete_unique \
+	"alias set print items = set print ele" \
+	"alias set print items = set print elements"
+
+   test_gdb_complete_unique \
+	"alias btfu = backt" \
+	"alias btfu = backtrace"
+
+   test_gdb_complete_unique \
+	"alias btfu = backtrace -fu" \
+	"alias btfu = backtrace -full"
+
+   test_gdb_complete_unique \
+	"alias btfu = backtrace -full -past-e" \
+	"alias btfu = backtrace -full -past-entry"
+
+    gdb_test_no_output "alias btfu = backtrace -full -past-entry" \
+	"alias btfu"
+
+}
+
+# Check alias of alias.
+with_test_prefix "alias_of_alias" {
+    # Verify we can alias an alias that has no default args.
+    # We allow an alias of an alias, to be backward compatible with
+    # GDB 9.1 .
+    gdb_test_no_output "alias aaa = backtrace"
+    gdb_test_no_output "alias bbb = backtrace"
+
+    # Verify that we cannot define an alias of an alias that has default args.
+    gdb_test_no_output "alias ccc = backtrace -full"
+    gdb_test "alias ddd = ccc" \
+	"Cannot define an alias of an alias that has default args"
+    
+}
+
diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp
index c34bb9a92a..ac1a0f5b6e 100644
--- a/gdb/testsuite/gdb.base/default.exp
+++ b/gdb/testsuite/gdb.base/default.exp
@@ -247,9 +247,9 @@ gdb_test_multiple "generate-core-file" "generate-core-file" {
 }
 
 #test help "h" abbreviation
-gdb_test "h" "List of classes of commands:(\[^\r\n\]*\[\r\n\])+aliases -- Aliases of other commands(\[^\r\n\]*\[\r\n\])+breakpoints -- Making program stop at certain points(\[^\r\n\]*\[\r\n\])+data -- Examining data(\[^\r\n\]*\[\r\n\])+files -- Specifying and examining files(\[^\r\n\]*\[\r\n\])+obscure -- Obscure features(\[^\r\n\]*\[\r\n\])+running -- Running the program(\[^\r\n\]*\[\r\n\])+stack -- Examining the stack(\[^\r\n\]*\[\r\n\])+status -- Status inquiries(\[^\r\n\]*\[\r\n\])+support -- Support facilities(\[^\r\n\]*\[\r\n\])+user-defined -- User-defined commands(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by a class name for a list of commands in that class.(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by command name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "help \"h\" abbreviation"
+gdb_test "h" "List of classes of commands:(\[^\r\n\]*\[\r\n\])+aliases -- User-defined aliases of other commands(\[^\r\n\]*\[\r\n\])+breakpoints -- Making program stop at certain points(\[^\r\n\]*\[\r\n\])+data -- Examining data(\[^\r\n\]*\[\r\n\])+files -- Specifying and examining files(\[^\r\n\]*\[\r\n\])+obscure -- Obscure features(\[^\r\n\]*\[\r\n\])+running -- Running the program(\[^\r\n\]*\[\r\n\])+stack -- Examining the stack(\[^\r\n\]*\[\r\n\])+status -- Status inquiries(\[^\r\n\]*\[\r\n\])+support -- Support facilities(\[^\r\n\]*\[\r\n\])+user-defined -- User-defined commands(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by a class name for a list of commands in that class.(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by command name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "help \"h\" abbreviation"
 #test help
-gdb_test "help" "List of classes of commands:(\[^\r\n\]*\[\r\n\])+aliases -- Aliases of other commands(\[^\r\n\]*\[\r\n\])+breakpoints -- Making program stop at certain points(\[^\r\n\]*\[\r\n\])+data -- Examining data(\[^\r\n\]*\[\r\n\])+files -- Specifying and examining files(\[^\r\n\]*\[\r\n\])+obscure -- Obscure features(\[^\r\n\]*\[\r\n\])+running -- Running the program(\[^\r\n\]*\[\r\n\])+stack -- Examining the stack(\[^\r\n\]*\[\r\n\])+status -- Status inquiries(\[^\r\n\]*\[\r\n\])+support -- Support facilities(\[^\r\n\]*\[\r\n\])+user-defined -- User-defined commands(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by a class name for a list of commands in that class.(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by command name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
+gdb_test "help" "List of classes of commands:(\[^\r\n\]*\[\r\n\])+aliases -- User-defined aliases of other commands(\[^\r\n\]*\[\r\n\])+breakpoints -- Making program stop at certain points(\[^\r\n\]*\[\r\n\])+data -- Examining data(\[^\r\n\]*\[\r\n\])+files -- Specifying and examining files(\[^\r\n\]*\[\r\n\])+obscure -- Obscure features(\[^\r\n\]*\[\r\n\])+running -- Running the program(\[^\r\n\]*\[\r\n\])+stack -- Examining the stack(\[^\r\n\]*\[\r\n\])+status -- Status inquiries(\[^\r\n\]*\[\r\n\])+support -- Support facilities(\[^\r\n\]*\[\r\n\])+user-defined -- User-defined commands(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by a class name for a list of commands in that class.(\[^\r\n\]*\[\r\n\])+Type \"help\" followed by command name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous."
 #test handle
 gdb_test "handle" "Argument required .signal to handle.*"
 #test info "i" abbreviation 
diff --git a/gdb/testsuite/gdb.base/help.exp b/gdb/testsuite/gdb.base/help.exp
index 8ed0be45db..0b6893cf79 100644
--- a/gdb/testsuite/gdb.base/help.exp
+++ b/gdb/testsuite/gdb.base/help.exp
@@ -25,7 +25,7 @@ gdb_start
 gdb_test_no_output "set height 0" "disable pagination"
 
 # Test all the help classes.
-test_class_help "aliases" {"Aliases of other commands\.\[\r\n\]+"}
+test_class_help "aliases" {"User-defined aliases of other commands\.\[\r\n\]+"}
 test_class_help "breakpoints" {
     "Making program stop at certain points\.\[\r\n\]+"
 }
diff --git a/gdb/testsuite/gdb.base/page.exp b/gdb/testsuite/gdb.base/page.exp
index c34c886c64..5936845885 100644
--- a/gdb/testsuite/gdb.base/page.exp
+++ b/gdb/testsuite/gdb.base/page.exp
@@ -23,7 +23,7 @@ gdb_test "show pagination" "State of pagination is off.*" "pagination is off"
 gdb_test_sequence "help" "unpaged help" {
     "List of classes of commands:"
     ""
-    "aliases -- Aliases of other commands"
+    "aliases -- User-defined aliases of other commands"
     "breakpoints -- Making program stop at certain points"
     "data -- Examining data"
     "files -- Specifying and examining files"
@@ -50,7 +50,7 @@ gdb_expect_list "paged help" \
 	".*$pagination_prompt" {
     "List of classes of commands:"
     ""
-    "aliases -- Aliases of other commands"
+    "aliases -- User-defined aliases of other commands"
     "breakpoints -- Making program stop at certain points"
     "data -- Examining data"
     "files -- Specifying and examining files"
diff --git a/gdb/testsuite/gdb.base/style.exp b/gdb/testsuite/gdb.base/style.exp
index 129f1746a3..bfd26144fa 100644
--- a/gdb/testsuite/gdb.base/style.exp
+++ b/gdb/testsuite/gdb.base/style.exp
@@ -120,7 +120,7 @@ save_vars { env(TERM) } {
 	[multi_line \
 	     "List of classes of commands:" \
 	     "" \
-	     "${aliases_expr} -- Aliases of other commands\." \
+	     "${aliases_expr} -- User-defined aliases of other commands\." \
 	     "${breakpoints_expr} -- Making program stop at certain points\." \
 	     ".*" \
 	    ] \
@@ -132,11 +132,13 @@ save_vars { env(TERM) } {
     gdb_test "apropos -v cut for 'thre" \
 	[multi_line \
 	     "" \
-	     "${taas_expr} --.*" \
+	     "${taas_expr}" \
+	     "Apply a command to all .*" \
 	     "Usage:.*" \
 	     "short${cut_for_thre_expr}ad apply.*" \
 	     "" \
-	     "${tfaas_expr} --.*" \
+	     "${tfaas_expr}" \
+	     "Apply a command to all .*" \
 	     "Usage:.*" \
 	     "short${cut_for_thre_expr}ad apply.*" \
 	    ]
diff --git a/gdb/testsuite/gdb.guile/guile.exp b/gdb/testsuite/gdb.guile/guile.exp
index 2b0c0ba1d4..5d7b50fa15 100644
--- a/gdb/testsuite/gdb.guile/guile.exp
+++ b/gdb/testsuite/gdb.guile/guile.exp
@@ -58,11 +58,12 @@ gdb_test_multiline "multi-line guile command" \
   "(print 23)" "" \
   "end" "= 23"
 
+# To avoid duplicate test error, prefix one of the "end" with spaces.
 gdb_test_multiline "show guile command" \
   "define zzq" "Type commands for definition of .* just \"end\"\\.*" \
   "guile" "" \
   "(print 23)" "" \
-  "end" "" \
+  "                     end" "" \
   "end" "" \
   "show user zzq" "User command \"zzq\":.*  guile.*\\(print 23\\).*  end"
 
@@ -80,5 +81,5 @@ gdb_test "guile (print x)" "= 23"
 gdb_test_no_output "guile (define a (execute \"help\" #:to-string #t))" \
     "collect help from uiout"
 
-gdb_test "guile (print a)" "= .*aliases -- Aliases of other commands.*" \
+gdb_test "guile (print a)" "= .*aliases -- User-defined aliases of other commands.*" \
     "verify help to uiout"
diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp
index a50a7b43e2..8045c666a3 100644
--- a/gdb/testsuite/gdb.python/python.exp
+++ b/gdb/testsuite/gdb.python/python.exp
@@ -77,11 +77,12 @@ with_test_prefix "python interactive help" {
     }
 }
 
+# To avoid duplicate test error, prefix one of the "end" with spaces.
 gdb_py_test_multiple "show python command" \
   "define zzq" "Type commands for definition of .* just \"end\"\\.*" \
   "python" "" \
   "print (23)" "" \
-  "end" "" \
+  "                     end" "" \
   "end" "" \
   "show user zzq" "User command \"zzq\":.*  python.*print \\(23\\).*  end"
 
@@ -187,7 +188,7 @@ gdb_test_no_output "set height 0"
 
 gdb_test_no_output "python a = gdb.execute('help', to_string=True)" "collect help from uiout"
 
-gdb_test "python print (a)" ".*aliases -- Aliases of other commands.*" "verify help to uiout"
+gdb_test "python print (a)" ".*aliases -- User-defined aliases of other commands.*" "verify help to uiout"
 
 # Test PR 12212, using InfThread.selected_thread() when no inferior is
 # loaded.
@@ -229,10 +230,10 @@ runto $lineno
 gdb_test "python gdb.decode_line(\"main.c:43\")" \
     "gdb.error: No source file named main.c.*" "test decode_line no source named main"
 
-gdb_py_test_silent_cmd "python symtab = gdb.decode_line()" "test decode_line current location" 1
-gdb_test "python print (len(symtab))" "2" "test decode_line current location"
-gdb_test "python print (symtab\[0\])" "None" "test decode_line expression parse"
-gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line current location"
+gdb_py_test_silent_cmd "python symtab = gdb.decode_line()" "test decode_line current location =" 1
+gdb_test "python print (len(symtab))" "2" "test decode_line current location len"
+gdb_test "python print (symtab\[0\])" "None" "test decode_line expression parse None"
+gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line current location len 1"
 
 # Test that decode_line with an empty string argument does not crash.
 gdb_py_test_silent_cmd "python symtab2 = gdb.decode_line('')" \
@@ -246,18 +247,18 @@ if { [is_remote host] } {
 gdb_test "python print (symtab\[1\]\[0\].symtab)" ".*${python_c}" "test decode_line current location filename"
 gdb_test "python print (symtab\[1\]\[0\].line)" "$lineno" "test decode_line current location line number"
 
-gdb_py_test_silent_cmd "python symtab = gdb.decode_line(\"python.c:26 if foo\")" "test decode_line python.c:26" 1
-gdb_test "python print (len(symtab))" "2" "test decode_line python.c:26 length"
+gdb_py_test_silent_cmd "python symtab = gdb.decode_line(\"python.c:26 if foo\")" "test decode_line python.c:26 decode" 1
+gdb_test "python print (len(symtab))" "2" "test decode_line python.c:26 length 2"
 gdb_test "python print (symtab\[0\])" "if foo" "test decode_line expression parse"
-gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line python.c:26 length"
+gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line python.c:26 length 1"
 gdb_test "python print (symtab\[1\]\[0\].symtab)" ".*${python_c}" "test decode_line python.c:26 filename"
 gdb_test "python print (symtab\[1\]\[0\].line)" "26" "test decode_line python.c:26 line number"
 
 gdb_test "python gdb.decode_line(\"randomfunc\")" \
     "gdb.error: Function \"randomfunc\" not defined.*" "test decode_line randomfunc"
 gdb_py_test_silent_cmd "python symtab = gdb.decode_line(\"func1\")" "test decode_line func1()" 1
-gdb_test "python print (len(symtab))" "2" "test decode_line func1 length"
-gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line func1 length"
+gdb_test "python print (len(symtab))" "2" "test decode_line func1 length 2"
+gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line func1 length 1"
 
 if { [is_remote host] } {
     set python_1_c [string_to_regexp "python-1.c"]
@@ -336,7 +337,7 @@ set testfake "testfake"
 
 gdb_test_multiple "python gdb.prompt_hook = prompt" "set the hook" {
     -re "\[\r\n\]$newprompt $" {
-	pass "set hook"
+	pass "set hook prompt"
     }
 }
 
@@ -395,7 +396,7 @@ gdb_test_multiple "end" "end programming" {
     }
 }
 
-gdb_py_test_multiple "prompt substitution readline" \
+gdb_py_test_multiple "prompt substitution readline import" \
   "python" "" \
   "import gdb.command.prompt" "" \
   "end" ""
@@ -449,7 +450,7 @@ gdb_test "show python print-stack" \
 gdb_py_test_silent_cmd "set python print-stack message" \
     "Test print-stack set setting to message" 1
 
-gdb_py_test_multiple "prompt substitution readline" \
+gdb_py_test_multiple "prompt substitution readline error_prompt" \
   "python" "" \
   "pCounter = 0" "" \
   "def error_prompt(current):" "" \
@@ -458,24 +459,24 @@ gdb_py_test_multiple "prompt substitution readline" \
 
 gdb_test_multiple "python gdb.prompt_hook = error_prompt" "set the hook" {
     -re "Python Exception (exceptions.RuntimeError|<(type 'exceptions.|class ')RuntimeError'>) Python exception called.*$gdb_prompt $" {
-	pass "set hook"
+	pass "set hook error_prompt"
     }
 }
 
 gdb_py_test_silent_cmd "python gdb.prompt_hook = None" \
-    "set the hook to default" 1
+    "set the hook to default 1" 1
 
 gdb_py_test_silent_cmd "set python print-stack full" \
     "set print-stack full for prompt error test" 1
 
 gdb_test_multiple "python gdb.prompt_hook = error_prompt" "set the hook" {
     -re "Traceback.*File.*line.*RuntimeError.*Python exception called.*$gdb_prompt $" {
-	pass "set hook"
+	pass "set hook error_prompt traceback"
     }
 }
 
 gdb_py_test_silent_cmd "python gdb.prompt_hook = None" \
-    "set the hook to default" 1
+    "set the hook to default 2" 1
 
 # Start with a fresh gdb.
 clean_restart ${testfile}
-- 
2.20.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [RFAv8 3/3] NEWS and documentation for alias default-args related concept and commands.
  2020-06-21 18:31 [RFAv8 0/3] Allow the user to define default args for aliases Philippe Waroquiers
  2020-06-21 18:31 ` [RFAv8 1/3] default-args: allow to define default arguments " Philippe Waroquiers
  2020-06-21 18:31 ` [RFAv8 2/3] Add tests for new alias default-args related commands and arguments Philippe Waroquiers
@ 2020-06-21 18:31 ` Philippe Waroquiers
  2020-06-21 19:02   ` Eli Zaretskii
  2020-06-22 20:40   ` Christian Biesinger
  2 siblings, 2 replies; 9+ messages in thread
From: Philippe Waroquiers @ 2020-06-21 18:31 UTC (permalink / raw)
  To: gdb-patches

gdb/ChangeLog
YYYY-MM-DD  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* NEWS: Mention changeto the alias command.

gdb/doc/ChangeLog
YYYY-MM-DD  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* gdb.texinfo (Command aliases default args): New node documenting
	how to use default args for a command using aliases.
	(Aliases): Document the new 'DEFAULT-ARGS...' option.
	(Help): Update help aliases text and describe when full alias
	definition is provided.
---
 gdb/NEWS            |  15 ++++++
 gdb/doc/gdb.texinfo | 118 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 127 insertions(+), 6 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index cebfd18f0c..f7585133c5 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -79,6 +79,21 @@ tui new-layout NAME WINDOW WEIGHT [WINDOW WEIGHT]...
   Define a new TUI layout, specifying its name and the windows that
   will be displayed.
 
+* Changed commands
+
+alias [-a] [--] ALIAS = COMMAND [DEFAULT-ARGS...]
+  The alias command can now specify default args for an alias.
+  GDB automatically prepends the alias default args to the argument list
+  provided explicitly by the user.
+  For example, to have a backtrace with full details, you can define
+  an alias 'bt_ALL' as
+  'alias bt_ALL = backtrace -entry-values both -frame-arg all
+     -past-main -past-entry -full'.
+  Alias default arguments can also use a set of nested 'with' commands,
+  e.g. 'alias pp10 = with print pretty -- with print elem 10 -- print'
+  defines the alias pp10 that will pretty print a maximum of 10 elements
+  of the given expression (if the expression is an array).
+
 * New targets
 
 GNU/Linux/RISC-V (gdbserver)	riscv*-*-linux*
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 59e3e75d18..7f572c37c5 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -1577,6 +1577,7 @@ show you the alternatives available, if there is more than one possibility).
 * Command Settings::            How to change default behavior of commands
 * Completion::                  Command completion
 * Command Options::             Command options
+* Command aliases default args::        Automatically prepend default arguments to user-defined aliases
 * Help::                        How to ask @value{GDBN} for help
 @end menu
 
@@ -1997,6 +1998,89 @@ uppercase.
 (For more on using the @code{print} command, see @ref{Data, ,Examining
 Data}.)
 
+@node Command aliases default args
+@section Automatically prepend default arguments to user-defined aliases
+
+You can tell @value{GDBN} to always prepend some default arguments to
+the list of arguments provided explicitly by the user when using a
+user-defined alias.
+
+If you repeatedly use the same arguments or options for a command, you
+can define an alias for this command and tell @value{GDBN} to
+automatically prepend these arguments or options to the list of
+arguments you type explicitly when using the alias@footnote{@value{GDBN}
+could easily accept default arguments for pre-defined commands and aliases,
+but it was deemed this would be confusing, and so is not allowed.}.
+
+For example, if you often use the command @code{thread apply all}
+specifying to work on the threads in ascending order and to continue in case it
+encounters an error, you can tell @value{GDBN} to automatically preprend
+the @code{-ascending} and @code{-c} options by using:
+
+@smallexample
+(@value{GDBP}) alias thread apply asc-all = thread apply all -ascending -c
+@end smallexample
+
+Once you have defined this alias with its default args, any time you type
+the @code{thread apply asc-all} followed by @code{some arguments},
+@value{GDBN} will execute  @code{thread apply all -ascending -c some arguments}.
+
+To have even less to type, you can also define a one word alias:
+@smallexample
+(@value{GDBP}) alias t_a_c = thread apply all -ascending -c
+@end smallexample
+
+As usual, unambiguous abbreviations can be used for @var{alias}
+and @var{default-args}.
+
+The different aliases of a command do not share their default args.
+For example, you define a new alias @code{bt_ALL} showing all possible
+information and another alias @code{bt_SMALL} showing very limited information
+using:
+@smallexample
+(@value{GDBP}) alias bt_ALL = backtrace -entry-values both -frame-arg all \
+   -past-main -past-entry -full
+(@value{GDBP}) alias bt_SMALL = backtrace -entry-values no -frame-arg none \
+   -past-main off -past-entry off
+@end smallexample
+
+(For more on using the @code{alias} command, see @ref{Aliases}.)
+
+Default args are not limited to the arguments and options of @var{command},
+but can specify nested commands if @var{command} accepts such a nested command
+as argument.
+For example, the below defines @code{faalocalsoftype} that lists the
+frames having locals of a certain type, together with the matching
+local vars:
+@smallexample
+(@value{GDBP}) alias faalocalsoftype = frame apply all info locals -q -t
+(@value{GDBP}) faalocalsoftype int
+#1  0x55554f5e in sleeper_or_burner (v=0xdf50) at sleepers.c:86
+i = 0
+ret = 21845
+@end smallexample
+
+This is also very useful to define an alias for a set of nested @code{with}
+commands to have a particular combination of temporary settings.  For example,
+the below defines the alias @code{pp10} that pretty prints an expression
+argument, with a maximum of 10 elements if the expression is a string or
+an array:
+@smallexample
+(@value{GDBP}) alias pp10 = with print pretty -- with print elements 10 -- print
+@end smallexample
+This defines the alias  @code{pp10} as being a sequence of 3 commands.
+The first part @code{with print pretty --} temporarily activates the setting
+@code{set print pretty}, then launches the command that follows the separator
+@code{--}.
+The command following the first part is also a @code{with} command that
+temporarily changes the setting @code{set print elements} to 10, then
+launches the command that follows the second separator @code{--}.
+The third part @code{print} is the command the @code{pp10} alias will launch,
+using the temporary values of the settings and the arguments explicitly given
+by the user.
+For more information about the @code{with} command usage,
+see @ref{Command Settings}.
+
 @node Help
 @section Getting Help
 @cindex online documentation
@@ -2016,7 +2100,7 @@ display a short list of named classes of commands:
 (@value{GDBP}) help
 List of classes of commands:
 
-aliases -- Aliases of other commands
+aliases -- User-defined aliases of other commands
 breakpoints -- Making program stop at certain points
 data -- Examining data
 files -- Specifying and examining files
@@ -2043,8 +2127,9 @@ Command name abbreviations are allowed if unambiguous.
 Using one of the general help classes as an argument, you can get a
 list of the individual commands in that class.  If a command has
 aliases, the aliases are given after the command name, separated by
-commas.  For example, here is the help display for the class
-@code{status}:
+commas.  If an alias has default arguments, the full definition of
+the alias is given after the first line.
+For example, here is the help display for the class @code{status}:
 
 @smallexample
 (@value{GDBP}) help status
@@ -2056,7 +2141,10 @@ List of commands:
 @c to fit in smallbook page size.
 info, inf, i -- Generic command for showing things
         about the program being debugged
-info address -- Describe where symbol SYM is stored.
+info address, iamain  -- Describe where symbol SYM is stored.
+  alias iamain = info address main
+info all-registers -- List of all registers and their contents,
+        for selected stack frame.
 ...
 show, info set -- Generic command for showing things
         about the debugger
@@ -2072,6 +2160,8 @@ With a command name as @code{help} argument, @value{GDBN} displays a
 short paragraph on how to use that command.  If that command has
 one or more aliases, @value{GDBN} will display a first line with
 the command name and all its aliases separated by commas.
+This first line will be followed by the full definition of all aliases
+having default arguments.
 
 @kindex apropos
 @item apropos [-v] @var{regexp}
@@ -2092,7 +2182,7 @@ results in:
 @smallexample
 @group
 alias -- Define a new command that is an alias of an existing command
-aliases -- Aliases of other commands
+aliases -- User-defined aliases of other commands
 @end group
 @end smallexample
 
@@ -27502,7 +27592,7 @@ You can define a new alias with the @samp{alias} command.
 @table @code
 
 @kindex alias
-@item alias [-a] [--] @var{ALIAS} = @var{COMMAND}
+@item alias [-a] [--] @var{ALIAS} = @var{COMMAND} [DEFAULT-ARGS...]
 
 @end table
 
@@ -27513,12 +27603,28 @@ underscores.
 @var{COMMAND} specifies the name of an existing command
 that is being aliased.
 
+@var{COMMAND} can also be the name of an existing alias.  In this case,
+@var{COMMAND} cannot be an alias that has default arguments.
+
 The @samp{-a} option specifies that the new alias is an abbreviation
 of the command.  Abbreviations are not used in command completion.
 
 The @samp{--} option specifies the end of options,
 and is useful when @var{ALIAS} begins with a dash.
 
+You can specify @var{default-args} for your alias.
+These @var{default-args} will be automatically added before the alias
+arguments typed explicitly on the command line.
+
+For example, the below defines an alias @code{btfullall} that shows all local
+variables and all frame arguments:
+@smallexample
+(@value{GDBP}) alias btfullall = backtrace -full -frame-arguments all
+@end smallexample
+
+For more information about @var{default-args}, see @ref{Command aliases default args,
+,Automatically prepend default arguments to user-defined aliases}.
+
 Here is a simple example showing how to make an abbreviation
 of a command so that there is less to type.
 Suppose you were tired of typing @samp{disas}, the current
-- 
2.20.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFAv8 3/3] NEWS and documentation for alias default-args related concept and commands.
  2020-06-21 18:31 ` [RFAv8 3/3] NEWS and documentation for alias default-args related concept and commands Philippe Waroquiers
@ 2020-06-21 19:02   ` Eli Zaretskii
  2020-06-22 20:40   ` Christian Biesinger
  1 sibling, 0 replies; 9+ messages in thread
From: Eli Zaretskii @ 2020-06-21 19:02 UTC (permalink / raw)
  To: Philippe Waroquiers; +Cc: gdb-patches

> Date: Sun, 21 Jun 2020 20:31:30 +0200
> From: Philippe Waroquiers via Gdb-patches <gdb-patches@sourceware.org>
> 
> gdb/ChangeLog
> YYYY-MM-DD  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
> 
> 	* NEWS: Mention changeto the alias command.
> 
> gdb/doc/ChangeLog
> YYYY-MM-DD  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
> 
> 	* gdb.texinfo (Command aliases default args): New node documenting
> 	how to use default args for a command using aliases.
> 	(Aliases): Document the new 'DEFAULT-ARGS...' option.
> 	(Help): Update help aliases text and describe when full alias
> 	definition is provided.

Thanks, this is OK.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFAv8 1/3] default-args: allow to define default arguments for aliases
  2020-06-21 18:31 ` [RFAv8 1/3] default-args: allow to define default arguments " Philippe Waroquiers
@ 2020-06-22 14:09   ` Simon Marchi
  0 siblings, 0 replies; 9+ messages in thread
From: Simon Marchi @ 2020-06-22 14:09 UTC (permalink / raw)
  To: Philippe Waroquiers, gdb-patches

On 2020-06-21 2:31 p.m., Philippe Waroquiers via Gdb-patches wrote:
> Currently, a user can define an alias, but cannot have default
> arguments for this alias.
> 
> This patch modifies the 'alias' command so that default args can
> be provided.
>     (gdb) h alias
>     Define a new command that is an alias of an existing command.
>     Usage: alias [-a] [--] ALIAS = COMMAND [DEFAULT-ARGS...]
>     ALIAS is the name of the alias command to create.
>     COMMAND is the command being aliased to.
> 
>     Options:
>       -a
>         Specify that ALIAS is an abbreviation of COMMAND.
>         Abbreviations are not used in command completion..
> 
>     GDB will automatically prepend the provided DEFAULT-ARGS to the list
>     of arguments explicitly provided when using ALIAS.
>     Use "help aliases" to list all user defined aliases and their default 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 --
>     (gdb)
> 
> The way 'default-args' is implemented makes it trivial to set default
> args also for GDB commands (such as "backtrace") and for GDB pre-defined
> aliases (such as "bt").  It was however deemed better to not allow to
> define default arguments for pre-defined commands and aliases, to avoid
> users believing that e.g. default args for "backtrace" would apply to "bt".
> 
> If needed, default-args could be allowed for GDB predefined commands
> and aliases by adding a command
> 'set default-args GDB_COMMAND_OR_PREDEFINED_ALIAS [DEFAULT-ARGS...]'.
> 
> * '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.
> 
> * Help and apropos commands show the definitions of the aliases
>   that have default arguments, e.g.
>         (gdb) help backtrace
>         backtrace, btf, where, bt
>           alias btf = backtrace -full -past-entry -past-main
>         Print backtrace of all stack frames, or innermost COUNT frames.
>         Usage: backtrace [OPTION]... [QUALIFIER]... [COUNT | -COUNT]
> 
>         Options:
>           -entry-values no|only|preferred|if-needed|both|compact|default
>             Set printing of function arguments at function entry.
>         ...

Some parts of the commit message talk about "set default-args" and are

Otherwise, this patch LGTM, thanks.

Simon

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFAv8 2/3] Add tests for new alias default-args related commands and arguments.
  2020-06-21 18:31 ` [RFAv8 2/3] Add tests for new alias default-args related commands and arguments Philippe Waroquiers
@ 2020-06-22 14:18   ` Simon Marchi
  2020-06-22 19:29     ` Philippe Waroquiers
  0 siblings, 1 reply; 9+ messages in thread
From: Simon Marchi @ 2020-06-22 14:18 UTC (permalink / raw)
  To: Philippe Waroquiers, gdb-patches

On 2020-06-21 2:31 p.m., Philippe Waroquiers via Gdb-patches wrote:
> Test the new default-args behaviour and completion for the alias command.
> Note that gdb.base/default-args.exp is somewhat copied from
> with.exp (the test of the with command), while default-exp.c
> is a plain copy of with.c.

I got:

Applying: Add tests for new alias default-args related commands and arguments.
.git/rebase-apply/patch:202: trailing whitespace.

.git/rebase-apply/patch:204: new blank line at EOF.
+
warning: 2 lines add whitespace errors.

I've noted a few comments, but with those addressed the patch LGTM.

> 
> gdb/testsuite/ChangeLog
> YYYY-MM-DD  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
> 
> 	* gdb.base/default-args.exp: New test.
> 	* gdb.base/default-args.c: New file.
> 	* gdb.base/alias.exp: Update expected error msg for alias foo=bar.
> 	* gdb.base/default.exp: Update to new help text and
> 	make test names unique.
> 	* gdb.base/help.exp: Likewise.
> 	* gdb.base/page.exp: Likewise.
> 	* gdb.base/style.exp: Likewise.
> 	* gdb.guile/guile.exp: Likewise.
> 	* gdb.python/python.exp: Likewise.
> ---
>  gdb/testsuite/gdb.base/alias.exp        |   2 +-
>  gdb/testsuite/gdb.base/default-args.c   |  41 ++++++++
>  gdb/testsuite/gdb.base/default-args.exp | 124 ++++++++++++++++++++++++
>  gdb/testsuite/gdb.base/default.exp      |   4 +-
>  gdb/testsuite/gdb.base/help.exp         |   2 +-
>  gdb/testsuite/gdb.base/page.exp         |   4 +-
>  gdb/testsuite/gdb.base/style.exp        |   8 +-
>  gdb/testsuite/gdb.guile/guile.exp       |   5 +-
>  gdb/testsuite/gdb.python/python.exp     |  37 +++----
>  9 files changed, 198 insertions(+), 29 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.base/default-args.c
>  create mode 100644 gdb/testsuite/gdb.base/default-args.exp
> 
> diff --git a/gdb/testsuite/gdb.base/alias.exp b/gdb/testsuite/gdb.base/alias.exp
> index 6993d42648..03c440dfd7 100644
> --- a/gdb/testsuite/gdb.base/alias.exp
> +++ b/gdb/testsuite/gdb.base/alias.exp
> @@ -56,7 +56,7 @@ test_abbrev_alias set6 "alias -a -- set6 = set" 46
>  test_abbrev_alias -a "alias -a -- -a = set" 47
>  
>  gdb_test "alias set2=set" "already exists: set2"
> -gdb_test "alias foo=bar" "Invalid command to alias to: bar"
> +gdb_test "alias foo=bar" "Undefined command: \"bar\".  Try \"help\"."
>  
>  gdb_test_no_output "alias spe = set p elem"
>  gdb_test_no_output "spe 50"
> diff --git a/gdb/testsuite/gdb.base/default-args.c b/gdb/testsuite/gdb.base/default-args.c
> new file mode 100644
> index 0000000000..c6426625d4
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/default-args.c
> @@ -0,0 +1,41 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2019 Free Software Foundation, Inc.

2020, or 2019-2020 if it was a copy of something that was copyright 2019.

> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +int xxx1 = 123;

This appears to be unused.

> +
> +struct S
> +{
> +  int a;
> +  int b;
> +  int c;
> +};
> +
> +struct S g_s = {1, 2, 3};
> +
> +static void
> +inc ()

(void)

> +{
> +  g_s.a++;;
> +}
> +
> +int
> +main ()

(void)

> diff --git a/gdb/testsuite/gdb.guile/guile.exp b/gdb/testsuite/gdb.guile/guile.exp
> index 2b0c0ba1d4..5d7b50fa15 100644
> --- a/gdb/testsuite/gdb.guile/guile.exp
> +++ b/gdb/testsuite/gdb.guile/guile.exp
> @@ -58,11 +58,12 @@ gdb_test_multiline "multi-line guile command" \
>    "(print 23)" "" \
>    "end" "= 23"
>  
> +# To avoid duplicate test error, prefix one of the "end" with spaces.
>  gdb_test_multiline "show guile command" \
>    "define zzq" "Type commands for definition of .* just \"end\"\\.*" \
>    "guile" "" \
>    "(print 23)" "" \
> -  "end" "" \
> +  "                     end" "" \
>    "end" "" \
>    "show user zzq" "User command \"zzq\":.*  guile.*\\(print 23\\).*  end"

Interesting.  I think that should eventually be fixed / handled in gdb_test_multiline.

Since it doesn't seem related to this patchset, I'd leave it out of the patch.

>  
> @@ -80,5 +81,5 @@ gdb_test "guile (print x)" "= 23"
>  gdb_test_no_output "guile (define a (execute \"help\" #:to-string #t))" \
>      "collect help from uiout"
>  
> -gdb_test "guile (print a)" "= .*aliases -- Aliases of other commands.*" \
> +gdb_test "guile (print a)" "= .*aliases -- User-defined aliases of other commands.*" \
>      "verify help to uiout"
> diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp
> index a50a7b43e2..8045c666a3 100644
> --- a/gdb/testsuite/gdb.python/python.exp
> +++ b/gdb/testsuite/gdb.python/python.exp
> @@ -77,11 +77,12 @@ with_test_prefix "python interactive help" {
>      }
>  }
>  
> +# To avoid duplicate test error, prefix one of the "end" with spaces.
>  gdb_py_test_multiple "show python command" \
>    "define zzq" "Type commands for definition of .* just \"end\"\\.*" \
>    "python" "" \
>    "print (23)" "" \
> -  "end" "" \
> +  "                     end" "" \
>    "end" "" \
>    "show user zzq" "User command \"zzq\":.*  python.*print \\(23\\).*  end"
>  
> @@ -187,7 +188,7 @@ gdb_test_no_output "set height 0"
>  
>  gdb_test_no_output "python a = gdb.execute('help', to_string=True)" "collect help from uiout"
>  
> -gdb_test "python print (a)" ".*aliases -- Aliases of other commands.*" "verify help to uiout"
> +gdb_test "python print (a)" ".*aliases -- User-defined aliases of other commands.*" "verify help to uiout"
>  
>  # Test PR 12212, using InfThread.selected_thread() when no inferior is
>  # loaded.
> @@ -229,10 +230,10 @@ runto $lineno
>  gdb_test "python gdb.decode_line(\"main.c:43\")" \
>      "gdb.error: No source file named main.c.*" "test decode_line no source named main"
>  
> -gdb_py_test_silent_cmd "python symtab = gdb.decode_line()" "test decode_line current location" 1
> -gdb_test "python print (len(symtab))" "2" "test decode_line current location"
> -gdb_test "python print (symtab\[0\])" "None" "test decode_line expression parse"
> -gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line current location"
> +gdb_py_test_silent_cmd "python symtab = gdb.decode_line()" "test decode_line current location =" 1
> +gdb_test "python print (len(symtab))" "2" "test decode_line current location len"
> +gdb_test "python print (symtab\[0\])" "None" "test decode_line expression parse None"
> +gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line current location len 1"
>  
>  # Test that decode_line with an empty string argument does not crash.
>  gdb_py_test_silent_cmd "python symtab2 = gdb.decode_line('')" \
> @@ -246,18 +247,18 @@ if { [is_remote host] } {
>  gdb_test "python print (symtab\[1\]\[0\].symtab)" ".*${python_c}" "test decode_line current location filename"
>  gdb_test "python print (symtab\[1\]\[0\].line)" "$lineno" "test decode_line current location line number"
>  
> -gdb_py_test_silent_cmd "python symtab = gdb.decode_line(\"python.c:26 if foo\")" "test decode_line python.c:26" 1
> -gdb_test "python print (len(symtab))" "2" "test decode_line python.c:26 length"
> +gdb_py_test_silent_cmd "python symtab = gdb.decode_line(\"python.c:26 if foo\")" "test decode_line python.c:26 decode" 1
> +gdb_test "python print (len(symtab))" "2" "test decode_line python.c:26 length 2"
>  gdb_test "python print (symtab\[0\])" "if foo" "test decode_line expression parse"
> -gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line python.c:26 length"
> +gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line python.c:26 length 1"
>  gdb_test "python print (symtab\[1\]\[0\].symtab)" ".*${python_c}" "test decode_line python.c:26 filename"
>  gdb_test "python print (symtab\[1\]\[0\].line)" "26" "test decode_line python.c:26 line number"
>  
>  gdb_test "python gdb.decode_line(\"randomfunc\")" \
>      "gdb.error: Function \"randomfunc\" not defined.*" "test decode_line randomfunc"
>  gdb_py_test_silent_cmd "python symtab = gdb.decode_line(\"func1\")" "test decode_line func1()" 1
> -gdb_test "python print (len(symtab))" "2" "test decode_line func1 length"
> -gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line func1 length"
> +gdb_test "python print (len(symtab))" "2" "test decode_line func1 length 2"
> +gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line func1 length 1"
>  
>  if { [is_remote host] } {
>      set python_1_c [string_to_regexp "python-1.c"]
> @@ -336,7 +337,7 @@ set testfake "testfake"
>  
>  gdb_test_multiple "python gdb.prompt_hook = prompt" "set the hook" {
>      -re "\[\r\n\]$newprompt $" {
> -	pass "set hook"
> +	pass "set hook prompt"
>      }
>  }
>  
> @@ -395,7 +396,7 @@ gdb_test_multiple "end" "end programming" {
>      }
>  }
>  
> -gdb_py_test_multiple "prompt substitution readline" \
> +gdb_py_test_multiple "prompt substitution readline import" \
>    "python" "" \
>    "import gdb.command.prompt" "" \
>    "end" ""
> @@ -449,7 +450,7 @@ gdb_test "show python print-stack" \
>  gdb_py_test_silent_cmd "set python print-stack message" \
>      "Test print-stack set setting to message" 1
>  
> -gdb_py_test_multiple "prompt substitution readline" \
> +gdb_py_test_multiple "prompt substitution readline error_prompt" \
>    "python" "" \
>    "pCounter = 0" "" \
>    "def error_prompt(current):" "" \
> @@ -458,24 +459,24 @@ gdb_py_test_multiple "prompt substitution readline" \
>  
>  gdb_test_multiple "python gdb.prompt_hook = error_prompt" "set the hook" {
>      -re "Python Exception (exceptions.RuntimeError|<(type 'exceptions.|class ')RuntimeError'>) Python exception called.*$gdb_prompt $" {
> -	pass "set hook"
> +	pass "set hook error_prompt"
>      }
>  }
>  
>  gdb_py_test_silent_cmd "python gdb.prompt_hook = None" \
> -    "set the hook to default" 1
> +    "set the hook to default 1" 1
>  
>  gdb_py_test_silent_cmd "set python print-stack full" \
>      "set print-stack full for prompt error test" 1
>  
>  gdb_test_multiple "python gdb.prompt_hook = error_prompt" "set the hook" {
>      -re "Traceback.*File.*line.*RuntimeError.*Python exception called.*$gdb_prompt $" {
> -	pass "set hook"
> +	pass "set hook error_prompt traceback"
>      }
>  }
>  
>  gdb_py_test_silent_cmd "python gdb.prompt_hook = None" \
> -    "set the hook to default" 1
> +    "set the hook to default 2" 1
>  
>  # Start with a fresh gdb.
>  clean_restart ${testfile}

A lot of changes in python.exp also appear to be related to making test names
unique, which is noble but unrelated to the scope of this patch.  Can you please
submit it as a separate patch?

Simon


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFAv8 2/3] Add tests for new alias default-args related commands and arguments.
  2020-06-22 14:18   ` Simon Marchi
@ 2020-06-22 19:29     ` Philippe Waroquiers
  0 siblings, 0 replies; 9+ messages in thread
From: Philippe Waroquiers @ 2020-06-22 19:29 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

Thanks for the reviews/comments, I have pushed the patch series after
handling the last comments.

Philippe

On Mon, 2020-06-22 at 10:18 -0400, Simon Marchi wrote:
> On 2020-06-21 2:31 p.m., Philippe Waroquiers via Gdb-patches wrote:
> > Test the new default-args behaviour and completion for the alias command.
> > Note that gdb.base/default-args.exp is somewhat copied from
> > with.exp (the test of the with command), while default-exp.c
> > is a plain copy of with.c.
> 
> I got:
> 
> Applying: Add tests for new alias default-args related commands and arguments.
> .git/rebase-apply/patch:202: trailing whitespace.
> 
> .git/rebase-apply/patch:204: new blank line at EOF.
> +
> warning: 2 lines add whitespace errors.
> 
> I've noted a few comments, but with those addressed the patch LGTM.
> 
> > gdb/testsuite/ChangeLog
> > YYYY-MM-DD  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
> > 
> > 	* gdb.base/default-args.exp: New test.
> > 	* gdb.base/default-args.c: New file.
> > 	* gdb.base/alias.exp: Update expected error msg for alias foo=bar.
> > 	* gdb.base/default.exp: Update to new help text and
> > 	make test names unique.
> > 	* gdb.base/help.exp: Likewise.
> > 	* gdb.base/page.exp: Likewise.
> > 	* gdb.base/style.exp: Likewise.
> > 	* gdb.guile/guile.exp: Likewise.
> > 	* gdb.python/python.exp: Likewise.
> > ---
> >  gdb/testsuite/gdb.base/alias.exp        |   2 +-
> >  gdb/testsuite/gdb.base/default-args.c   |  41 ++++++++
> >  gdb/testsuite/gdb.base/default-args.exp | 124 ++++++++++++++++++++++++
> >  gdb/testsuite/gdb.base/default.exp      |   4 +-
> >  gdb/testsuite/gdb.base/help.exp         |   2 +-
> >  gdb/testsuite/gdb.base/page.exp         |   4 +-
> >  gdb/testsuite/gdb.base/style.exp        |   8 +-
> >  gdb/testsuite/gdb.guile/guile.exp       |   5 +-
> >  gdb/testsuite/gdb.python/python.exp     |  37 +++----
> >  9 files changed, 198 insertions(+), 29 deletions(-)
> >  create mode 100644 gdb/testsuite/gdb.base/default-args.c
> >  create mode 100644 gdb/testsuite/gdb.base/default-args.exp
> > 
> > diff --git a/gdb/testsuite/gdb.base/alias.exp b/gdb/testsuite/gdb.base/alias.exp
> > index 6993d42648..03c440dfd7 100644
> > --- a/gdb/testsuite/gdb.base/alias.exp
> > +++ b/gdb/testsuite/gdb.base/alias.exp
> > @@ -56,7 +56,7 @@ test_abbrev_alias set6 "alias -a -- set6 = set" 46
> >  test_abbrev_alias -a "alias -a -- -a = set" 47
> >  
> >  gdb_test "alias set2=set" "already exists: set2"
> > -gdb_test "alias foo=bar" "Invalid command to alias to: bar"
> > +gdb_test "alias foo=bar" "Undefined command: \"bar\".  Try \"help\"."
> >  
> >  gdb_test_no_output "alias spe = set p elem"
> >  gdb_test_no_output "spe 50"
> > diff --git a/gdb/testsuite/gdb.base/default-args.c b/gdb/testsuite/gdb.base/default-args.c
> > new file mode 100644
> > index 0000000000..c6426625d4
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.base/default-args.c
> > @@ -0,0 +1,41 @@
> > +/* This testcase is part of GDB, the GNU debugger.
> > +
> > +   Copyright 2019 Free Software Foundation, Inc.
> 
> 2020, or 2019-2020 if it was a copy of something that was copyright 2019.
> 
> > +
> > +   This program is free software; you can redistribute it and/or modify
> > +   it under the terms of the GNU General Public License as published by
> > +   the Free Software Foundation; either version 3 of the License, or
> > +   (at your option) any later version.
> > +
> > +   This program is distributed in the hope that it will be useful,
> > +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > +   GNU General Public License for more details.
> > +
> > +   You should have received a copy of the GNU General Public License
> > +   along with this program.  If not, see <http://www.gnu.org/licenses/>;.  */
> > +
> > +int xxx1 = 123;
> 
> This appears to be unused.
> 
> > +
> > +struct S
> > +{
> > +  int a;
> > +  int b;
> > +  int c;
> > +};
> > +
> > +struct S g_s = {1, 2, 3};
> > +
> > +static void
> > +inc ()
> 
> (void)
> 
> > +{
> > +  g_s.a++;;
> > +}
> > +
> > +int
> > +main ()
> 
> (void)
> 
> > diff --git a/gdb/testsuite/gdb.guile/guile.exp b/gdb/testsuite/gdb.guile/guile.exp
> > index 2b0c0ba1d4..5d7b50fa15 100644
> > --- a/gdb/testsuite/gdb.guile/guile.exp
> > +++ b/gdb/testsuite/gdb.guile/guile.exp
> > @@ -58,11 +58,12 @@ gdb_test_multiline "multi-line guile command" \
> >    "(print 23)" "" \
> >    "end" "= 23"
> >  
> > +# To avoid duplicate test error, prefix one of the "end" with spaces.
> >  gdb_test_multiline "show guile command" \
> >    "define zzq" "Type commands for definition of .* just \"end\"\\.*" \
> >    "guile" "" \
> >    "(print 23)" "" \
> > -  "end" "" \
> > +  "                     end" "" \
> >    "end" "" \
> >    "show user zzq" "User command \"zzq\":.*  guile.*\\(print 23\\).*  end"
> 
> Interesting.  I think that should eventually be fixed / handled in gdb_test_multiline.
> 
> Since it doesn't seem related to this patchset, I'd leave it out of the patch.
> 
> >  
> > @@ -80,5 +81,5 @@ gdb_test "guile (print x)" "= 23"
> >  gdb_test_no_output "guile (define a (execute \"help\" #:to-string #t))" \
> >      "collect help from uiout"
> >  
> > -gdb_test "guile (print a)" "= .*aliases -- Aliases of other commands.*" \
> > +gdb_test "guile (print a)" "= .*aliases -- User-defined aliases of other commands.*" \
> >      "verify help to uiout"
> > diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp
> > index a50a7b43e2..8045c666a3 100644
> > --- a/gdb/testsuite/gdb.python/python.exp
> > +++ b/gdb/testsuite/gdb.python/python.exp
> > @@ -77,11 +77,12 @@ with_test_prefix "python interactive help" {
> >      }
> >  }
> >  
> > +# To avoid duplicate test error, prefix one of the "end" with spaces.
> >  gdb_py_test_multiple "show python command" \
> >    "define zzq" "Type commands for definition of .* just \"end\"\\.*" \
> >    "python" "" \
> >    "print (23)" "" \
> > -  "end" "" \
> > +  "                     end" "" \
> >    "end" "" \
> >    "show user zzq" "User command \"zzq\":.*  python.*print \\(23\\).*  end"
> >  
> > @@ -187,7 +188,7 @@ gdb_test_no_output "set height 0"
> >  
> >  gdb_test_no_output "python a = gdb.execute('help', to_string=True)" "collect help from uiout"
> >  
> > -gdb_test "python print (a)" ".*aliases -- Aliases of other commands.*" "verify help to uiout"
> > +gdb_test "python print (a)" ".*aliases -- User-defined aliases of other commands.*" "verify help to uiout"
> >  
> >  # Test PR 12212, using InfThread.selected_thread() when no inferior is
> >  # loaded.
> > @@ -229,10 +230,10 @@ runto $lineno
> >  gdb_test "python gdb.decode_line(\"main.c:43\")" \
> >      "gdb.error: No source file named main.c.*" "test decode_line no source named main"
> >  
> > -gdb_py_test_silent_cmd "python symtab = gdb.decode_line()" "test decode_line current location" 1
> > -gdb_test "python print (len(symtab))" "2" "test decode_line current location"
> > -gdb_test "python print (symtab\[0\])" "None" "test decode_line expression parse"
> > -gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line current location"
> > +gdb_py_test_silent_cmd "python symtab = gdb.decode_line()" "test decode_line current location =" 1
> > +gdb_test "python print (len(symtab))" "2" "test decode_line current location len"
> > +gdb_test "python print (symtab\[0\])" "None" "test decode_line expression parse None"
> > +gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line current location len 1"
> >  
> >  # Test that decode_line with an empty string argument does not crash.
> >  gdb_py_test_silent_cmd "python symtab2 = gdb.decode_line('')" \
> > @@ -246,18 +247,18 @@ if { [is_remote host] } {
> >  gdb_test "python print (symtab\[1\]\[0\].symtab)" ".*${python_c}" "test decode_line current location filename"
> >  gdb_test "python print (symtab\[1\]\[0\].line)" "$lineno" "test decode_line current location line number"
> >  
> > -gdb_py_test_silent_cmd "python symtab = gdb.decode_line(\"python.c:26 if foo\")" "test decode_line python.c:26" 1
> > -gdb_test "python print (len(symtab))" "2" "test decode_line python.c:26 length"
> > +gdb_py_test_silent_cmd "python symtab = gdb.decode_line(\"python.c:26 if foo\")" "test decode_line python.c:26 decode" 1
> > +gdb_test "python print (len(symtab))" "2" "test decode_line python.c:26 length 2"
> >  gdb_test "python print (symtab\[0\])" "if foo" "test decode_line expression parse"
> > -gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line python.c:26 length"
> > +gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line python.c:26 length 1"
> >  gdb_test "python print (symtab\[1\]\[0\].symtab)" ".*${python_c}" "test decode_line python.c:26 filename"
> >  gdb_test "python print (symtab\[1\]\[0\].line)" "26" "test decode_line python.c:26 line number"
> >  
> >  gdb_test "python gdb.decode_line(\"randomfunc\")" \
> >      "gdb.error: Function \"randomfunc\" not defined.*" "test decode_line randomfunc"
> >  gdb_py_test_silent_cmd "python symtab = gdb.decode_line(\"func1\")" "test decode_line func1()" 1
> > -gdb_test "python print (len(symtab))" "2" "test decode_line func1 length"
> > -gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line func1 length"
> > +gdb_test "python print (len(symtab))" "2" "test decode_line func1 length 2"
> > +gdb_test "python print (len(symtab\[1\]))" "1" "test decode_line func1 length 1"
> >  
> >  if { [is_remote host] } {
> >      set python_1_c [string_to_regexp "python-1.c"]
> > @@ -336,7 +337,7 @@ set testfake "testfake"
> >  
> >  gdb_test_multiple "python gdb.prompt_hook = prompt" "set the hook" {
> >      -re "\[\r\n\]$newprompt $" {
> > -	pass "set hook"
> > +	pass "set hook prompt"
> >      }
> >  }
> >  
> > @@ -395,7 +396,7 @@ gdb_test_multiple "end" "end programming" {
> >      }
> >  }
> >  
> > -gdb_py_test_multiple "prompt substitution readline" \
> > +gdb_py_test_multiple "prompt substitution readline import" \
> >    "python" "" \
> >    "import gdb.command.prompt" "" \
> >    "end" ""
> > @@ -449,7 +450,7 @@ gdb_test "show python print-stack" \
> >  gdb_py_test_silent_cmd "set python print-stack message" \
> >      "Test print-stack set setting to message" 1
> >  
> > -gdb_py_test_multiple "prompt substitution readline" \
> > +gdb_py_test_multiple "prompt substitution readline error_prompt" \
> >    "python" "" \
> >    "pCounter = 0" "" \
> >    "def error_prompt(current):" "" \
> > @@ -458,24 +459,24 @@ gdb_py_test_multiple "prompt substitution readline" \
> >  
> >  gdb_test_multiple "python gdb.prompt_hook = error_prompt" "set the hook" {
> >      -re "Python Exception (exceptions.RuntimeError|<(type 'exceptions.|class ')RuntimeError'>) Python exception called.*$gdb_prompt $" {
> > -	pass "set hook"
> > +	pass "set hook error_prompt"
> >      }
> >  }
> >  
> >  gdb_py_test_silent_cmd "python gdb.prompt_hook = None" \
> > -    "set the hook to default" 1
> > +    "set the hook to default 1" 1
> >  
> >  gdb_py_test_silent_cmd "set python print-stack full" \
> >      "set print-stack full for prompt error test" 1
> >  
> >  gdb_test_multiple "python gdb.prompt_hook = error_prompt" "set the hook" {
> >      -re "Traceback.*File.*line.*RuntimeError.*Python exception called.*$gdb_prompt $" {
> > -	pass "set hook"
> > +	pass "set hook error_prompt traceback"
> >      }
> >  }
> >  
> >  gdb_py_test_silent_cmd "python gdb.prompt_hook = None" \
> > -    "set the hook to default" 1
> > +    "set the hook to default 2" 1
> >  
> >  # Start with a fresh gdb.
> >  clean_restart ${testfile}
> 
> A lot of changes in python.exp also appear to be related to making test names
> unique, which is noble but unrelated to the scope of this patch.  Can you please
> submit it as a separate patch?
> 
> Simon
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFAv8 3/3] NEWS and documentation for alias default-args related concept and commands.
  2020-06-21 18:31 ` [RFAv8 3/3] NEWS and documentation for alias default-args related concept and commands Philippe Waroquiers
  2020-06-21 19:02   ` Eli Zaretskii
@ 2020-06-22 20:40   ` Christian Biesinger
  1 sibling, 0 replies; 9+ messages in thread
From: Christian Biesinger @ 2020-06-22 20:40 UTC (permalink / raw)
  To: Philippe Waroquiers; +Cc: gdb-patches

On Sun, Jun 21, 2020 at 1:31 PM Philippe Waroquiers via Gdb-patches
<gdb-patches@sourceware.org> wrote:
>
> gdb/ChangeLog
> YYYY-MM-DD  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
>
>         * NEWS: Mention changeto the alias command.

Missing space between "change" and "to"

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-06-22 20:41 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-21 18:31 [RFAv8 0/3] Allow the user to define default args for aliases Philippe Waroquiers
2020-06-21 18:31 ` [RFAv8 1/3] default-args: allow to define default arguments " Philippe Waroquiers
2020-06-22 14:09   ` Simon Marchi
2020-06-21 18:31 ` [RFAv8 2/3] Add tests for new alias default-args related commands and arguments Philippe Waroquiers
2020-06-22 14:18   ` Simon Marchi
2020-06-22 19:29     ` Philippe Waroquiers
2020-06-21 18:31 ` [RFAv8 3/3] NEWS and documentation for alias default-args related concept and commands Philippe Waroquiers
2020-06-21 19:02   ` Eli Zaretskii
2020-06-22 20:40   ` Christian Biesinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).