Split TRY_CATCH into TRY + CATCH
[deliverable/binutils-gdb.git] / gdb / top.c
index fc2b84d70bb96301280639247c5dee61714a80d9..f746af8ef8b197a54d34a66dda813a0fdcbf1a3f 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1,6 +1,6 @@
 /* Top level stuff for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2014 Free Software Foundation, Inc.
+   Copyright (C) 1986-2015 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -26,7 +26,6 @@
 #include "symtab.h"
 #include "inferior.h"
 #include "infrun.h"
-#include "exceptions.h"
 #include <signal.h>
 #include "target.h"
 #include "target-dcache.h"
@@ -216,7 +215,7 @@ void (*deprecated_warning_hook) (const char *, va_list);
    window and it can close it.  */
 
 void (*deprecated_readline_begin_hook) (char *, ...);
-char *(*deprecated_readline_hook) (char *);
+char *(*deprecated_readline_hook) (const char *);
 void (*deprecated_readline_end_hook) (void);
 
 /* Called as appropriate to notify the interface that we have attached
@@ -373,6 +372,23 @@ check_frame_language_change (void)
     }
 }
 
+/* See top.h.  */
+
+void
+maybe_wait_sync_command_done (int was_sync)
+{
+  /* If the interpreter is in sync mode (we're running a user
+     command's list, running command hooks or similars), and we
+     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;
+    }
+}
+
 /* Execute the line P as a command, in the current user context.
    Pass FROM_TTY as second argument to the defining function.  */
 
@@ -446,7 +462,7 @@ execute_command (char *p, int from_tty)
        deprecated_cmd_warning (line);
 
       /* c->user_commands would be NULL in the case of a python command.  */
-      if (c->class == class_user && c->user_commands)
+      if (c->theclass == class_user && c->user_commands)
        execute_user_command (c, arg);
       else if (c->type == set_cmd)
        do_set_command (arg, from_tty, c);
@@ -459,16 +475,7 @@ execute_command (char *p, int from_tty)
       else
        cmd_func (c, arg, from_tty);
 
-      /* If the interpreter is in sync mode (we're running a user
-        command's list, running command hooks or similars), and we
-        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;
-       }
+      maybe_wait_sync_command_done (was_sync);
 
       /* If this command has been post-hooked, run the hook last.  */
       execute_cmd_post_hook (c);
@@ -613,7 +620,7 @@ prevent_dont_repeat (void)
 
    A NULL return means end of file.  */
 char *
-gdb_readline (char *prompt_arg)
+gdb_readline (const char *prompt_arg)
 {
   int c;
   char *result;
@@ -756,9 +763,14 @@ gdb_readline_wrapper_line (char *line)
 
   /* Prevent parts of the prompt from being redisplayed if annotations
      are enabled, and readline's state getting out of sync.  We'll
-     restore it in gdb_readline_wrapper_cleanup.  */
+     reinstall the callback handler, which puts the terminal in raw
+     mode (or in readline lingo, in prepped state), when we're next
+     ready to process user input, either in display_gdb_prompt, or if
+     we're handling an asynchronous target event and running in the
+     background, just before returning to the event loop to process
+     further input (or more target events).  */
   if (async_command_editing_p)
-    rl_callback_handler_remove ();
+    gdb_rl_callback_handler_remove ();
 }
 
 struct gdb_readline_wrapper_cleanup
@@ -780,10 +792,12 @@ gdb_readline_wrapper_cleanup (void *arg)
   gdb_assert (input_handler == gdb_readline_wrapper_line);
   input_handler = cleanup->handler_orig;
 
-  /* Reinstall INPUT_HANDLER in readline, without displaying a
-     prompt.  */
-  if (async_command_editing_p)
-    rl_callback_handler_install (NULL, input_handler);
+  /* Don't restore our input handler in readline yet.  That would make
+     readline prep the terminal (putting it in raw mode), while the
+     line we just read may trigger execution of a command that expects
+     the terminal in the default cooked/canonical mode, such as e.g.,
+     running Python's interactive online help utility.  See
+     gdb_readline_wrapper_line for when we'll reinstall it.  */
 
   gdb_readline_wrapper_result = NULL;
   gdb_readline_wrapper_done = 0;
@@ -798,7 +812,7 @@ gdb_readline_wrapper_cleanup (void *arg)
 }
 
 char *
-gdb_readline_wrapper (char *prompt)
+gdb_readline_wrapper (const char *prompt)
 {
   struct cleanup *back_to;
   struct gdb_readline_wrapper_cleanup *cleanup;
@@ -881,7 +895,74 @@ gdb_rl_operate_and_get_next (int count, int key)
 
   return rl_newline (1, key);
 }
-\f
+
+/* Number of user commands executed during this session.  */
+
+static int command_count = 0;
+
+/* Add the user command COMMAND to the input history list.  */
+
+void
+gdb_add_history (const char *command)
+{
+  add_history (command);
+  command_count++;
+}
+
+/* Safely append new history entries to the history file in a corruption-free
+   way using an intermediate local history file.  */
+
+static void
+gdb_safe_append_history (void)
+{
+  int ret, saved_errno;
+  char *local_history_filename;
+  struct cleanup *old_chain;
+
+  local_history_filename
+    = xstrprintf ("%s-gdb%d~", history_filename, getpid ());
+  old_chain = make_cleanup (xfree, local_history_filename);
+
+  ret = rename (history_filename, local_history_filename);
+  saved_errno = errno;
+  if (ret < 0 && saved_errno != ENOENT)
+    {
+      warning (_("Could not rename %s to %s: %s"),
+              history_filename, local_history_filename,
+              safe_strerror (saved_errno));
+    }
+  else
+    {
+      if (ret < 0)
+       {
+         /* If the rename failed with ENOENT then either the global history
+            file never existed in the first place or another GDB process is
+            currently appending to it (and has thus temporarily renamed it).
+            Since we can't distinguish between these two cases, we have to
+            conservatively assume the first case and therefore must write out
+            (not append) our known history to our local history file and try
+            to move it back anyway.  Otherwise a global history file would
+            never get created!  */
+          gdb_assert (saved_errno == ENOENT);
+          write_history (local_history_filename);
+       }
+      else
+       {
+         append_history (command_count, local_history_filename);
+         history_truncate_file (local_history_filename, history_max_entries);
+       }
+
+      ret = rename (local_history_filename, history_filename);
+      saved_errno = errno;
+      if (ret < 0 && saved_errno != EEXIST)
+        warning (_("Could not rename %s to %s: %s"),
+                local_history_filename, history_filename,
+                safe_strerror (saved_errno));
+    }
+
+  do_cleanups (old_chain);
+}
+
 /* Read one line from the command input stream `instream'
    into the local static buffer `linebuffer' (whose current length
    is `linelength').
@@ -898,14 +979,14 @@ gdb_rl_operate_and_get_next (int count, int key)
    simple input as the user has requested.  */
 
 char *
-command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
+command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix)
 {
   static char *linebuffer = 0;
   static unsigned linelength = 0;
+  const char *prompt = prompt_arg;
   char *p;
   char *p1;
   char *rl;
-  char *local_prompt = prompt_arg;
   char *nline;
   char got_eof = 0;
 
@@ -915,15 +996,19 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
 
   if (annotation_level > 1 && instream == stdin)
     {
-      local_prompt = alloca ((prompt_arg == NULL ? 0 : strlen (prompt_arg))
+      char *local_prompt;
+
+      local_prompt = alloca ((prompt == NULL ? 0 : strlen (prompt))
                             + strlen (annotation_suffix) + 40);
-      if (prompt_arg == NULL)
+      if (prompt == NULL)
        local_prompt[0] = '\0';
       else
-       strcpy (local_prompt, prompt_arg);
+       strcpy (local_prompt, prompt);
       strcat (local_prompt, "\n\032\032");
       strcat (local_prompt, annotation_suffix);
       strcat (local_prompt, "\n");
+
+      prompt = local_prompt;
     }
 
   if (linebuffer == 0)
@@ -965,15 +1050,15 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
       /* Don't use fancy stuff if not talking to stdin.  */
       if (deprecated_readline_hook && input_from_terminal_p ())
        {
-         rl = (*deprecated_readline_hook) (local_prompt);
+         rl = (*deprecated_readline_hook) (prompt);
        }
       else if (command_editing_p && input_from_terminal_p ())
        {
-         rl = gdb_readline_wrapper (local_prompt);
+         rl = gdb_readline_wrapper (prompt);
        }
       else
        {
-         rl = gdb_readline (local_prompt);
+         rl = gdb_readline (prompt);
        }
 
       if (annotation_level > 1 && instream == stdin)
@@ -1007,7 +1092,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
        break;
 
       p--;                     /* Put on top of '\'.  */
-      local_prompt = (char *) 0;
+      prompt = NULL;
     }
 
 #ifdef STOP_SIGNAL
@@ -1050,7 +1135,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
          if (expanded < 0)
            {
              xfree (history_value);
-             return command_line_input (prompt_arg, repeat,
+             return command_line_input (prompt, repeat,
                                         annotation_suffix);
            }
          if (strlen (history_value) > linelength)
@@ -1076,7 +1161,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
 
   /* Add line to history if appropriate.  */
   if (*linebuffer && input_from_terminal_p ())
-    add_history (linebuffer);
+    gdb_add_history (linebuffer);
 
   /* Save into global buffer if appropriate.  */
   if (repeat)
@@ -1106,7 +1191,7 @@ print_gdb_version (struct ui_file *stream)
   /* Second line is a copyright notice.  */
 
   fprintf_filtered (stream,
-                   "Copyright (C) 2014 Free Software Foundation, Inc.\n");
+                   "Copyright (C) 2015 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
@@ -1380,7 +1465,6 @@ quit_force (char *args, int from_tty)
 {
   int exit_code = 0;
   struct qt_args qt;
-  volatile struct gdb_exception ex;
 
   /* An optional expression may be used to cause gdb to terminate with the 
      value of that expression.  */
@@ -1396,47 +1480,55 @@ quit_force (char *args, int from_tty)
   qt.args = args;
   qt.from_tty = from_tty;
 
-  /* Wrappers to make the code below a bit more readable.  */
-#define DO_TRY \
-  TRY_CATCH (ex, RETURN_MASK_ALL)
-
-#define DO_PRINT_EX \
-  if (ex.reason < 0) \
-    exception_print (gdb_stderr, ex)
-
   /* We want to handle any quit errors and exit regardless.  */
 
   /* Get out of tfind mode, and kill or detach all inferiors.  */
-  DO_TRY
+  TRY
     {
       disconnect_tracing ();
       iterate_over_inferiors (kill_or_detach, &qt);
     }
-  DO_PRINT_EX;
+  CATCH (ex, RETURN_MASK_ALL)
+    {
+      exception_print (gdb_stderr, ex);
+    }
+  END_CATCH
 
   /* Give all pushed targets a chance to do minimal cleanup, and pop
      them all out.  */
-  DO_TRY
+  TRY
     {
       pop_all_targets ();
     }
-  DO_PRINT_EX;
+  CATCH (ex, RETURN_MASK_ALL)
+    {
+      exception_print (gdb_stderr, ex);
+    }
+  END_CATCH
 
   /* Save the history information if it is appropriate to do so.  */
-  DO_TRY
+  TRY
     {
       if (write_history_p && history_filename
          && input_from_terminal_p ())
-       write_history (history_filename);
+       gdb_safe_append_history ();
+    }
+  CATCH (ex, RETURN_MASK_ALL)
+    {
+      exception_print (gdb_stderr, ex);
     }
-  DO_PRINT_EX;
+  END_CATCH
 
   /* Do any final cleanups before exiting.  */
-  DO_TRY
+  TRY
     {
       do_final_cleanups (all_cleanups ());
     }
-  DO_PRINT_EX;
+  CATCH (ex, RETURN_MASK_ALL)
+    {
+      exception_print (gdb_stderr, ex);
+    }
+  END_CATCH
 
   exit (exit_code);
 }
@@ -1743,6 +1835,7 @@ init_main (void)
   rl_completion_entry_function = readline_line_completion_function;
   rl_completer_word_break_characters = default_word_break_characters ();
   rl_completer_quote_characters = get_gdb_completer_quote_characters ();
+  rl_completion_display_matches_hook = cli_display_match_list;
   rl_readline_name = "gdb";
   rl_terminal_name = getenv ("TERM");
 
@@ -1867,11 +1960,14 @@ gdb_init (char *argv0)
   initialize_inferiors ();
   initialize_current_architecture ();
   init_cli_cmds();
-  initialize_event_loop ();
   init_main ();                        /* But that omits this file!  Do it now.  */
 
   initialize_stdin_serial ();
 
+  /* Take a snapshot of our tty state before readline/ncurses have had a chance
+     to alter it.  */
+  set_initial_gdb_ttystate ();
+
   async_init_signals ();
 
   /* We need a default language for parsing expressions, so simple
This page took 0.030019 seconds and 4 git commands to generate.