Whoops, forgot to commit this yesterday:
[deliverable/binutils-gdb.git] / gdb / top.c
index 5d644dc00b4e4fc44b8f17dfa1223c0e63572004..3798a3b7ce909028a8c8c02c8b1f013c65f2925b 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -41,6 +41,7 @@
 #include "version.h"
 #include "serial.h"
 #include "doublest.h"
+#include "gdb_assert.h"
 
 /* readline include files */
 #include <readline/readline.h>
@@ -334,10 +335,11 @@ return_to_top_level (enum return_reason reason)
   (NORETURN void) SIGLONGJMP (*catch_return, (int) reason);
 }
 
-/* Call FUNC with arg ARGS, catching any errors.  If there is no
-   error, return the value returned by FUNC.  If there is an error,
-   print ERRSTRING, print the specific error message, then return
-   zero.
+/* Call FUNC() with args FUNC_UIOUT and FUNC_ARGS, catching any
+   errors.  Set FUNC_CAUGHT to an ``enum return_reason'' if the
+   function is aborted (using return_to_top_level() or zero if the
+   function returns normally.  Set FUNC_VAL to the value returned by
+   the function or 0 if the function was aborted.
 
    Must not be called with immediate_quit in effect (bad things might
    happen, say we got a signal in the middle of a memcpy to quit_return).
@@ -365,21 +367,30 @@ return_to_top_level (enum return_reason reason)
    be consolidated into a single file instead of being distributed
    between utils.c and top.c? */
 
-int
-catch_errors (catch_errors_ftype *func, void * args, char *errstring,
-             return_mask mask)
+static void
+catcher (catch_exceptions_ftype *func,
+        struct ui_out *func_uiout,
+        void *func_args,
+        int *func_val,
+        enum return_reason *func_caught,
+        char *errstring,
+        return_mask mask)
 {
   SIGJMP_BUF *saved_catch;
   SIGJMP_BUF catch;
-  int val;
   struct cleanup *saved_cleanup_chain;
   char *saved_error_pre_print;
   char *saved_quit_pre_print;
+  struct ui_out *saved_uiout;
 
   /* Return value from SIGSETJMP(): enum return_reason if error or
      quit caught, 0 otherwise. */
   int caught;
 
+  /* Return value from FUNC(): Hopefully non-zero. Explicitly set to
+     zero if an error quit was caught.  */
+  int val;
+
   /* Override error/quit messages during FUNC. */
 
   saved_error_pre_print = error_pre_print;
@@ -390,6 +401,11 @@ catch_errors (catch_errors_ftype *func, void * args, char *errstring,
   if (mask & RETURN_MASK_QUIT)
     quit_pre_print = errstring;
 
+  /* Override the global ``struct ui_out'' builder.  */
+
+  saved_uiout = uiout;
+  uiout = func_uiout;
+
   /* Prevent error/quit during FUNC from calling cleanups established
      prior to here. */
 
@@ -401,7 +417,7 @@ catch_errors (catch_errors_ftype *func, void * args, char *errstring,
   catch_return = &catch;
   caught = SIGSETJMP (catch);
   if (!caught)
-    val = (*func) (args);
+    val = (*func) (func_uiout, func_args);
   else
     val = 0;
   catch_return = saved_catch;
@@ -413,47 +429,78 @@ catch_errors (catch_errors_ftype *func, void * args, char *errstring,
      do_cleanups call (to cover the problem) or an assertion check to
      detect bad FUNCs code. */
 
-  /* Restore the cleanup chain and error/quit messages to their
-     original states. */
+  /* Restore the cleanup chain, the error/quit messages, and the uiout
+     builder, to their original states. */
 
   restore_cleanups (saved_cleanup_chain);
 
+  uiout = saved_uiout;
+
   if (mask & RETURN_MASK_QUIT)
     quit_pre_print = saved_quit_pre_print;
   if (mask & RETURN_MASK_ERROR)
     error_pre_print = saved_error_pre_print;
 
-  /* Return normally if no error/quit event occurred. */
+  /* Return normally if no error/quit event occurred or this catcher
+     can handle this exception.  The caller analyses the func return
+     values.  */
 
-  if (!caught)
-    return val;
+  if (!caught || (mask & RETURN_MASK (caught)))
+    {
+      *func_val = val;
+      *func_caught = caught;
+      return;
+    }
 
-  /* If the caller didn't request that the event be caught, relay the
+  /* The caller didn't request that the event be caught, relay the
      event to the next containing catch_errors(). */
 
-  if (!(mask & RETURN_MASK (caught)))
-    return_to_top_level (caught);
-
-  /* Tell the caller that an event was caught.
-
-     FIXME: nsd/2000-02-22: When MASK is RETURN_MASK_ALL, the caller
-     can't tell what type of event occurred.
+  return_to_top_level (caught);
+}
 
-     A possible fix is to add a new interface, catch_event(), that
-     returns enum return_reason after catching an error or a quit.
+int
+catch_exceptions (struct ui_out *uiout,
+                 catch_exceptions_ftype *func,
+                 void *func_args,
+                 char *errstring,
+                 return_mask mask)
+{
+  int val;
+  enum return_reason caught;
+  catcher (func, uiout, func_args, &val, &caught, errstring, mask);
+  gdb_assert (val >= 0);
+  gdb_assert (caught <= 0);
+  if (caught < 0)
+    return caught;
+  return val;
+}
 
-     When returning normally, i.e. without catching an error or a
-     quit, catch_event() could return RETURN_NORMAL, which would be
-     added to enum return_reason.  FUNC would return information
-     exclusively via ARGS.
+struct catch_errors_args
+{
+  catch_errors_ftype *func;
+  void *func_args;
+};
 
-     Alternatively, normal catch_event() could return FUNC's return
-     value.  The caller would need to be aware of potential overlap
-     with enum return_reason, which could be publicly restricted to
-     negative values to simplify return value processing in FUNC and
-     in the caller. */
+int
+do_catch_errors (struct ui_out *uiout, void *data)
+{
+  struct catch_errors_args *args = data;
+  return args->func (args->func_args);
+}
 
-  return 0;
+int
+catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
+             return_mask mask)
+{
+  int val;
+  enum return_reason caught;
+  struct catch_errors_args args;
+  args.func = func;
+  args.func_args = func_args;
+  catcher (do_catch_errors, uiout, &args, &val, &caught, errstring, mask);
+  if (caught != 0)
+    return 0;
+  return val;
 }
 
 struct captured_command_args
@@ -1225,12 +1272,7 @@ print_gdb_version (struct ui_file *stream)
      program to parse, and is just canonical program name and version
      number, which starts after last space. */
 
-#ifdef MI_OUT
-  /* Print it console style until a format is defined */
-  fprintf_filtered (stream, "GNU gdb %s (MI_OUT)\n", version);
-#else
   fprintf_filtered (stream, "GNU gdb %s\n", version);
-#endif
 
   /* Second line is a copyright notice. */
 
@@ -1389,7 +1431,7 @@ get_prompt_1 (void *data)
                  break;
                case TYPE_CODE_PTR:
                  elt_type = check_typedef (TYPE_TARGET_TYPE (arg_type));
-                 addrval = value_as_pointer (arg_val);
+                 addrval = value_as_address (arg_val);
 
                  if (TYPE_LENGTH (elt_type) == 1 &&
                      TYPE_CODE (elt_type) == TYPE_CODE_INT &&
This page took 0.02582 seconds and 4 git commands to generate.