/* Top level stuff for GDB, the GNU debugger.
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2022 Free Software Foundation, Inc.
This file is part of GDB.
extern void initialize_all_files (void);
-static bool history_filename_empty (void);
-
#define PROMPT(X) the_prompts.prompt_stack[the_prompts.top + X].prompt
#define PREFIX(X) the_prompts.prompt_stack[the_prompts.top + X].prefix
#define SUFFIX(X) the_prompts.prompt_stack[the_prompts.top + X].suffix
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. */
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;
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. */
ui.release ();
}
- printf_unfiltered ("New UI allocated\n");
+ printf_filtered ("New UI allocated\n");
}
/* Handler for SIGHUP. */
command_handler (command);
}
}
-\f
-void (*pre_init_ui_hook) (void);
#ifdef __MSDOS__
static void
{
if (language_mode == language_mode_auto && info_verbose)
{
- language_info (1); /* Print what changed. */
+ /* Print what changed. */
+ language_info ();
}
warned = 0;
}
scoped_restore save_ui = make_scoped_restore (¤t_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;
}
/* 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
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->prefixlist && !c->allow_unknown)
+ && 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. */
{
- printf_unfiltered
- ("\"%.*s\" must be followed by the name of a subcommand.\n",
- (int) strlen (c->prefixname) - 1, c->prefixname);
- help_list (*c->prefixlist, c->prefixname, all_commands, gdb_stdout);
+ 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);
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. */
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. */
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. */
+ character position to be off, since the newline we read from
+ the user is not accounted for. */
fputs_unfiltered (prompt, gdb_stdout);
gdb_flush (gdb_stdout);
}
variable must be set to something sensible. */
static bool 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)
{
- if (!write_history_p || !history_filename_empty ())
+ if (!write_history_p || !history_filename.empty ())
fprintf_filtered (file, _("Saving of the history record on exit is %s.\n"),
value);
else
value);
}
-/* 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 char *history_filename;
-
-/* Return true if the history_filename is either NULL or the empty string,
- indicating that we should not try to read, nor write out the history. */
-static bool
-history_filename_empty (void)
-{
- return (history_filename == nullptr || *history_filename == '\0');
-}
-
/* Implement 'show history filename'. */
static void
show_history_filename (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
- if (!history_filename_empty ())
+ 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));
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 %ps to %ps: %s"),
- styled_string (file_name_style.style (), history_filename),
+ 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));
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));
}
}
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. */
+ let you get away with leaving out some of the gdb_flush, but
+ not all. */
wrap_here ("");
gdb_flush (gdb_stdout);
gdb_flush (gdb_stderr);
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) 2020 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
"), 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\
+ --with-babeltrace\n\
"));
#else
fprintf_filtered (stream, _("\
- --without-babeltrace\n\
+ --without-babeltrace\n\
"));
#endif
#if HAVE_LIBIPT
fprintf_filtered (stream, _("\
- --with-intel-pt\n\
+ --with-intel-pt\n\
"));
#else
fprintf_filtered (stream, _("\
- --without-intel-pt\n\
+ --without-intel-pt\n\
"));
#endif
#if HAVE_LIBMPFR
fprintf_filtered (stream, _("\
- --with-mpfr\n\
+ --with-mpfr\n\
"));
#else
fprintf_filtered (stream, _("\
- --without-mpfr\n\
+ --without-mpfr\n\
"));
#endif
#if HAVE_LIBXXHASH
fprintf_filtered (stream, _("\
- --with-xxhash\n\
+ --with-xxhash\n\
"));
#else
fprintf_filtered (stream, _("\
- --without-xxhash\n\
+ --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\
+ --with-debuginfod\n\
"));
#else
fprintf_filtered (stream, _("\
- --without-debuginfod\n\
+ --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)" : "");
if (SYSTEM_GDBINIT_DIR[0])
fprintf_filtered (stream, _("\
- --with-system-gdbinit-dir=%s%s\n\
+ --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
/* 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;
}
void
set_prompt (const char *s)
{
- char *p = xstrdup (s);
-
- xfree (top_prompt);
- top_prompt = p;
+ top_prompt = s;
}
\f
switch_to_thread (thread);
/* Leave core files alone. */
- if (target_has_execution)
+ if (target_has_execution ())
{
if (inf->attach_flag)
target_detach (inf, from_tty);
{
int exit_code = 0;
- undo_terminal_modifications_before_exit ();
-
/* An optional expression may be used to cause gdb to terminate with the
value of that expression. */
if (exit_arg)
else if (return_child_result)
exit_code = return_child_result_value;
+ gdb::observers::gdb_exiting.notify (exit_code);
+
+ undo_terminal_modifications_before_exit ();
+
/* We want to handle any quit errors and exit regardless. */
/* Get out of tfind mode, and kill or detach all inferiors. */
/* 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 ())
{
int save = 0;
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);
}
set_readline_history_size (history_size_setshow_var);
- tmpenv = getenv ("GDBHISTFILE");
- if (tmpenv != nullptr)
- history_filename = xstrdup (tmpenv);
- else if (history_filename == nullptr)
- {
- /* 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.release ();
- }
-
- if (!history_filename_empty ())
- read_history (history_filename);
+ if (!history_filename.empty ())
+ read_history (history_filename.c_str ());
}
static void
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 ();
}
/* 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 (!history_filename_empty () && !IS_ABSOLUTE_PATH (history_filename))
+ if (!history_filename.empty ()
+ && !IS_ABSOLUTE_PATH (history_filename.c_str ()))
{
- gdb::unique_xmalloc_ptr<char> temp (gdb_abspath (history_filename));
+ gdb::unique_xmalloc_ptr<char> temp
+ (gdb_abspath (history_filename.c_str ()));
- xfree (history_filename);
- history_filename = temp.release ();
+ 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
init_gdb_version_vars (void)
{
&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\
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\
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__
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
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 ();
+ }
+}