-/* A stack of exception messages.
- This is needed to handle nested calls to throw_it: we don't want to
- xfree space for a message before it's used.
- This can happen if we throw an exception during a cleanup:
- An outer TRY_CATCH may have an exception message it wants to print,
- but while doing cleanups further calls to throw_it are made.
-
- This is indexed by the size of the current_catcher list.
- It is a dynamically allocated array so that we don't care how deeply
- GDB nests its TRY_CATCHs. */
-static char **exception_messages;
-
-/* The number of currently allocated entries in exception_messages. */
-static int exception_messages_size;
-
-static void ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0)
-throw_it (enum return_reason reason, enum errors error, const char *fmt,
- va_list ap)
-{
- struct gdb_exception e;
- char *new_message;
- int depth = catcher_list_size ();
-
- gdb_assert (depth > 0);
-
- /* Note: The new message may use an old message's text. */
- new_message = xstrvprintf (fmt, ap);
-
- if (depth > exception_messages_size)
- {
- int old_size = exception_messages_size;
-
- exception_messages_size = depth + 10;
- exception_messages = (char **) xrealloc (exception_messages,
- exception_messages_size
- * sizeof (char *));
- memset (exception_messages + old_size, 0,
- (exception_messages_size - old_size) * sizeof (char *));
- }
-
- xfree (exception_messages[depth - 1]);
- exception_messages[depth - 1] = new_message;
-
- /* Create the exception. */
- e.reason = reason;
- e.error = error;
- e.message = new_message;
-
- /* Throw the exception. */
- throw_exception (e);
-}
-
-void
-throw_verror (enum errors error, const char *fmt, va_list ap)
-{
- throw_it (RETURN_ERROR, error, fmt, ap);
-}
-
-void
-throw_vquit (const char *fmt, va_list ap)
-{
- throw_it (RETURN_QUIT, GDB_NO_ERROR, fmt, ap);
-}
-
-void
-throw_error (enum errors error, const char *fmt, ...)
-{
- va_list args;
-
- va_start (args, fmt);
- throw_verror (error, fmt, args);
- va_end (args);
-}
-
-void
-throw_quit (const char *fmt, ...)
-{
- va_list args;
-
- va_start (args, fmt);
- throw_vquit (fmt, args);
- va_end (args);
-}
-
-/* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception
- handler. If an exception (enum return_reason) is thrown using
- throw_exception() than all cleanups installed since
- catch_exceptions() was entered are invoked, the (-ve) exception
- value is then returned by catch_exceptions. If FUNC() returns
- normally (with a positive or zero return value) then that value is
- returned by catch_exceptions(). It is an internal_error() for
- FUNC() to return a negative value.
-
- See exceptions.h for further usage details.
-
- 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).
- This is an OK restriction; with very few exceptions immediate_quit can
- be replaced by judicious use of QUIT. */
-
-/* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
- error() et al. could maintain a set of flags that indicate the
- current state of each of the longjmp buffers. This would give the
- longjmp code the chance to detect a longjmp botch (before it gets
- to longjmperror()). Prior to 1999-11-05 this wasn't possible as
- code also randomly used a SET_TOP_LEVEL macro that directly
- initialized the longjmp buffers. */
-
-int
-catch_exceptions (struct ui_out *uiout,
- catch_exceptions_ftype *func,
- void *func_args,
- return_mask mask)
-{
- return catch_exceptions_with_msg (uiout, func, func_args, NULL, mask);
-}
-
-int
-catch_exceptions_with_msg (struct ui_out *func_uiout,
- catch_exceptions_ftype *func,
- void *func_args,
- char **gdberrmsg,
- return_mask mask)
-{
- volatile struct gdb_exception exception;
- volatile int val = 0;
- struct ui_out *saved_uiout;
-
- /* Save and override the global ``struct ui_out'' builder. */
- saved_uiout = current_uiout;
- current_uiout = func_uiout;
-
- TRY_CATCH (exception, RETURN_MASK_ALL)
- {
- val = (*func) (current_uiout, func_args);
- }
-
- /* Restore the global builder. */
- current_uiout = saved_uiout;
-
- if (exception.reason < 0 && (mask & RETURN_MASK (exception.reason)) == 0)
- {
- /* The caller didn't request that the event be caught.
- Rethrow. */
- throw_exception (exception);
- }
-
- exception_print (gdb_stderr, exception);
- gdb_assert (val >= 0);
- gdb_assert (exception.reason <= 0);
- if (exception.reason < 0)
- {
- /* If caller wants a copy of the low-level error message, make
- one. This is used in the case of a silent error whereby the
- caller may optionally want to issue the message. */
- if (gdberrmsg != NULL)
- {
- if (exception.message != NULL)
- *gdberrmsg = xstrdup (exception.message);
- else
- *gdberrmsg = NULL;
- }
- return exception.reason;
- }
- return val;
-}
-
-/* This function is superseded by catch_exceptions(). */