/* Top level stuff for GDB, the GNU debugger.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
- Free Software Foundation, Inc.
+ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ 2008 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "gdbcmd.h"
#include "serial.h"
#include "doublest.h"
#include "gdb_assert.h"
+#include "main.h"
+#include "event-loop.h"
/* readline include files */
#include "readline/readline.h"
/* Initialization file name for gdb. This is overridden in some configs. */
+#ifndef PATH_MAX
+# ifdef FILENAME_MAX
+# define PATH_MAX FILENAME_MAX
+# else
+# define PATH_MAX 512
+# endif
+#endif
+
#ifndef GDBINIT_FILENAME
#define GDBINIT_FILENAME ".gdbinit"
#endif
-char gdbinit[] = GDBINIT_FILENAME;
+char gdbinit[PATH_MAX + 1] = GDBINIT_FILENAME;
int inhibit_gdbinit = 0;
/* Flag for whether we want all the "from_tty" gubbish printed. */
int caution = 1; /* Default is yes, sigh. */
+static void
+show_caution (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Whether to confirm potentially dangerous operations is %s.\n"),
+ value);
+}
/* stdio stream that command input is being read from. Set to stdin normally.
Set by source_command to the file we are sourcing. Set to NULL if we are
FILE *instream;
+/* Flag to indicate whether a user defined command is currently running. */
+
+int in_user_command;
+
/* Current working directory. */
char *current_directory;
target is off and running, which gdb is doing something else. */
int target_executing = 0;
-/* Level of control structure. */
-static int control_level;
-
/* Sbrk location on entry to main. Used for statistics only. */
#ifdef HAVE_SBRK
char *lim_at_start;
void (*deprecated_interactive_hook) (void);
-/* Called when the registers have changed, as a hint to a GUI
- to minimize window update. */
-
-void (*deprecated_registers_changed_hook) (void);
-
/* Tell the GUI someone changed the register REGNO. -1 means
that the caller does not know which register changed or
that several registers have changed (see value_assign). */
if (p == NULL)
return;
- serial_log_command (p);
+ target_log_command (p);
while (*p == ' ' || *p == '\t')
p++;
char *arg;
line = p;
+ /* If trace-commands is set then this will print this command. */
+ print_command_trace (p);
+
c = lookup_cmd (&p, cmdlist, "", 0, 1);
/* If the target is running, we allow only a limited set of
long space_now = lim - lim_at_start;
long space_diff = space_now - space_at_cmd_start;
- printf_unfiltered (_("Space used: %ld (%c%ld for this command)\n"),
+ printf_unfiltered (_("Space used: %ld (%s%ld for this command)\n"),
space_now,
- (space_diff >= 0 ? '+' : '-'),
+ (space_diff >= 0 ? "+" : ""),
space_diff);
#endif
}
substitution. These variables are given default values at the end
of this file. */
static int 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 int write_history_p;
+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);
+}
+
static int history_size;
+static void
+show_history_size (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("The size of the command history is %s.\n"),
+ value);
+}
+
static char *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);
+}
/* This is like readline(), but it has some gdb-specific behavior.
- gdb can use readline in both the synchronous and async modes during
+ gdb may want readline in both the synchronous and async modes during
a single gdb invocation. At the ordinary top-level prompt we might
be using the async readline. That means we can't use
rl_pre_input_hook, since it doesn't work properly in async mode.
However, for a secondary prompt (" >", such as occurs during a
- `define'), gdb just calls readline() directly, running it in
- synchronous mode. So for operate-and-get-next to work in this
- situation, we have to switch the hooks around. That is what
- gdb_readline_wrapper is for. */
+ `define'), gdb wants a synchronous response.
+
+ We used to call readline() directly, running it in synchronous
+ mode. But mixing modes this way is not supported, and as of
+ readline 5.x it no longer works; the arrow keys come unbound during
+ the synchronous call. So we make a nested call into the event
+ loop. That's what gdb_readline_wrapper is for. */
+
+/* A flag set as soon as gdb_readline_wrapper_line is called; we can't
+ rely on gdb_readline_wrapper_result, which might still be NULL if
+ the user types Control-D for EOF. */
+static int gdb_readline_wrapper_done;
+
+/* The result of the current call to gdb_readline_wrapper, once a newline
+ is seen. */
+static char *gdb_readline_wrapper_result;
+
+/* Any intercepted hook. Operate-and-get-next sets this, expecting it
+ to be called after the newline is processed (which will redisplay
+ the prompt). But in gdb_readline_wrapper we will not get a new
+ prompt until the next call, or until we return to the event loop.
+ So we disable this hook around the newline and restore it before we
+ return. */
+static void (*saved_after_char_processing_hook) (void);
+
+/* This function is called when readline has seen a complete line of
+ text. */
+
+static void
+gdb_readline_wrapper_line (char *line)
+{
+ gdb_assert (!gdb_readline_wrapper_done);
+ gdb_readline_wrapper_result = line;
+ gdb_readline_wrapper_done = 1;
+
+ /* Prevent operate-and-get-next from acting too early. */
+ saved_after_char_processing_hook = after_char_processing_hook;
+ after_char_processing_hook = NULL;
+
+ /* Prevent parts of the prompt from being redisplayed if annotations
+ are enabled, and readline's state getting out of sync. */
+ if (async_command_editing_p)
+ rl_callback_handler_remove ();
+}
+
+struct gdb_readline_wrapper_cleanup
+ {
+ void (*handler_orig) (char *);
+ int already_prompted_orig;
+ };
+
+static void
+gdb_readline_wrapper_cleanup (void *arg)
+{
+ struct gdb_readline_wrapper_cleanup *cleanup = arg;
+
+ rl_already_prompted = cleanup->already_prompted_orig;
+
+ gdb_assert (input_handler == gdb_readline_wrapper_line);
+ input_handler = cleanup->handler_orig;
+ gdb_readline_wrapper_result = NULL;
+ gdb_readline_wrapper_done = 0;
+
+ after_char_processing_hook = saved_after_char_processing_hook;
+ saved_after_char_processing_hook = NULL;
+
+ xfree (cleanup);
+}
+
char *
gdb_readline_wrapper (char *prompt)
{
- /* Set the hook that works in this case. */
+ struct cleanup *back_to;
+ struct gdb_readline_wrapper_cleanup *cleanup;
+ char *retval;
+
+ cleanup = xmalloc (sizeof (*cleanup));
+ cleanup->handler_orig = input_handler;
+ input_handler = gdb_readline_wrapper_line;
+
+ cleanup->already_prompted_orig = rl_already_prompted;
+
+ back_to = make_cleanup (gdb_readline_wrapper_cleanup, cleanup);
+
+ /* Display our prompt and prevent double prompt display. */
+ display_gdb_prompt (prompt);
+ rl_already_prompted = 1;
+
if (after_char_processing_hook)
- {
- rl_pre_input_hook = (Function *) after_char_processing_hook;
- after_char_processing_hook = NULL;
- }
+ (*after_char_processing_hook) ();
+ gdb_assert (after_char_processing_hook == NULL);
+
+ /* gdb_do_one_event argument is unused. */
+ while (gdb_do_one_event (NULL) >= 0)
+ if (gdb_readline_wrapper_done)
+ break;
- return readline (prompt);
+ retval = gdb_readline_wrapper_result;
+ do_cleanups (back_to);
+ return retval;
}
\f
}
/* Don't use fancy stuff if not talking to stdin. */
- if (deprecated_readline_hook && instream == NULL)
+ if (deprecated_readline_hook && input_from_terminal_p ())
{
rl = (*deprecated_readline_hook) (local_prompt);
}
- else if (command_editing_p && instream == stdin && ISATTY (instream))
+ else if (command_editing_p && input_from_terminal_p ())
{
rl = gdb_readline_wrapper (local_prompt);
}
}
strcpy (linebuffer, history_value);
p = linebuffer + strlen (linebuffer);
- xfree (history_value);
}
+ xfree (history_value);
}
/* If we just got an empty line, and that is supposed
/* Second line is a copyright notice. */
- fprintf_filtered (stream, "Copyright 2004 Free Software Foundation, Inc.\n");
+ fprintf_filtered (stream, "Copyright (C) 2008 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
there is no warranty. */
fprintf_filtered (stream, "\
-GDB is free software, covered by the GNU General Public License, and you are\n\
-welcome to change it and/or distribute copies of it under certain conditions.\n\
-Type \"show copying\" to see the conditions.\n\
-There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n");
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
+This 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");
/* After the required info we print the configuration information. */
exit_code = (int) value_as_long (val);
}
+ else if (return_child_result)
+ exit_code = return_child_result_value;
qt.args = args;
qt.from_tty = from_tty;
exit (exit_code);
}
-/* Returns whether GDB is running on a terminal and whether the user
- desires that questions be asked of them on that terminal. */
+/* Returns whether GDB is running on a terminal and input is
+ currently coming from that terminal. */
int
input_from_terminal_p (void)
{
- return gdb_has_a_terminal () && (instream == stdin) & caution;
+ if (gdb_has_a_terminal () && instream == stdin)
+ return 1;
+
+ /* If INSTREAM is unset, and we are not in a user command, we
+ must be in Insight. That's like having a terminal, for our
+ purposes. */
+ if (instream == NULL && !in_user_command)
+ return 1;
+
+ return 0;
}
\f
static void
that was read. */
#ifdef __MSDOS__
/* No leading dots in file names are allowed on MSDOS. */
- history_filename = concat (current_directory, "/_gdb_history", NULL);
+ history_filename = concat (current_directory, "/_gdb_history",
+ (char *)NULL);
#else
- history_filename = concat (current_directory, "/.gdb_history", NULL);
+ history_filename = concat (current_directory, "/.gdb_history",
+ (char *)NULL);
#endif
}
read_history (history_filename);
}
+static void
+show_new_async_prompt (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Gdb's prompt is \"%s\".\n"), value);
+}
+
+static void
+show_async_command_editing_p (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Editing of command lines as they are typed is %s.\n"),
+ value);
+}
+
+static void
+show_annotation_level (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Annotation_level is %s.\n"), value);
+}
+
+static void
+show_exec_done_display_p (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Notification of completion for asynchronous execution commands is %s.\n"),
+ value);
+}
static void
init_main (void)
{
Set gdb's prompt"), _("\
Show gdb's prompt"), NULL,
set_async_prompt,
- NULL, /* FIXME: i18n: */
+ show_new_async_prompt,
&setlist, &showlist);
add_com ("dont-repeat", class_support, dont_repeat_command, _("\
Without an argument, command line editing is enabled. To edit, use\n\
EMACS-like or VI-like commands like control-P or ESC."),
set_async_editing_command,
- NULL, /* FIXME: i18n: */
+ show_async_command_editing_p,
&setlist, &showlist);
add_setshow_boolean_cmd ("save", no_class, &write_history_p, _("\
Use \"on\" to enable the saving, and \"off\" to disable it.\n\
Without an argument, saving is enabled."),
NULL,
- NULL, /* FIXME: i18n: */
+ show_write_history_p,
&sethistlist, &showhistlist);
add_setshow_integer_cmd ("size", no_class, &history_size, _("\
Show the size of the command history,"), _("\
ie. the number of previous commands to keep a record of."),
set_history_size_command,
- NULL, /* FIXME: i18n: */
+ show_history_size,
&sethistlist, &showhistlist);
add_setshow_filename_cmd ("filename", no_class, &history_filename, _("\
Show the filename in which to record the command history"), _("\
(the list of previous commands of which a record is kept)."),
NULL,
- NULL, /* FIXME: i18n: */
+ show_history_filename,
&sethistlist, &showhistlist);
add_setshow_boolean_cmd ("confirm", class_support, &caution, _("\
Set whether to confirm potentially dangerous operations."), _("\
Show whether to confirm potentially dangerous operations."), NULL,
NULL,
- NULL, /* FIXME: i18n: */
+ show_caution,
&setlist, &showlist);
add_setshow_zinteger_cmd ("annotate", class_obscure, &annotation_level, _("\
0 == normal; 1 == fullname (for use when running under emacs)\n\
2 == output annotated suitably for use by programs that control GDB."),
set_async_annotation_level,
- NULL, /* FIXME: i18n: */
+ show_annotation_level,
&setlist, &showlist);
add_setshow_boolean_cmd ("exec-done-display", class_support,
Show notification of completion for asynchronous execution commands."), _("\
Use \"on\" to enable the notification, and \"off\" to disable it."),
NULL,
- NULL, /* FIXME: i18n: */
+ show_exec_done_display_p,
&setlist, &showlist);
}
init_cli_cmds();
init_main (); /* But that omits this file! Do it now */
+ initialize_stdin_serial ();
+
async_init_signals ();
/* We need a default language for parsing expressions, so simple things like