2005-02-08 Andrew Cagney <cagney@gnu.org>
authorAndrew Cagney <cagney@redhat.com>
Tue, 8 Feb 2005 23:44:06 +0000 (23:44 +0000)
committerAndrew Cagney <cagney@redhat.com>
Tue, 8 Feb 2005 23:44:06 +0000 (23:44 +0000)
* exceptions.c: Do not include <setjmp.h>.
(SIGJMP_BUF, SIGSETJMP, SIGLONGJMP): Delete macros.
(catch_exception, catch_exceptions_with_msg, catch_errors)
(catch_command_errors): Use TRY_CATCH.
(struct catcher): Use EXCEPTIONS_SIGJMP_BUF.
(exceptions_state_mc_init): Rename catcher_init.
(exceptions_state_mc): Rename catcher_state_machine.
(exceptions_state_mc_action_iter)
(exceptions_state_mc_action_iter_1): New functions.
* exceptions.h: Include <setjmp.h>.
(EXCEPTIONS_SIGJMP_BUF, EXCEPTIONS_SIGSETJMP)
(EXCEPTIONS_SIGLONGJMP): Define.
(exceptions_state_mc_init, exceptions_state_mc_action_iter)
(exceptions_state_mc_action_iter_1): Declare.
(TRY_CATCH): Define.

gdb/ChangeLog
gdb/exceptions.c
gdb/exceptions.h

index 637ac3e6a06906219a584bd761f7c0fb78f36624..0d49be8c870a61179e01e3cfa25bd409fe53bf27 100644 (file)
@@ -1,5 +1,21 @@
 2005-02-08  Andrew Cagney  <cagney@gnu.org>
 
+       * exceptions.c: Do not include <setjmp.h>.
+       (SIGJMP_BUF, SIGSETJMP, SIGLONGJMP): Delete macros.
+       (catch_exception, catch_exceptions_with_msg, catch_errors) 
+       (catch_command_errors): Use TRY_CATCH.
+       (struct catcher): Use EXCEPTIONS_SIGJMP_BUF.
+       (exceptions_state_mc_init): Rename catcher_init.
+       (exceptions_state_mc): Rename catcher_state_machine.
+       (exceptions_state_mc_action_iter)
+       (exceptions_state_mc_action_iter_1): New functions.
+       * exceptions.h: Include <setjmp.h>.
+       (EXCEPTIONS_SIGJMP_BUF, EXCEPTIONS_SIGSETJMP) 
+       (EXCEPTIONS_SIGLONGJMP): Define.
+       (exceptions_state_mc_init, exceptions_state_mc_action_iter)
+       (exceptions_state_mc_action_iter_1): Declare.
+       (TRY_CATCH): Define.
+
        * ppc-linux-tdep.c (ppc_linux_init_abi): Do not set malloc name,
        no longer needed.
 
index fae2372002edbb53eb2968430e0032ce3b870934..610f1682d6b0f4c9c52379ebb21fe600eb712106 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "defs.h"
 #include "exceptions.h"
-#include <setjmp.h>
 #include "breakpoint.h"
 #include "target.h"
 #include "inferior.h"
 
 const struct exception exception_none = { 0, NO_ERROR, NULL };
 
-/* One should use catch_errors rather than manipulating these
-   directly.  */
-#if defined(HAVE_SIGSETJMP)
-#define SIGJMP_BUF             sigjmp_buf
-#define SIGSETJMP(buf)         sigsetjmp((buf), 1)
-#define SIGLONGJMP(buf,val)    siglongjmp((buf), (val))
-#else
-#define SIGJMP_BUF             jmp_buf
-#define SIGSETJMP(buf)         setjmp(buf)
-#define SIGLONGJMP(buf,val)    longjmp((buf), (val))
-#endif
-
 /* Possible catcher states.  */
 enum catcher_state {
   /* Initial state, a new catcher has just been created.  */
@@ -69,7 +56,7 @@ struct catcher
 {
   enum catcher_state state;
   /* Jump buffer pointing back at the exception handler.  */
-  SIGJMP_BUF buf;
+  EXCEPTIONS_SIGJMP_BUF buf;
   /* Status buffer belonging to the exception handler.  */
   volatile struct exception *exception;
   /* Saved/current state.  */
@@ -83,10 +70,10 @@ struct catcher
 /* Where to go for throw_exception().  */
 static struct catcher *current_catcher;
 
-static SIGJMP_BUF *
-catcher_init (struct ui_out *func_uiout,
-             volatile struct exception *exception,
-             return_mask mask)
+EXCEPTIONS_SIGJMP_BUF *
+exceptions_state_mc_init (struct ui_out *func_uiout,
+                         volatile struct exception *exception,
+                         return_mask mask)
 {
   struct catcher *new_catcher = XZALLOC (struct catcher);
 
@@ -133,8 +120,8 @@ catcher_pop (void)
 /* Catcher state machine.  Returns non-zero if the m/c should be run
    again, zero if it should abort.  */
 
-int
-catcher_state_machine (enum catcher_action action)
+static int
+exceptions_state_mc (enum catcher_action action)
 {
   switch (current_catcher->state)
     {
@@ -210,6 +197,18 @@ catcher_state_machine (enum catcher_action action)
     }
 }
 
+int
+exceptions_state_mc_action_iter (void)
+{
+  return exceptions_state_mc (CATCH_ITER);
+}
+
+int
+exceptions_state_mc_action_iter_1 (void)
+{
+  return exceptions_state_mc (CATCH_ITER_1);
+}
+
 /* Return EXCEPTION to the nearest containing catch_errors().  */
 
 NORETURN void
@@ -232,9 +231,9 @@ throw_exception (struct exception exception)
   /* Jump to the containing catch_errors() call, communicating REASON
      to that call via setjmp's return value.  Note that REASON can't
      be zero, by definition in defs.h. */
-  catcher_state_machine (CATCH_THROWING);
+  exceptions_state_mc (CATCH_THROWING);
   *current_catcher->exception = exception;
-  SIGLONGJMP (current_catcher->buf, exception.reason);
+  EXCEPTIONS_SIGLONGJMP (current_catcher->buf, exception.reason);
 }
 
 static char *last_message;
@@ -465,11 +464,10 @@ catch_exception (struct ui_out *uiout,
                 return_mask mask)
 {
   volatile struct exception exception;
-  SIGJMP_BUF *catch;
-  catch = catcher_init (uiout, &exception, mask);
-  for (SIGSETJMP ((*catch));
-       catcher_state_machine (CATCH_ITER);)
-    (*func) (uiout, func_args);
+  TRY_CATCH (exception, mask)
+    {
+      (*func) (uiout, func_args);
+    }
   return exception;
 }
 
@@ -482,9 +480,10 @@ catch_exceptions_with_msg (struct ui_out *uiout,
 {
   volatile struct exception exception;
   volatile int val = 0;
-  SIGJMP_BUF *catch = catcher_init (uiout, &exception, mask);
-  for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
-    val = (*func) (uiout, func_args);
+  TRY_CATCH (exception, mask)
+    {
+      val = (*func) (uiout, func_args);
+    }
   print_any_exception (gdb_stderr, NULL, exception);
   gdb_assert (val >= 0);
   gdb_assert (exception.reason <= 0);
@@ -511,12 +510,10 @@ catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
 {
   volatile int val = 0;
   volatile struct exception exception;
-  SIGJMP_BUF *catch = catcher_init (uiout, &exception, mask);
-  /* This illustrates how it is possible to nest the mechanism and
-     hence catch "break".  Of course this doesn't address the need to
-     also catch "return".  */
-  for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
-    val = func (func_args);
+  TRY_CATCH (exception, mask)
+    {
+      val = func (func_args);
+    }
   print_any_exception (gdb_stderr, errstring, exception);
   if (exception.reason != 0)
     return 0;
@@ -528,9 +525,10 @@ catch_command_errors (catch_command_errors_ftype * command,
                      char *arg, int from_tty, return_mask mask)
 {
   volatile struct exception e;
-  SIGJMP_BUF *catch = catcher_init (uiout, &e, mask);
-  for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
-    command (arg, from_tty);
+  TRY_CATCH (e, mask)
+    {
+      command (arg, from_tty);
+    }
   print_any_exception (gdb_stderr, NULL, e);
   if (e.reason < 0)
     return 0;
index fe19ecdae80978a0cd95141822b59fc0606df4cd..a47742a384f1306003e27165f376e022f12e532e 100644 (file)
 #ifndef EXCEPTIONS_H
 #define EXCEPTIONS_H
 
+struct ui_out;
+
+#include <setjmp.h>
+
 /* Reasons for calling throw_exceptions().  NOTE: all reason values
    must be less than zero.  enum value 0 is reserved for internal use
    as the return value from an initial setjmp().  The function
@@ -66,6 +70,59 @@ struct exception
 /* A pre-defined non-exception.  */
 extern const struct exception exception_none;
 
+/* Wrap set/long jmp so that it's more portable (internal to
+   exceptions).  */
+
+#if defined(HAVE_SIGSETJMP)
+#define EXCEPTIONS_SIGJMP_BUF          sigjmp_buf
+#define EXCEPTIONS_SIGSETJMP(buf)      sigsetjmp((buf), 1)
+#define EXCEPTIONS_SIGLONGJMP(buf,val) siglongjmp((buf), (val))
+#else
+#define EXCEPTIONS_SIGJMP_BUF          jmp_buf
+#define EXCEPTIONS_SIGSETJMP(buf)      setjmp(buf)
+#define EXCEPTIONS_SIGLONGJMP(buf,val) longjmp((buf), (val))
+#endif
+
+/* Functions to drive the exceptions state m/c (internal to
+   exceptions).  */
+EXCEPTIONS_SIGJMP_BUF *exceptions_state_mc_init (struct ui_out *func_uiout,
+                                                volatile struct exception *
+                                                exception,
+                                                return_mask mask);
+int exceptions_state_mc_action_iter (void);
+int exceptions_state_mc_action_iter_1 (void);
+
+/* Macro to wrap up standard try/catch behavior.
+
+   The double loop lets us correctly handle code "break"ing out of the
+   try catch block.  (It works as the "break" only exits the inner
+   "while" loop, the outer for loop detects this handling it
+   correctly.)  Of course "return" and "goto" are not so lucky.
+
+   For instance:
+
+   *INDENT-OFF*
+
+   volatile struct exception e;
+   TRY_CATCH (e, RETURN_MASK_ERROR)
+     {
+     }
+   switch (e.reason)
+     {
+     case RETURN_ERROR: ...
+     }
+
+  */
+
+#define TRY_CATCH(EXCEPTION,MASK) \
+    for (EXCEPTIONS_SIGSETJMP \
+           (*exceptions_state_mc_init (uiout, &(EXCEPTION), (MASK))); \
+         exceptions_state_mc_action_iter (); ) \
+      while (exceptions_state_mc_action_iter_1 ())
+
+/* *INDENT-ON* */
+
+
 /* If E is an exception, print it's error message on the specified
    stream. for _fprintf, prefix the message with PREFIX...  */
 extern void exception_print (struct ui_file *file, struct exception e);