Implement "set cwd" command on GDB
[deliverable/binutils-gdb.git] / gdb / cli / cli-cmds.c
index c05f77f1d7654bda4b76990cb2828ff1f118d282..dad5ffa42e06fc935013568f8bd56de76ebf20bd 100644 (file)
@@ -1,6 +1,6 @@
 /* GDB CLI commands.
 
-   Copyright (C) 2000-2013 Free Software Foundation, Inc.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include "exceptions.h"
 #include "arch-utils.h"
-#include "dyn-string.h"
 #include "readline/readline.h"
 #include "readline/tilde.h"
 #include "completer.h"
 #include "target.h"    /* For baud_rate, remote_debug and remote_timeout.  */
 #include "gdb_wait.h"  /* For shell escape implementation.  */
 #include "gdb_regex.h" /* Used by apropos_command.  */
-#include "gdb_string.h"
 #include "gdb_vfork.h"
 #include "linespec.h"
 #include "expression.h"
@@ -39,6 +36,8 @@
 #include "source.h"
 #include "disasm.h"
 #include "tracepoint.h"
+#include "filestuff.h"
+#include "location.h"
 
 #include "ui-out.h"
 
 #include "cli/cli-cmds.h"
 #include "cli/cli-utils.h"
 
-#include "python/python.h"
+#include "extension.h"
 
 #ifdef TUI
 #include "tui/tui.h"   /* For tui_active et.al.  */
 #endif
 
 #include <fcntl.h>
+#include <algorithm>
+#include <string>
 
 /* Prototypes for local command functions */
 
@@ -65,8 +66,6 @@ static void echo_command (char *, int);
 
 static void pwd_command (char *, int);
 
-static void show_version (char *, int);
-
 static void help_command (char *, int);
 
 static void show_command (char *, int);
@@ -77,11 +76,9 @@ static void show_debug (char *, int);
 
 static void set_debug (char *, int);
 
-static void show_user (char *, int);
-
 static void make_command (char *, int);
 
-static void shell_escape (char *, int);
+static void shell_escape (const char *, int);
 
 static void edit_command (char *, int);
 
@@ -89,9 +86,13 @@ static void list_command (char *, int);
 
 /* Prototypes for local utility functions */
 
-static void ambiguous_line_spec (struct symtabs_and_lines *);
+static void print_sal_location (const symtab_and_line &sal);
+
+static void ambiguous_line_spec (gdb::array_view<const symtab_and_line> sals,
+                                const char *format, ...)
+  ATTRIBUTE_PRINTF (2, 3);
 
-static void filter_sals (struct symtabs_and_lines *);
+static void filter_sals (std::vector<symtab_and_line> &);
 
 \f
 /* Limit the call depth of user-defined commands */
@@ -115,10 +116,6 @@ struct cmd_list_element *enablelist;
 
 struct cmd_list_element *disablelist;
 
-/* Chain containing all defined toggle subcommands.  */
-
-struct cmd_list_element *togglelist;
-
 /* Chain containing all defined stop subcommands.  */
 
 struct cmd_list_element *stoplist;
@@ -171,6 +168,10 @@ struct cmd_list_element *maintenanceinfolist;
 
 struct cmd_list_element *maintenanceprintlist;
 
+/* Chain containing all defined "maintenance check" subcommands.  */
+
+struct cmd_list_element *maintenancechecklist;
+
 struct cmd_list_element *setprintlist;
 
 struct cmd_list_element *showprintlist;
@@ -207,7 +208,7 @@ static const char *script_ext_mode = script_ext_soft;
    none is supplied.  */
 
 void
-error_no_arg (char *why)
+error_no_arg (const char *why)
 {
   error (_("Argument required (%s)."), why);
 }
@@ -221,7 +222,7 @@ info_command (char *arg, int from_tty)
 {
   printf_unfiltered (_("\"info\" must be followed by "
                       "the name of an info command.\n"));
-  help_list (infolist, "info ", -1, gdb_stdout);
+  help_list (infolist, "info ", all_commands, gdb_stdout);
 }
 
 /* The "show" command with no arguments shows all the settings.  */
@@ -241,63 +242,93 @@ help_command (char *command, int from_tty)
   help_cmd (command, gdb_stdout);
 }
 \f
-/* The "complete" command is used by Emacs to implement completion.  */
+
+/* Note: The "complete" command is used by Emacs to implement completion.
+   [Is that why this function writes output with *_unfiltered?]  */
 
 static void
-complete_command (char *arg, int from_tty)
+complete_command (char *arg_entry, int from_tty)
 {
-  int argpoint;
-  char *point, *arg_prefix;
-  VEC (char_ptr) *completions;
+  const char *arg = arg_entry;
 
   dont_repeat ();
 
-  if (arg == NULL)
-    arg = "";
-  argpoint = strlen (arg);
-
-  /* complete_line assumes that its first argument is somewhere
-     within, and except for filenames at the beginning of, the word to
-     be completed.  The following crude imitation of readline's
-     word-breaking tries to accomodate this.  */
-  point = arg + argpoint;
-  while (point > arg)
+  if (max_completions == 0)
     {
-      if (strchr (rl_completer_word_break_characters, point[-1]) != 0)
-        break;
-      point--;
+      /* Only print this for non-mi frontends.  An MI frontend may not
+        be able to handle this.  */
+      if (!current_uiout->is_mi_like_p ())
+       {
+         printf_unfiltered (_("max-completions is zero,"
+                              " completion is disabled.\n"));
+       }
+      return;
     }
 
-  arg_prefix = alloca (point - arg + 1);
-  memcpy (arg_prefix, arg, point - arg);
-  arg_prefix[point - arg] = 0;
+  if (arg == NULL)
+    arg = "";
+
+  completion_tracker tracker_handle_brkchars;
+  completion_tracker tracker_handle_completions;
+  completion_tracker *tracker;
 
-  completions = complete_line (point, arg, argpoint);
+  int quote_char = '\0';
+  const char *word;
 
-  if (completions)
+  TRY
+    {
+      word = completion_find_completion_word (tracker_handle_brkchars,
+                                             arg, &quote_char);
+
+      /* Completers that provide a custom word point in the
+        handle_brkchars phase also compute their completions then.
+        Completers that leave the completion word handling to readline
+        must be called twice.  */
+      if (tracker_handle_brkchars.use_custom_word_point ())
+       tracker = &tracker_handle_brkchars;
+      else
+       {
+         complete_line (tracker_handle_completions, word, arg, strlen (arg));
+         tracker = &tracker_handle_completions;
+       }
+    }
+  CATCH (ex, RETURN_MASK_ALL)
     {
-      int ix, size = VEC_length (char_ptr, completions);
-      char *item, *prev = NULL;
+      return;
+    }
+
+  std::string arg_prefix (arg, word - arg);
 
-      qsort (VEC_address (char_ptr, completions), size,
-            sizeof (char *), compare_strings);
+  completion_result result
+    = tracker->build_completion_result (word, word - arg, strlen (arg));
 
-      /* We do extra processing here since we only want to print each
-        unique item once.  */
-      for (ix = 0; VEC_iterate (char_ptr, completions, ix, item); ++ix)
+  if (result.number_matches != 0)
+    {
+      if (result.number_matches == 1)
+       printf_unfiltered ("%s%s\n", arg_prefix.c_str (), result.match_list[0]);
+      else
        {
-         if (prev == NULL || strcmp (item, prev) != 0)
+         result.sort_match_list ();
+
+         for (size_t i = 0; i < result.number_matches; i++)
            {
-             printf_unfiltered ("%s%s\n", arg_prefix, item);
-             xfree (prev);
-             prev = item;
+             printf_unfiltered ("%s%s",
+                                arg_prefix.c_str (),
+                                result.match_list[i + 1]);
+             if (quote_char)
+               printf_unfiltered ("%c", quote_char);
+             printf_unfiltered ("\n");
            }
-         else
-           xfree (item);
        }
 
-      xfree (prev);
-      VEC_free (char_ptr, completions);
+      if (result.number_matches == max_completions)
+       {
+         /* ARG_PREFIX and WORD are included in the output so that emacs
+            will include the message in the output.  */
+         printf_unfiltered (_("%s%s %s\n"),
+                            arg_prefix.c_str (), word,
+                            get_max_completions_reached_message ());
+       }
     }
 }
 
@@ -308,23 +339,40 @@ is_complete_command (struct cmd_list_element *c)
 }
 
 static void
-show_version (char *args, int from_tty)
+show_version (const char *args, int from_tty)
 {
   print_gdb_version (gdb_stdout);
   printf_filtered ("\n");
 }
 
+static void
+show_configuration (const char *args, int from_tty)
+{
+  print_gdb_configuration (gdb_stdout);
+}
+
 /* Handle the quit command.  */
 
 void
 quit_command (char *args, int from_tty)
 {
+  int exit_code = 0;
+
+  /* An optional expression may be used to cause gdb to terminate with
+     the value of that expression.  */
+  if (args)
+    {
+      struct value *val = parse_and_eval (args);
+
+      exit_code = (int) value_as_long (val);
+    }
+
   if (!quit_confirm ())
     error (_("Not confirmed."));
 
-  disconnect_tracing (from_tty);
+  query_if_trace_running (from_tty);
 
-  quit_force (args, from_tty);
+  quit_force (args ? &exit_code : NULL, from_tty);
 }
 
 static void
@@ -332,19 +380,22 @@ pwd_command (char *args, int from_tty)
 {
   if (args)
     error (_("The \"pwd\" command does not take an argument: %s"), args);
-  if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)))
+
+  gdb::unique_xmalloc_ptr<char> cwd (getcwd (NULL, 0));
+
+  if (cwd == NULL)
     error (_("Error finding name of working directory: %s"),
            safe_strerror (errno));
 
-  if (strcmp (gdb_dirbuf, current_directory) != 0)
+  if (strcmp (cwd.get (), current_directory) != 0)
     printf_unfiltered (_("Working directory %s\n (canonically %s).\n"),
-                      current_directory, gdb_dirbuf);
+                      current_directory, cwd.get ());
   else
     printf_unfiltered (_("Working directory %s.\n"), current_directory);
 }
 
 void
-cd_command (char *dir, int from_tty)
+cd_command (const char *dir, int from_tty)
 {
   int len;
   /* Found something other than leading repetitions of "/..".  */
@@ -355,11 +406,9 @@ cd_command (char *dir, int from_tty)
      repeat might be useful but is more likely to be a mistake.  */
   dont_repeat ();
 
-  if (dir == 0)
-    dir = "~";
-
-  dir = tilde_expand (dir);
-  make_cleanup (xfree, dir);
+  gdb::unique_xmalloc_ptr<char> dir_holder
+    (tilde_expand (dir != NULL ? dir : "~"));
+  dir = dir_holder.get ();
 
   if (chdir (dir) < 0)
     perror_with_name (dir);
@@ -368,7 +417,8 @@ cd_command (char *dir, int from_tty)
   /* There's too much mess with DOSish names like "d:", "d:.",
      "d:./foo" etc.  Instead of having lots of special #ifdef'ed code,
      simply get the canonicalized name of the current directory.  */
-  dir = getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
+  gdb::unique_xmalloc_ptr<char> cwd (getcwd (NULL, 0));
+  dir = cwd.get ();
 #endif
 
   len = strlen (dir);
@@ -384,17 +434,20 @@ cd_command (char *dir, int from_tty)
        len--;
     }
 
-  dir = savestring (dir, len);
-  if (IS_ABSOLUTE_PATH (dir))
-    current_directory = dir;
+  dir_holder.reset (savestring (dir, len));
+  if (IS_ABSOLUTE_PATH (dir_holder.get ()))
+    {
+      xfree (current_directory);
+      current_directory = dir_holder.release ();
+    }
   else
     {
       if (IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1]))
-       current_directory = concat (current_directory, dir, (char *)NULL);
+       current_directory = concat (current_directory, dir_holder.get (),
+                                   (char *) NULL);
       else
        current_directory = concat (current_directory, SLASH_STRING,
-                                   dir, (char *)NULL);
-      xfree (dir);
+                                   dir_holder.get (), (char *) NULL);
     }
 
   /* Now simplify any occurrences of `.' and `..' in the pathname.  */
@@ -458,91 +511,87 @@ show_script_ext_mode (struct ui_file *file, int from_tty,
 
 /* Try to open SCRIPT_FILE.
    If successful, the full path name is stored in *FULL_PATHP,
-   the stream is stored in *STREAMP, and return 1.
-   The caller is responsible for freeing *FULL_PATHP.
-   If not successful, return 0; errno is set for the last file
+   and the stream is returned.
+   If not successful, return NULL; errno is set for the last file
    we tried to open.
 
    If SEARCH_PATH is non-zero, and the file isn't found in cwd,
    search for it in the source search path.  */
 
-int
-find_and_open_script (const char *script_file, int search_path,
-                     FILE **streamp, char **full_pathp)
+gdb::optional<open_script>
+find_and_open_script (const char *script_file, int search_path)
 {
-  char *file;
   int fd;
-  struct cleanup *old_cleanups;
-  int search_flags = OPF_TRY_CWD_FIRST;
+  int search_flags = OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH;
+  gdb::optional<open_script> opened;
 
-  file = tilde_expand (script_file);
-  old_cleanups = make_cleanup (xfree, file);
+  gdb::unique_xmalloc_ptr<char> file (tilde_expand (script_file));
 
   if (search_path)
     search_flags |= OPF_SEARCH_IN_PATH;
 
   /* Search for and open 'file' on the search path used for source
      files.  Put the full location in *FULL_PATHP.  */
+  char *temp_path;
   fd = openp (source_path, search_flags,
-             file, O_RDONLY, full_pathp);
+             file.get (), O_RDONLY, &temp_path);
+  gdb::unique_xmalloc_ptr<char> full_path (temp_path);
 
   if (fd == -1)
-    {
-      int save_errno = errno;
-      do_cleanups (old_cleanups);
-      errno = save_errno;
-      return 0;
-    }
-
-  do_cleanups (old_cleanups);
+    return opened;
 
-  *streamp = fdopen (fd, FOPEN_RT);
-  if (*streamp == NULL)
+  FILE *result = fdopen (fd, FOPEN_RT);
+  if (result == NULL)
     {
       int save_errno = errno;
 
       close (fd);
-      if (full_pathp)
-       xfree (*full_pathp);
       errno = save_errno;
-      return 0;
     }
+  else
+    opened.emplace (gdb_file_up (result), std::move (full_path));
 
-  return 1;
+  return opened;
 }
 
-/* Load script FILE, which has already been opened as STREAM.  */
+/* Load script FILE, which has already been opened as STREAM.
+   FILE_TO_OPEN is the form of FILE to use if one needs to open the file.
+   This is provided as FILE may have been found via the source search path.
+   An important thing to note here is that FILE may be a symlink to a file
+   with a different or non-existing suffix, and thus one cannot infer the
+   extension language from FILE_TO_OPEN.  */
 
 static void
-source_script_from_stream (FILE *stream, const char *file)
+source_script_from_stream (FILE *stream, const char *file,
+                          const char *file_to_open)
 {
-  if (script_ext_mode != script_ext_off
-      && strlen (file) > 3 && !strcmp (&file[strlen (file) - 3], ".py"))
+  if (script_ext_mode != script_ext_off)
     {
-      volatile struct gdb_exception e;
+      const struct extension_language_defn *extlang
+       = get_ext_lang_of_file (file);
 
-      TRY_CATCH (e, RETURN_MASK_ERROR)
+      if (extlang != NULL)
        {
-         source_python_script (stream, file);
-       }
-      if (e.reason < 0)
-       {
-         /* Should we fallback to ye olde GDB script mode?  */
-         if (script_ext_mode == script_ext_soft
-             && e.reason == RETURN_ERROR && e.error == UNSUPPORTED_ERROR)
+         if (ext_lang_present_p (extlang))
            {
-             fseek (stream, 0, SEEK_SET);
-             script_from_file (stream, (char*) file);
+             script_sourcer_func *sourcer
+               = ext_lang_script_sourcer (extlang);
+
+             gdb_assert (sourcer != NULL);
+             sourcer (extlang, stream, file_to_open);
+             return;
            }
-         else
+         else if (script_ext_mode == script_ext_soft)
            {
-             /* Nope, just punt.  */
-             throw_exception (e);
+             /* Assume the file is a gdb script.
+                This is handled below.  */
            }
+         else
+           throw_ext_lang_unsupported (extlang);
        }
     }
-  else
-    script_from_file (stream, file);
+
+  script_from_file (stream, file);
 }
 
 /* Worker to perform the "source" command.
@@ -553,65 +602,51 @@ source_script_from_stream (FILE *stream, const char *file)
 static void
 source_script_with_search (const char *file, int from_tty, int search_path)
 {
-  FILE *stream;
-  char *full_path;
-  struct cleanup *old_cleanups;
 
   if (file == NULL || *file == 0)
     error (_("source command requires file name of file to source."));
 
-  if (!find_and_open_script (file, search_path, &stream, &full_path))
+  gdb::optional<open_script> opened = find_and_open_script (file, search_path);
+  if (!opened)
     {
       /* The script wasn't found, or was otherwise inaccessible.
          If the source command was invoked interactively, throw an
         error.  Otherwise (e.g. if it was invoked by a script),
-        silently ignore the error.  */
+        just emit a warning, rather than cause an error.  */
       if (from_tty)
        perror_with_name (file);
       else
-       return;
+       {
+         perror_warning_with_name (file);
+         return;
+       }
     }
 
-  old_cleanups = make_cleanup (xfree, full_path);
-  make_cleanup_fclose (stream);
   /* The python support reopens the file, so we need to pass full_path here
      in case the file was found on the search path.  It's useful to do this
      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 (stream, search_path ? full_path : file);
-  do_cleanups (old_cleanups);
+  source_script_from_stream (opened->stream.get (), file,
+                            search_path ? opened->full_path.get () : file);
 }
 
 /* Wrapper around source_script_with_search to export it to main.c
    for use in loading .gdbinit scripts.  */
 
 void
-source_script (char *file, int from_tty)
+source_script (const char *file, int from_tty)
 {
   source_script_with_search (file, from_tty, 0);
 }
 
-/* Return the source_verbose global variable to its previous state
-   on exit from the source command, by whatever means.  */
 static void
-source_verbose_cleanup (void *old_value)
+source_command (const char *args, int from_tty)
 {
-  source_verbose = *(int *)old_value;
-  xfree (old_value);
-}
-
-static void
-source_command (char *args, int from_tty)
-{
-  struct cleanup *old_cleanups;
-  char *file = args;
-  int *old_source_verbose = xmalloc (sizeof(int));
+  const char *file = args;
   int search_path = 0;
 
-  *old_source_verbose = source_verbose;
-  old_cleanups = make_cleanup (source_verbose_cleanup, 
-                              old_source_verbose);
+  scoped_restore save_source_verbose = make_scoped_restore (&source_verbose);
 
   /* -v causes the source command to run in verbose mode.
      -s causes the file to be searched in the source search path,
@@ -652,15 +687,13 @@ source_command (char *args, int from_tty)
     }
 
   source_script_with_search (file, from_tty, search_path);
-
-  do_cleanups (old_cleanups);
 }
 
 
 static void
 echo_command (char *text, int from_tty)
 {
-  char *p = text;
+  const char *p = text;
   int c;
 
   if (text)
@@ -687,7 +720,7 @@ echo_command (char *text, int from_tty)
 }
 
 static void
-shell_escape (char *arg, int from_tty)
+shell_escape (const char *arg, int from_tty)
 {
 #if defined(CANT_FORK) || \
       (!defined(HAVE_WORKING_VFORK) && !defined(HAVE_WORKING_FORK))
@@ -721,6 +754,8 @@ shell_escape (char *arg, int from_tty)
     {
       const char *p, *user_shell;
 
+      close_most_fds ();
+
       if ((user_shell = (char *) getenv ("SHELL")) == NULL)
        user_shell = "/bin/sh";
 
@@ -745,14 +780,20 @@ shell_escape (char *arg, int from_tty)
 #endif /* Can fork.  */
 }
 
+/* Implementation of the "shell" command.  */
+
+static void
+shell_command (char *arg, int from_tty)
+{
+  shell_escape (arg, from_tty);
+}
+
 static void
 edit_command (char *arg, int from_tty)
 {
-  struct symtabs_and_lines sals;
   struct symtab_and_line sal;
   struct symbol *sym;
-  char *arg1;
-  char *editor;
+  const char *editor;
   char *p;
   const char *fn;
 
@@ -773,26 +814,30 @@ edit_command (char *arg, int from_tty)
     }
   else
     {
-      /* Now should only be one argument -- decode it in SAL.  */
+      const char *arg1;
 
+      /* Now should only be one argument -- decode it in SAL.  */
       arg1 = arg;
-      sals = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE, 0, 0);
-
-      filter_sals (&sals);
-      if (! sals.nelts)
+      event_location_up location = string_to_event_location (&arg1,
+                                                            current_language);
+      std::vector<symtab_and_line> sals = decode_line_1 (location.get (),
+                                                        DECODE_LINE_LIST_MODE,
+                                                        NULL, NULL, 0);
+
+      filter_sals (sals);
+      if (sals.empty ())
        {
          /*  C++  */
          return;
        }
-      if (sals.nelts > 1)
+      if (sals.size () > 1)
        {
-         ambiguous_line_spec (&sals);
-         xfree (sals.sals);
+         ambiguous_line_spec (sals,
+                              _("Specified line is ambiguous:\n"));
          return;
        }
 
-      sal = sals.sals[0];
-      xfree (sals.sals);
+      sal = sals[0];
 
       if (*arg1)
         error (_("Junk at end of line specification."));
@@ -806,11 +851,10 @@ edit_command (char *arg, int from_tty)
          struct gdbarch *gdbarch;
 
           if (sal.symtab == 0)
-           /* FIXME-32x64--assumes sal.pc fits in long.  */
            error (_("No source file for address %s."),
-                  hex_string ((unsigned long) sal.pc));
+                  paddress (get_current_arch (), sal.pc));
 
-         gdbarch = get_objfile_arch (sal.symtab->objfile);
+         gdbarch = get_objfile_arch (SYMTAB_OBJFILE (sal.symtab));
           sym = find_pc_function (sal.pc);
           if (sym)
            printf_filtered ("%s is in %s (%s:%d).\n",
@@ -847,12 +891,8 @@ edit_command (char *arg, int from_tty)
 static void
 list_command (char *arg, int from_tty)
 {
-  struct symtabs_and_lines sals, sals_end;
-  struct symtab_and_line sal = { 0 };
-  struct symtab_and_line sal_end = { 0 };
-  struct symtab_and_line cursal = { 0 };
   struct symbol *sym;
-  char *arg1;
+  const char *arg1;
   int no_end = 1;
   int dummy_end = 0;
   int dummy_beg = 0;
@@ -860,29 +900,49 @@ list_command (char *arg, int from_tty)
   char *p;
 
   /* Pull in the current default source line if necessary.  */
-  if (arg == 0 || arg[0] == '+' || arg[0] == '-')
+  if (arg == NULL || ((arg[0] == '+' || arg[0] == '-') && arg[1] == '\0'))
     {
       set_default_source_symtab_and_line ();
-      cursal = get_current_source_symtab_and_line ();
-    }
+      symtab_and_line cursal = get_current_source_symtab_and_line ();
 
-  /* "l" or "l +" lists next ten lines.  */
+      /* If this is the first "list" since we've set the current
+        source line, center the listing around that line.  */
+      if (get_first_line_listed () == 0)
+       {
+         int first;
 
-  if (arg == 0 || strcmp (arg, "+") == 0)
-    {
-      print_source_lines (cursal.symtab, cursal.line,
-                         cursal.line + get_lines_to_list (), 0);
-      return;
-    }
+         first = std::max (cursal.line - get_lines_to_list () / 2, 1);
+
+         /* A small special case --- if listing backwards, and we
+            should list only one line, list the preceding line,
+            instead of the exact line we've just shown after e.g.,
+            stopping for a breakpoint.  */
+         if (arg != NULL && arg[0] == '-'
+             && get_lines_to_list () == 1 && first > 1)
+           first -= 1;
+
+         print_source_lines (cursal.symtab, first,
+                             first + get_lines_to_list (), 0);
+       }
+
+      /* "l" or "l +" lists next ten lines.  */
+      else if (arg == NULL || arg[0] == '+')
+       print_source_lines (cursal.symtab, cursal.line,
+                           cursal.line + get_lines_to_list (), 0);
+
+      /* "l -" lists previous ten lines, the ones before the ten just
+        listed.  */
+      else if (arg[0] == '-')
+       {
+         if (get_first_line_listed () == 1)
+           error (_("Already at the start of %s."),
+                  symtab_to_filename_for_display (cursal.symtab));
+         print_source_lines (cursal.symtab,
+                             std::max (get_first_line_listed ()
+                                       - get_lines_to_list (), 1),
+                             get_first_line_listed (), 0);
+       }
 
-  /* "l -" lists previous ten lines, the ones before the ten just
-     listed.  */
-  if (strcmp (arg, "-") == 0)
-    {
-      print_source_lines (cursal.symtab,
-                         max (get_first_line_listed () 
-                              - get_lines_to_list (), 1),
-                         get_first_line_listed (), 0);
       return;
     }
 
@@ -895,25 +955,26 @@ list_command (char *arg, int from_tty)
   if (!have_full_symbols () && !have_partial_symbols ())
     error (_("No symbol table is loaded.  Use the \"file\" command."));
 
+  std::vector<symtab_and_line> sals;
+  symtab_and_line sal, sal_end;
+
   arg1 = arg;
   if (*arg1 == ',')
     dummy_beg = 1;
   else
     {
-      sals = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE, 0, 0);
-
-      filter_sals (&sals);
-      if (!sals.nelts)
-       return;                 /*  C++  */
-      if (sals.nelts > 1)
+      event_location_up location = string_to_event_location (&arg1,
+                                                            current_language);
+      sals = decode_line_1 (location.get (), DECODE_LINE_LIST_MODE,
+                           NULL, NULL, 0);
+      filter_sals (sals);
+      if (sals.empty ())
        {
-         ambiguous_line_spec (&sals);
-         xfree (sals.sals);
+         /*  C++  */
          return;
        }
 
-      sal = sals.sals[0];
-      xfree (sals.sals);
+      sal = sals[0];
     }
 
   /* Record whether the BEG arg is all digits.  */
@@ -921,11 +982,23 @@ list_command (char *arg, int from_tty)
   for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++);
   linenum_beg = (p == arg1);
 
+  /* Save the range of the first argument, in case we need to let the
+     user know it was ambiguous.  */
+  const char *beg = arg;
+  size_t beg_len = arg1 - beg;
+
   while (*arg1 == ' ' || *arg1 == '\t')
     arg1++;
   if (*arg1 == ',')
     {
       no_end = 0;
+      if (sals.size () > 1)
+       {
+         ambiguous_line_spec (sals,
+                              _("Specified first line '%.*s' is ambiguous:\n"),
+                              (int) beg_len, beg);
+         return;
+       }
       arg1++;
       while (*arg1 == ' ' || *arg1 == '\t')
        arg1++;
@@ -933,22 +1006,31 @@ list_command (char *arg, int from_tty)
        dummy_end = 1;
       else
        {
-         if (dummy_beg)
-           sals_end = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE, 0, 0);
-         else
-           sals_end = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE,
-                                     sal.symtab, sal.line);
-         filter_sals (&sals_end);
-         if (sals_end.nelts == 0)
+         /* Save the last argument, in case we need to let the user
+            know it was ambiguous.  */
+         const char *end_arg = arg1;
+
+         event_location_up location
+           = string_to_event_location (&arg1, current_language);
+
+         std::vector<symtab_and_line> sals_end
+           = (dummy_beg
+              ? decode_line_1 (location.get (), DECODE_LINE_LIST_MODE,
+                               NULL, NULL, 0)
+              : decode_line_1 (location.get (), DECODE_LINE_LIST_MODE,
+                               NULL, sal.symtab, sal.line));
+
+         filter_sals (sals_end);
+         if (sals_end.empty ())
            return;
-         if (sals_end.nelts > 1)
+         if (sals_end.size () > 1)
            {
-             ambiguous_line_spec (&sals_end);
-             xfree (sals_end.sals);
+             ambiguous_line_spec (sals_end,
+                                  _("Specified last line '%s' is ambiguous:\n"),
+                                  end_arg);
              return;
            }
-         sal_end = sals_end.sals[0];
-         xfree (sals_end.sals);
+         sal_end = sals_end[0];
        }
     }
 
@@ -957,7 +1039,7 @@ list_command (char *arg, int from_tty)
 
   if (!no_end && !dummy_beg && !dummy_end
       && sal.symtab != sal_end.symtab)
-    error (_("Specified start and end are in different files."));
+    error (_("Specified first and last lines are in different files."));
   if (dummy_beg && dummy_end)
     error (_("Two empty args do not say what lines to list."));
 
@@ -971,11 +1053,10 @@ list_command (char *arg, int from_tty)
       struct gdbarch *gdbarch;
 
       if (sal.symtab == 0)
-       /* FIXME-32x64--assumes sal.pc fits in long.  */
        error (_("No source file for address %s."),
-              hex_string ((unsigned long) sal.pc));
+              paddress (get_current_arch (), sal.pc));
 
-      gdbarch = get_objfile_arch (sal.symtab->objfile);
+      gdbarch = get_objfile_arch (SYMTAB_OBJFILE (sal.symtab));
       sym = find_pc_function (sal.pc);
       if (sym)
        printf_filtered ("%s is in %s (%s:%d).\n",
@@ -1005,20 +1086,25 @@ list_command (char *arg, int from_tty)
     error (_("No default source file yet.  Do \"help list\"."));
   if (dummy_beg)
     print_source_lines (sal_end.symtab,
-                       max (sal_end.line - (get_lines_to_list () - 1), 1),
+                       std::max (sal_end.line - (get_lines_to_list () - 1), 1),
                        sal_end.line + 1, 0);
   else if (sal.symtab == 0)
     error (_("No default source file yet.  Do \"help list\"."));
   else if (no_end)
     {
-      int first_line = sal.line - get_lines_to_list () / 2;
-
-      if (first_line < 1) first_line = 1;
-
-      print_source_lines (sal.symtab,
-                         first_line,
-                         first_line + get_lines_to_list (),
-                         0);
+      for (int i = 0; i < sals.size (); i++)
+       {
+         sal = sals[i];
+         int first_line = sal.line - get_lines_to_list () / 2;
+         if (first_line < 1)
+           first_line = 1;
+         if (sals.size () > 1)
+           print_sal_location (sal);
+         print_source_lines (sal.symtab,
+                             first_line,
+                             first_line + get_lines_to_list (),
+                             0);
+       }
     }
   else
     print_source_lines (sal.symtab, sal.line,
@@ -1036,7 +1122,8 @@ list_command (char *arg, int from_tty)
 
 static void
 print_disassembly (struct gdbarch *gdbarch, const char *name,
-                  CORE_ADDR low, CORE_ADDR high, int flags)
+                  CORE_ADDR low, CORE_ADDR high,
+                  gdb_disassembly_flags flags)
 {
 #if defined(TUI)
   if (!tui_is_window_visible (DISASSEM_WIN))
@@ -1050,7 +1137,7 @@ print_disassembly (struct gdbarch *gdbarch, const char *name,
                         paddress (gdbarch, low), paddress (gdbarch, high));
 
       /* Dump the specified range.  */
-      gdb_disassembly (gdbarch, current_uiout, 0, flags, -1, low, high);
+      gdb_disassembly (gdbarch, current_uiout, flags, -1, low, high);
 
       printf_filtered ("End of assembler dump.\n");
       gdb_flush (gdb_stdout);
@@ -1067,7 +1154,7 @@ print_disassembly (struct gdbarch *gdbarch, const char *name,
    Print a disassembly of the current function according to FLAGS.  */
 
 static void
-disassemble_current_function (int flags)
+disassemble_current_function (gdb_disassembly_flags flags)
 {
   struct frame_info *frame;
   struct gdbarch *gdbarch;
@@ -1094,16 +1181,26 @@ disassemble_current_function (int flags)
 /* Dump a specified section of assembly code.
 
    Usage:
-     disassemble [/mr]
+     disassemble [/mrs]
        - dump the assembly code for the function of the current pc
-     disassemble [/mr] addr
+     disassemble [/mrs] addr
        - dump the assembly code for the function at ADDR
-     disassemble [/mr] low,high
-     disassemble [/mr] low,+length
+     disassemble [/mrs] low,high
+     disassemble [/mrs] low,+length
        - dump the assembly code in the range [LOW,HIGH), or [LOW,LOW+length)
 
-   A /m modifier will include source code with the assembly.
-   A /r modifier will include raw instructions in hex with the assembly.  */
+   A /m modifier will include source code with the assembly in a
+   "source centric" view.  This view lists only the file of the first insn,
+   even if other source files are involved (e.g., inlined functions), and
+   the output is in source order, even with optimized code.  This view is
+   considered deprecated as it hasn't been useful in practice.
+
+   A /r modifier will include raw instructions in hex with the assembly.
+
+   A /s modifier will include source code with the assembly, like /m, with
+   two important differences:
+   1) The output is still in pc address order.
+   2) File names and contents for all relevant source files are displayed.  */
 
 static void
 disassemble_command (char *arg, int from_tty)
@@ -1112,7 +1209,7 @@ disassemble_command (char *arg, int from_tty)
   CORE_ADDR low, high;
   const char *name;
   CORE_ADDR pc;
-  int flags;
+  gdb_disassembly_flags flags;
   const char *p;
 
   p = arg;
@@ -1131,19 +1228,26 @@ disassemble_command (char *arg, int from_tty)
          switch (*p++)
            {
            case 'm':
-             flags |= DISASSEMBLY_SOURCE;
+             flags |= DISASSEMBLY_SOURCE_DEPRECATED;
              break;
            case 'r':
              flags |= DISASSEMBLY_RAW_INSN;
              break;
+           case 's':
+             flags |= DISASSEMBLY_SOURCE;
+             break;
            default:
              error (_("Invalid disassembly modifier."));
            }
        }
 
-      p = skip_spaces_const (p);
+      p = skip_spaces (p);
     }
 
+  if ((flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
+      == (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
+    error (_("Cannot specify both /m and /s."));
+
   if (! p || ! *p)
     {
       flags |= DISASSEMBLY_OMIT_FNAME;
@@ -1174,7 +1278,7 @@ disassemble_command (char *arg, int from_tty)
       /* Two arguments.  */
       int incl_flag = 0;
       low = pc;
-      p = skip_spaces_const (p);
+      p = skip_spaces (p);
       if (p[0] == '+')
        {
          ++p;
@@ -1191,22 +1295,18 @@ disassemble_command (char *arg, int from_tty)
 static void
 make_command (char *arg, int from_tty)
 {
-  char *p;
-
   if (arg == 0)
-    p = "make";
+    shell_escape ("make", from_tty);
   else
     {
-      p = xmalloc (sizeof ("make ") + strlen (arg));
-      strcpy (p, "make ");
-      strcpy (p + sizeof ("make ") - 1, arg);
-    }
+      std::string cmd = std::string ("make ") + arg;
 
-  shell_escape (p, from_tty);
+      shell_escape (cmd.c_str (), from_tty);
+    }
 }
 
 static void
-show_user (char *args, int from_tty)
+show_user (const char *args, int from_tty)
 {
   struct cmd_list_element *c;
   extern struct cmd_list_element *cmdlist;
@@ -1216,8 +1316,7 @@ show_user (char *args, int from_tty)
       const char *comname = args;
 
       c = lookup_cmd (&comname, cmdlist, "", 0, 1);
-      /* c->user_commands would be NULL if it's a python command.  */
-      if (c->class != class_user || !c->user_commands)
+      if (!cli_user_command_p (c))
        error (_("Not a user command."));
       show_user_1 (c, "", args, gdb_stdout);
     }
@@ -1225,7 +1324,7 @@ show_user (char *args, int from_tty)
     {
       for (c = cmdlist; c; c = c->next)
        {
-         if (c->class == class_user || c->prefixlist != NULL)
+         if (cli_user_command_p (c) || c->prefixlist != NULL)
            show_user_1 (c, "", c->name, gdb_stdout);
        }
     }
@@ -1237,28 +1336,13 @@ show_user (char *args, int from_tty)
 static void 
 apropos_command (char *searchstr, int from_tty)
 {
-  regex_t pattern;
-  int code;
-
   if (searchstr == NULL)
     error (_("REGEXP string is empty"));
 
-  code = regcomp (&pattern, searchstr, REG_ICASE);
-  if (code == 0)
-    {
-      struct cleanup *cleanups;
+  compiled_regex pattern (searchstr, REG_ICASE,
+                         _("Error in regular expression"));
 
-      cleanups = make_regfree_cleanup (&pattern);
-      apropos_cmd (gdb_stdout, cmdlist, &pattern, "");
-      do_cleanups (cleanups);
-    }
-  else
-    {
-      char *err = get_regcomp_error (code, &pattern);
-
-      make_cleanup (xfree, err);
-      error (_("Error in regular expression: %s"), err);
-    }
+  apropos_cmd (gdb_stdout, cmdlist, pattern, "");
 }
 
 /* Subroutine of alias_command to simplify it.
@@ -1268,11 +1352,11 @@ apropos_command (char *searchstr, int from_tty)
    This does not take care of quoting elements in case they contain spaces
    on purpose.  */
 
-static dyn_string_t
-argv_to_dyn_string (char **argv, int n)
+static std::string
+argv_to_string (char **argv, int n)
 {
   int i;
-  dyn_string_t result = dyn_string_new (10);
+  std::string result;
 
   gdb_assert (argv != NULL);
   gdb_assert (n >= 0 && n <= countargv (argv));
@@ -1280,8 +1364,8 @@ argv_to_dyn_string (char **argv, int n)
   for (i = 0; i < n; ++i)
     {
       if (i > 0)
-       dyn_string_append_char (result, ' ');
-      dyn_string_append_cstr (result, argv[i]);
+       result += " ";
+      result += argv[i];
     }
 
   return result;
@@ -1308,6 +1392,14 @@ valid_command_p (const char *command)
   return *command == '\0';
 }
 
+/* Called when "alias" was incorrectly used.  */
+
+static void
+alias_usage_error (void)
+{
+  error (_("Usage: alias [-a] [--] ALIAS = COMMAND"));
+}
+
 /* Make an alias of an existing command.  */
 
 static void
@@ -1315,31 +1407,27 @@ alias_command (char *args, int from_tty)
 {
   int i, alias_argc, command_argc;
   int abbrev_flag = 0;
-  char *args2, *equals, *alias, *command;
-  char **alias_argv, **command_argv;
-  dyn_string_t alias_dyn_string, command_dyn_string;
-  static const char usage[] = N_("Usage: alias [-a] [--] ALIAS = COMMAND");
+  char *equals;
+  const char *alias, *command;
 
   if (args == NULL || strchr (args, '=') == NULL)
-    error (_(usage));
-
-  args2 = xstrdup (args);
-  make_cleanup (xfree, args2);
-  equals = strchr (args2, '=');
-  *equals = '\0';
-  alias_argv = gdb_buildargv (args2);
-  make_cleanup_freeargv (alias_argv);
-  command_argv = gdb_buildargv (equals + 1);
-  make_cleanup_freeargv (command_argv);
-
-  for (i = 0; alias_argv[i] != NULL; )
+    alias_usage_error ();
+
+  equals = strchr (args, '=');
+  std::string args2 (args, equals - args);
+
+  gdb_argv built_alias_argv (args2.c_str ());
+  gdb_argv command_argv (equals + 1);
+
+  char **alias_argv = built_alias_argv.get ();
+  while (alias_argv[0] != NULL)
     {
-      if (strcmp (alias_argv[i], "-a") == 0)
+      if (strcmp (alias_argv[0], "-a") == 0)
        {
          ++alias_argv;
          abbrev_flag = 1;
        }
-      else if (strcmp (alias_argv[i], "--") == 0)
+      else if (strcmp (alias_argv[0], "--") == 0)
        {
          ++alias_argv;
          break;
@@ -1350,7 +1438,7 @@ alias_command (char *args, int from_tty)
 
   if (alias_argv[0] == NULL || command_argv[0] == NULL
       || *alias_argv[0] == '\0' || *command_argv[0] == '\0')
-    error (_(usage));
+    alias_usage_error ();
 
   for (i = 0; alias_argv[i] != NULL; ++i)
     {
@@ -1364,21 +1452,20 @@ alias_command (char *args, int from_tty)
     }
 
   alias_argc = countargv (alias_argv);
-  command_argc = countargv (command_argv);
+  command_argc = command_argv.count ();
 
   /* COMMAND must exist.
      Reconstruct the command to remove any extraneous spaces,
      for better error messages.  */
-  command_dyn_string = argv_to_dyn_string (command_argv, command_argc);
-  make_cleanup_dyn_string_delete (command_dyn_string);
-  command = dyn_string_buf (command_dyn_string);
+  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);
 
   /* ALIAS must not exist.  */
-  alias_dyn_string = argv_to_dyn_string (alias_argv, alias_argc);
-  make_cleanup_dyn_string_delete (alias_dyn_string);
-  alias = dyn_string_buf (alias_dyn_string);
+  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);
 
@@ -1399,7 +1486,6 @@ alias_command (char *args, int from_tty)
     }
   else
     {
-      dyn_string_t alias_prefix_dyn_string, command_prefix_dyn_string;
       const char *alias_prefix, *command_prefix;
       struct cmd_list_element *c_alias, *c_command;
 
@@ -1408,14 +1494,12 @@ alias_command (char *args, int from_tty)
 
       /* Create copies of ALIAS and COMMAND without the last word,
         and use that to verify the leading elements match.  */
-      alias_prefix_dyn_string =
-       argv_to_dyn_string (alias_argv, alias_argc - 1);
-      make_cleanup_dyn_string_delete (alias_prefix_dyn_string);
-      command_prefix_dyn_string =
-       argv_to_dyn_string (alias_argv, command_argc - 1);
-      make_cleanup_dyn_string_delete (command_prefix_dyn_string);
-      alias_prefix = dyn_string_buf (alias_prefix_dyn_string);
-      command_prefix = dyn_string_buf (command_prefix_dyn_string);
+      std::string alias_prefix_string (argv_to_string (alias_argv,
+                                                      alias_argc - 1));
+      std::string command_prefix_string (argv_to_string (alias_argv,
+                                                        command_argc - 1));
+      alias_prefix = alias_prefix_string.c_str ();
+      command_prefix = command_prefix_string.c_str ();
 
       c_command = lookup_cmd_1 (& command_prefix, cmdlist, NULL, 1);
       /* We've already tried to look up COMMAND.  */
@@ -1433,100 +1517,101 @@ alias_command (char *args, int from_tty)
     }
 }
 \f
+/* Print the file / line number / symbol name of the location
+   specified by SAL.  */
+
+static void
+print_sal_location (const symtab_and_line &sal)
+{
+  scoped_restore_current_program_space restore_pspace;
+  set_current_program_space (sal.pspace);
+
+  const char *sym_name = NULL;
+  if (sal.symbol != NULL)
+    sym_name = SYMBOL_PRINT_NAME (sal.symbol);
+  printf_filtered (_("file: \"%s\", line number: %d, symbol: \"%s\"\n"),
+                  symtab_to_filename_for_display (sal.symtab),
+                  sal.line, sym_name != NULL ? sym_name : "???");
+}
+
 /* Print a list of files and line numbers which a user may choose from
    in order to list a function which was specified ambiguously (as
-   with `list classname::overloadedfuncname', for example).  The
-   vector in SALS provides the filenames and line numbers.  */
+   with `list classname::overloadedfuncname', for example).  The SALS
+   array provides the filenames and line numbers.  FORMAT is a
+   printf-style format string used to tell the user what was
+   ambiguous.  */
 
 static void
-ambiguous_line_spec (struct symtabs_and_lines *sals)
+ambiguous_line_spec (gdb::array_view<const symtab_and_line> sals,
+                    const char *format, ...)
 {
-  int i;
+  va_list ap;
+  va_start (ap, format);
+  vprintf_filtered (format, ap);
+  va_end (ap);
 
-  for (i = 0; i < sals->nelts; ++i)
-    printf_filtered (_("file: \"%s\", line number: %d\n"),
-                    symtab_to_filename_for_display (sals->sals[i].symtab),
-                    sals->sals[i].line);
+  for (const auto &sal : sals)
+    print_sal_location (sal);
 }
 
-/* Sort function for filter_sals.  */
+/* Comparison function for filter_sals.  Returns a qsort-style
+   result.  */
 
 static int
-compare_symtabs (const void *a, const void *b)
+cmp_symtabs (const symtab_and_line &sala, const symtab_and_line &salb)
 {
-  const struct symtab_and_line *sala = a;
-  const struct symtab_and_line *salb = b;
+  const char *dira = SYMTAB_DIRNAME (sala.symtab);
+  const char *dirb = SYMTAB_DIRNAME (salb.symtab);
   int r;
 
-  if (!sala->symtab->dirname)
+  if (dira == NULL)
     {
-      if (salb->symtab->dirname)
+      if (dirb != NULL)
        return -1;
     }
-  else if (!salb->symtab->dirname)
+  else if (dirb == NULL)
     {
-      if (sala->symtab->dirname)
+      if (dira != NULL)
        return 1;
     }
   else
     {
-      r = filename_cmp (sala->symtab->dirname, salb->symtab->dirname);
+      r = filename_cmp (dira, dirb);
       if (r)
        return r;
     }
 
-  r = filename_cmp (sala->symtab->filename, salb->symtab->filename);
+  r = filename_cmp (sala.symtab->filename, salb.symtab->filename);
   if (r)
     return r;
 
-  if (sala->line < salb->line)
+  if (sala.line < salb.line)
     return -1;
-  return sala->line == salb->line ? 0 : 1;
+  return sala.line == salb.line ? 0 : 1;
 }
 
 /* Remove any SALs that do not match the current program space, or
    which appear to be "file:line" duplicates.  */
 
 static void
-filter_sals (struct symtabs_and_lines *sals)
+filter_sals (std::vector<symtab_and_line> &sals)
 {
-  int i, out, prev;
-
-  out = 0;
-  for (i = 0; i < sals->nelts; ++i)
-    {
-      if (sals->sals[i].pspace == current_program_space
-         && sals->sals[i].symtab != NULL)
-       {
-         sals->sals[out] = sals->sals[i];
-         ++out;
-       }
-    }
-  sals->nelts = out;
-
-  qsort (sals->sals, sals->nelts, sizeof (struct symtab_and_line),
-        compare_symtabs);
-
-  out = 1;
-  prev = 0;
-  for (i = 1; i < sals->nelts; ++i)
-    {
-      if (compare_symtabs (&sals->sals[prev], &sals->sals[i]))
-       {
-         /* Symtabs differ.  */
-         sals->sals[out] = sals->sals[i];
-         prev = out;
-         ++out;
-       }
-    }
-
-  if (sals->nelts == 0)
-    {
-      xfree (sals->sals);
-      sals->sals = NULL;
-    }
-  else
-    sals->nelts = out;
+  /* Remove SALs that do not match.  */
+  auto from = std::remove_if (sals.begin (), sals.end (),
+                             [&] (const symtab_and_line &sal)
+    { return (sal.pspace != current_program_space || sal.symtab == NULL); });
+
+  /* Remove dups.  */
+  std::sort (sals.begin (), from,
+            [] (const symtab_and_line &sala, const symtab_and_line &salb)
+   { return cmp_symtabs (sala, salb) < 0; });
+
+  from = std::unique (sals.begin (), from,
+                     [&] (const symtab_and_line &sala,
+                          const symtab_and_line &salb)
+    { return cmp_symtabs (sala, salb) == 0; });
+
+  sals.erase (from, sals.end ());
 }
 
 static void
@@ -1534,7 +1619,7 @@ set_debug (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 ", -1, gdb_stdout);
+  help_list (setdebuglist, "set debug ", all_commands, gdb_stdout);
 }
 
 static void
@@ -1547,28 +1632,6 @@ void
 init_cmd_lists (void)
 {
   max_user_call_depth = 1024;
-
-  cmdlist = NULL;
-  infolist = NULL;
-  enablelist = NULL;
-  disablelist = NULL;
-  togglelist = NULL;
-  stoplist = NULL;
-  deletelist = NULL;
-  detachlist = NULL;
-  setlist = NULL;
-  unsetlist = NULL;
-  showlist = NULL;
-  sethistlist = NULL;
-  showhistlist = NULL;
-  unsethistlist = NULL;
-  maintenancelist = NULL;
-  maintenanceinfolist = NULL;
-  maintenanceprintlist = NULL;
-  setprintlist = NULL;
-  showprintlist = NULL;
-  setchecklist = NULL;
-  showchecklist = NULL;
 }
 
 static void
@@ -1592,14 +1655,6 @@ show_history_expansion_p (struct ui_file *file, int from_tty,
                    value);
 }
 
-static void
-show_baud_rate (struct ui_file *file, int from_tty,
-               struct cmd_list_element *c, const char *value)
-{
-  fprintf_filtered (file, _("Baud rate for remote serial I/O is %s.\n"),
-                   value);
-}
-
 static void
 show_remote_debug (struct ui_file *file, int from_tty,
                   struct cmd_list_element *c, const char *value)
@@ -1626,10 +1681,6 @@ show_max_user_call_depth (struct ui_file *file, int from_tty,
                    value);
 }
 
-\f
-
-initialize_file_ftype _initialize_cli_cmds;
-
 void
 _initialize_cli_cmds (void)
 {
@@ -1638,28 +1689,28 @@ _initialize_cli_cmds (void)
   /* Define the classes of commands.
      They will appear in the help list in alphabetical order.  */
 
-  add_cmd ("internals", class_maintenance, NULL, _("\
+  add_cmd ("internals", class_maintenance, _("\
 Maintenance commands.\n\
 Some gdb commands are provided just for use by gdb maintainers.\n\
 These commands are subject to frequent change, and may not be as\n\
 well documented as user commands."),
           &cmdlist);
-  add_cmd ("obscure", class_obscure, NULL, _("Obscure features."), &cmdlist);
-  add_cmd ("aliases", class_alias, NULL,
+  add_cmd ("obscure", class_obscure, _("Obscure features."), &cmdlist);
+  add_cmd ("aliases", class_alias,
           _("Aliases of other commands."), &cmdlist);
-  add_cmd ("user-defined", class_user, NULL, _("\
+  add_cmd ("user-defined", class_user, _("\
 User-defined commands.\n\
 The commands in this class are those defined by the user.\n\
 Use the \"define\" command to define a command."), &cmdlist);
-  add_cmd ("support", class_support, NULL, _("Support facilities."), &cmdlist);
+  add_cmd ("support", class_support, _("Support facilities."), &cmdlist);
   if (!dbx_commands)
-    add_cmd ("status", class_info, NULL, _("Status inquiries."), &cmdlist);
-  add_cmd ("files", class_files, NULL, _("Specifying and examining files."),
+    add_cmd ("status", class_info, _("Status inquiries."), &cmdlist);
+  add_cmd ("files", class_files, _("Specifying and examining files."),
           &cmdlist);
-  add_cmd ("breakpoints", class_breakpoint, NULL,
+  add_cmd ("breakpoints", class_breakpoint,
           _("Making program stop at certain points."), &cmdlist);
-  add_cmd ("data", class_vars, NULL, _("Examining data."), &cmdlist);
-  add_cmd ("stack", class_stack, NULL, _("\
+  add_cmd ("data", class_vars, _("Examining data."), &cmdlist);
+  add_cmd ("stack", class_stack, _("\
 Examining the stack.\n\
 The stack is made up of stack frames.  Gdb assigns numbers to stack frames\n\
 counting from zero for the innermost (currently executing) frame.\n\n\
@@ -1668,7 +1719,7 @@ 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);
-  add_cmd ("running", class_run, NULL, _("Running the program."), &cmdlist);
+  add_cmd ("running", class_run, _("Running the program."), &cmdlist);
 
   /* Define general commands.  */
 
@@ -1676,9 +1727,11 @@ The commands below can be used to select other frames by number or address."),
 Print working directory.  This is used for your program as well."));
 
   c = add_cmd ("cd", class_files, cd_command, _("\
-Set working directory to DIR for debugger and program being debugged.\n\
-The change does not take effect for the program being debugged\n\
-until the next time it is started."), &cmdlist);
+Set working directory to DIR for debugger.\n\
+The debugger's current working directory specifies where scripts and other\n\
+files that can be loaded by GDB are located.\n\
+In order to change the inferior's current working directory, the recommended\n\
+way is to use the \"set cwd\" command."), &cmdlist);
   set_cmd_completer (c, filename_completer);
 
   add_com ("echo", class_support, echo_command, _("\
@@ -1703,7 +1756,11 @@ strict == evaluate script according to filename extension, error if not supporte
                        show_script_ext_mode,
                        &setlist, &showlist);
 
-  add_com ("quit", class_support, quit_command, _("Exit gdb."));
+  add_com ("quit", class_support, quit_command, _("\
+Exit gdb.\n\
+Usage: quit [EXPR]\n\
+The optional expression EXPR, if present, is evaluated and the result\n\
+used as GDB's exit code.  The default is zero."));
   c = add_com ("help", class_support, help_command,
               _("Print list of commands."));
   set_cmd_completer (c, command_completer);
@@ -1756,16 +1813,8 @@ the previous command number shown."),
   add_cmd ("version", no_set_class, show_version,
           _("Show what version of GDB this is."), &showlist);
 
-  /* If target is open when baud changes, it doesn't take effect until
-     the next open (I think, not sure).  */
-  add_setshow_zinteger_cmd ("remotebaud", no_class, &baud_rate, _("\
-Set baud rate for remote serial I/O."), _("\
-Show baud rate for remote serial I/O."), _("\
-This value is used to set the speed of the serial port when debugging\n\
-using remote targets."),
-                           NULL,
-                           show_baud_rate,
-                           &setlist, &showlist);
+  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."), _("\
@@ -1794,7 +1843,7 @@ from the target."),
                  _("Generic command for showing gdb debugging flags"),
                  &showdebuglist, "show debug ", 0, &showlist);
 
-  c = add_com ("shell", class_support, shell_escape, _("\
+  c = add_com ("shell", class_support, shell_command, _("\
 Execute the rest of the line as a shell command.\n\
 With no arguments, run an inferior shell."));
   set_cmd_completer (c, filename_completer);
@@ -1823,13 +1872,14 @@ Lines can be specified in these ways:\n\
   FUNCTION, to list around beginning of that function,\n\
   FILE:FUNCTION, to distinguish among like-named static functions.\n\
   *ADDRESS, to list around the line containing that address.\n\
-With two args if one is empty it stands for ten lines away from \
-the other arg."));
+With two args, if one is empty, it stands for ten lines away from\n\
+the other arg.\n\
+\n\
+By default, when a single location is given, display ten lines.\n\
+This can be changed using \"set listsize\", and the current value\n\
+can be shown using \"show listsize\"."));
 
-  if (!xdb_commands)
-    add_com_alias ("l", "list", class_files, 1);
-  else
-    add_com_alias ("v", "list", class_files, 1);
+  add_com_alias ("l", "list", class_files, 1);
 
   if (dbx_commands)
     add_com_alias ("file", "list", class_files, 1);
@@ -1837,8 +1887,21 @@ the other arg."));
   c = add_com ("disassemble", class_vars, disassemble_command, _("\
 Disassemble a specified section of memory.\n\
 Default is the function surrounding the pc of the selected frame.\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\
+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\
 Two arguments (separated by a comma) are taken as a range of memory to dump,\n\
   in the form of \"start,end\", or \"start,+length\".\n\
@@ -1848,8 +1911,6 @@ like in the \"break\" command.\n\
 So, for example, if you want to disassemble function bar in file foo.c\n\
 you must type \"disassemble 'foo.c'::bar\" and not \"disassemble foo.c:bar\"."));
   set_cmd_completer (c, location_completer);
-  if (xdb_commands)
-    add_com_alias ("va", "disassemble", class_xdb, 0);
 
   add_com_alias ("!", "shell", class_support, 0);
 
@@ -1857,7 +1918,7 @@ you must type \"disassemble 'foo.c'::bar\" and not \"disassemble foo.c:bar\"."))
 Run the ``make'' program using the rest of the line as arguments."));
   set_cmd_completer (c, filename_completer);
   add_cmd ("user", no_class, show_user, _("\
-Show definitions of non-python user defined commands.\n\
+Show definitions of non-python/scheme user defined commands.\n\
 Argument is the name of the user defined command.\n\
 With no argument, show definitions of all user defined commands."), &showlist);
   add_com ("apropos", class_support, apropos_command,
@@ -1865,8 +1926,8 @@ With no argument, show definitions of all user defined commands."), &showlist);
 
   add_setshow_uinteger_cmd ("max-user-call-depth", no_class,
                           &max_user_call_depth, _("\
-Set the max call depth for non-python user-defined commands."), _("\
-Show the max call depth for non-python user-defined commands."), NULL,
+Set the max call depth for non-python/scheme user-defined commands."), _("\
+Show the max call depth for non-python/scheme user-defined commands."), NULL,
                            NULL,
                            show_max_user_call_depth,
                            &setlist, &showlist);
This page took 0.045488 seconds and 4 git commands to generate.