gdb: Add an overloaded ui_out::text accepting a const std::string &
[binutils-gdb.git] / gdb / cli / cli-cmds.c
index a39ea22604511c9b09c0581eb8f077f6963b3557..0bf418e510eaa5bd3720e5adfe8cf19227b05c30 100644 (file)
@@ -1,6 +1,6 @@
 /* GDB CLI commands.
 
-   Copyright (C) 2000-2019 Free Software Foundation, Inc.
+   Copyright (C) 2000-2021 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -19,7 +19,6 @@
 
 #include "defs.h"
 #include "arch-utils.h"
-#include "readline/readline.h"
 #include "readline/tilde.h"
 #include "completer.h"
 #include "target.h"    /* For baud_rate, remote_debug and remote_timeout.  */
 #include "cli/cli-cmds.h"
 #include "cli/cli-style.h"
 #include "cli/cli-utils.h"
+#include "cli/cli-style.h"
 
 #include "extension.h"
 #include "gdbsupport/pathstuff.h"
+#include "gdbsupport/gdb_tilde_expand.h"
 
 #ifdef TUI
 #include "tui/tui.h"   /* For tui_active et.al.  */
@@ -151,6 +152,10 @@ struct cmd_list_element *maintenanceprintlist;
 
 struct cmd_list_element *maintenancechecklist;
 
+/* Chain containing all defined "maintenance flush" subcommands.  */
+
+struct cmd_list_element *maintenanceflushlist;
+
 struct cmd_list_element *setprintlist;
 
 struct cmd_list_element *showprintlist;
@@ -192,26 +197,17 @@ error_no_arg (const char *why)
   error (_("Argument required (%s)."), why);
 }
 
-/* The "info" command is defined as a prefix, with allow_unknown = 0.
-   Therefore, its own definition is called only for "info" with no
-   args.  */
+/* This implements the "info" prefix command.  Normally such commands
+   are automatically handled by add_basic_prefix_cmd, but in this case
+   a separate command is used so that it can be hooked into by
+   gdb-gdb.gdb.  */
 
 static void
 info_command (const char *arg, int from_tty)
 {
-  printf_unfiltered (_("\"info\" must be followed by "
-                      "the name of an info command.\n"));
   help_list (infolist, "info ", all_commands, gdb_stdout);
 }
 
-/* The "show" command with no arguments shows all the settings.  */
-
-static void
-show_command (const char *arg, int from_tty)
-{
-  cmd_show_list (showlist, from_tty, "");
-}
-
 /* See cli/cli-cmds.h.  */
 
 void
@@ -231,6 +227,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);
@@ -325,7 +322,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.  */
 
@@ -449,7 +493,7 @@ pwd_command (const char *args, int from_tty)
 
   if (cwd == NULL)
     error (_("Error finding name of working directory: %s"),
-           safe_strerror (errno));
+          safe_strerror (errno));
 
   if (strcmp (cwd.get (), current_directory) != 0)
     printf_unfiltered (_("Working directory %ps\n (canonically %ps).\n"),
@@ -493,7 +537,7 @@ cd_command (const char *dir, int from_tty)
   if (IS_DIR_SEPARATOR (dir[len - 1]))
     {
       /* Remove the trailing slash unless this is a root directory
-         (including a drive letter on non-Unix systems).  */
+        (including a drive letter on non-Unix systems).  */
       if (!(len == 1)          /* "/" */
 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
          && !(len == 3 && dir[1] == ':') /* "d:/" */
@@ -532,7 +576,7 @@ cd_command (const char *dir, int from_tty)
          if (found_real_path)
            {
              /* Search backwards for the directory just before the "/.."
-                and obliterate it and the "/..".  */
+                and obliterate it and the "/..".  */
              char *q = p;
 
              while (q != current_directory && !IS_DIR_SEPARATOR (q[-1]))
@@ -677,7 +721,7 @@ source_script_with_search (const char *file, int from_tty, int search_path)
   if (!opened)
     {
       /* The script wasn't found, or was otherwise inaccessible.
-         If the source command was invoked interactively, throw an
+        If the source command was invoked interactively, throw an
         error.  Otherwise (e.g. if it was invoked by a script),
         just emit a warning, rather than cause an error.  */
       if (from_tty)
@@ -694,8 +738,16 @@ source_script_with_search (const char *file, int from_tty, int search_path)
      anyway so that error messages show the actual file used.  But only do
      this if we (may have) used search_path, as printing the full path in
      errors for the non-search case can be more noise than signal.  */
-  source_script_from_stream (opened->stream.get (), file,
-                            search_path ? opened->full_path.get () : file);
+  const char *file_to_open;
+  gdb::unique_xmalloc_ptr<char> tilde_expanded_file;
+  if (search_path)
+    file_to_open = opened->full_path.get ();
+  else
+    {
+      tilde_expanded_file = gdb_tilde_expand_up (file);
+      file_to_open = tilde_expanded_file.get ();
+    }
+  source_script_from_stream (opened->stream.get (), file, file_to_open);
 }
 
 /* Wrapper around source_script_with_search to export it to main.c
@@ -801,6 +853,18 @@ exit_status_set_internal_vars (int exit_status)
   clear_internalvar (var_signal);
   if (WIFEXITED (exit_status))
     set_internalvar_integer (var_code, WEXITSTATUS (exit_status));
+#ifdef __MINGW32__
+  else if (WIFSIGNALED (exit_status) && WTERMSIG (exit_status) == -1)
+    {
+      /* The -1 condition can happen on MinGW, if we don't recognize
+        the fatal exception code encoded in the exit status; see
+        gdbsupport/gdb_wait.c.  We don't want to lose information in
+        the exit status in that case.  Record it as a normal exit
+        with the full exit status, including the higher 0xC0000000
+        bits.  */
+      set_internalvar_integer (var_code, exit_status);
+    }
+#endif
   else if (WIFSIGNALED (exit_status))
     set_internalvar_integer (var_signal, WTERMSIG (exit_status));
   else
@@ -828,8 +892,8 @@ shell_escape (const char *arg, int from_tty)
   /* Make sure to return to the directory GDB thinks it is, in case
      the shell command we just ran changed it.  */
   chdir (current_directory);
-  exit_status_set_internal_vars (rc);
 #endif
+  exit_status_set_internal_vars (rc);
 #else /* Can fork.  */
   int status, pid;
 
@@ -920,40 +984,40 @@ edit_command (const char *arg, int from_tty)
       sal = sals[0];
 
       if (*arg1)
-        error (_("Junk at end of line specification."));
+       error (_("Junk at end of line specification."));
 
       /* If line was specified by address, first print exactly which
-         line, and which file.  In this case, sal.symtab == 0 means
-         address is outside of all known source files, not that user
-         failed to give a filename.  */
+        line, and which file.  In this case, sal.symtab == 0 means
+        address is outside of all known source files, not that user
+        failed to give a filename.  */
       if (*arg == '*')
-        {
+       {
          struct gdbarch *gdbarch;
 
-          if (sal.symtab == 0)
+         if (sal.symtab == 0)
            error (_("No source file for address %s."),
                   paddress (get_current_arch (), sal.pc));
 
-         gdbarch = get_objfile_arch (SYMTAB_OBJFILE (sal.symtab));
-          sym = find_pc_function (sal.pc);
-          if (sym)
+         gdbarch = SYMTAB_OBJFILE (sal.symtab)->arch ();
+         sym = find_pc_function (sal.pc);
+         if (sym)
            printf_filtered ("%s is in %s (%s:%d).\n",
                             paddress (gdbarch, sal.pc),
-                            SYMBOL_PRINT_NAME (sym),
+                            sym->print_name (),
                             symtab_to_filename_for_display (sal.symtab),
                             sal.line);
-          else
+         else
            printf_filtered ("%s is at %s:%d.\n",
                             paddress (gdbarch, sal.pc),
                             symtab_to_filename_for_display (sal.symtab),
                             sal.line);
-        }
+       }
 
       /* If what was given does not imply a symtab, it must be an
-         undebuggable symbol which means no source code.  */
+        undebuggable symbol which means no source code.  */
 
       if (sal.symtab == 0)
-        error (_("No line number known for %s."), arg);
+       error (_("No line number known for %s."), arg);
     }
 
   if ((editor = getenv ("EDITOR")) == NULL)
@@ -1059,7 +1123,7 @@ pipe_command (const char *arg, int from_tty)
 
   if (exit_status < 0)
     error (_("shell command \"%s\" failed: %s"), shell_command,
-           safe_strerror (errno));
+          safe_strerror (errno));
   exit_status_set_internal_vars (exit_status);
 }
 
@@ -1266,12 +1330,12 @@ list_command (const char *arg, int from_tty)
        error (_("No source file for address %s."),
               paddress (get_current_arch (), sal.pc));
 
-      gdbarch = get_objfile_arch (SYMTAB_OBJFILE (sal.symtab));
+      gdbarch = SYMTAB_OBJFILE (sal.symtab)->arch ();
       sym = find_pc_function (sal.pc);
       if (sym)
        printf_filtered ("%s is in %s (%s:%d).\n",
                         paddress (gdbarch, sal.pc),
-                        SYMBOL_PRINT_NAME (sym),
+                        sym->print_name (),
                         symtab_to_filename_for_display (sal.symtab), sal.line);
       else
        printf_filtered ("%s is at %s:%d.\n",
@@ -1339,42 +1403,44 @@ print_disassembly (struct gdbarch *gdbarch, const char *name,
                   gdb_disassembly_flags flags)
 {
 #if defined(TUI)
-  if (!tui_is_window_visible (DISASSEM_WIN))
+  if (tui_is_window_visible (DISASSEM_WIN))
+    tui_show_assembly (gdbarch, low);
+  else
 #endif
     {
-      printf_filtered ("Dump of assembler code ");
+      printf_filtered (_("Dump of assembler code "));
       if (name != NULL)
-       printf_filtered ("for function %s:\n", name);
+       printf_filtered (_("for function %ps:\n"),
+                        styled_string (function_name_style.style (), name));
       if (block == nullptr || BLOCK_CONTIGUOUS_P (block))
-        {
+       {
          if (name == NULL)
-           printf_filtered ("from %s to %s:\n",
-                            paddress (gdbarch, low), paddress (gdbarch, high));
+           printf_filtered (_("from %ps to %ps:\n"),
+                            styled_string (address_style.style (),
+                                           paddress (gdbarch, low)),
+                            styled_string (address_style.style (),
+                                           paddress (gdbarch, high)));
 
          /* Dump the specified range.  */
          gdb_disassembly (gdbarch, current_uiout, flags, -1, low, high);
        }
       else
-        {
+       {
          for (int i = 0; i < BLOCK_NRANGES (block); i++)
            {
              CORE_ADDR range_low = BLOCK_RANGE_START (block, i);
              CORE_ADDR range_high = BLOCK_RANGE_END (block, i);
-             printf_filtered (_("Address range %s to %s:\n"),
-                              paddress (gdbarch, range_low),
-                              paddress (gdbarch, range_high));
+             printf_filtered (_("Address range %ps to %ps:\n"),
+                              styled_string (address_style.style (),
+                                             paddress (gdbarch, range_low)),
+                              styled_string (address_style.style (),
+                                             paddress (gdbarch, range_high)));
              gdb_disassembly (gdbarch, current_uiout, flags, -1,
                               range_low, range_high);
            }
        }
-      printf_filtered ("End of assembler dump.\n");
-    }
-#if defined(TUI)
-  else
-    {
-      tui_show_assembly (gdbarch, low);
+      printf_filtered (_("End of assembler dump.\n"));
     }
-#endif
 }
 
 /* Subroutine of disassemble_command to simplify it.
@@ -1435,6 +1501,7 @@ disassemble_command (const char *arg, int from_tty)
 {
   struct gdbarch *gdbarch = get_current_arch ();
   CORE_ADDR low, high;
+  const general_symbol_info *symbol = nullptr;
   const char *name;
   CORE_ADDR pc;
   gdb_disassembly_flags flags;
@@ -1490,8 +1557,14 @@ disassemble_command (const char *arg, int from_tty)
   if (p[0] == '\0')
     {
       /* One argument.  */
-      if (find_pc_partial_function (pc, &name, &low, &high, &block) == 0)
+      if (!find_pc_partial_function_sym (pc, &symbol, &low, &high, &block))
        error (_("No function contains specified address."));
+
+      if (asm_demangle)
+       name = symbol->print_name ();
+      else
+       name = symbol->linkage_name ();
+
 #if defined(TUI)
       /* NOTE: cagney/2003-02-13 The `tui_active' was previously
         `tui_version'.  */
@@ -1543,7 +1616,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);
@@ -1552,7 +1625,7 @@ show_user (const char *args, int from_tty)
     {
       for (c = cmdlist; c; c = c->next)
        {
-         if (cli_user_command_p (c) || c->prefixlist != NULL)
+         if (cli_user_command_p (c) || c->is_prefix ())
            show_user_1 (c, "", c->name, gdb_stdout);
        }
     }
@@ -1575,6 +1648,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.
@@ -1602,24 +1740,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.  */
@@ -1627,7 +1770,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.  */
@@ -1635,8 +1778,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;
 
@@ -1647,24 +1795,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')
@@ -1684,20 +1826,42 @@ 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));
   alias = alias_string.c_str ();
-  if (valid_command_p (alias))
-    error (_("Alias already exists: %s"), alias);
+  {
+    cmd_list_element *alias_cmd, *prefix_cmd, *cmd;
+
+    if (lookup_cmd_composition (alias, &alias_cmd, &prefix_cmd, &cmd))
+      {
+       const char *alias_name = alias_argv[alias_argc-1];
+
+       /* If we found an existing ALIAS_CMD, check that the prefix differ or
+          the name differ.  */
+
+       if (alias_cmd != nullptr
+           && alias_cmd->prefix == prefix_cmd
+           && strcmp (alias_name, alias_cmd->name) == 0)
+         error (_("Alias already exists: %s"), alias);
+
+       /* Check ALIAS differs from the found CMD.  */
+
+       if (cmd->prefix == prefix_cmd
+           && strcmp (alias_name, cmd->name) == 0)
+         error (_("Alias %s is the name of an existing command"), alias);
+      }
+  }
+
+
+  struct cmd_list_element *alias_cmd;
 
   /* If ALIAS is one word, it is an alias for the entire COMMAND.
      Example: alias spe = set print elements
@@ -1711,8 +1875,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
     {
@@ -1732,19 +1896,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);
+      gdb_assert (c_command->is_prefix ());
+      c_alias = lookup_cmd_1 (& alias_prefix, cmdlist, NULL, NULL, 1);
       if (c_alias != c_command)
        error (_("ALIAS and COMMAND prefixes do not match."));
 
       /* add_cmd requires *we* allocate space for name, hence the xstrdup.  */
-      add_alias_cmd (xstrdup (alias_argv[alias_argc - 1]),
-                    command_argv[command_argc - 1],
-                    class_alias, abbrev_flag, c_command->prefixlist);
+      alias_cmd = add_alias_cmd (xstrdup (alias_argv[alias_argc - 1]),
+                                command_argv[command_argc - 1],
+                                class_alias, a_opts.abbrev_flag,
+                                c_command->subcommands);
+    }
+
+  gdb_assert (alias_cmd != nullptr);
+  gdb_assert (alias_cmd->default_args.empty ());
+  if (default_args != nullptr)
+    {
+      default_args = skip_spaces (default_args);
+
+      alias_cmd->default_args = default_args;
     }
 }
 \f
@@ -1759,7 +1933,7 @@ print_sal_location (const symtab_and_line &sal)
 
   const char *sym_name = NULL;
   if (sal.symbol != NULL)
-    sym_name = SYMBOL_PRINT_NAME (sal.symbol);
+    sym_name = sal.symbol->print_name ();
   printf_filtered (_("file: \"%s\", line number: %d, symbol: \"%s\"\n"),
                   symtab_to_filename_for_display (sal.symtab),
                   sal.line, sym_name != NULL ? sym_name : "???");
@@ -1845,20 +2019,6 @@ filter_sals (std::vector<symtab_and_line> &sals)
   sals.erase (from, sals.end ());
 }
 
-static void
-set_debug (const char *arg, int from_tty)
-{
-  printf_unfiltered (_("\"set debug\" must be followed by "
-                      "the name of a debug subcommand.\n"));
-  help_list (setdebuglist, "set debug ", all_commands, gdb_stdout);
-}
-
-static void
-show_debug (const char *args, int from_tty)
-{
-  cmd_show_list (showdebuglist, from_tty, "");
-}
-
 void
 init_cmd_lists (void)
 {
@@ -1887,33 +2047,211 @@ show_history_expansion_p (struct ui_file *file, int from_tty,
 }
 
 static void
-show_remote_debug (struct ui_file *file, int from_tty,
-                  struct cmd_list_element *c, const char *value)
+show_max_user_call_depth (struct ui_file *file, int from_tty,
+                         struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Debugging of remote protocol is %s.\n"),
+  fprintf_filtered (file,
+                   _("The max call depth for user-defined commands is %s.\n"),
                    value);
 }
 
-static void
-show_remote_timeout (struct ui_file *file, int from_tty,
-                    struct cmd_list_element *c, const char *value)
+/* Returns the cmd_list_element in SHOWLIST corresponding to the first
+   argument of ARGV, which must contain one single value.
+   Throws an error if no value provided, or value not correct.
+   FNNAME is used in the error message.  */
+
+static cmd_list_element *
+setting_cmd (const char *fnname, struct cmd_list_element *showlist,
+            int argc, struct value **argv)
 {
-  fprintf_filtered (file,
-                   _("Timeout limit to wait for target to respond is %s.\n"),
-                   value);
+  if (argc == 0)
+    error (_("You must provide an argument to %s"), fnname);
+  if (argc != 1)
+    error (_("You can only provide one argument to %s"), fnname);
+
+  struct type *type0 = check_typedef (value_type (argv[0]));
+
+  if (type0->code () != TYPE_CODE_ARRAY
+      && type0->code () != TYPE_CODE_STRING)
+    error (_("First argument of %s must be a string."), fnname);
+
+  const char *a0 = (const char *) value_contents (argv[0]);
+  cmd_list_element *cmd = lookup_cmd (&a0, showlist, "", NULL, -1, 0);
+
+  if (cmd == nullptr || cmd->type != show_cmd)
+    error (_("First argument of %s must be a "
+            "valid setting of the 'show' command."), fnname);
+
+  return cmd;
 }
 
-static void
-show_max_user_call_depth (struct ui_file *file, int from_tty,
-                         struct cmd_list_element *c, const char *value)
+/* Builds a value from the show CMD.  */
+
+static struct value *
+value_from_setting (const cmd_list_element *cmd, struct gdbarch *gdbarch)
 {
-  fprintf_filtered (file,
-                   _("The max call depth for user-defined commands is %s.\n"),
-                   value);
+  switch (cmd->var_type)
+    {
+    case var_integer:
+      if (*(int *) cmd->var == INT_MAX)
+       return value_from_longest (builtin_type (gdbarch)->builtin_int,
+                                  0);
+      else
+       return value_from_longest (builtin_type (gdbarch)->builtin_int,
+                                  *(int *) cmd->var);
+    case var_zinteger:
+      return value_from_longest (builtin_type (gdbarch)->builtin_int,
+                                *(int *) cmd->var);
+    case var_boolean:
+      return value_from_longest (builtin_type (gdbarch)->builtin_int,
+                                *(bool *) cmd->var ? 1 : 0);
+    case var_zuinteger_unlimited:
+      return value_from_longest (builtin_type (gdbarch)->builtin_int,
+                                *(int *) cmd->var);
+    case var_auto_boolean:
+      {
+       int val;
+
+       switch (*(enum auto_boolean*) cmd->var)
+         {
+         case AUTO_BOOLEAN_TRUE:
+           val = 1;
+           break;
+         case AUTO_BOOLEAN_FALSE:
+           val = 0;
+           break;
+         case AUTO_BOOLEAN_AUTO:
+           val = -1;
+           break;
+         default:
+           gdb_assert_not_reached ("invalid var_auto_boolean");
+         }
+       return value_from_longest (builtin_type (gdbarch)->builtin_int,
+                                  val);
+      }
+    case var_uinteger:
+      if (*(unsigned int *) cmd->var == UINT_MAX)
+       return value_from_ulongest
+         (builtin_type (gdbarch)->builtin_unsigned_int, 0);
+      else
+       return value_from_ulongest
+         (builtin_type (gdbarch)->builtin_unsigned_int,
+          *(unsigned int *) cmd->var);
+    case var_zuinteger:
+      return value_from_ulongest (builtin_type (gdbarch)->builtin_unsigned_int,
+                                 *(unsigned int *) cmd->var);
+    case var_string:
+    case var_string_noescape:
+    case var_optional_filename:
+    case var_filename:
+    case var_enum:
+      if (*(char **) cmd->var)
+       return value_cstring (*(char **) cmd->var, strlen (*(char **) cmd->var),
+                             builtin_type (gdbarch)->builtin_char);
+      else
+       return value_cstring ("", 1,
+                             builtin_type (gdbarch)->builtin_char);
+    default:
+      gdb_assert_not_reached ("bad var_type");
+    }
+}
+
+/* Implementation of the convenience function $_gdb_setting.  */
+
+static struct value *
+gdb_setting_internal_fn (struct gdbarch *gdbarch,
+                        const struct language_defn *language,
+                        void *cookie, int argc, struct value **argv)
+{
+  return value_from_setting (setting_cmd ("$_gdb_setting", showlist,
+                                         argc, argv),
+                            gdbarch);
+}
+
+/* Implementation of the convenience function $_gdb_maint_setting.  */
+
+static struct value *
+gdb_maint_setting_internal_fn (struct gdbarch *gdbarch,
+                              const struct language_defn *language,
+                              void *cookie, int argc, struct value **argv)
+{
+  return value_from_setting (setting_cmd ("$_gdb_maint_setting",
+                                         maintenance_show_cmdlist,
+                                         argc, argv),
+                            gdbarch);
+}
+
+/* Builds a string value from the show CMD.  */
+
+static struct value *
+str_value_from_setting (const cmd_list_element *cmd, struct gdbarch *gdbarch)
+{
+  switch (cmd->var_type)
+    {
+    case var_integer:
+    case var_zinteger:
+    case var_boolean:
+    case var_zuinteger_unlimited:
+    case var_auto_boolean:
+    case var_uinteger:
+    case var_zuinteger:
+      {
+       std::string cmd_val = get_setshow_command_value_string (cmd);
+
+       return value_cstring (cmd_val.c_str (), cmd_val.size (),
+                             builtin_type (gdbarch)->builtin_char);
+      }
+
+    case var_string:
+    case var_string_noescape:
+    case var_optional_filename:
+    case var_filename:
+    case var_enum:
+      /* For these cases, we do not use get_setshow_command_value_string,
+        as this function handle some characters specially, e.g. by
+        escaping quotes.  So, we directly use the cmd->var string value,
+        similarly to the value_from_setting code for these cases.  */
+      if (*(char **) cmd->var)
+       return value_cstring (*(char **) cmd->var, strlen (*(char **) cmd->var),
+                             builtin_type (gdbarch)->builtin_char);
+      else
+       return value_cstring ("", 1,
+                             builtin_type (gdbarch)->builtin_char);
+
+    default:
+      gdb_assert_not_reached ("bad var_type");
+    }
+}
+
+/* Implementation of the convenience function $_gdb_setting_str.  */
+
+static struct value *
+gdb_setting_str_internal_fn (struct gdbarch *gdbarch,
+                            const struct language_defn *language,
+                            void *cookie, int argc, struct value **argv)
+{
+  return str_value_from_setting (setting_cmd ("$_gdb_setting_str",
+                                             showlist, argc, argv),
+                                gdbarch);
+}
+
+
+/* Implementation of the convenience function $_gdb_maint_setting_str.  */
+
+static struct value *
+gdb_maint_setting_str_internal_fn (struct gdbarch *gdbarch,
+                                  const struct language_defn *language,
+                                  void *cookie, int argc, struct value **argv)
+{
+  return str_value_from_setting (setting_cmd ("$_gdb_maint_setting_str",
+                                             maintenance_show_cmdlist,
+                                             argc, argv),
+                                gdbarch);
 }
 
+void _initialize_cli_cmds ();
 void
-_initialize_cli_cmds (void)
+_initialize_cli_cmds ()
 {
   struct cmd_list_element *c;
 
@@ -1928,7 +2266,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\
@@ -1950,6 +2288,12 @@ Variable lookups are done with respect to the selected frame.\n\
 When the program being debugged stops, gdb selects the innermost frame.\n\
 The commands below can be used to select other frames by number or address."),
           &cmdlist);
+#ifdef TUI
+  add_cmd ("text-user-interface", class_tui,
+          _("TUI is the GDB text based interface.\n\
+In TUI mode, GDB can display several text windows showing\n\
+the source file, the processor registers, the program disassembly, ..."), &cmdlist);
+#endif
   add_cmd ("running", class_run, _("Running the program."), &cmdlist);
 
   /* Define general commands.  */
@@ -2006,12 +2350,12 @@ Show verbosity."), NULL,
                           show_info_verbose,
                           &setlist, &showlist);
 
-  add_prefix_cmd ("history", class_support, set_history,
-                 _("Generic command for setting command history parameters."),
-                 &sethistlist, "set history ", 0, &setlist);
-  add_prefix_cmd ("history", class_support, show_history,
-                 _("Generic command for showing command history parameters."),
-                 &showhistlist, "show history ", 0, &showlist);
+  add_basic_prefix_cmd ("history", class_support, _("\
+Generic command for setting command history parameters."),
+                       &sethistlist, 0, &setlist);
+  add_show_prefix_cmd ("history", class_support, _("\
+Generic command for showing command history parameters."),
+                      &showhistlist, 0, &showlist);
 
   add_setshow_boolean_cmd ("expansion", no_class, &history_expansion_p, _("\
 Set history expansion on command input."), _("\
@@ -2023,18 +2367,18 @@ Without an argument, history expansion is enabled."),
 
   add_prefix_cmd ("info", class_info, info_command, _("\
 Generic command for showing things about the program being debugged."),
-                 &infolist, "info ", 0, &cmdlist);
+                 &infolist, 0, &cmdlist);
   add_com_alias ("i", "info", class_info, 1);
   add_com_alias ("inf", "info", class_info, 1);
 
   add_com ("complete", class_obscure, complete_command,
           _("List the completions for the rest of the line as a command."));
 
-  add_prefix_cmd ("show", class_info, show_command, _("\
+  c = add_show_prefix_cmd ("show", class_info, _("\
 Generic command for showing things about the debugger."),
-                 &showlist, "show ", 0, &cmdlist);
+                          &showlist, 0, &cmdlist);
   /* Another way to get at the same thing.  */
-  add_info ("set", show_command, _("Show all GDB settings."));
+  add_alias_cmd ("set", c, class_info, 0, &infolist);
 
   c = add_com ("with", class_vars, with_command, _("\
 Temporarily set SETTING to VALUE, run COMMAND, and restore SETTING.\n\
@@ -2053,6 +2397,44 @@ abbreviations for commands and/or values.  E.g.:\n\
   set_cmd_completer_handle_brkchars (c, with_command_completer);
   add_com_alias ("w", "with", class_vars, 1);
 
+  add_internal_function ("_gdb_setting_str", _("\
+$_gdb_setting_str - returns the value of a GDB setting as a string.\n\
+Usage: $_gdb_setting_str (setting)\n\
+\n\
+auto-boolean values are \"off\", \"on\", \"auto\".\n\
+boolean values are \"off\", \"on\".\n\
+Some integer settings accept an unlimited value, returned\n\
+as \"unlimited\"."),
+                        gdb_setting_str_internal_fn, NULL);
+
+  add_internal_function ("_gdb_setting", _("\
+$_gdb_setting - returns the value of a GDB setting.\n\
+Usage: $_gdb_setting (setting)\n\
+auto-boolean values are \"off\", \"on\", \"auto\".\n\
+boolean values are \"off\", \"on\".\n\
+Some integer settings accept an unlimited value, returned\n\
+as 0 or -1 depending on the setting."),
+                        gdb_setting_internal_fn, NULL);
+
+  add_internal_function ("_gdb_maint_setting_str", _("\
+$_gdb_maint_setting_str - returns the value of a GDB maintenance setting as a string.\n\
+Usage: $_gdb_maint_setting_str (setting)\n\
+\n\
+auto-boolean values are \"off\", \"on\", \"auto\".\n\
+boolean values are \"off\", \"on\".\n\
+Some integer settings accept an unlimited value, returned\n\
+as \"unlimited\"."),
+                        gdb_maint_setting_str_internal_fn, NULL);
+
+  add_internal_function ("_gdb_maint_setting", _("\
+$_gdb_maint_setting - returns the value of a GDB maintenance setting.\n\
+Usage: $_gdb_maint_setting (setting)\n\
+auto-boolean values are \"off\", \"on\", \"auto\".\n\
+boolean values are \"off\", \"on\".\n\
+Some integer settings accept an unlimited value, returned\n\
+as 0 or -1 depending on the setting."),
+                        gdb_maint_setting_internal_fn, NULL);
+
   add_cmd ("commands", no_set_class, show_commands, _("\
 Show the history of commands you typed.\n\
 You can supply a command number to start with, or a `+' to start after\n\
@@ -2065,32 +2447,13 @@ the previous command number shown."),
   add_cmd ("configuration", no_set_class, show_configuration,
           _("Show how GDB was configured at build time."), &showlist);
 
-  add_setshow_zinteger_cmd ("remote", no_class, &remote_debug, _("\
-Set debugging of remote protocol."), _("\
-Show debugging of remote protocol."), _("\
-When enabled, each packet sent or received with the remote target\n\
-is displayed."),
-                           NULL,
-                           show_remote_debug,
-                           &setdebuglist, &showdebuglist);
-
-  add_setshow_zuinteger_unlimited_cmd ("remotetimeout", no_class,
-                                      &remote_timeout, _("\
-Set timeout limit to wait for target to respond."), _("\
-Show timeout limit to wait for target to respond."), _("\
-This value is used to set the time limit for gdb to wait for a response\n\
-from the target."),
-                                      NULL,
-                                      show_remote_timeout,
-                                      &setlist, &showlist);
-
-  add_prefix_cmd ("debug", no_class, set_debug,
-                 _("Generic command for setting gdb debugging flags."),
-                 &setdebuglist, "set debug ", 0, &setlist);
-
-  add_prefix_cmd ("debug", no_class, show_debug,
-                 _("Generic command for showing gdb debugging flags."),
-                 &showdebuglist, "show debug ", 0, &showlist);
+  add_basic_prefix_cmd ("debug", no_class,
+                       _("Generic command for setting gdb debugging flags."),
+                       &setdebuglist, 0, &setlist);
+
+  add_show_prefix_cmd ("debug", no_class,
+                      _("Generic command for showing gdb debugging flags."),
+                      &showdebuglist, 0, &showlist);
 
   c = add_com ("shell", class_support, shell_command, _("\
 Execute the rest of the line as a shell command.\n\
@@ -2155,8 +2518,13 @@ can be shown using \"show listsize\"."));
 
   c = add_com ("disassemble", class_vars, disassemble_command, _("\
 Disassemble a specified section of memory.\n\
+Usage: disassemble[/m|/r|/s] START [, END]\n\
 Default is the function surrounding the pc of the selected frame.\n\
 \n\
+With a /s modifier, source lines are included (if available).\n\
+In this mode, the output is displayed in PC address order, and\n\
+file names and contents for all relevant source files are displayed.\n\
+\n\
 With a /m modifier, source lines are included (if available).\n\
 This view is \"source centric\": the output is in source line order,\n\
 regardless of any optimization that is present.  Only the main source file\n\
@@ -2164,11 +2532,6 @@ is displayed, not those of, e.g., any inlined functions.\n\
 This modifier hasn't proved useful in practice and is deprecated\n\
 in favor of /s.\n\
 \n\
-With a /s modifier, source lines are included (if available).\n\
-This differs from /m in two important respects:\n\
-- the output is still in pc address order, and\n\
-- file names and contents for all relevant source files are displayed.\n\
-\n\
 With a /r modifier, raw instructions in hex are included.\n\
 \n\
 With a single argument, the function surrounding that address is dumped.\n\
@@ -2210,19 +2573,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 appear in help command list output.\n\
+\n\
+Options:\n\
+%OPTIONS%\n\
+\n\
+GDB will automatically prepend the provided DEFAULT-ARGS to the list\n\
+of arguments explicitly provided when using ALIAS.\n\
+Use \"help aliases\" to list all user defined aliases and their default args.\n\
 \n\
 Examples:\n\
 Make \"spe\" an alias of \"set print elements\":\n\
   alias spe = set print elements\n\
 Make \"elms\" an alias of \"elements\" in the \"set print\" command:\n\
-  alias -a set print elms = set print elements"));
+  alias -a set print elms = set print elements\n\
+Make \"btf\" an alias of \"backtrace -full -past-entry -past-main\" :\n\
+  alias btf = backtrace -full -past-entry -past-main\n\
+Make \"wLapPeu\" an alias of 2 nested \"with\":\n\
+  alias wLapPeu = with language pascal -- with print elements unlimited --"),
+                              alias_opts);
+
+  c = add_com ("alias", class_support, alias_command,
+              alias_help.c_str ());
+
+  set_cmd_completer_handle_brkchars (c, alias_command_completer);
 
   const char *source_help_text = xstrprintf (_("\
 Read commands from a file named FILE.\n\