Make gdb_stdout&co be per UI
[deliverable/binutils-gdb.git] / gdb / top.c
index f8f926b62d4a5cabcbf58cd3c52de3a1fd92b4fd..a34635b8b508aaa0e8c635bf54eddb0797b91143 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1,6 +1,6 @@
 /* Top level stuff for GDB, the GNU debugger.
 
 /* Top level stuff for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2015 Free Software Foundation, Inc.
+   Copyright (C) 1986-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
@@ -49,6 +49,9 @@
 #include "observer.h"
 #include "maint.h"
 #include "filenames.h"
 #include "observer.h"
 #include "maint.h"
 #include "filenames.h"
+#include "frame.h"
+#include "buffer.h"
+#include "gdb_select.h"
 
 /* readline include files.  */
 #include "readline/readline.h"
 
 /* readline include files.  */
 #include "readline/readline.h"
 #include "tracepoint.h"
 #include "inf-loop.h"
 
 #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
 extern void initialize_all_files (void);
 
 #define PROMPT(X) the_prompts.prompt_stack[the_prompts.top + X].prompt
@@ -79,6 +86,21 @@ extern void initialize_all_files (void);
 #define DEFAULT_PROMPT "(gdb) "
 #endif
 
 #define DEFAULT_PROMPT "(gdb) "
 #endif
 
+/* Generate a function that exports a pointer to a field of the
+   current UI.  */
+
+#define gen_ret_current_ui_field_ptr(type, name)       \
+type *                                                 \
+current_ui_## name ## _ptr (void)                      \
+{                                                      \
+  return &current_ui->m_ ## name;              \
+}
+
+gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stdout)
+gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stdin)
+gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stderr)
+gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stdlog)
+
 /* Initialization file name for gdb.  This is host-dependent.  */
 
 const char gdbinit[] = GDBINIT;
 /* Initialization file name for gdb.  This is host-dependent.  */
 
 const char gdbinit[] = GDBINIT;
@@ -119,17 +141,9 @@ char *current_directory;
 /* The directory name is actually stored here (usually).  */
 char gdb_dirbuf[1024];
 
 /* The directory name is actually stored here (usually).  */
 char gdb_dirbuf[1024];
 
-/* Function to call before reading a command, if nonzero.
-   The function receives two args: an input stream,
-   and a prompt string.  */
-
-void (*window_hook) (FILE *, char *);
-
-/* Buffer used for reading command lines, and the size
-   allocated for it so far.  */
-
+/* The last command line executed on the console.  Used for command
+   repetitions.  */
 char *saved_command_line;
 char *saved_command_line;
-int saved_command_line_size = 100;
 
 /* Nonzero if the current command is modified by "server ".  This
    affects things like recording into the command history, commands
 
 /* Nonzero if the current command is modified by "server ".  This
    affects things like recording into the command history, commands
@@ -221,11 +235,6 @@ void (*deprecated_detach_hook) (void);
 
 void (*deprecated_interactive_hook) (void);
 
 
 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.  */
 
 /* Called when going to wait for the target.  Usually allows the GUI
    to run while waiting for target events.  */
 
@@ -278,7 +287,7 @@ void
 do_restore_instream_cleanup (void *stream)
 {
   /* Restore the previous input stream.  */
 do_restore_instream_cleanup (void *stream)
 {
   /* Restore the previous input stream.  */
-  instream = stream;
+  instream = (FILE *) stream;
 }
 
 /* Read commands from STREAM.  */
 }
 
 /* Read commands from STREAM.  */
@@ -289,7 +298,21 @@ read_command_file (FILE *stream)
 
   cleanups = make_cleanup (do_restore_instream_cleanup, instream);
   instream = stream;
 
   cleanups = make_cleanup (do_restore_instream_cleanup, instream);
   instream = stream;
-  command_loop ();
+
+  /* Read commands from `instream' and execute them until end of file
+     or error reading instream.  */
+
+  while (instream != NULL && !feof (instream))
+    {
+      char *command;
+
+      /* Get a command-line.  This calls the readline package.  */
+      command = command_line_input (NULL, 0, NULL);
+      if (command == NULL)
+       break;
+      command_handler (command);
+    }
+
   do_cleanups (cleanups);
 }
 \f
   do_cleanups (cleanups);
 }
 \f
@@ -330,10 +353,11 @@ void
 check_frame_language_change (void)
 {
   static int warned = 0;
 check_frame_language_change (void)
 {
   static int warned = 0;
+  struct frame_info *frame;
 
   /* First make sure that a new frame has been selected, in case the
      command or the hooks changed the program state.  */
 
   /* First make sure that a new frame has been selected, in case the
      command or the hooks changed the program state.  */
-  deprecated_safe_get_selected_frame ();
+  frame = deprecated_safe_get_selected_frame ();
   if (current_language != expected_language)
     {
       if (language_mode == language_mode_auto && info_verbose)
   if (current_language != expected_language)
     {
       if (language_mode == language_mode_auto && info_verbose)
@@ -353,7 +377,7 @@ check_frame_language_change (void)
     {
       enum language flang;
 
     {
       enum language flang;
 
-      flang = get_frame_language ();
+      flang = get_frame_language (frame);
       if (!warned
          && flang != language_unknown
          && flang != current_language->la_language)
       if (!warned
          && flang != language_unknown
          && flang != current_language->la_language)
@@ -366,6 +390,16 @@ check_frame_language_change (void)
 
 /* See top.h.  */
 
 
 /* See top.h.  */
 
+void
+wait_sync_command_done (void)
+{
+  while (gdb_do_one_event () >= 0)
+    if (!sync_execution)
+      break;
+}
+
+/* See top.h.  */
+
 void
 maybe_wait_sync_command_done (int was_sync)
 {
 void
 maybe_wait_sync_command_done (int was_sync)
 {
@@ -374,11 +408,7 @@ maybe_wait_sync_command_done (int was_sync)
      just ran a synchronous command that started the target, wait
      for that command to end.  */
   if (!interpreter_async && !was_sync && sync_execution)
      just ran a synchronous command that started the target, wait
      for that command to end.  */
   if (!interpreter_async && !was_sync && sync_execution)
-    {
-      while (gdb_do_one_event () >= 0)
-       if (!sync_execution)
-         break;
-    }
+    wait_sync_command_done ();
 }
 
 /* Execute the line P as a command, in the current user context.
 }
 
 /* Execute the line P as a command, in the current user context.
@@ -527,49 +557,6 @@ execute_command_to_string (char *p, int from_tty)
   return retval;
 }
 
   return retval;
 }
 
-/* Read commands from `instream' and execute them
-   until end of file or error reading instream.  */
-
-void
-command_loop (void)
-{
-  struct cleanup *old_chain;
-  char *command;
-  int stdin_is_tty = ISATTY (stdin);
-
-  while (instream && !feof (instream))
-    {
-      if (window_hook && instream == stdin)
-       (*window_hook) (instream, get_prompt ());
-
-      clear_quit_flag ();
-      if (instream == stdin && stdin_is_tty)
-       reinitialize_more_filter ();
-      old_chain = make_cleanup (null_cleanup, 0);
-
-      /* Get a command-line.  This calls the readline package.  */
-      command = command_line_input (instream == stdin ?
-                                   get_prompt () : (char *) NULL,
-                                   instream == stdin, "prompt");
-      if (command == 0)
-       {
-         do_cleanups (old_chain);
-         return;
-       }
-
-      make_command_stats_cleanup (1);
-
-      /* Do not execute commented lines.  */
-      if (command[0] != '#')
-       {
-         execute_command (command, instream == stdin);
-
-         /* Do any commands attached to breakpoint we are stopped at.  */
-         bpstat_do_actions ();
-       }
-      do_cleanups (old_chain);
-    }
-}
 \f
 /* When nonzero, cause dont_repeat to do nothing.  This should only be
    set via prevent_dont_repeat.  */
 \f
 /* When nonzero, cause dont_repeat to do nothing.  This should only be
    set via prevent_dont_repeat.  */
@@ -606,64 +593,80 @@ prevent_dont_repeat (void)
 \f
 /* Read a line from the stream "instream" without command line editing.
 
 \f
 /* Read a line from the stream "instream" without command line editing.
 
-   It prints PROMPT_ARG once at the start.
+   It prints PROMPT once at the start.
    Action is compatible with "readline", e.g. space for the result is
    malloc'd and should be freed by the caller.
 
    A NULL return means end of file.  */
    Action is compatible with "readline", e.g. space for the result is
    malloc'd and should be freed by the caller.
 
    A NULL return means end of file.  */
-char *
-gdb_readline (const char *prompt_arg)
+
+static char *
+gdb_readline_no_editing (const char *prompt)
 {
 {
-  int c;
-  char *result;
-  int input_index = 0;
-  int result_size = 80;
+  struct buffer line_buffer;
+  /* Read from stdin if we are executing a user defined command.  This
+     is the right thing for prompt_for_continue, at least.  */
+  FILE *stream = instream != NULL ? instream : stdin;
+  int fd = fileno (stream);
 
 
-  if (prompt_arg)
+  buffer_init (&line_buffer);
+
+  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.  */
     {
       /* 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.  */
-      fputs_unfiltered (prompt_arg, gdb_stdout);
+      fputs_unfiltered (prompt, gdb_stdout);
       gdb_flush (gdb_stdout);
     }
 
       gdb_flush (gdb_stdout);
     }
 
-  result = (char *) xmalloc (result_size);
-
   while (1)
     {
   while (1)
     {
-      /* Read from stdin if we are executing a user defined command.
-         This is the right thing for prompt_for_continue, at least.  */
-      c = fgetc (instream ? instream : stdin);
+      int c;
+      int numfds;
+      fd_set readfds;
+
+      QUIT;
+
+      /* Wait until at least one byte of data is available.  Control-C
+        can interrupt interruptible_select, but not fgetc.  */
+      FD_ZERO (&readfds);
+      FD_SET (fd, &readfds);
+      if (interruptible_select (fd + 1, &readfds, NULL, NULL, NULL) == -1)
+       {
+         if (errno == EINTR)
+           {
+             /* If this was ctrl-c, the QUIT above handles it.  */
+             continue;
+           }
+         perror_with_name (("select"));
+       }
+
+      c = fgetc (stream);
 
       if (c == EOF)
        {
 
       if (c == EOF)
        {
-         if (input_index > 0)
+         if (line_buffer.used_size > 0)
            /* The last line does not end with a newline.  Return it, and
               if we are called again fgetc will still return EOF and
               we'll return NULL then.  */
            break;
            /* The last line does not end with a newline.  Return it, and
               if we are called again fgetc will still return EOF and
               we'll return NULL then.  */
            break;
-         xfree (result);
+         xfree (buffer_finish (&line_buffer));
          return NULL;
        }
 
       if (c == '\n')
        {
          return NULL;
        }
 
       if (c == '\n')
        {
-         if (input_index > 0 && result[input_index - 1] == '\r')
-           input_index--;
+         if (line_buffer.used_size > 0
+             && line_buffer.buffer[line_buffer.used_size - 1] == '\r')
+           line_buffer.used_size--;
          break;
        }
 
          break;
        }
 
-      result[input_index++] = c;
-      while (input_index >= result_size)
-       {
-         result_size *= 2;
-         result = (char *) xrealloc (result, result_size);
-       }
+      buffer_grow_char (&line_buffer, c);
     }
 
     }
 
-  result[input_index++] = '\0';
-  return result;
+  buffer_grow_char (&line_buffer, '\0');
+  return buffer_finish (&line_buffer);
 }
 
 /* Variables which control command line editing and history
 }
 
 /* Variables which control command line editing and history
@@ -698,6 +701,20 @@ show_history_size (struct ui_file *file, int from_tty,
                    value);
 }
 
                    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,
 static char *history_filename;
 static void
 show_history_filename (struct ui_file *file, int from_tty,
@@ -739,6 +756,21 @@ static char *gdb_readline_wrapper_result;
    return.  */
 static void (*saved_after_char_processing_hook) (void);
 
    return.  */
 static void (*saved_after_char_processing_hook) (void);
 
+
+/* The number of nested readline secondary prompts that are currently
+   active.  */
+
+static int gdb_secondary_prompt_depth = 0;
+
+/* See top.h.  */
+
+int
+gdb_in_secondary_prompt_p (void)
+{
+  return gdb_secondary_prompt_depth > 0;
+}
+
+
 /* This function is called when readline has seen a complete line of
    text.  */
 
 /* This function is called when readline has seen a complete line of
    text.  */
 
@@ -777,12 +809,14 @@ struct gdb_readline_wrapper_cleanup
 static void
 gdb_readline_wrapper_cleanup (void *arg)
 {
 static void
 gdb_readline_wrapper_cleanup (void *arg)
 {
-  struct gdb_readline_wrapper_cleanup *cleanup = arg;
+  struct ui *ui = current_ui;
+  struct gdb_readline_wrapper_cleanup *cleanup
+    = (struct gdb_readline_wrapper_cleanup *) arg;
 
   rl_already_prompted = cleanup->already_prompted_orig;
 
 
   rl_already_prompted = cleanup->already_prompted_orig;
 
-  gdb_assert (input_handler == gdb_readline_wrapper_line);
-  input_handler = cleanup->handler_orig;
+  gdb_assert (ui->input_handler == gdb_readline_wrapper_line);
+  ui->input_handler = cleanup->handler_orig;
 
   /* Don't restore our input handler in readline yet.  That would make
      readline prep the terminal (putting it in raw mode), while the
 
   /* Don't restore our input handler in readline yet.  That would make
      readline prep the terminal (putting it in raw mode), while the
@@ -793,6 +827,8 @@ gdb_readline_wrapper_cleanup (void *arg)
 
   gdb_readline_wrapper_result = NULL;
   gdb_readline_wrapper_done = 0;
 
   gdb_readline_wrapper_result = NULL;
   gdb_readline_wrapper_done = 0;
+  gdb_secondary_prompt_depth--;
+  gdb_assert (gdb_secondary_prompt_depth >= 0);
 
   after_char_processing_hook = saved_after_char_processing_hook;
   saved_after_char_processing_hook = NULL;
 
   after_char_processing_hook = saved_after_char_processing_hook;
   saved_after_char_processing_hook = NULL;
@@ -806,18 +842,20 @@ gdb_readline_wrapper_cleanup (void *arg)
 char *
 gdb_readline_wrapper (const char *prompt)
 {
 char *
 gdb_readline_wrapper (const char *prompt)
 {
+  struct ui *ui = current_ui;
   struct cleanup *back_to;
   struct gdb_readline_wrapper_cleanup *cleanup;
   char *retval;
 
   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 = XNEW (struct gdb_readline_wrapper_cleanup);
+  cleanup->handler_orig = ui->input_handler;
+  ui->input_handler = gdb_readline_wrapper_line;
 
   cleanup->already_prompted_orig = rl_already_prompted;
 
   cleanup->target_is_async_orig = target_is_async_p ();
 
 
   cleanup->already_prompted_orig = rl_already_prompted;
 
   cleanup->target_is_async_orig = target_is_async_p ();
 
+  gdb_secondary_prompt_depth++;
   back_to = make_cleanup (gdb_readline_wrapper_cleanup, cleanup);
 
   if (cleanup->target_is_async_orig)
   back_to = make_cleanup (gdb_readline_wrapper_cleanup, cleanup);
 
   if (cleanup->target_is_async_orig)
@@ -897,8 +935,43 @@ static int command_count = 0;
 void
 gdb_add_history (const char *command)
 {
 void
 gdb_add_history (const char *command)
 {
-  add_history (command);
   command_count++;
   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
 }
 
 /* Safely append new history entries to the history file in a corruption-free
@@ -956,32 +1029,26 @@ gdb_safe_append_history (void)
   do_cleanups (old_chain);
 }
 
   do_cleanups (old_chain);
 }
 
-/* Read one line from the command input stream `instream'
-   into the local static buffer `linebuffer' (whose current length
-   is `linelength').
-   The buffer is made bigger as necessary.
-   Returns the address of the start of the line.
+/* Read one line from the command input stream `instream' into a local
+   static buffer.  The buffer is made bigger as necessary.  Returns
+   the address of the start of the line.
 
    NULL is returned for end of file.
 
 
    NULL is returned for end of file.
 
-   *If* the instream == stdin & stdin is a terminal, the line read
-   is copied into the file line saver (global var char *line,
-   length linesize) so that it can be duplicated.
+   *If* the instream == stdin & stdin is a terminal, 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.  */
+   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, char *annotation_suffix)
 {
 
 char *
 command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix)
 {
-  static char *linebuffer = 0;
-  static unsigned linelength = 0;
+  static struct buffer cmd_line_buffer;
+  static int cmd_line_buffer_initialized;
   const char *prompt = prompt_arg;
   const char *prompt = prompt_arg;
-  char *p;
-  char *p1;
-  char *rl;
-  char *nline;
-  char got_eof = 0;
+  char *cmd;
 
   /* The annotation suffix must be non-NULL.  */
   if (annotation_suffix == NULL)
 
   /* The annotation suffix must be non-NULL.  */
   if (annotation_suffix == NULL)
@@ -991,8 +1058,9 @@ command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix)
     {
       char *local_prompt;
 
     {
       char *local_prompt;
 
-      local_prompt = alloca ((prompt == NULL ? 0 : strlen (prompt))
-                            + strlen (annotation_suffix) + 40);
+      local_prompt
+       = (char *) alloca ((prompt == NULL ? 0 : strlen (prompt))
+                          + strlen (annotation_suffix) + 40);
       if (prompt == NULL)
        local_prompt[0] = '\0';
       else
       if (prompt == NULL)
        local_prompt[0] = '\0';
       else
@@ -1004,18 +1072,15 @@ command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix)
       prompt = local_prompt;
     }
 
       prompt = local_prompt;
     }
 
-  if (linebuffer == 0)
+  if (!cmd_line_buffer_initialized)
     {
     {
-      linelength = 80;
-      linebuffer = (char *) xmalloc (linelength);
+      buffer_init (&cmd_line_buffer);
+      cmd_line_buffer_initialized = 1;
     }
 
     }
 
-  p = linebuffer;
+  /* Starting a new command line.  */
+  cmd_line_buffer.used_size = 0;
 
 
-  /* Control-C quits instantly if typed while in this loop
-     since it should not wait until the user types a newline.  */
-  immediate_quit++;
-  QUIT;
 #ifdef STOP_SIGNAL
   if (job_control)
     signal (STOP_SIGNAL, handle_stop_sig);
 #ifdef STOP_SIGNAL
   if (job_control)
     signal (STOP_SIGNAL, handle_stop_sig);
@@ -1023,6 +1088,8 @@ command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix)
 
   while (1)
     {
 
   while (1)
     {
+      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.  */
       /* 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.  */
@@ -1051,40 +1118,19 @@ command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix)
        }
       else
        {
        }
       else
        {
-         rl = gdb_readline (prompt);
+         rl = gdb_readline_no_editing (prompt);
        }
 
        }
 
-      if (annotation_level > 1 && instream == stdin)
+      cmd = handle_line_of_input (&cmd_line_buffer, rl,
+                                 repeat, annotation_suffix);
+      if (cmd == (char *) EOF)
        {
        {
-         puts_unfiltered ("\n\032\032post-");
-         puts_unfiltered (annotation_suffix);
-         puts_unfiltered ("\n");
-       }
-
-      if (!rl || rl == (char *) EOF)
-       {
-         got_eof = 1;
+         cmd = NULL;
          break;
        }
          break;
        }
-      if (strlen (rl) + 1 + (p - linebuffer) > linelength)
-       {
-         linelength = strlen (rl) + 1 + (p - linebuffer);
-         nline = (char *) xrealloc (linebuffer, linelength);
-         p += nline - linebuffer;
-         linebuffer = nline;
-       }
-      p1 = rl;
-      /* Copy line.  Don't copy null at end.  (Leaves line alone
-         if this was just a newline).  */
-      while (*p1)
-       *p++ = *p1++;
-
-      xfree (rl);              /* Allocated in readline.  */
-
-      if (p == linebuffer || *(p - 1) != '\\')
+      if (cmd != NULL)
        break;
 
        break;
 
-      p--;                     /* Put on top of '\'.  */
       prompt = NULL;
     }
 
       prompt = NULL;
     }
 
@@ -1092,83 +1138,8 @@ command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix)
   if (job_control)
     signal (STOP_SIGNAL, SIG_DFL);
 #endif
   if (job_control)
     signal (STOP_SIGNAL, SIG_DFL);
 #endif
-  immediate_quit--;
-
-  if (got_eof)
-    return NULL;
 
 
-#define SERVER_COMMAND_LENGTH 7
-  server_command =
-    (p - linebuffer > SERVER_COMMAND_LENGTH)
-    && strncmp (linebuffer, "server ", SERVER_COMMAND_LENGTH) == 0;
-  if (server_command)
-    {
-      /* Note that we don't set `line'.  Between this and the check in
-         dont_repeat, this insures that repeating will still do the
-         right thing.  */
-      *p = '\0';
-      return linebuffer + SERVER_COMMAND_LENGTH;
-    }
-
-  /* Do history expansion if that is wished.  */
-  if (history_expansion_p && instream == stdin
-      && ISATTY (instream))
-    {
-      char *history_value;
-      int expanded;
-
-      *p = '\0';               /* Insert null now.  */
-      expanded = history_expand (linebuffer, &history_value);
-      if (expanded)
-       {
-         /* Print the changes.  */
-         printf_unfiltered ("%s\n", history_value);
-
-         /* If there was an error, call this function again.  */
-         if (expanded < 0)
-           {
-             xfree (history_value);
-             return command_line_input (prompt, repeat,
-                                        annotation_suffix);
-           }
-         if (strlen (history_value) > linelength)
-           {
-             linelength = strlen (history_value) + 1;
-             linebuffer = (char *) xrealloc (linebuffer, linelength);
-           }
-         strcpy (linebuffer, history_value);
-         p = linebuffer + strlen (linebuffer);
-       }
-      xfree (history_value);
-    }
-
-  /* If we just got an empty line, and that is supposed to repeat the
-     previous command, return the value in the global buffer.  */
-  if (repeat && p == linebuffer)
-    return saved_command_line;
-  for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++);
-  if (repeat && !*p1)
-    return saved_command_line;
-
-  *p = 0;
-
-  /* Add line to history if appropriate.  */
-  if (*linebuffer && input_from_terminal_p ())
-    gdb_add_history (linebuffer);
-
-  /* Save into global buffer if appropriate.  */
-  if (repeat)
-    {
-      if (linelength > saved_command_line_size)
-       {
-         saved_command_line = xrealloc (saved_command_line, linelength);
-         saved_command_line_size = linelength;
-       }
-      strcpy (saved_command_line, linebuffer);
-      return saved_command_line;
-    }
-
-  return linebuffer;
+  return cmd;
 }
 \f
 /* Print the GDB banner.  */
 }
 \f
 /* Print the GDB banner.  */
@@ -1184,7 +1155,7 @@ print_gdb_version (struct ui_file *stream)
   /* Second line is a copyright notice.  */
 
   fprintf_filtered (stream,
   /* Second line is a copyright notice.  */
 
   fprintf_filtered (stream,
-                   "Copyright (C) 2015 Free Software Foundation, Inc.\n");
+                   "Copyright (C) 2016 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
 
   /* Following the copyright is a brief statement that the program is
      free software, that users are free to copy and change it on
@@ -1363,7 +1334,7 @@ struct qt_args
 static int
 kill_or_detach (struct inferior *inf, void *args)
 {
 static int
 kill_or_detach (struct inferior *inf, void *args)
 {
-  struct qt_args *qt = args;
+  struct qt_args *qt = (struct qt_args *) args;
   struct thread_info *thread;
 
   if (inf->pid == 0)
   struct thread_info *thread;
 
   if (inf->pid == 0)
@@ -1394,7 +1365,7 @@ kill_or_detach (struct inferior *inf, void *args)
 static int
 print_inferior_quit_action (struct inferior *inf, void *arg)
 {
 static int
 print_inferior_quit_action (struct inferior *inf, void *arg)
 {
-  struct ui_file *stb = arg;
+  struct ui_file *stb = (struct ui_file *) arg;
 
   if (inf->pid == 0)
     return 0;
 
   if (inf->pid == 0)
     return 0;
@@ -1442,6 +1413,21 @@ quit_confirm (void)
   return qr;
 }
 
   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
 /* Quit without asking for confirmation.  */
 
 void
@@ -1450,6 +1436,8 @@ quit_force (char *args, int from_tty)
   int exit_code = 0;
   struct qt_args qt;
 
   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)
   /* An optional expression may be used to cause gdb to terminate with the 
      value of that expression.  */
   if (args)
@@ -1681,24 +1669,42 @@ init_history (void)
 {
   char *tmpenv;
 
 {
   char *tmpenv;
 
-  tmpenv = getenv ("HISTSIZE");
+  tmpenv = getenv ("GDBHISTSIZE");
   if (tmpenv)
     {
   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);
     history_size_setshow_var = 256;
 
   set_readline_history_size (history_size_setshow_var);
@@ -1795,10 +1801,6 @@ init_main (void)
      the DEFAULT_PROMPT is.  */
   set_prompt (DEFAULT_PROMPT);
 
      the DEFAULT_PROMPT is.  */
   set_prompt (DEFAULT_PROMPT);
 
-  /* Set things up for annotation_level > 1, if the user ever decides
-     to use it.  */
-  async_annotation_suffix = "prompt";
-
   /* Set the important stuff up for command editing.  */
   command_editing_p = 1;
   history_expansion_p = 0;
   /* Set the important stuff up for command editing.  */
   command_editing_p = 1;
   history_expansion_p = 0;
@@ -1857,11 +1859,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\
 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);
 
                            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"), _("\
   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"), _("\
This page took 0.033175 seconds and 4 git commands to generate.