/* Top level stuff for GDB, the GNU debugger.
- Copyright (C) 1986-2017 Free Software Foundation, Inc.
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "expression.h"
#include "value.h"
#include "language.h"
-#include "terminal.h" /* For job_control. */
-#include "job-control.h"
+#include "terminal.h"
+#include "common/job-control.h"
#include "annotate.h"
#include "completer.h"
#include "top.h"
-#include "version.h"
+#include "common/version.h"
#include "serial.h"
#include "main.h"
#include "event-loop.h"
#include "gdbthread.h"
#include "extension.h"
#include "interps.h"
-#include "observer.h"
+#include "observable.h"
#include "maint.h"
#include "filenames.h"
#include "frame.h"
-#include "buffer.h"
+#include "common/buffer.h"
#include "gdb_select.h"
+#include "common/scope-exit.h"
/* readline include files. */
#include "readline/readline.h"
char *current_directory;
/* The last command line executed on the console. Used for command
- repetitions. */
-char *saved_command_line;
+ repetitions when the user enters an empty line. */
+
+static char *saved_command_line;
+
+/* If not NULL, the arguments that should be passed if
+ saved_command_line is repeated. */
+
+static const char *repeat_arguments;
+
+/* The previous last command line executed on the console. Used for command
+ repetitions when a command wants to relaunch the previously launched
+ 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;
+
+/* If not NULL, the arguments that should be passed if the
+ previous_saved_command_line is repeated. */
+
+static const char *previous_repeat_arguments;
/* Nonzero if the current command is modified by "server ". This
affects things like recording into the command history, commands
/* Timeout limit for response from target. */
-/* The default value has been changed many times over the years. It
- was originally 5 seconds. But that was thought to be a long time
+/* The default value has been changed many times over the years. It
+ was originally 5 seconds. But that was thought to be a long time
to sit and wait, so it was changed to 2 seconds. That was thought
- to be plenty unless the connection was going through some terminal
+ to be plenty unless the connection was going through some terminal
server or multiplexer or other form of hairy serial connection.
- In mid-1996, remote_timeout was moved from remote.c to top.c and
+ In mid-1996, remote_timeout was moved from remote.c to top.c and
it began being used in other remote-* targets. It appears that the
default was changed to 20 seconds at that time, perhaps because the
Renesas E7000 ICE didn't always respond in a timely manner.
But if 5 seconds is a long time to sit and wait for retransmissions,
- 20 seconds is far worse. This demonstrates the difficulty of using
+ 20 seconds is far worse. This demonstrates the difficulty of using
a single variable for all protocol timeouts.
- As remote.c is used much more than remote-e7000.c, it was changed
+ As remote.c is used much more than remote-e7000.c, it was changed
back to 2 seconds in 1999. */
int remote_timeout = 2;
int remote_debug = 0;
/* Sbrk location on entry to main. Used for statistics only. */
-#ifdef HAVE_SBRK
+#ifdef HAVE_USEFUL_SBRK
char *lim_at_start;
#endif
/* Called from print_frame_info to list the line we stopped in. */
-void (*deprecated_print_frame_info_listing_hook) (struct symtab * s,
+void (*deprecated_print_frame_info_listing_hook) (struct symtab * s,
int line,
- int stopline,
+ int stopline,
int noerror);
/* Replaces most of query. */
/* Used by UI as a wrapper around command execution. May do various
things like enabling/disabling buttons, etc... */
-void (*deprecated_call_command_hook) (struct cmd_list_element * c,
- char *cmd, int from_tty);
+void (*deprecated_call_command_hook) (struct cmd_list_element * c,
+ const char *cmd, int from_tty);
/* Called when the current thread changes. Argument is thread id. */
static void
new_ui_command (const char *args, int from_tty)
{
- struct interp *interp;
gdb_file_up stream[3];
int i;
- int res;
int argc;
const char *interpreter_name;
const char *tty_name;
argc = argv.count ();
if (argc < 2)
- error (_("usage: new-ui <interpreter> <tty>"));
+ error (_("Usage: new-ui INTERPRETER TTY"));
interpreter_name = argv[0];
tty_name = argv[1];
/* 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 */ const char *source_file_name;
+/* static */ std::string source_file_name;
/* Read commands from STREAM. */
void
char *command;
/* Get a command-line. This calls the readline package. */
- command = command_line_input (NULL, 0, NULL);
+ command = command_line_input (NULL, NULL);
if (command == NULL)
break;
command_handler (command);
wait_sync_command_done ();
}
+/* See command.h. */
+
+void
+set_repeat_arguments (const char *args)
+{
+ repeat_arguments = args;
+}
+
/* Execute the line P as a command, in the current user context.
Pass FROM_TTY as second argument to the defining function. */
void
-execute_command (char *p, int from_tty)
+execute_command (const char *p, int from_tty)
{
- struct cleanup *cleanup_if_error;
struct cmd_list_element *c;
- char *line;
+ const char *line;
+ const char *cmd_start = p;
- cleanup_if_error = make_bpstat_clear_actions_cleanup ();
+ auto cleanup_if_error = make_scope_exit (bpstat_clear_actions);
scoped_value_mark cleanup = prepare_execute_command ();
/* Force cleanup of any alloca areas if using C alloca instead of
/* This can happen when command_line_input hits end of file. */
if (p == NULL)
{
- discard_cleanups (cleanup_if_error);
+ cleanup_if_error.release ();
return;
}
if (*p)
{
const char *cmd = p;
- char *arg;
+ const char *arg;
int was_sync = current_ui->prompt_state == PROMPT_BLOCKED;
line = p;
/* If trace-commands is set then this will print this command. */
- print_command_trace (p);
+ print_command_trace ("%s", p);
c = lookup_cmd (&cmd, cmdlist, "", 0, 1);
- p = (char *) cmd;
+ 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;
is_complete_command hack is testing for. */
/* Clear off trailing whitespace, except for set and complete
command. */
+ std::string without_whitespace;
if (arg
&& c->type != set_cmd
&& !is_complete_command (c))
{
- p = arg + strlen (arg) - 1;
+ const char *old_end = arg + strlen (arg) - 1;
+ p = old_end;
while (p >= arg && (*p == ' ' || *p == '\t'))
p--;
- *(p + 1) = '\0';
+ if (p != old_end)
+ {
+ without_whitespace = std::string (arg, p + 1);
+ arg = without_whitespace.c_str ();
+ }
}
/* If this command has been pre-hooked, run the hook first. */
/* If this command has been post-hooked, run the hook last. */
execute_cmd_post_hook (c);
+ if (repeat_arguments != NULL && cmd_start == saved_command_line)
+ {
+ gdb_assert (strlen (args_pointer) >= strlen (repeat_arguments));
+ strcpy (saved_command_line + (args_pointer - cmd_start),
+ repeat_arguments);
+ }
}
- check_frame_language_change ();
+ /* Only perform the frame-language-change check if the command
+ we just finished executing did not resume the inferior's execution.
+ If it did resume the inferior, we will do that check after
+ the inferior stopped. */
+ if (has_stack_frames () && inferior_thread ()->state != THREAD_RUNNING)
+ check_frame_language_change ();
- discard_cleanups (cleanup_if_error);
+ cleanup_if_error.release ();
}
-/* 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
+/* 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. */
-std::string
-execute_command_to_string (char *p, int from_tty)
+void
+execute_command_to_ui_file (struct ui_file *file, const char *p, int from_tty)
{
/* GDB_STDOUT should be better already restored during these
restoration callbacks. */
scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
- string_file str_file;
-
{
- current_uiout->redirect (&str_file);
+ current_uiout->redirect (file);
ui_out_redirect_pop redirect_popper (current_uiout);
scoped_restore save_stdout
- = make_scoped_restore (&gdb_stdout, &str_file);
+ = make_scoped_restore (&gdb_stdout, file);
scoped_restore save_stderr
- = make_scoped_restore (&gdb_stderr, &str_file);
+ = make_scoped_restore (&gdb_stderr, file);
scoped_restore save_stdlog
- = make_scoped_restore (&gdb_stdlog, &str_file);
+ = make_scoped_restore (&gdb_stdlog, file);
scoped_restore save_stdtarg
- = make_scoped_restore (&gdb_stdtarg, &str_file);
+ = make_scoped_restore (&gdb_stdtarg, file);
scoped_restore save_stdtargerr
- = make_scoped_restore (&gdb_stdtargerr, &str_file);
+ = make_scoped_restore (&gdb_stdtargerr, file);
execute_command (p, from_tty);
}
+}
+/* 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. */
+
+std::string
+execute_command_to_string (const char *p, int from_tty,
+ 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 ());
}
static int suppress_dont_repeat = 0;
-/* Commands call this if they do not want to be repeated by null lines. */
+/* See command.h */
void
dont_repeat (void)
thing read from stdin in line and don't want to delete it. Null
lines won't repeat here in any case. */
if (ui->instream == ui->stdin_stream)
- *saved_command_line = 0;
+ {
+ *saved_command_line = 0;
+ repeat_arguments = NULL;
+ }
+}
+
+/* See command.h */
+
+void
+repeat_previous ()
+{
+ /* Do not repeat this command, as this command is a repeating command. */
+ dont_repeat ();
+
+ /* We cannot free saved_command_line, as this line is being executed,
+ so swap it with previous_saved_command_line. */
+ std::swap (previous_saved_command_line, saved_command_line);
+ std::swap (previous_repeat_arguments, repeat_arguments);
}
-/* Prevent dont_repeat from working, and return a cleanup that
- restores the previous state. */
+/* See command.h. */
scoped_restore_tmpl<int>
prevent_dont_repeat (void)
return make_scoped_restore (&suppress_dont_repeat, 1);
}
+/* See command.h. */
+
+char *
+get_saved_command_line ()
+{
+ return saved_command_line;
+}
+
+/* See command.h. */
+
+void
+save_command_line (const char *cmd)
+{
+ xfree (previous_saved_command_line);
+ previous_saved_command_line = saved_command_line;
+ previous_repeat_arguments = repeat_arguments;
+ saved_command_line = xstrdup (cmd);
+ repeat_arguments = NULL;
+}
+
\f
/* Read a line from the stream "instream" without command line editing.
while (1)
{
int c;
- int numfds;
fd_set readfds;
QUIT;
text. */
static void
-gdb_readline_wrapper_line (char *line)
+gdb_readline_wrapper_line (gdb::unique_xmalloc_ptr<char> &&line)
{
gdb_assert (!gdb_readline_wrapper_done);
- gdb_readline_wrapper_result = line;
+ gdb_readline_wrapper_result = line.release ();
gdb_readline_wrapper_done = 1;
/* Prevent operate-and-get-next from acting too early. */
gdb_rl_callback_handler_remove ();
}
-struct gdb_readline_wrapper_cleanup
- {
- void (*handler_orig) (char *);
- int already_prompted_orig;
-
- /* Whether the target was async. */
- int target_is_async_orig;
- };
-
-static void
-gdb_readline_wrapper_cleanup (void *arg)
+class gdb_readline_wrapper_cleanup
{
- struct ui *ui = current_ui;
- struct gdb_readline_wrapper_cleanup *cleanup
- = (struct gdb_readline_wrapper_cleanup *) arg;
+public:
+ gdb_readline_wrapper_cleanup ()
+ : m_handler_orig (current_ui->input_handler),
+ m_already_prompted_orig (current_ui->command_editing
+ ? rl_already_prompted : 0),
+ m_target_is_async_orig (target_is_async_p ()),
+ m_save_ui (¤t_ui)
+ {
+ current_ui->input_handler = gdb_readline_wrapper_line;
+ current_ui->secondary_prompt_depth++;
- if (ui->command_editing)
- rl_already_prompted = cleanup->already_prompted_orig;
+ if (m_target_is_async_orig)
+ target_async (0);
+ }
- gdb_assert (ui->input_handler == gdb_readline_wrapper_line);
- ui->input_handler = cleanup->handler_orig;
+ ~gdb_readline_wrapper_cleanup ()
+ {
+ struct ui *ui = current_ui;
- /* Don't restore our input handler in readline yet. That would make
- readline prep the terminal (putting it in raw mode), while the
- line we just read may trigger execution of a command that expects
- the terminal in the default cooked/canonical mode, such as e.g.,
- running Python's interactive online help utility. See
- gdb_readline_wrapper_line for when we'll reinstall it. */
+ if (ui->command_editing)
+ rl_already_prompted = m_already_prompted_orig;
- gdb_readline_wrapper_result = NULL;
- gdb_readline_wrapper_done = 0;
- ui->secondary_prompt_depth--;
- gdb_assert (ui->secondary_prompt_depth >= 0);
+ gdb_assert (ui->input_handler == gdb_readline_wrapper_line);
+ ui->input_handler = m_handler_orig;
- after_char_processing_hook = saved_after_char_processing_hook;
- saved_after_char_processing_hook = NULL;
+ /* Don't restore our input handler in readline yet. That would make
+ readline prep the terminal (putting it in raw mode), while the
+ line we just read may trigger execution of a command that expects
+ the terminal in the default cooked/canonical mode, such as e.g.,
+ running Python's interactive online help utility. See
+ gdb_readline_wrapper_line for when we'll reinstall it. */
- if (cleanup->target_is_async_orig)
- target_async (1);
+ gdb_readline_wrapper_result = NULL;
+ gdb_readline_wrapper_done = 0;
+ ui->secondary_prompt_depth--;
+ gdb_assert (ui->secondary_prompt_depth >= 0);
- xfree (cleanup);
-}
+ after_char_processing_hook = saved_after_char_processing_hook;
+ saved_after_char_processing_hook = NULL;
-char *
-gdb_readline_wrapper (const char *prompt)
-{
- struct ui *ui = current_ui;
- struct cleanup *back_to;
- struct gdb_readline_wrapper_cleanup *cleanup;
- char *retval;
+ if (m_target_is_async_orig)
+ target_async (1);
+ }
- cleanup = XNEW (struct gdb_readline_wrapper_cleanup);
- cleanup->handler_orig = ui->input_handler;
- ui->input_handler = gdb_readline_wrapper_line;
+ DISABLE_COPY_AND_ASSIGN (gdb_readline_wrapper_cleanup);
- if (ui->command_editing)
- cleanup->already_prompted_orig = rl_already_prompted;
- else
- cleanup->already_prompted_orig = 0;
+private:
- cleanup->target_is_async_orig = target_is_async_p ();
+ void (*m_handler_orig) (gdb::unique_xmalloc_ptr<char> &&);
+ int m_already_prompted_orig;
- ui->secondary_prompt_depth++;
- back_to = make_cleanup (gdb_readline_wrapper_cleanup, cleanup);
+ /* Whether the target was async. */
+ int m_target_is_async_orig;
/* Processing events may change the current UI. */
- scoped_restore save_ui = make_scoped_restore (¤t_ui);
+ scoped_restore_tmpl<struct ui *> m_save_ui;
+};
- if (cleanup->target_is_async_orig)
- target_async (0);
+char *
+gdb_readline_wrapper (const char *prompt)
+{
+ struct ui *ui = current_ui;
+
+ gdb_readline_wrapper_cleanup cleanup;
/* Display our prompt and prevent double prompt display. Don't pass
down a NULL prompt, since that has special meaning for
if (gdb_readline_wrapper_done)
break;
- retval = gdb_readline_wrapper_result;
- do_cleanups (back_to);
- return retval;
+ return gdb_readline_wrapper_result;
}
\f
NULL is returned for end of file.
- *If* input is from an interactive stream (stdin), the line read is
- copied into the global 'saved_command_line' so that it can be
- repeated.
-
This routine either uses fancy command line editing or simple input
as the user has requested. */
char *
-command_line_input (const char *prompt_arg, int repeat,
- const char *annotation_suffix)
+command_line_input (const char *prompt_arg, const char *annotation_suffix)
{
static struct buffer cmd_line_buffer;
static int cmd_line_buffer_initialized;
while (1)
{
- char *rl;
+ 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
gdb_flush (gdb_stdout);
gdb_flush (gdb_stderr);
- if (source_file_name != NULL)
+ if (!source_file_name.empty ())
++source_line_number;
if (from_tty && annotation_level > 1)
&& from_tty
&& input_interactive_p (current_ui))
{
- rl = (*deprecated_readline_hook) (prompt);
+ rl.reset ((*deprecated_readline_hook) (prompt));
}
else if (command_editing_p
&& from_tty
&& input_interactive_p (current_ui))
{
- rl = gdb_readline_wrapper (prompt);
+ rl.reset (gdb_readline_wrapper (prompt));
}
else
{
- rl = gdb_readline_no_editing (prompt);
+ rl.reset (gdb_readline_no_editing (prompt));
}
- cmd = handle_line_of_input (&cmd_line_buffer, rl,
- repeat, annotation_suffix);
+ cmd = handle_line_of_input (&cmd_line_buffer, rl.get (),
+ 0, annotation_suffix);
if (cmd == (char *) EOF)
{
cmd = NULL;
return cmd;
}
\f
-/* Print the GDB banner. */
+/* See top.h. */
void
-print_gdb_version (struct ui_file *stream)
+print_gdb_version (struct ui_file *stream, bool interactive)
{
/* From GNU coding standards, first line is meant to be easy for a
program to parse, and is just canonical program name and version
number, which starts after last space. */
- fprintf_filtered (stream, "GNU gdb %s%s\n", PKGVERSION, version);
+ 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);
/* Second line is a copyright notice. */
fprintf_filtered (stream,
- "Copyright (C) 2017 Free Software Foundation, Inc.\n");
+ "Copyright (C) 2019 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
fprintf_filtered (stream, "\
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\
\nThis is free software: you are free to change and redistribute it.\n\
-There is NO WARRANTY, to the extent permitted by law. Type \"show copying\"\n\
-and \"show warranty\" for details.\n");
+There is NO WARRANTY, to the extent permitted by law.");
+
+ if (!interactive)
+ return;
+
+ fprintf_filtered (stream, ("\nType \"show copying\" and "
+ "\"show warranty\" for details.\n"));
/* After the required info we print the configuration information. */
{
fprintf_filtered (stream, "%s", host_name);
}
- fprintf_filtered (stream, "\".\n\
-Type \"show configuration\" for configuration details.");
+ fprintf_filtered (stream, "\".\n");
+
+ fprintf_filtered (stream, _("Type \"show configuration\" "
+ "for configuration details.\n"));
if (REPORT_BUGS_TO[0])
{
fprintf_filtered (stream,
- _("\nFor bug reporting instructions, please see:\n"));
+ _("For bug reporting instructions, please see:\n"));
fprintf_filtered (stream, "%s.\n", REPORT_BUGS_TO);
}
fprintf_filtered (stream,
_("Find the GDB manual and other documentation \
-resources online at:\n<http://www.gnu.org/software/gdb/documentation/>.\n"));
+resources online at:\n <http://www.gnu.org/software/gdb/documentation/>."));
+ fprintf_filtered (stream, "\n\n");
fprintf_filtered (stream, _("For help, type \"help\".\n"));
- fprintf_filtered (stream, _("Type \"apropos word\" to search for \
-commands related to \"word\"."));
+ fprintf_filtered (stream,
+ _("Type \"apropos word\" to search for commands \
+related to \"word\"."));
}
/* Print the details of GDB build-time configuration. */
--without-lzma\n\
"));
#endif
+#if HAVE_LIBBABELTRACE
+ fprintf_filtered (stream, _("\
+ --with-babeltrace\n\
+"));
+#else
+ fprintf_filtered (stream, _("\
+ --without-babeltrace\n\
+"));
+#endif
+#if HAVE_LIBIPT
+ fprintf_filtered (stream, _("\
+ --with-intel-pt\n\
+"));
+#else
+ fprintf_filtered (stream, _("\
+ --without-intel-pt\n\
+"));
+#endif
+#if HAVE_LIBMCHECK
+ fprintf_filtered (stream, _("\
+ --enable-libmcheck\n\
+"));
+#else
+ fprintf_filtered (stream, _("\
+ --disable-libmcheck\n\
+"));
+#endif
+#if HAVE_LIBMPFR
+ fprintf_filtered (stream, _("\
+ --with-mpfr\n\
+"));
+#else
+ fprintf_filtered (stream, _("\
+ --without-mpfr\n\
+"));
+#endif
#ifdef WITH_PYTHON_PATH
fprintf_filtered (stream, _("\
--with-python=%s%s\n\
"), WITH_PYTHON_PATH, PYTHON_PATH_RELOCATABLE ? " (relocatable)" : "");
+#else
+ fprintf_filtered (stream, _("\
+ --without-python\n\
+"));
#endif
#if HAVE_GUILE
fprintf_filtered (stream, _("\
--without-guile\n\
"));
#endif
+#if HAVE_SOURCE_HIGHLIGHT
+ fprintf_filtered (stream, _("\
+ --enable-source-highlight\n\
+"));
+#else
+ fprintf_filtered (stream, _("\
+ --disable-source-highlight\n\
+"));
+#endif
#ifdef RELOC_SRCDIR
fprintf_filtered (stream, _("\
--with-relocated-sources=%s\n\
fprintf_filtered (stream, _("\
--with-system-gdbinit=%s%s\n\
"), SYSTEM_GDBINIT, SYSTEM_GDBINIT_RELOCATABLE ? " (relocatable)" : "");
-#if HAVE_LIBBABELTRACE
- fprintf_filtered (stream, _("\
- --with-babeltrace\n\
-"));
-#else
- fprintf_filtered (stream, _("\
- --without-babeltrace\n\
-"));
-#endif
/* 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\
struct qt_args
{
- char *args;
int from_tty;
};
kill_or_detach (struct inferior *inf, void *args)
{
struct qt_args *qt = (struct qt_args *) args;
- struct thread_info *thread;
if (inf->pid == 0)
return 0;
- thread = any_thread_of_process (inf->pid);
+ thread_info *thread = any_thread_of_inferior (inf);
if (thread != NULL)
{
- switch_to_thread (thread->ptid);
+ switch_to_thread (thread);
/* Leave core files alone. */
if (target_has_execution)
{
if (inf->attach_flag)
- target_detach (qt->args, qt->from_tty);
+ target_detach (inf, qt->from_tty);
else
target_kill ();
}
if (inf->attach_flag)
fprintf_filtered (stb,
_("\tInferior %d [%s] will be detached.\n"), inf->num,
- target_pid_to_str (pid_to_ptid (inf->pid)));
+ target_pid_to_str (ptid_t (inf->pid)).c_str ());
else
fprintf_filtered (stb,
_("\tInferior %d [%s] will be killed.\n"), inf->num,
- target_pid_to_str (pid_to_ptid (inf->pid)));
+ target_pid_to_str (ptid_t (inf->pid)).c_str ());
return 0;
}
undo_terminal_modifications_before_exit ();
- /* An optional expression may be used to cause gdb to terminate with the
+ /* An optional expression may be used to cause gdb to terminate with the
value of that expression. */
if (exit_arg)
exit_code = *exit_arg;
else if (return_child_result)
exit_code = return_child_result_value;
- qt.args = NULL;
qt.from_tty = from_tty;
/* We want to handle any quit errors and exit regardless. */
/* Get out of tfind mode, and kill or detach all inferiors. */
- TRY
+ try
{
disconnect_tracing ();
iterate_over_inferiors (kill_or_detach, &qt);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
exception_print (gdb_stderr, ex);
}
- END_CATCH
/* Give all pushed targets a chance to do minimal cleanup, and pop
them all out. */
- TRY
+ try
{
pop_all_targets ();
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
exception_print (gdb_stderr, ex);
}
- END_CATCH
/* Save the history information if it is appropriate to do so. */
- TRY
+ try
{
if (write_history_p && history_filename)
{
gdb_safe_append_history ();
}
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
exception_print (gdb_stderr, ex);
}
- END_CATCH
+
+ /* Destroy any values currently allocated now instead of leaving it
+ to global destructors, because that may be too late. For
+ example, the destructors of xmethod values call into the Python
+ runtime, which is finalized via a final cleanup. */
+ finalize_values ();
/* Do any final cleanups before exiting. */
- TRY
+ try
{
- do_final_cleanups (all_cleanups ());
+ do_final_cleanups ();
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
exception_print (gdb_stderr, ex);
}
- END_CATCH
exit (exit_code);
}
}
\f
static void
-dont_repeat_command (char *ignored, int from_tty)
+dont_repeat_command (const char *ignored, int from_tty)
{
/* Can't call dont_repeat here because we're not necessarily reading
from stdin. */
/* Number of commands to print in each call to show_commands. */
#define Hist_print 10
void
-show_commands (char *args, int from_tty)
+show_commands (const char *args, int from_tty)
{
/* Index for history commands. Relative to history_base. */
int offset;
"show commands +" does. This is unnecessary if arg is null,
because "show commands +" is not useful after "show commands". */
if (from_tty && args)
- {
- args[0] = '+';
- args[1] = '\0';
- }
+ set_repeat_arguments ("+");
}
/* Update the size of our command history file to HISTORY_SIZE.
/* Called by do_setshow_command. */
static void
-set_history_size_command (char *args, int from_tty, struct cmd_list_element *c)
+set_history_size_command (const char *args,
+ int from_tty, struct cmd_list_element *c)
{
set_readline_history_size (history_size_setshow_var);
}
int info_verbose = 0; /* Default verbose msgs off. */
-/* Called by do_setshow_command. An elaborate joke. */
+/* Called by do_set_command. An elaborate joke. */
void
-set_verbose (char *args, int from_tty, struct cmd_list_element *c)
+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);
gdb_assert (showcmd != NULL && showcmd != CMD_LIST_AMBIGUOUS);
+ if (c->doc && c->doc_allocated)
+ xfree ((char *) c->doc);
+ if (showcmd->doc && showcmd->doc_allocated)
+ xfree ((char *) showcmd->doc);
if (info_verbose)
{
- c->doc = "Set verbose printing of informational messages.";
- showcmd->doc = "Show verbose printing of informational messages.";
+ c->doc = _("Set verbose printing of informational messages.");
+ showcmd->doc = _("Show verbose printing of informational messages.");
}
else
{
- c->doc = "Set verbosity.";
- showcmd->doc = "Show verbosity.";
+ c->doc = _("Set verbosity.");
+ showcmd->doc = _("Show verbosity.");
}
+ c->doc_allocated = 0;
+ showcmd->doc_allocated = 0;
}
/* Init the history buffer. Note that we are called after the init file(s)
void
init_history (void)
{
- char *tmpenv;
+ const char *tmpenv;
tmpenv = getenv ("GDBHISTSIZE");
if (tmpenv)
/* "set editing" command. */
static void
-set_editing (char *args, int from_tty, struct cmd_list_element *c)
+set_editing (const char *args, int from_tty, struct cmd_list_element *c)
{
change_line_handler (set_editing_cmd_var);
/* Update the control variable so that MI's =cmd-param-changed event
/* "set" command for the gdb_datadir configuration variable. */
static void
-set_gdb_datadir (char *args, int from_tty, struct cmd_list_element *c)
+set_gdb_datadir (const char *args, int from_tty, struct cmd_list_element *c)
{
set_gdb_data_directory (staged_gdb_datadir);
- observer_notify_gdb_datadir_changed ();
+ gdb::observers::gdb_datadir_changed.notify ();
}
/* "show" command for the gdb_datadir configuration variable. */
}
static void
-set_history_filename (char *args, int from_tty, struct cmd_list_element *c)
+set_history_filename (const char *args,
+ int from_tty, struct cmd_list_element *c)
{
/* We include the current directory so that if the user changes
directories the file written will be the same as the one
history_filename, (char *) NULL);
}
+static void
+init_gdb_version_vars (void)
+{
+ struct internalvar *major_version_var = create_internalvar ("_gdb_major");
+ struct internalvar *minor_version_var = create_internalvar ("_gdb_minor");
+ int vmajor = 0, vminor = 0, vrevision = 0;
+ sscanf (version, "%d.%d.%d", &vmajor, &vminor, &vrevision);
+ set_internalvar_integer (major_version_var, vmajor);
+ set_internalvar_integer (minor_version_var, vminor + (vrevision > 0));
+}
+
static void
init_main (void)
{
c = add_cmd ("new-ui", class_support, new_ui_command, _("\
Create a new UI. It takes two arguments:\n\
The first argument is the name of the interpreter to run.\n\
-The second argument is the terminal the UI runs on.\n"), &cmdlist);
+The second argument is the terminal the UI runs on."), &cmdlist);
set_cmd_completer (c, interpreter_completer);
}
void
gdb_init (char *argv0)
{
+ saved_command_line = xstrdup ("");
+ previous_saved_command_line = xstrdup ("");
+
if (pre_init_ui_hook)
pre_init_ui_hook ();
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 ();
}