windows-nat: Cleanups in get_windows_debug_event
[deliverable/binutils-gdb.git] / gdb / event-top.c
index 3f9deec2c23fb1c2763e6189664707632d3fce55..e9cc2d7d3e174c512fe32c6f8f08c0b49002a048 100644 (file)
@@ -1,6 +1,6 @@
 /* Top level stuff for GDB, the GNU debugger.
 
-   Copyright (C) 1999-2014 Free Software Foundation, Inc.
+   Copyright (C) 1999-2015 Free Software Foundation, Inc.
 
    Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
 
@@ -119,6 +119,11 @@ int exec_done_display_p = 0;
    read commands from.  */
 int input_fd;
 
+/* Used by the stdin event handler to compensate for missed stdin events.
+   Setting this to a non-zero value inside an stdin callback makes the callback
+   run again.  */
+int call_stdin_event_handler_again_p;
+
 /* Signal handling variables.  */
 /* Each of these is a pointer to a function that the event loop will
    invoke if the corresponding signal has received.  The real signal
@@ -205,7 +210,7 @@ change_line_handler (void)
   else
     {
       /* Turn off editing by using gdb_readline2.  */
-      rl_callback_handler_remove ();
+      gdb_rl_callback_handler_remove ();
       call_readline = gdb_readline2;
 
       /* Set up the command handler as well, in case we are called as
@@ -214,6 +219,57 @@ change_line_handler (void)
     }
 }
 
+/* The functions below are wrappers for rl_callback_handler_remove and
+   rl_callback_handler_install that keep track of whether the callback
+   handler is installed in readline.  This is necessary because after
+   handling a target event of a background execution command, we may
+   need to reinstall the callback handler if it was removed due to a
+   secondary prompt.  See gdb_readline_wrapper_line.  We don't
+   unconditionally install the handler for every target event because
+   that also clears the line buffer, thus installing it while the user
+   is typing would lose input.  */
+
+/* Whether we've registered a callback handler with readline.  */
+static int callback_handler_installed;
+
+/* See event-top.h, and above.  */
+
+void
+gdb_rl_callback_handler_remove (void)
+{
+  rl_callback_handler_remove ();
+  callback_handler_installed = 0;
+}
+
+/* See event-top.h, and above.  Note this wrapper doesn't have an
+   actual callback parameter because we always install
+   INPUT_HANDLER.  */
+
+void
+gdb_rl_callback_handler_install (const char *prompt)
+{
+  /* Calling rl_callback_handler_install resets readline's input
+     buffer.  Calling this when we were already processing input
+     therefore loses input.  */
+  gdb_assert (!callback_handler_installed);
+
+  rl_callback_handler_install (prompt, input_handler);
+  callback_handler_installed = 1;
+}
+
+/* See event-top.h, and above.  */
+
+void
+gdb_rl_callback_handler_reinstall (void)
+{
+  if (!callback_handler_installed)
+    {
+      /* Passing NULL as prompt argument tells readline to not display
+        a prompt.  */
+      gdb_rl_callback_handler_install (NULL);
+    }
+}
+
 /* Displays the prompt.  If the argument NEW_PROMPT is NULL, the
    prompt that is displayed is the current top level prompt.
    Otherwise, it displays whatever NEW_PROMPT is as a local/secondary
@@ -232,7 +288,7 @@ change_line_handler (void)
    3. On prompting for pagination.  */
 
 void
-display_gdb_prompt (char *new_prompt)
+display_gdb_prompt (const char *new_prompt)
 {
   char *actual_gdb_prompt = NULL;
   struct cleanup *old_chain;
@@ -267,7 +323,7 @@ display_gdb_prompt (char *new_prompt)
             the above two functions.  Calling
             rl_callback_handler_remove(), does the job.  */
 
-         rl_callback_handler_remove ();
+         gdb_rl_callback_handler_remove ();
          do_cleanups (old_chain);
          return;
        }
@@ -282,8 +338,8 @@ display_gdb_prompt (char *new_prompt)
 
   if (async_command_editing_p)
     {
-      rl_callback_handler_remove ();
-      rl_callback_handler_install (actual_gdb_prompt, input_handler);
+      gdb_rl_callback_handler_remove ();
+      gdb_rl_callback_handler_install (actual_gdb_prompt);
     }
   /* new_prompt at this point can be the top of the stack or the one
      passed in.  It can't be NULL.  */
@@ -369,7 +425,13 @@ stdin_event_handler (int error, gdb_client_data client_data)
       quit_command ((char *) 0, stdin == instream);
     }
   else
-    (*call_readline) (client_data);
+    {
+      do
+       {
+         call_stdin_event_handler_again_p = 0;
+         (*call_readline) (client_data);
+       } while (call_stdin_event_handler_again_p != 0);
+    }
 }
 
 /* Re-enable stdin after the end of an execution command in
@@ -467,6 +529,7 @@ command_line_handler (char *rl)
     {
       linelength = 80;
       linebuffer = (char *) xmalloc (linelength);
+      linebuffer[0] = '\0';
     }
 
   p = linebuffer;
@@ -604,7 +667,7 @@ command_line_handler (char *rl)
 
   /* Add line to history if appropriate.  */
   if (*linebuffer && input_from_terminal_p ())
-    add_history (linebuffer);
+    gdb_add_history (linebuffer);
 
   /* Note: lines consisting solely of comments are added to the command
      history.  This is useful when you type a command, and then
@@ -872,24 +935,28 @@ handle_sighup (int sig)
 static void
 async_disconnect (gdb_client_data arg)
 {
-  volatile struct gdb_exception exception;
 
-  TRY_CATCH (exception, RETURN_MASK_ALL)
+  TRY
     {
       quit_cover ();
     }
 
-  if (exception.reason < 0)
+  CATCH (exception, RETURN_MASK_ALL)
     {
       fputs_filtered ("Could not kill the program being debugged",
                      gdb_stderr);
       exception_print (gdb_stderr, exception);
     }
+  END_CATCH
 
-  TRY_CATCH (exception, RETURN_MASK_ALL)
+  TRY
     {
       pop_all_targets ();
     }
+  CATCH (exception, RETURN_MASK_ALL)
+    {
+    }
+  END_CATCH
 
   signal (SIGHUP, SIG_DFL);    /*FIXME: ???????????  */
   raise (SIGHUP);
@@ -1039,6 +1106,6 @@ gdb_disable_readline (void)
   gdb_stdtargerr = NULL;
 #endif
 
-  rl_callback_handler_remove ();
+  gdb_rl_callback_handler_remove ();
   delete_file_handler (input_fd);
 }
This page took 0.026236 seconds and 4 git commands to generate.