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.
This commit is contained in:
parent
c36e61546a
commit
6941d02a18
3 changed files with 110 additions and 39 deletions
|
@ -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.
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#include "defs.h"
|
||||
#include "exceptions.h"
|
||||
#include <setjmp.h>
|
||||
#include "breakpoint.h"
|
||||
#include "target.h"
|
||||
#include "inferior.h"
|
||||
|
@ -35,18 +34,6 @@
|
|||
|
||||
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;
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
#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);
|
||||
|
|
Loading…
Reference in a new issue