#include "tracepoint.h"
#include "inf-loop.h"
+#if defined(TUI)
+# include "tui/tui.h"
+#endif
+
extern void initialize_all_files (void);
#define PROMPT(X) the_prompts.prompt_stack[the_prompts.top + X].prompt
/* Hooks for alternate command interfaces. */
-/* Called after most modules have been initialized, but before taking
- users command file.
-
- If the UI fails to initialize and it wants GDB to continue using
- the default UI, then it should clear this hook before returning. */
-
-void (*deprecated_init_ui_hook) (char *argv0);
-
/* This hook is called from within gdb's many mini-event loops which
could steal control from a real user interface's event loop. It
returns non-zero if the user is requesting a detach, zero
void (*deprecated_interactive_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). */
-void (*deprecated_register_changed_hook) (int regno);
-
/* Called when going to wait for the target. Usually allows the GUI
to run while waiting for target events. */
}
/* The variable associated with the "set/show history size"
- command. */
-static unsigned int history_size_setshow_var;
+ command. The value -1 means unlimited, and -2 means undefined. */
+static int history_size_setshow_var = -2;
static void
show_history_size (struct ui_file *file, int from_tty,
value);
}
+/* Variable associated with the "history remove-duplicates" option.
+ The value -1 means unlimited. */
+static int history_remove_duplicates = 0;
+
+static void
+show_history_remove_duplicates (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file,
+ _("The number of history entries to look back at for "
+ "duplicates is %s.\n"),
+ value);
+}
+
static char *history_filename;
static void
show_history_filename (struct ui_file *file, int from_tty,
void
gdb_add_history (const char *command)
{
- add_history (command);
command_count++;
+
+ if (history_remove_duplicates != 0)
+ {
+ int lookbehind;
+ int lookbehind_threshold;
+
+ /* The lookbehind threshold for finding a duplicate history entry is
+ bounded by command_count because we can't meaningfully delete
+ history entries that are already stored in the history file since
+ the history file is appended to. */
+ if (history_remove_duplicates == -1
+ || history_remove_duplicates > command_count)
+ lookbehind_threshold = command_count;
+ else
+ lookbehind_threshold = history_remove_duplicates;
+
+ using_history ();
+ for (lookbehind = 0; lookbehind < lookbehind_threshold; lookbehind++)
+ {
+ HIST_ENTRY *temp = previous_history ();
+
+ if (temp == NULL)
+ break;
+
+ if (strcmp (temp->line, command) == 0)
+ {
+ HIST_ENTRY *prev = remove_history (where_history ());
+ command_count--;
+ free_history_entry (prev);
+ break;
+ }
+ }
+ using_history ();
+ }
+
+ add_history (command);
}
/* Safely append new history entries to the history file in a corruption-free
else
{
append_history (command_count, local_history_filename);
- history_truncate_file (local_history_filename, history_max_entries);
+ if (history_is_stifled ())
+ history_truncate_file (local_history_filename, history_max_entries);
}
ret = rename (local_history_filename, history_filename);
fprintf_filtered (stream, _("\
--with-system-gdbinit=%s%s\n\
"), SYSTEM_GDBINIT, SYSTEM_GDBINIT_RELOCATABLE ? " (relocatable)" : "");
-#if HAVE_ZLIB_H
- fprintf_filtered (stream, _("\
- --with-zlib\n\
-"));
-#else
- fprintf_filtered (stream, _("\
- --without-zlib\n\
-"));
-#endif
#if HAVE_LIBBABELTRACE
fprintf_filtered (stream, _("\
--with-babeltrace\n\
return qr;
}
+/* Prepare to exit GDB cleanly by undoing any changes made to the
+ terminal so that we leave the terminal in the state we acquired it. */
+
+static void
+undo_terminal_modifications_before_exit (void)
+{
+ target_terminal_ours ();
+#if defined(TUI)
+ tui_disable ();
+#endif
+ if (async_command_editing_p)
+ gdb_disable_readline ();
+}
+
+
/* Quit without asking for confirmation. */
void
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. */
if (args)
}
}
-/* Called by do_setshow_command. */
-static void
-set_history_size_command (char *args, int from_tty, struct cmd_list_element *c)
-{
- /* Readline's history interface works with 'int', so it can only
- handle history sizes up to INT_MAX. The command itself is
- uinteger, so UINT_MAX means "unlimited", but we only get that if
- the user does "set history size 0" -- "set history size <UINT_MAX>"
- throws out-of-range. */
- if (history_size_setshow_var > INT_MAX
- && history_size_setshow_var != UINT_MAX)
- {
- unsigned int new_value = history_size_setshow_var;
+/* Update the size of our command history file to HISTORY_SIZE.
- /* Restore previous value before throwing. */
- if (history_is_stifled ())
- history_size_setshow_var = history_max_entries;
- else
- history_size_setshow_var = UINT_MAX;
+ A HISTORY_SIZE of -1 stands for unlimited. */
- error (_("integer %u out of range"), new_value);
- }
+static void
+set_readline_history_size (int history_size)
+{
+ gdb_assert (history_size >= -1);
- /* Commit the new value to readline's history. */
- if (history_size_setshow_var == UINT_MAX)
+ if (history_size == -1)
unstifle_history ();
else
- stifle_history (history_size_setshow_var);
+ stifle_history (history_size);
+}
+
+/* Called by do_setshow_command. */
+static void
+set_history_size_command (char *args, int from_tty, struct cmd_list_element *c)
+{
+ set_readline_history_size (history_size_setshow_var);
}
void
{
char *tmpenv;
- tmpenv = getenv ("HISTSIZE");
+ tmpenv = getenv ("GDBHISTSIZE");
if (tmpenv)
{
- int var;
+ long var;
+ int saved_errno;
+ char *endptr;
- var = atoi (tmpenv);
- if (var < 0)
- {
- /* Prefer ending up with no history rather than overflowing
- readline's history interface, which uses signed 'int'
- everywhere. */
- var = 0;
- }
-
- history_size_setshow_var = var;
+ tmpenv = skip_spaces (tmpenv);
+ errno = 0;
+ var = strtol (tmpenv, &endptr, 10);
+ saved_errno = errno;
+ endptr = skip_spaces (endptr);
+
+ /* If GDBHISTSIZE is non-numeric then ignore it. If GDBHISTSIZE is the
+ empty string, a negative number or a huge positive number (larger than
+ INT_MAX) then set the history size to unlimited. Otherwise set our
+ history size to the number we have read. This behavior is consistent
+ with how bash handles HISTSIZE. */
+ if (*endptr != '\0')
+ ;
+ else if (*tmpenv == '\0'
+ || var < 0
+ || var > INT_MAX
+ /* On targets where INT_MAX == LONG_MAX, we have to look at
+ errno after calling strtol to distinguish between a value that
+ is exactly INT_MAX and an overflowing value that was clamped
+ to INT_MAX. */
+ || (var == INT_MAX && saved_errno == ERANGE))
+ history_size_setshow_var = -1;
+ else
+ history_size_setshow_var = var;
}
- /* If the init file hasn't set a size yet, pick the default. */
- else if (history_size_setshow_var == 0)
+
+ /* If neither the init file nor GDBHISTSIZE has set a size yet, pick the
+ default. */
+ if (history_size_setshow_var == -2)
history_size_setshow_var = 256;
- /* Note that unlike "set history size 0", "HISTSIZE=0" really sets
- the history size to 0... */
- stifle_history (history_size_setshow_var);
+ set_readline_history_size (history_size_setshow_var);
tmpenv = getenv ("GDBHISTFILE");
if (tmpenv)
show_write_history_p,
&sethistlist, &showhistlist);
- add_setshow_uinteger_cmd ("size", no_class, &history_size_setshow_var, _("\
+ add_setshow_zuinteger_unlimited_cmd ("size", no_class,
+ &history_size_setshow_var, _("\
Set the size of the command history,"), _("\
Show the size of the command history,"), _("\
ie. the number of previous commands to keep a record of.\n\
If set to \"unlimited\", the number of commands kept in the history\n\
list is unlimited. This defaults to the value of the environment\n\
-variable \"HISTSIZE\", or to 256 if this variable is not set."),
+variable \"GDBHISTSIZE\", or to 256 if this variable is not set."),
set_history_size_command,
show_history_size,
&sethistlist, &showhistlist);
+ add_setshow_zuinteger_unlimited_cmd ("remove-duplicates", no_class,
+ &history_remove_duplicates, _("\
+Set how far back in history to look for and remove duplicate entries."), _("\
+Show how far back in history to look for and remove duplicate entries."), _("\
+If set to a nonzero value N, GDB will look back at the last N history entries\n\
+and remove the first history entry that is a duplicate of the most recent\n\
+entry, each time a new history entry is added.\n\
+If set to \"unlimited\", this lookbehind is unbounded.\n\
+Only history entries added during this session are considered for removal.\n\
+If set to 0, removal of duplicate history entries is disabled.\n\
+By default this option is set to 0."),
+ NULL,
+ show_history_remove_duplicates,
+ &sethistlist, &showhistlist);
+
add_setshow_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"), _("\
initialize_targets (); /* Setup target_terminal macros for utils.c. */
initialize_utils (); /* Make errors and warnings possible. */
+ init_page_info ();
+
/* Here is where we call all the _initialize_foo routines. */
initialize_all_files ();
set_language (language_c);
expected_language = current_language; /* Don't warn about the change. */
- /* Allow another UI to initialize. If the UI fails to initialize,
- and it wants GDB to revert to the CLI, it should clear
- deprecated_init_ui_hook. */
- if (deprecated_init_ui_hook)
- deprecated_init_ui_hook (argv0);
-
/* 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