Don't set immediate_quit in prompt_for_continue
[deliverable/binutils-gdb.git] / gdb / event-top.c
index 885723594862bce99a1de29ce5b7fd3c435adf39..a119fe98734e67a0ccfc3bbbe9a054a937fcb06c 100644 (file)
@@ -49,7 +49,6 @@
 static void rl_callback_read_char_wrapper (gdb_client_data client_data);
 static void command_line_handler (char *rl);
 static void change_line_handler (void);
-static void command_handler (char *command);
 static char *top_level_prompt (void);
 
 /* Signal handlers.  */
@@ -140,20 +139,6 @@ static struct async_signal_handler *sigtstp_token;
 #endif
 static struct async_signal_handler *async_sigterm_token;
 
-/* Structure to save a partially entered command.  This is used when
-   the user types '\' at the end of a command line.  This is necessary
-   because each line of input is handled by a different call to
-   command_line_handler, and normally there is no state retained
-   between different calls.  */
-static int more_to_come = 0;
-
-struct readline_input_state
-  {
-    char *linebuffer;
-    char *linebuffer_ptr;
-  }
-readline_input_state;
-
 /* This hook is called by rl_callback_read_char_wrapper after each
    character is processed.  */
 void (*after_char_processing_hook) (void);
@@ -383,6 +368,24 @@ top_level_prompt (void)
   return xstrdup (prompt);
 }
 
+/* Get a pointer to the command line buffer.  This is used to
+   construct a whole line of input from partial input.  */
+
+static struct buffer *
+get_command_line_buffer (void)
+{
+  static struct buffer line_buffer;
+  static int line_buffer_initialized;
+
+  if (!line_buffer_initialized)
+    {
+      buffer_init (&line_buffer);
+      line_buffer_initialized = 1;
+    }
+
+  return &line_buffer;
+}
+
 /* When there is an event ready on the stdin file descriptor, instead
    of calling readline directly throught the callback function, or
    instead of calling gdb_readline_no_editing_callback, give gdb a
@@ -400,6 +403,15 @@ stdin_event_handler (int error, gdb_client_data client_data)
     }
   else
     {
+    /* This makes sure a ^C immediately followed by further input is
+       always processed in that order.  E.g,. with input like
+       "^Cprint 1\n", the SIGINT handler runs, marks the async signal
+       handler, and then select/poll may return with stdin ready,
+       instead of -1/EINTR.  The
+       gdb.base/double-prompt-target-event-error.exp test exercises
+       this.  */
+      QUIT;
+
       do
        {
          call_stdin_event_handler_again_p = 0;
@@ -436,152 +448,122 @@ async_disable_stdin (void)
 }
 \f
 
-/* Handles a gdb command.  This function is called by
-   command_line_handler, which has processed one or more input lines
-   into COMMAND.  */
-/* NOTE: 1999-04-30 This is the asynchronous version of the command_loop
-   function.  The command_loop function will be obsolete when we
-   switch to use the event loop at every execution of gdb.  */
-static void
+/* Handle a gdb command line.  This function is called when
+   handle_line_of_input has concatenated one or more input lines into
+   a whole command.  */
+
+void
 command_handler (char *command)
 {
   struct cleanup *stat_chain;
+  char *c;
 
   clear_quit_flag ();
   if (instream == stdin)
     reinitialize_more_filter ();
 
-  /* If readline returned a NULL command, it means that the connection
-     with the terminal is gone.  This happens at the end of a
-     testsuite run, after Expect has hung up but GDB is still alive.
-     In such a case, we just quit gdb killing the inferior program
-     too.  */
-  if (command == 0)
-    {
-      printf_unfiltered ("quit\n");
-      execute_command ("quit", stdin == instream);
-    }
-
   stat_chain = make_command_stats_cleanup (1);
 
-  execute_command (command, instream == stdin);
+  /* Do not execute commented lines.  */
+  for (c = command; *c == ' ' || *c == '\t'; c++)
+    ;
+  if (c[0] != '#')
+    {
+      execute_command (command, instream == stdin);
 
-  /* Do any commands attached to breakpoint we stopped at.  */
-  bpstat_do_actions ();
+      /* Do any commands attached to breakpoint we stopped at.  */
+      bpstat_do_actions ();
+    }
 
   do_cleanups (stat_chain);
 }
 
-/* Handle a complete line of input.  This is called by the callback
-   mechanism within the readline library.  Deal with incomplete
-   commands as well, by saving the partial input in a global
-   buffer.  */
+/* Append RL, an input line returned by readline or one of its
+   emulations, to CMD_LINE_BUFFER.  Returns the command line if we
+   have a whole command line ready to be processed by the command
+   interpreter or NULL if the command line isn't complete yet (input
+   line ends in a backslash).  Takes ownership of RL.  */
 
-/* NOTE: 1999-04-30 This is the asynchronous version of the
-   command_line_input function; command_line_input will become
-   obsolete once we use the event loop as the default mechanism in
-   GDB.  */
-static void
-command_line_handler (char *rl)
+static char *
+command_line_append_input_line (struct buffer *cmd_line_buffer, char *rl)
 {
-  static char *linebuffer = 0;
-  static unsigned linelength = 0;
-  char *p;
-  char *p1;
-  char *nline;
-  int repeat = (instream == stdin);
+  char *cmd;
+  size_t len;
 
-  if (annotation_level > 1 && instream == stdin)
-    printf_unfiltered (("\n\032\032post-prompt\n"));
+  len = strlen (rl);
 
-  if (linebuffer == 0)
+  if (len > 0 && rl[len - 1] == '\\')
     {
-      linelength = 80;
-      linebuffer = (char *) xmalloc (linelength);
-      linebuffer[0] = '\0';
+      /* Don't copy the backslash and wait for more.  */
+      buffer_grow (cmd_line_buffer, rl, len - 1);
+      cmd = NULL;
     }
-
-  p = linebuffer;
-
-  if (more_to_come)
+  else
     {
-      strcpy (linebuffer, readline_input_state.linebuffer);
-      p = readline_input_state.linebuffer_ptr;
-      xfree (readline_input_state.linebuffer);
-      more_to_come = 0;
+      /* Copy whole line including terminating null, and we're
+        done.  */
+      buffer_grow (cmd_line_buffer, rl, len + 1);
+      cmd = cmd_line_buffer->buffer;
     }
 
-#ifdef STOP_SIGNAL
-  if (job_control)
-    signal (STOP_SIGNAL, handle_stop_sig);
-#endif
+  /* Allocated in readline.  */
+  xfree (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.  */
-  wrap_here ("");
-  gdb_flush (gdb_stdout);
-  gdb_flush (gdb_stderr);
+  return cmd;
+}
 
-  if (source_file_name != NULL)
-    ++source_line_number;
+/* Handle a line of input coming from readline.
 
-  /* If we are in this case, then command_handler will call quit 
-     and exit from gdb.  */
-  if (!rl || rl == (char *) EOF)
-    {
-      command_handler (0);
-      return;                  /* Lint.  */
-    }
-  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++;
+   If the read line ends with a continuation character (backslash),
+   save the partial input in CMD_LINE_BUFFER (except the backslash),
+   and return NULL.  Otherwise, save the partial input and return a
+   pointer to CMD_LINE_BUFFER's buffer (null terminated), indicating a
+   whole command line is ready to be executed.
 
-  xfree (rl);                  /* Allocated in readline.  */
+   Returns EOF on end of file.
 
-  if (p > linebuffer && *(p - 1) == '\\')
-    {
-      *p = '\0';
-      p--;                     /* Put on top of '\'.  */
+   If REPEAT, handle command repetitions:
 
-      readline_input_state.linebuffer = xstrdup (linebuffer);
-      readline_input_state.linebuffer_ptr = p;
+     - If the input command line is NOT empty, the command returned is
+       copied into the global 'saved_command_line' var so that it can
+       be repeated later.
 
-      /* We will not invoke a execute_command if there is more
-        input expected to complete the command.  So, we need to
-        print an empty prompt here.  */
-      more_to_come = 1;
-      display_gdb_prompt ("");
-      return;
-    }
+     - OTOH, if the input command line IS empty, return the previously
+       saved command instead of the empty input line.
+*/
 
-#ifdef STOP_SIGNAL
-  if (job_control)
-    signal (STOP_SIGNAL, SIG_DFL);
-#endif
+char *
+handle_line_of_input (struct buffer *cmd_line_buffer,
+                     char *rl, int repeat, char *annotation_suffix)
+{
+  char *p1;
+  char *cmd;
+
+  if (rl == NULL)
+    return (char *) EOF;
+
+  cmd = command_line_append_input_line (cmd_line_buffer, rl);
+  if (cmd == NULL)
+    return NULL;
+
+  /* We have a complete command line now.  Prepare for the next
+     command, but leave ownership of memory to the buffer .  */
+  cmd_line_buffer->used_size = 0;
 
-#define SERVER_COMMAND_LENGTH 7
-  server_command =
-    (p - linebuffer > SERVER_COMMAND_LENGTH)
-    && strncmp (linebuffer, "server ", SERVER_COMMAND_LENGTH) == 0;
-  if (server_command)
+  if (annotation_level > 1 && instream == stdin)
     {
-      /* 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';
-      command_handler (linebuffer + SERVER_COMMAND_LENGTH);
-      display_gdb_prompt (0);
-      return;
+      printf_unfiltered (("\n\032\032post-"));
+      puts_unfiltered (annotation_suffix);
+      printf_unfiltered (("\n"));
+    }
+
+#define SERVER_COMMAND_PREFIX "server "
+  if (startswith (cmd, SERVER_COMMAND_PREFIX))
+    {
+      /* Note that we don't set `saved_command_line'.  Between this
+         and the check in dont_repeat, this insures that repeating
+         will still do the right thing.  */
+      return cmd + strlen (SERVER_COMMAND_PREFIX);
     }
 
   /* Do history expansion if that is wished.  */
@@ -591,10 +573,11 @@ command_line_handler (char *rl)
       char *history_value;
       int expanded;
 
-      *p = '\0';               /* Insert null now.  */
-      expanded = history_expand (linebuffer, &history_value);
+      expanded = history_expand (cmd, &history_value);
       if (expanded)
        {
+         size_t len;
+
          /* Print the changes.  */
          printf_unfiltered ("%s\n", history_value);
 
@@ -602,72 +585,81 @@ command_line_handler (char *rl)
          if (expanded < 0)
            {
              xfree (history_value);
-             return;
+             return cmd;
            }
-         if (strlen (history_value) > linelength)
-           {
-             linelength = strlen (history_value) + 1;
-             linebuffer = (char *) xrealloc (linebuffer, linelength);
-           }
-         strcpy (linebuffer, history_value);
-         p = linebuffer + strlen (linebuffer);
+
+         /* history_expand returns an allocated string.  Just replace
+            our buffer with it.  */
+         len = strlen (history_value);
+         xfree (buffer_finish (cmd_line_buffer));
+         cmd_line_buffer->buffer = history_value;
+         cmd_line_buffer->buffer_size = len + 1;
+         cmd = history_value;
        }
-      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 && *p != '\\')
-    {
-      command_handler (saved_command_line);
-      display_gdb_prompt (0);
-      return;
-    }
+     previous command, return the previously saved command.  */
+  for (p1 = cmd; *p1 == ' ' || *p1 == '\t'; p1++)
+    ;
+  if (repeat && *p1 == '\0')
+    return saved_command_line;
+
+  /* Add command to history if appropriate.  Note: lines consisting
+     solely of comments are also added to the command history.  This
+     is useful when you type a command, and then realize you don't
+     want to execute it quite yet.  You can comment out the command
+     and then later fetch it from the value history and remove the
+     '#'.  The kill ring is probably better, but some people are in
+     the habit of commenting things out.  */
+  if (*cmd != '\0' && input_from_terminal_p ())
+    gdb_add_history (cmd);
 
-  for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++);
-  if (repeat && !*p1)
+  /* Save into global buffer if appropriate.  */
+  if (repeat)
     {
-      command_handler (saved_command_line);
-      display_gdb_prompt (0);
-      return;
+      xfree (saved_command_line);
+      saved_command_line = xstrdup (cmd);
+      return saved_command_line;
     }
+  else
+    return cmd;
+}
 
-  *p = 0;
+/* Handle a complete line of input.  This is called by the callback
+   mechanism within the readline library.  Deal with incomplete
+   commands as well, by saving the partial input in a global
+   buffer.
 
-  /* Add line to history if appropriate.  */
-  if (*linebuffer && input_from_terminal_p ())
-    gdb_add_history (linebuffer);
+   NOTE: This is the asynchronous version of the command_line_input
+   function.  */
 
-  /* Note: lines consisting solely of comments are added to the command
-     history.  This is useful when you type a command, and then
-     realize you don't want to execute it quite yet.  You can comment
-     out the command and then later fetch it from the value history
-     and remove the '#'.  The kill ring is probably better, but some
-     people are in the habit of commenting things out.  */
-  if (*p1 == '#')
-    *p1 = '\0';                        /* Found a comment.  */
+void
+command_line_handler (char *rl)
+{
+  struct buffer *line_buffer = get_command_line_buffer ();
+  char *cmd;
 
-  /* Save into global buffer if appropriate.  */
-  if (repeat)
+  cmd = handle_line_of_input (line_buffer, rl, instream == stdin, "prompt");
+  if (cmd == (char *) EOF)
     {
-      if (linelength > saved_command_line_size)
-       {
-         saved_command_line
-           = (char *) xrealloc (saved_command_line, linelength);
-         saved_command_line_size = linelength;
-       }
-      strcpy (saved_command_line, linebuffer);
-      if (!more_to_come)
-       {
-         command_handler (saved_command_line);
-         display_gdb_prompt (0);
-       }
-      return;
+      /* stdin closed.  The connection with the terminal is gone.
+        This happens at the end of a testsuite run, after Expect has
+        hung up but GDB is still alive.  In such a case, we just quit
+        gdb killing the inferior program too.  */
+      printf_unfiltered ("quit\n");
+      execute_command ("quit", stdin == instream);
+    }
+  else if (cmd == NULL)
+    {
+      /* We don't have a full line yet.  Print an empty prompt.  */
+      display_gdb_prompt ("");
+    }
+  else
+    {
+      command_handler (cmd);
+      display_gdb_prompt (0);
     }
-
-  command_handler (linebuffer);
-  display_gdb_prompt (0);
-  return;
 }
 
 /* Does reading of input from terminal w/o the editing features
This page took 0.035265 seconds and 4 git commands to generate.