Only have one API for unfiltered output
[binutils-gdb.git] / gdb / top.c
index 9d4ce1fa3bdc2dd59fb76ace3f6e932b87dd7805..afd3c94283d4e6deea15d0852101f466d81e070f 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1,6 +1,6 @@
 /* Top level stuff for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2019 Free Software Foundation, Inc.
+   Copyright (C) 1986-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -42,7 +42,7 @@
 #include "gdbsupport/version.h"
 #include "serial.h"
 #include "main.h"
-#include "event-loop.h"
+#include "gdbsupport/event-loop.h"
 #include "gdbthread.h"
 #include "extension.h"
 #include "interps.h"
 #include "filenames.h"
 #include "frame.h"
 #include "gdbsupport/buffer.h"
-#include "gdb_select.h"
+#include "gdbsupport/gdb_select.h"
 #include "gdbsupport/scope-exit.h"
 #include "gdbarch.h"
+#include "gdbsupport/pathstuff.h"
+#include "cli/cli-style.h"
 
 /* readline include files.  */
 #include "readline/readline.h"
@@ -86,36 +88,48 @@ extern void initialize_all_files (void);
 #define PREFIX(X) the_prompts.prompt_stack[the_prompts.top + X].prefix
 #define SUFFIX(X) the_prompts.prompt_stack[the_prompts.top + X].suffix
 
-/* Default command line prompt.  This is overriden in some configs.  */
+/* Default command line prompt.  This is overridden in some configs.  */
 
 #ifndef DEFAULT_PROMPT
 #define DEFAULT_PROMPT "(gdb) "
 #endif
 
-/* Generate a function that exports a pointer to a field of the
-   current UI.  */
+struct ui_file **
+current_ui_gdb_stdout_ptr ()
+{
+  return &current_ui->m_gdb_stdout;
+}
 
-#define gen_ret_current_ui_field_ptr(type, name)       \
-type *                                                 \
-current_ui_## name ## _ptr (void)                      \
-{                                                      \
-  return &current_ui->m_ ## name;              \
+struct ui_file **
+current_ui_gdb_stdin_ptr ()
+{
+  return &current_ui->m_gdb_stdin;
 }
 
-gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stdout)
-gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stdin)
-gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stderr)
-gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stdlog)
-gen_ret_current_ui_field_ptr (struct ui_out *, current_uiout)
+struct ui_file **
+current_ui_gdb_stderr_ptr ()
+{
+  return &current_ui->m_gdb_stderr;
+}
 
-int inhibit_gdbinit = 0;
+struct ui_file **
+current_ui_gdb_stdlog_ptr ()
+{
+  return &current_ui->m_gdb_stdlog;
+}
+
+struct ui_out **
+current_ui_current_uiout_ptr ()
+{
+  return &current_ui->m_current_uiout;
+}
 
-extern char lang_frame_mismatch_warn[];                /* language.c */
+int inhibit_gdbinit = 0;
 
 /* Flag for whether we want to confirm potentially dangerous
    operations.  Default is yes.  */
 
-int confirm = 1;
+bool confirm = true;
 
 static void
 show_confirm (struct ui_file *file, int from_tty,
@@ -145,7 +159,7 @@ static const char *repeat_arguments;
    command.  We need this as when a command is running, saved_command_line
    already contains the line of the currently executing command.  */
 
-char *previous_saved_command_line;
+static char *previous_saved_command_line;
 
 /* If not NULL, the arguments that should be passed if the
    previous_saved_command_line is repeated.  */
@@ -158,7 +172,7 @@ static const char *previous_repeat_arguments;
    whatever) can issue its own commands and also send along commands
    from the user, and have the user not notice that the user interface
    is issuing commands too.  */
-int server_command;
+bool server_command;
 
 /* Timeout limit for response from target.  */
 
@@ -182,10 +196,6 @@ int server_command;
 
 int remote_timeout = 2;
 
-/* Non-zero tells remote* modules to output debugging info.  */
-
-int remote_debug = 0;
-
 /* Sbrk location on entry to main.  Used for statistics only.  */
 #ifdef HAVE_USEFUL_SBRK
 char *lim_at_start;
@@ -237,13 +247,6 @@ void (*deprecated_readline_end_hook) (void);
 void (*deprecated_attach_hook) (void);
 void (*deprecated_detach_hook) (void);
 
-/* Called when going to wait for the target.  Usually allows the GUI
-   to run while waiting for target events.  */
-
-ptid_t (*deprecated_target_wait_hook) (ptid_t ptid,
-                                      struct target_waitstatus *status,
-                                      int options);
-
 /* Used by UI as a wrapper around command execution.  May do various
    things like enabling/disabling buttons, etc...  */
 
@@ -323,13 +326,11 @@ ui::~ui ()
 static gdb_file_up
 open_terminal_stream (const char *name)
 {
-  int fd;
-
-  fd = gdb_open_cloexec (name, O_RDWR | O_NOCTTY, 0);
-  if (fd < 0)
+  scoped_fd fd = gdb_open_cloexec (name, O_RDWR | O_NOCTTY, 0);
+  if (fd.get () < 0)
     perror_with_name  (_("opening terminal failed"));
 
-  return gdb_file_up (fdopen (fd, "w+"));
+  return fd.to_file ("w+");
 }
 
 /* Implementation of the "new-ui" command.  */
@@ -377,7 +378,7 @@ new_ui_command (const char *args, int from_tty)
     ui.release ();
   }
 
-  printf_unfiltered ("New UI allocated\n");
+  printf_filtered ("New UI allocated\n");
 }
 
 /* Handler for SIGHUP.  */
@@ -422,7 +423,7 @@ read_command_file (FILE *stream)
 
   while (ui->instream != NULL && !feof (ui->instream))
     {
-      char *command;
+      const char *command;
 
       /* Get a command-line.  This calls the readline package.  */
       command = command_line_input (NULL, NULL);
@@ -431,8 +432,6 @@ read_command_file (FILE *stream)
       command_handler (command);
     }
 }
-\f
-void (*pre_init_ui_hook) (void);
 
 #ifdef __MSDOS__
 static void
@@ -472,7 +471,8 @@ check_frame_language_change (void)
     {
       if (language_mode == language_mode_auto && info_verbose)
        {
-         language_info (1);    /* Print what changed.  */
+         /* Print what changed.  */
+         language_info ();
        }
       warned = 0;
     }
@@ -492,7 +492,7 @@ check_frame_language_change (void)
          && flang != language_unknown
          && flang != current_language->la_language)
        {
-         printf_filtered ("%s\n", lang_frame_mismatch_warn);
+         printf_filtered ("%s\n", _(lang_frame_mismatch_warn));
          warned = 1;
        }
     }
@@ -507,6 +507,13 @@ wait_sync_command_done (void)
   scoped_restore save_ui = make_scoped_restore (&current_ui);
   struct ui *ui = current_ui;
 
+  /* We're about to wait until the target stops after having resumed
+     it so must force-commit resumptions, in case we're being called
+     in some context where a scoped_disable_commit_resumed object is
+     active.  I.e., this function is a commit-resumed sync/flush
+     point.  */
+  scoped_enable_commit_resumed enable ("sync wait");
+
   while (gdb_do_one_event () >= 0)
     if (ui->prompt_state != PROMPT_BLOCKED)
       break;
@@ -563,6 +570,8 @@ execute_command (const char *p, int from_tty)
     {
       const char *cmd = p;
       const char *arg;
+      std::string default_args;
+      std::string default_args_and_arg;
       int was_sync = current_ui->prompt_state == PROMPT_BLOCKED;
 
       line = p;
@@ -570,26 +579,37 @@ execute_command (const char *p, int from_tty)
       /* If trace-commands is set then this will print this command.  */
       print_command_trace ("%s", p);
 
-      c = lookup_cmd (&cmd, cmdlist, "", 0, 1);
+      c = lookup_cmd (&cmd, cmdlist, "", &default_args, 0, 1);
       p = cmd;
 
       scoped_restore save_repeat_args
        = make_scoped_restore (&repeat_arguments, nullptr);
       const char *args_pointer = p;
 
-      /* Pass null arg rather than an empty one.  */
-      arg = *p ? p : 0;
+      if (!default_args.empty ())
+       {
+         if (*p != '\0')
+           default_args_and_arg = default_args + ' ' + p;
+         else
+           default_args_and_arg = default_args;
+         arg = default_args_and_arg.c_str ();
+       }
+      else
+       {
+         /* Pass null arg rather than an empty one.  */
+         arg = *p == '\0' ? nullptr : p;
+       }
 
       /* FIXME: cagney/2002-02-02: The c->type test is pretty dodgy
-         while the is_complete_command(cfunc) test is just plain
-         bogus.  They should both be replaced by a test of the form
-         c->strip_trailing_white_space_p.  */
+        while the is_complete_command(cfunc) test is just plain
+        bogus.  They should both be replaced by a test of the form
+        c->strip_trailing_white_space_p.  */
       /* NOTE: cagney/2002-02-02: The function.cfunc in the below
-         can't be replaced with func.  This is because it is the
-         cfunc, and not the func, that has the value that the
-         is_complete_command hack is testing for.  */
+        can't be replaced with func.  This is because it is the
+        cfunc, and not the func, that has the value that the
+        is_complete_command hack is testing for.  */
       /* Clear off trailing whitespace, except for set and complete
-         command.  */
+        command.  */
       std::string without_whitespace;
       if (arg
          && c->type != set_cmd
@@ -610,16 +630,32 @@ execute_command (const char *p, int from_tty)
       execute_cmd_pre_hook (c);
 
       if (c->deprecated_warn_user)
-       deprecated_cmd_warning (line);
+       deprecated_cmd_warning (line, cmdlist);
 
       /* c->user_commands would be NULL in the case of a python command.  */
       if (c->theclass == class_user && c->user_commands)
        execute_user_command (c, arg);
+      else if (c->theclass == class_user
+              && c->is_prefix () && !c->allow_unknown)
+       /* If this is a user defined prefix that does not allow unknown
+          (in other words, C is a prefix command and not a command
+          that can be followed by its args), report the list of
+          subcommands.  */
+       {
+         std::string prefixname = c->prefixname ();
+          std::string prefixname_no_space
+           = prefixname.substr (0, prefixname.length () - 1);
+         printf_filtered
+           ("\"%s\" must be followed by the name of a subcommand.\n",
+            prefixname_no_space.c_str ());
+         help_list (*c->subcommands, prefixname.c_str (), all_commands,
+                    gdb_stdout);
+       }
       else if (c->type == set_cmd)
        do_set_command (arg, from_tty, c);
       else if (c->type == show_cmd)
        do_show_command (arg, from_tty, c);
-      else if (!cmd_func_p (c))
+      else if (c->is_command_class_help ())
        error (_("That is not a command, just a help topic."));
       else if (deprecated_call_command_hook)
        deprecated_call_command_hook (c, arg, from_tty);
@@ -649,12 +685,10 @@ execute_command (const char *p, int from_tty)
   cleanup_if_error.release ();
 }
 
-/* Run execute_command for P and FROM_TTY.  Sends its output to FILE,
-   do not display it to the screen.  BATCH_FLAG will be
-   temporarily set to true.  */
+/* See gdbcmd.h.  */
 
 void
-execute_command_to_ui_file (struct ui_file *file, const char *p, int from_tty)
+execute_fn_to_ui_file (struct ui_file *file, std::function<void(void)> fn)
 {
   /* GDB_STDOUT should be better already restored during these
      restoration callbacks.  */
@@ -677,24 +711,62 @@ execute_command_to_ui_file (struct ui_file *file, const char *p, int from_tty)
     scoped_restore save_stdtargerr
       = make_scoped_restore (&gdb_stdtargerr, file);
 
-    execute_command (p, from_tty);
+    fn ();
   }
 }
 
-/* Run execute_command for P and FROM_TTY.  Capture its output into the
-   returned string, do not display it to the screen.  BATCH_FLAG will be
-   temporarily set to true.  */
+/* See gdbcmd.h.  */
 
-std::string
-execute_command_to_string (const char *p, int from_tty,
-                          bool term_out)
+void
+execute_fn_to_string (std::string &res, std::function<void(void)> fn,
+                     bool term_out)
 {
   string_file str_file (term_out);
 
-  execute_command_to_ui_file (&str_file, p, from_tty);
-  return std::move (str_file.string ());
+  try
+    {
+      execute_fn_to_ui_file (&str_file, fn);
+    }
+  catch (...)
+    {
+      /* Finally.  */
+      res = std::move (str_file.string ());
+      throw;
+    }
+
+  /* And finally.  */
+  res = std::move (str_file.string ());
 }
 
+/* See gdbcmd.h.  */
+
+void
+execute_command_to_ui_file (struct ui_file *file,
+                           const char *p, int from_tty)
+{
+  execute_fn_to_ui_file (file, [=]() { execute_command (p, from_tty); });
+}
+
+/* See gdbcmd.h.  */
+
+void
+execute_command_to_string (std::string &res, const char *p, int from_tty,
+                          bool term_out)
+{
+  execute_fn_to_string (res, [=]() { execute_command (p, from_tty); },
+                       term_out);
+}
+
+/* See gdbcmd.h.  */
+
+void
+execute_command_to_string (const char *p, int from_tty,
+                          bool term_out)
+{
+  std::string dummy;
+  execute_fn_to_string (dummy, [=]() { execute_command (p, from_tty); },
+                       term_out);
+}
 \f
 /* When nonzero, cause dont_repeat to do nothing.  This should only be
    set via prevent_dont_repeat.  */
@@ -792,9 +864,9 @@ gdb_readline_no_editing (const char *prompt)
   if (prompt != NULL)
     {
       /* Don't use a _filtered function here.  It causes the assumed
-         character position to be off, since the newline we read from
-         the user is not accounted for.  */
-      fputs_unfiltered (prompt, gdb_stdout);
+        character position to be off, since the newline we read from
+        the user is not accounted for.  */
+      printf_unfiltered ("%s", prompt);
       gdb_flush (gdb_stdout);
     }
 
@@ -850,21 +922,34 @@ gdb_readline_no_editing (const char *prompt)
 /* Variables which control command line editing and history
    substitution.  These variables are given default values at the end
    of this file.  */
-static int command_editing_p;
+static bool command_editing_p;
 
 /* NOTE 1999-04-29: This variable will be static again, once we modify
    gdb to use the event loop as the default command loop and we merge
    event-top.c into this file, top.c.  */
 
-/* static */ int history_expansion_p;
+/* static */ bool history_expansion_p;
+
+/* Should we write out the command history on exit?  In order to write out
+   the history both this flag must be true, and the history_filename
+   variable must be set to something sensible.  */
+static bool write_history_p;
 
-static int write_history_p;
+/* The name of the file in which GDB history will be written.  If this is
+   set to NULL, of the empty string then history will not be written.  */
+static std::string history_filename;
+
+/* Implement 'show history save'.  */
 static void
 show_write_history_p (struct ui_file *file, int from_tty,
                      struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Saving of the history record on exit is %s.\n"),
-                   value);
+  if (!write_history_p || !history_filename.empty ())
+    fprintf_filtered (file, _("Saving of the history record on exit is %s.\n"),
+                     value);
+  else
+    fprintf_filtered (file, _("Saving of the history is disabled due to "
+                             "the value of 'history filename'.\n"));
 }
 
 /* The variable associated with the "set/show history size"
@@ -893,14 +978,18 @@ show_history_remove_duplicates (struct ui_file *file, int from_tty,
                    value);
 }
 
-static char *history_filename;
+/* Implement 'show history filename'.  */
 static void
 show_history_filename (struct ui_file *file, int from_tty,
                       struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("The filename in which to record "
-                           "the command history is \"%s\".\n"),
-                   value);
+  if (!history_filename.empty ())
+    fprintf_filtered (file, _("The filename in which to record "
+                             "the command history is \"%ps\".\n"),
+                     styled_string (file_name_style.style (), value));
+  else
+    fprintf_filtered (file, _("There is no filename currently set for "
+                             "recording the command history in.\n"));
 }
 
 /* This is like readline(), but it has some gdb-specific behavior.
@@ -1161,14 +1250,17 @@ gdb_safe_append_history (void)
   int ret, saved_errno;
 
   std::string local_history_filename
-    = string_printf ("%s-gdb%ld~", history_filename, (long) getpid ());
+    = string_printf ("%s-gdb%ld~", history_filename.c_str (), (long) getpid ());
 
-  ret = rename (history_filename, local_history_filename.c_str ());
+  ret = rename (history_filename.c_str (), local_history_filename.c_str ());
   saved_errno = errno;
   if (ret < 0 && saved_errno != ENOENT)
     {
-      warning (_("Could not rename %s to %s: %s"),
-              history_filename, local_history_filename.c_str (),
+      warning (_("Could not rename %ps to %ps: %s"),
+              styled_string (file_name_style.style (),
+                             history_filename.c_str ()),
+              styled_string (file_name_style.style (),
+                             local_history_filename.c_str ()),
               safe_strerror (saved_errno));
     }
   else
@@ -1194,11 +1286,11 @@ gdb_safe_append_history (void)
                                   history_max_entries);
        }
 
-      ret = rename (local_history_filename.c_str (), history_filename);
+      ret = rename (local_history_filename.c_str (), history_filename.c_str ());
       saved_errno = errno;
       if (ret < 0 && saved_errno != EEXIST)
-        warning (_("Could not rename %s to %s: %s"),
-                local_history_filename.c_str (), history_filename,
+       warning (_("Could not rename %s to %s: %s"),
+                local_history_filename.c_str (), history_filename.c_str (),
                 safe_strerror (saved_errno));
     }
 }
@@ -1212,7 +1304,7 @@ gdb_safe_append_history (void)
    This routine either uses fancy command line editing or simple input
    as the user has requested.  */
 
-char *
+const char *
 command_line_input (const char *prompt_arg, const char *annotation_suffix)
 {
   static struct buffer cmd_line_buffer;
@@ -1263,9 +1355,9 @@ command_line_input (const char *prompt_arg, const char *annotation_suffix)
       gdb::unique_xmalloc_ptr<char> rl;
 
       /* Make sure that all output has been output.  Some machines may
-         let you get away with leaving out some of the gdb_flush, but
-         not all.  */
-      wrap_here ("");
+        let you get away with leaving out some of the gdb_flush, but
+        not all.  */
+      gdb_stdout->wrap_here (0);
       gdb_flush (gdb_stdout);
       gdb_flush (gdb_stderr);
 
@@ -1273,11 +1365,7 @@ command_line_input (const char *prompt_arg, const char *annotation_suffix)
        ++source_line_number;
 
       if (from_tty && annotation_level > 1)
-       {
-         puts_unfiltered ("\n\032\032pre-");
-         puts_unfiltered (annotation_suffix);
-         puts_unfiltered ("\n");
-       }
+       printf_unfiltered ("\n\032\032pre-%s\n", annotation_suffix);
 
       /* Don't use fancy stuff if not talking to stdin.  */
       if (deprecated_readline_hook
@@ -1329,19 +1417,14 @@ print_gdb_version (struct ui_file *stream, bool interactive)
      program to parse, and is just canonical program name and version
      number, which starts after last space.  */
 
-  ui_file_style style;
-  if (interactive)
-    {
-      ui_file_style nstyle = { ui_file_style::MAGENTA, ui_file_style::NONE,
-                              ui_file_style::BOLD };
-      style = nstyle;
-    }
-  fprintf_styled (stream, style, "GNU gdb %s%s\n", PKGVERSION, version);
+  std::string v_str = string_printf ("GNU gdb %s%s", PKGVERSION, version);
+  fprintf_filtered (stream, "%ps\n",
+                   styled_string (version_style.style (), v_str.c_str ()));
 
   /* Second line is a copyright notice.  */
 
   fprintf_filtered (stream,
-                   "Copyright (C) 2019 Free Software Foundation, Inc.\n");
+                   "Copyright (C) 2022 Free Software Foundation, Inc.\n");
 
   /* Following the copyright is a brief statement that the program is
      free software, that users are free to copy and change it on
@@ -1400,124 +1483,174 @@ print_gdb_configuration (struct ui_file *stream)
 This GDB was configured as follows:\n\
    configure --host=%s --target=%s\n\
 "), host_name, target_name);
+
   fprintf_filtered (stream, _("\
-             --with-auto-load-dir=%s\n\
-             --with-auto-load-safe-path=%s\n\
+            --with-auto-load-dir=%s\n\
+            --with-auto-load-safe-path=%s\n\
 "), AUTO_LOAD_DIR, AUTO_LOAD_SAFE_PATH);
+
 #if HAVE_LIBEXPAT
   fprintf_filtered (stream, _("\
-             --with-expat\n\
+            --with-expat\n\
 "));
 #else
   fprintf_filtered (stream, _("\
-             --without-expat\n\
+            --without-expat\n\
 "));
 #endif
+
   if (GDB_DATADIR[0])
     fprintf_filtered (stream, _("\
-             --with-gdb-datadir=%s%s\n\
+            --with-gdb-datadir=%s%s\n\
 "), GDB_DATADIR, GDB_DATADIR_RELOCATABLE ? " (relocatable)" : "");
+
 #ifdef ICONV_BIN
   fprintf_filtered (stream, _("\
-             --with-iconv-bin=%s%s\n\
+            --with-iconv-bin=%s%s\n\
 "), ICONV_BIN, ICONV_BIN_RELOCATABLE ? " (relocatable)" : "");
 #endif
+
   if (JIT_READER_DIR[0])
     fprintf_filtered (stream, _("\
-             --with-jit-reader-dir=%s%s\n\
+            --with-jit-reader-dir=%s%s\n\
 "), JIT_READER_DIR, JIT_READER_DIR_RELOCATABLE ? " (relocatable)" : "");
+
 #if HAVE_LIBUNWIND_IA64_H
   fprintf_filtered (stream, _("\
-             --with-libunwind-ia64\n\
+            --with-libunwind-ia64\n\
 "));
 #else
   fprintf_filtered (stream, _("\
-             --without-libunwind-ia64\n\
+            --without-libunwind-ia64\n\
 "));
 #endif
+
 #if HAVE_LIBLZMA
   fprintf_filtered (stream, _("\
-             --with-lzma\n\
+            --with-lzma\n\
 "));
 #else
   fprintf_filtered (stream, _("\
-             --without-lzma\n\
+            --without-lzma\n\
 "));
 #endif
+
 #if HAVE_LIBBABELTRACE
-    fprintf_filtered (stream, _("\
-             --with-babeltrace\n\
+  fprintf_filtered (stream, _("\
+            --with-babeltrace\n\
 "));
 #else
-    fprintf_filtered (stream, _("\
-             --without-babeltrace\n\
+  fprintf_filtered (stream, _("\
+            --without-babeltrace\n\
 "));
 #endif
+
 #if HAVE_LIBIPT
-    fprintf_filtered (stream, _("\
-             --with-intel-pt\n\
+  fprintf_filtered (stream, _("\
+            --with-intel-pt\n\
 "));
 #else
-    fprintf_filtered (stream, _("\
-             --without-intel-pt\n\
+  fprintf_filtered (stream, _("\
+            --without-intel-pt\n\
 "));
 #endif
+
 #if HAVE_LIBMPFR
-    fprintf_filtered (stream, _("\
-             --with-mpfr\n\
+  fprintf_filtered (stream, _("\
+            --with-mpfr\n\
 "));
 #else
-    fprintf_filtered (stream, _("\
-             --without-mpfr\n\
+  fprintf_filtered (stream, _("\
+            --without-mpfr\n\
+"));
+#endif
+#if HAVE_LIBXXHASH
+  fprintf_filtered (stream, _("\
+            --with-xxhash\n\
+"));
+#else
+  fprintf_filtered (stream, _("\
+            --without-xxhash\n\
 "));
 #endif
 #ifdef WITH_PYTHON_PATH
   fprintf_filtered (stream, _("\
-             --with-python=%s%s\n\
+            --with-python=%s%s\n\
 "), WITH_PYTHON_PATH, PYTHON_PATH_RELOCATABLE ? " (relocatable)" : "");
 #else
   fprintf_filtered (stream, _("\
-             --without-python\n\
+            --without-python\n\
+"));
+#endif
+#ifdef WITH_PYTHON_LIBDIR
+  fprintf_filtered (stream, _("\
+            --with-python-libdir=%s%s\n\
+"), WITH_PYTHON_LIBDIR, PYTHON_LIBDIR_RELOCATABLE ? " (relocatable)" : "");
+#else
+  fprintf_filtered (stream, _("\
+            --without-python-libdir\n\
+"));
+#endif
+
+#if HAVE_LIBDEBUGINFOD
+  fprintf_filtered (stream, _("\
+            --with-debuginfod\n\
+"));
+#else
+   fprintf_filtered (stream, _("\
+            --without-debuginfod\n\
 "));
 #endif
+
 #if HAVE_GUILE
   fprintf_filtered (stream, _("\
-             --with-guile\n\
+            --with-guile\n\
 "));
 #else
   fprintf_filtered (stream, _("\
-             --without-guile\n\
+            --without-guile\n\
 "));
 #endif
+
 #if HAVE_SOURCE_HIGHLIGHT
   fprintf_filtered (stream, _("\
-             --enable-source-highlight\n\
+            --enable-source-highlight\n\
 "));
 #else
   fprintf_filtered (stream, _("\
-             --disable-source-highlight\n\
+            --disable-source-highlight\n\
 "));
 #endif
+
 #ifdef RELOC_SRCDIR
   fprintf_filtered (stream, _("\
-             --with-relocated-sources=%s\n\
+            --with-relocated-sources=%s\n\
 "), RELOC_SRCDIR);
 #endif
+
   if (DEBUGDIR[0])
     fprintf_filtered (stream, _("\
-             --with-separate-debug-dir=%s%s\n\
+            --with-separate-debug-dir=%s%s\n\
 "), DEBUGDIR, DEBUGDIR_RELOCATABLE ? " (relocatable)" : "");
+
   if (TARGET_SYSTEM_ROOT[0])
     fprintf_filtered (stream, _("\
-             --with-sysroot=%s%s\n\
+            --with-sysroot=%s%s\n\
 "), TARGET_SYSTEM_ROOT, TARGET_SYSTEM_ROOT_RELOCATABLE ? " (relocatable)" : "");
+
   if (SYSTEM_GDBINIT[0])
     fprintf_filtered (stream, _("\
-             --with-system-gdbinit=%s%s\n\
+            --with-system-gdbinit=%s%s\n\
 "), SYSTEM_GDBINIT, SYSTEM_GDBINIT_RELOCATABLE ? " (relocatable)" : "");
-    /* We assume "relocatable" will be printed at least once, thus we always
-       print this text.  It's a reasonably safe assumption for now.  */
-    fprintf_filtered (stream, _("\n\
+
+  if (SYSTEM_GDBINIT_DIR[0])
+    fprintf_filtered (stream, _("\
+            --with-system-gdbinit-dir=%s%s\n\
+"), SYSTEM_GDBINIT_DIR, SYSTEM_GDBINIT_DIR_RELOCATABLE ? " (relocatable)" : "");
+
+  /* We assume "relocatable" will be printed at least once, thus we always
+     print this text.  It's a reasonably safe assumption for now.  */
+  fprintf_filtered (stream, _("\n\
 (\"Relocatable\" means the directory can be moved with the GDB installation\n\
 tree, and GDB will still find it.)\n\
 "));
@@ -1526,12 +1659,12 @@ tree, and GDB will still find it.)\n\
 
 /* The current top level prompt, settable with "set prompt", and/or
    with the python `gdb.prompt_hook' hook.  */
-static char *top_prompt;
+static std::string top_prompt;
 
 /* Access method for the GDB prompt string.  */
 
-char *
-get_prompt (void)
+const std::string &
+get_prompt ()
 {
   return top_prompt;
 }
@@ -1541,28 +1674,18 @@ get_prompt (void)
 void
 set_prompt (const char *s)
 {
-  char *p = xstrdup (s);
-
-  xfree (top_prompt);
-  top_prompt = p;
+  top_prompt = s;
 }
 \f
 
-struct qt_args
-{
-  int from_tty;
-};
-
-/* Callback for iterate_over_inferiors.  Kills or detaches the given
-   inferior, depending on how we originally gained control of it.  */
+/* Kills or detaches the given inferior, depending on how we originally
+   gained control of it.  */
 
-static int
-kill_or_detach (struct inferior *inf, void *args)
+static void
+kill_or_detach (inferior *inf, int from_tty)
 {
-  struct qt_args *qt = (struct qt_args *) args;
-
   if (inf->pid == 0)
-    return 0;
+    return;
 
   thread_info *thread = any_thread_of_inferior (inf);
   if (thread != NULL)
@@ -1570,40 +1693,33 @@ kill_or_detach (struct inferior *inf, void *args)
       switch_to_thread (thread);
 
       /* Leave core files alone.  */
-      if (target_has_execution)
+      if (target_has_execution ())
        {
          if (inf->attach_flag)
-           target_detach (inf, qt->from_tty);
+           target_detach (inf, from_tty);
          else
            target_kill ();
        }
     }
-
-  return 0;
 }
 
-/* Callback for iterate_over_inferiors.  Prints info about what GDB
-   will do to each inferior on a "quit".  ARG points to a struct
-   ui_out where output is to be collected.  */
+/* Prints info about what GDB will do to inferior INF on a "quit".  OUT is
+   where to collect the output.  */
 
-static int
-print_inferior_quit_action (struct inferior *inf, void *arg)
+static void
+print_inferior_quit_action (inferior *inf, ui_file *out)
 {
-  struct ui_file *stb = (struct ui_file *) arg;
-
   if (inf->pid == 0)
-    return 0;
+    return;
 
   if (inf->attach_flag)
-    fprintf_filtered (stb,
+    fprintf_filtered (out,
                      _("\tInferior %d [%s] will be detached.\n"), inf->num,
                      target_pid_to_str (ptid_t (inf->pid)).c_str ());
   else
-    fprintf_filtered (stb,
+    fprintf_filtered (out,
                      _("\tInferior %d [%s] will be killed.\n"), inf->num,
                      target_pid_to_str (ptid_t (inf->pid)).c_str ());
-
-  return 0;
 }
 
 /* If necessary, make the user confirm that we should quit.  Return
@@ -1620,7 +1736,10 @@ quit_confirm (void)
   string_file stb;
 
   stb.puts (_("A debugging session is active.\n\n"));
-  iterate_over_inferiors (print_inferior_quit_action, &stb);
+
+  for (inferior *inf : all_inferiors ())
+    print_inferior_quit_action (inf, &stb);
+
   stb.puts (_("\nQuit anyway? "));
 
   return query ("%s", stb.c_str ());
@@ -1653,9 +1772,6 @@ void
 quit_force (int *exit_arg, int from_tty)
 {
   int exit_code = 0;
-  struct qt_args qt;
-
-  undo_terminal_modifications_before_exit ();
 
   /* An optional expression may be used to cause gdb to terminate with the
      value of that expression.  */
@@ -1664,7 +1780,9 @@ quit_force (int *exit_arg, int from_tty)
   else if (return_child_result)
     exit_code = return_child_result_value;
 
-  qt.from_tty = from_tty;
+  gdb::observers::gdb_exiting.notify (exit_code);
+
+  undo_terminal_modifications_before_exit ();
 
   /* We want to handle any quit errors and exit regardless.  */
 
@@ -1672,7 +1790,8 @@ quit_force (int *exit_arg, int from_tty)
   try
     {
       disconnect_tracing ();
-      iterate_over_inferiors (kill_or_detach, &qt);
+      for (inferior *inf : all_inferiors ())
+       kill_or_detach (inf, from_tty);
     }
   catch (const gdb_exception &ex)
     {
@@ -1681,26 +1800,29 @@ quit_force (int *exit_arg, int from_tty)
 
   /* Give all pushed targets a chance to do minimal cleanup, and pop
      them all out.  */
-  try
+  for (inferior *inf : all_inferiors ())
     {
-      pop_all_targets ();
-    }
-  catch (const gdb_exception &ex)
-    {
-      exception_print (gdb_stderr, ex);
+      switch_to_inferior_no_thread (inf);
+      try
+       {
+         pop_all_targets ();
+       }
+      catch (const gdb_exception &ex)
+       {
+         exception_print (gdb_stderr, ex);
+       }
     }
 
   /* Save the history information if it is appropriate to do so.  */
   try
     {
-      if (write_history_p && history_filename)
+      if (write_history_p && !history_filename.empty ())
        {
-         struct ui *ui;
          int save = 0;
 
          /* History is currently shared between all UIs.  If there's
             any UI with a terminal, save history.  */
-         ALL_UIS (ui)
+         for (ui *ui : all_uis ())
            {
              if (input_interactive_p (ui))
                {
@@ -1744,13 +1866,13 @@ static enum auto_boolean interactive_mode = AUTO_BOOLEAN_AUTO;
 
 static void
 show_interactive_mode (struct ui_file *file, int from_tty,
-                       struct cmd_list_element *c,
-                       const char *value)
+                      struct cmd_list_element *c,
+                      const char *value)
 {
   if (interactive_mode == AUTO_BOOLEAN_AUTO)
     fprintf_filtered (file, "Debugger's interactive mode "
-                           "is %s (currently %s).\n",
-                      value, input_interactive_p (current_ui) ? "on" : "off");
+                           "is %s (currently %s).\n",
+                     value, input_interactive_p (current_ui) ? "on" : "off");
   else
     fprintf_filtered (file, "Debugger's interactive mode is %s.\n", value);
 }
@@ -1862,21 +1984,7 @@ set_history_size_command (const char *args,
   set_readline_history_size (history_size_setshow_var);
 }
 
-void
-set_history (const char *args, int from_tty)
-{
-  printf_unfiltered (_("\"set history\" must be followed "
-                      "by the name of a history subcommand.\n"));
-  help_list (sethistlist, "set history ", all_commands, gdb_stdout);
-}
-
-void
-show_history (const char *args, int from_tty)
-{
-  cmd_show_list (showhistlist, from_tty, "");
-}
-
-int info_verbose = 0;          /* Default verbose msgs off.  */
+bool info_verbose = false;     /* Default verbose msgs off.  */
 
 /* Called by do_set_command.  An elaborate joke.  */
 void
@@ -1885,7 +1993,7 @@ set_verbose (const char *args, int from_tty, struct cmd_list_element *c)
   const char *cmdname = "verbose";
   struct cmd_list_element *showcmd;
 
-  showcmd = lookup_cmd_1 (&cmdname, showlist, NULL, 1);
+  showcmd = lookup_cmd_1 (&cmdname, showlist, NULL, NULL, 1);
   gdb_assert (showcmd != NULL && showcmd != CMD_LIST_AMBIGUOUS);
 
   if (c->doc && c->doc_allocated)
@@ -1956,24 +2064,8 @@ init_history (void)
 
   set_readline_history_size (history_size_setshow_var);
 
-  tmpenv = getenv ("GDBHISTFILE");
-  if (tmpenv)
-    history_filename = xstrdup (tmpenv);
-  else if (!history_filename)
-    {
-      /* We include the current directory so that if the user changes
-         directories the file written will be the same as the one
-         that was read.  */
-#ifdef __MSDOS__
-      /* No leading dots in file names are allowed on MSDOS.  */
-      history_filename = concat (current_directory, "/_gdb_history",
-                                (char *)NULL);
-#else
-      history_filename = concat (current_directory, "/.gdb_history",
-                                (char *)NULL);
-#endif
-    }
-  read_history (history_filename);
+  if (!history_filename.empty ())
+    read_history (history_filename.c_str ());
 }
 
 static void
@@ -2019,15 +2111,25 @@ show_exec_done_display_p (struct ui_file *file, int from_tty,
                    value);
 }
 
-/* New values of the "data-directory" parameter are staged here.  */
-static char *staged_gdb_datadir;
+/* New values of the "data-directory" parameter are staged here.
+   Extension languages, for example Python's gdb.parameter API, will read
+   the value directory from this variable, so we must ensure that this
+   always contains the correct value.  */
+static std::string staged_gdb_datadir;
 
 /* "set" command for the gdb_datadir configuration variable.  */
 
 static void
 set_gdb_datadir (const char *args, int from_tty, struct cmd_list_element *c)
 {
-  set_gdb_data_directory (staged_gdb_datadir);
+  set_gdb_data_directory (staged_gdb_datadir.c_str ());
+
+  /* SET_GDB_DATA_DIRECTORY will resolve relative paths in
+     STAGED_GDB_DATADIR, so we now copy the value from GDB_DATADIR
+     back into STAGED_GDB_DATADIR so the extension languages can read the
+     correct value.  */
+  staged_gdb_datadir = gdb_datadir;
+
   gdb::observers::gdb_datadir_changed.notify ();
 }
 
@@ -2037,10 +2139,13 @@ static void
 show_gdb_datadir (struct ui_file *file, int from_tty,
                  struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("GDB's data directory is \"%s\".\n"),
-                   gdb_datadir);
+  fprintf_filtered (file, _("GDB's data directory is \"%ps\".\n"),
+                   styled_string (file_name_style.style (),
+                                  gdb_datadir.c_str ()));
 }
 
+/* Implement 'set history filename'.  */
+
 static void
 set_history_filename (const char *args,
                      int from_tty, struct cmd_list_element *c)
@@ -2048,9 +2153,36 @@ set_history_filename (const char *args,
   /* We include the current directory so that if the user changes
      directories the file written will be the same as the one
      that was read.  */
-  if (!IS_ABSOLUTE_PATH (history_filename))
-    history_filename = reconcat (history_filename, current_directory, "/", 
-                                history_filename, (char *) NULL);
+  if (!history_filename.empty ()
+      && !IS_ABSOLUTE_PATH (history_filename.c_str ()))
+    {
+      gdb::unique_xmalloc_ptr<char> temp
+       (gdb_abspath (history_filename.c_str ()));
+
+      history_filename = temp.get ();
+    }
+}
+
+/* Whether we're in quiet startup mode.  */
+
+static bool startup_quiet;
+
+/* See top.h.  */
+
+bool
+check_quiet_mode ()
+{
+  return startup_quiet;
+}
+
+/* Show whether GDB should start up in quiet mode.  */
+
+static void
+show_startup_quiet (struct ui_file *file, int from_tty,
+             struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Whether to start up quietly is %s.\n"),
+                   value);
 }
 
 static void
@@ -2151,7 +2283,7 @@ By default this option is set to 0."),
                           show_history_remove_duplicates,
                           &sethistlist, &showhistlist);
 
-  add_setshow_filename_cmd ("filename", no_class, &history_filename, _("\
+  add_setshow_optional_filename_cmd ("filename", no_class, &history_filename, _("\
 Set the filename in which to record the command history."), _("\
 Show the filename in which to record the command history."), _("\
 (the list of previous commands of which a record is kept)."),
@@ -2185,16 +2317,18 @@ Use \"on\" to enable the notification, and \"off\" to disable it."),
                           &setlist, &showlist);
 
   add_setshow_filename_cmd ("data-directory", class_maintenance,
-                           &staged_gdb_datadir, _("Set GDB's data directory."),
-                           _("Show GDB's data directory."),
-                           _("\
+                          &staged_gdb_datadir, _("Set GDB's data directory."),
+                          _("Show GDB's data directory."),
+                          _("\
 When set, GDB uses the specified path to search for data files."),
-                           set_gdb_datadir, show_gdb_datadir,
-                           &setlist,
-                           &showlist);
+                          set_gdb_datadir, show_gdb_datadir,
+                          &setlist,
+                           &showlist);
+  /* Prime the initial value for data-directory.  */
+  staged_gdb_datadir = gdb_datadir;
 
   add_setshow_auto_boolean_cmd ("interactive-mode", class_support,
-                                &interactive_mode, _("\
+                               &interactive_mode, _("\
 Set whether GDB's standard input is a terminal."), _("\
 Show whether GDB's standard input is a terminal."), _("\
 If on, GDB assumes that standard input is a terminal.  In practice, it\n\
@@ -2203,9 +2337,20 @@ commands entered at the command prompt.  If off, GDB assumes that standard\n\
 input is not a terminal, and uses the default answer to all queries.\n\
 If auto (the default), determine which mode to use based on the standard\n\
 input settings."),
-                        NULL,
-                        show_interactive_mode,
-                        &setlist, &showlist);
+                       NULL,
+                       show_interactive_mode,
+                       &setlist, &showlist);
+
+  add_setshow_boolean_cmd ("startup-quietly", class_support,
+                              &startup_quiet, _("\
+Set whether GDB should start up quietly."), _("                \
+Show whether GDB should start up quietly."), _("\
+This setting will not affect the current session.  Instead this command\n\
+should be added to the .gdbearlyinit file in the users home directory to\n\
+affect future GDB sessions."),
+                              NULL,
+                              show_startup_quiet,
+                              &setlist, &showlist);
 
   c = add_cmd ("new-ui", class_support, new_ui_command, _("\
 Create a new UI.\n\
@@ -2215,15 +2360,14 @@ The second argument is the terminal the UI runs on."), &cmdlist);
   set_cmd_completer (c, interpreter_completer);
 }
 
+/* See top.h.  */
+
 void
-gdb_init (char *argv0)
+gdb_init ()
 {
   saved_command_line = xstrdup ("");
   previous_saved_command_line = xstrdup ("");
 
-  if (pre_init_ui_hook)
-    pre_init_ui_hook ();
-
   /* Run the init function of each source file.  */
 
 #ifdef __MSDOS__
@@ -2233,8 +2377,6 @@ gdb_init (char *argv0)
 #endif
 
   init_cmd_lists ();       /* This needs to be done first.  */
-  initialize_targets ();    /* Setup target_terminal macros for utils.c.  */
-  initialize_utils ();     /* Make errors and warnings possible.  */
 
   init_page_info ();
 
@@ -2257,7 +2399,7 @@ gdb_init (char *argv0)
      to alter it.  */
   set_initial_gdb_ttystate ();
 
-  async_init_signals ();
+  gdb_init_signals ();
 
   /* We need a default language for parsing expressions, so simple
      things like "set width 0" won't fail if no language is explicitly
@@ -2266,12 +2408,31 @@ gdb_init (char *argv0)
   set_language (language_c);
   expected_language = current_language;        /* Don't warn about the change.  */
 
-  /* Python initialization, for example, can require various commands to be
-     installed.  For example "info pretty-printer" needs the "info"
-     prefix to be installed.  Keep things simple and just do final
-     script initialization here.  */
-  finish_ext_lang_initialization ();
-
   /* Create $_gdb_major and $_gdb_minor convenience variables.  */
   init_gdb_version_vars ();
 }
+
+void _initialize_top ();
+void
+_initialize_top ()
+{
+  /* Determine a default value for the history filename.  */
+  const char *tmpenv = getenv ("GDBHISTFILE");
+  if (tmpenv != nullptr)
+    history_filename = tmpenv;
+  else
+    {
+      /* We include the current directory so that if the user changes
+        directories the file written will be the same as the one
+        that was read.  */
+#ifdef __MSDOS__
+      /* No leading dots in file names are allowed on MSDOS.  */
+      const char *fname = "_gdb_history";
+#else
+      const char *fname = ".gdb_history";
+#endif
+
+      gdb::unique_xmalloc_ptr<char> temp (gdb_abspath (fname));
+      history_filename = temp.get ();
+    }
+}