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:
Andrew Cagney 2005-02-08 23:44:06 +00:00
parent c36e61546a
commit 6941d02a18
3 changed files with 110 additions and 39 deletions

View 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.

View File

@ -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;

View File

@ -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);