X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ftop.c;h=01fddd2c95f675f731b28d02adcb760211cdff7b;hb=607685ecee1015d6c37e0d800d40453dc0aadc8c;hp=74e1e071370ef83de766a9b46fe097cd033b0a3c;hpb=ebfd00d210ca6190239140b250499e194fd5af20;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/top.c b/gdb/top.c index 74e1e07137..01fddd2c95 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -698,6 +698,20 @@ 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, @@ -897,8 +911,43 @@ static int command_count = 0; 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 @@ -941,7 +990,8 @@ gdb_safe_append_history (void) 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); @@ -1680,24 +1730,42 @@ init_history (void) { char *tmpenv; - tmpenv = getenv ("HISTSIZE"); + tmpenv = getenv ("GDBHISTSIZE"); if (tmpenv) { - int var; - - 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; - } + long var; + int saved_errno; + char *endptr; - 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 == -2) + + /* 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; set_readline_history_size (history_size_setshow_var); @@ -1856,11 +1924,26 @@ 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"), _("\