* defs.h (error_last_message, error_init): Delete declaration.
* utils.c (fatal, vfatal): Call throw_vfatal.
(error, verror): Call throw_verror;
(do_write, error_stream_1): Delete function.
(error_stream): Simplify, call error.
(error_last_message, error_init, gdb_lasterr): Delete.
(error_silent): Simplify, call throw_vsilent.
* mi/mi-interp.c (mi_cmd_interpreter_exec): Dup the message.
* main.c (captured_main): Delete call to error_init.
* exceptions.c (throw_verror, throw_verror)
(throw_vsilent): New functions.
(do_write, print_and_throw): New functions.
(last_message): New global.
(throw_reason): Replace error_last_message with last_message.
(catch_exceptions_with_msg): Dup the message.
* exceptions.h (throw_verror, throw_vfatal, throw_vsilent):
Declare.
+2005-01-13 Andrew Cagney <cagney@gnu.org>
+
+ * defs.h (error_last_message, error_init): Delete declaration.
+ * utils.c (fatal, vfatal): Call throw_vfatal.
+ (error, verror): Call throw_verror;
+ (do_write, error_stream_1): Delete function.
+ (error_stream): Simplify, call error.
+ (error_last_message, error_init, gdb_lasterr): Delete.
+ (error_silent): Simplify, call throw_vsilent.
+ * mi/mi-interp.c (mi_cmd_interpreter_exec): Dup the message.
+ * main.c (captured_main): Delete call to error_init.
+ * exceptions.c (throw_verror, throw_verror)
+ (throw_vsilent): New functions.
+ (do_write, print_and_throw): New functions.
+ (last_message): New global.
+ (throw_reason): Replace error_last_message with last_message.
+ (catch_exceptions_with_msg): Dup the message.
+ * exceptions.h (throw_verror, throw_vfatal, throw_vsilent):
+ Declare.
+
2005-01-13 Michael Snyder <msnyder@redhat.com>
* remote-st.c: Whitespace tweaks.
extern NORETURN void error_stream (struct ui_file *) ATTR_NORETURN;
-/* Initialize the error buffer. */
-extern void error_init (void);
-
-/* Returns a freshly allocate buffer containing the last error
- message. */
-extern char *error_last_message (void);
-
/* Output arbitrary error message. */
extern void error_output_message (char *pre_print, char *msg);
SIGLONGJMP (current_catcher->buf, exception.reason);
}
+static char *last_message;
+
NORETURN void
throw_reason (enum return_reason reason)
{
break;
case RETURN_ERROR:
exception.error = GENERIC_ERROR;
- exception.message = error_last_message ();
+ exception.message = last_message;
break;
default:
internal_error (__FILE__, __LINE__, "bad switch");
throw_exception (exception);
}
+static void
+do_write (void *data, const char *buffer, long length_buffer)
+{
+ ui_file_write (data, buffer, length_buffer);
+}
+
+
+NORETURN static void
+print_and_throw (enum return_reason reason, enum errors error,
+ const char *prefix, const char *fmt,
+ va_list ap) ATTR_NORETURN;
+NORETURN static void
+print_and_throw (enum return_reason reason, enum errors error,
+ const char *prefix, const char *fmt, va_list ap)
+{
+ /* FIXME: cagney/2005-01-13: While xstrvprintf is simpler it alters
+ GDB's output. Instead of the message being printed
+ line-at-a-time the message comes out all at once. The problem is
+ that the MI testsuite is checks for line-at-a-time messages and
+ changing this behavior means updating the testsuite. */
+
+ struct exception e;
+ struct ui_file *tmp_stream;
+ long len;
+
+ /* Convert the message into a print stream. */
+ tmp_stream = mem_fileopen ();
+ make_cleanup_ui_file_delete (tmp_stream);
+ vfprintf_unfiltered (tmp_stream, fmt, ap);
+
+ /* Save the message. */
+ xfree (last_message);
+ last_message = ui_file_xstrdup (tmp_stream, &len);
+
+ if (deprecated_error_begin_hook)
+ deprecated_error_begin_hook ();
+
+ /* Write the message plus any pre_print to gdb_stderr. */
+ target_terminal_ours ();
+ wrap_here (""); /* Force out any buffered output */
+ gdb_flush (gdb_stdout);
+ annotate_error_begin ();
+ if (error_pre_print)
+ fputs_filtered (error_pre_print, gdb_stderr);
+ ui_file_put (tmp_stream, do_write, gdb_stderr);
+ fprintf_filtered (gdb_stderr, "\n");
+
+ /* Throw the exception. */
+ e.reason = reason;
+ e.error = error;
+ e.message = last_message;
+ throw_exception (e);
+}
+
+NORETURN void
+throw_verror (enum errors error, const char *fmt, va_list ap)
+{
+ print_and_throw (RETURN_ERROR, error, error_pre_print, fmt, ap);
+}
+
+NORETURN void
+throw_vfatal (const char *fmt, va_list ap)
+{
+ print_and_throw (RETURN_QUIT, NO_ERROR, quit_pre_print, fmt, ap);
+}
+
+NORETURN void
+throw_vsilent (const char *fmt, va_list ap)
+{
+ struct exception e;
+ e.reason = RETURN_ERROR;
+ e.error = GENERIC_ERROR;
+ xfree (last_message);
+ last_message = xstrvprintf (fmt, ap);
+ e.message = last_message;
+ throw_exception (e);
+}
+
/* 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 throw_exception() or zero if the
one. This is used in the case of a silent error whereby the
caller may optionally want to issue the message. */
if (gdberrmsg != NULL)
- *gdberrmsg = exception.message;
+ {
+ if (exception.message != NULL)
+ *gdberrmsg = xstrdup (exception.message);
+ else
+ *gdberrmsg = NULL;
+ }
return exception.reason;
}
return val;
extern NORETURN void throw_exception (struct exception exception) ATTR_NORETURN;
extern NORETURN void throw_reason (enum return_reason reason) ATTR_NORETURN;
+extern NORETURN void throw_verror (enum errors, const char *fmt,
+ va_list ap) ATTR_NORETURN;
+extern NORETURN void throw_vfatal (const char *fmt, va_list ap) ATTR_NORETURN;
+extern NORETURN void throw_vsilent (const char *fmt, va_list ap) ATTR_NORETURN;
/* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception
gdb_stdtargerr = gdb_stderr; /* for moment */
gdb_stdtargin = gdb_stdin; /* for moment */
- /* initialize error() */
- error_init ();
-
/* Set the sysroot path. */
#ifdef TARGET_SYSTEM_ROOT_RELOCATABLE
gdb_sysroot = make_relative_prefix (argv[0], BINDIR, TARGET_SYSTEM_ROOT);
struct exception e = interp_exec (interp_to_use, argv[i]);
if (e.reason < 0)
{
- mi_error_message = e.message;
+ mi_error_message = xstrdup (e.message);
result = MI_CMD_ERROR;
break;
}
void (*deprecated_error_begin_hook) (void);
-/* Holds the last error message issued by gdb */
-
-static struct ui_file *gdb_lasterr;
-
/* Prototypes for local functions */
static void vfprintf_maybe_filtered (struct ui_file *, const char *,
static void set_screen_size (void);
static void set_width (void);
-static NORETURN void error_stream_1 (struct ui_file *stream,
- enum return_reason reason) ATTR_NORETURN;
-
/* Chain of cleanup actions established with make_cleanup,
to be executed if an error happens. */
NORETURN void
verror (const char *string, va_list args)
{
- struct ui_file *tmp_stream = mem_fileopen ();
- make_cleanup_ui_file_delete (tmp_stream);
- vfprintf_unfiltered (tmp_stream, string, args);
- error_stream_1 (tmp_stream, RETURN_ERROR);
+ throw_verror (GENERIC_ERROR, string, args);
}
NORETURN void
{
va_list args;
va_start (args, string);
- verror (string, args);
+ throw_verror (GENERIC_ERROR, string, args);
va_end (args);
}
NORETURN void
vfatal (const char *string, va_list args)
{
- struct ui_file *tmp_stream = mem_fileopen ();
- make_cleanup_ui_file_delete (tmp_stream);
- vfprintf_unfiltered (tmp_stream, string, args);
- error_stream_1 (tmp_stream, RETURN_QUIT);
+ throw_vfatal (string, args);
}
NORETURN void
{
va_list args;
va_start (args, string);
- vfatal (string, args);
+ throw_vfatal (string, args);
va_end (args);
}
-static void
-do_write (void *data, const char *buffer, long length_buffer)
-{
- ui_file_write (data, buffer, length_buffer);
-}
-
/* Cause a silent error to occur. Any error message is recorded
though it is not issued. */
NORETURN void
error_silent (const char *string, ...)
{
va_list args;
- struct ui_file *tmp_stream = mem_fileopen ();
va_start (args, string);
- make_cleanup_ui_file_delete (tmp_stream);
- vfprintf_unfiltered (tmp_stream, string, args);
- /* Copy the stream into the GDB_LASTERR buffer. */
- ui_file_rewind (gdb_lasterr);
- ui_file_put (tmp_stream, do_write, gdb_lasterr);
+ throw_vsilent (string, args);
va_end (args);
-
- throw_reason (RETURN_ERROR);
}
/* Output an error message including any pre-print text to gdb_stderr. */
fprintf_filtered (gdb_stderr, "\n");
}
-static NORETURN void
-error_stream_1 (struct ui_file *stream, enum return_reason reason)
-{
- if (deprecated_error_begin_hook)
- deprecated_error_begin_hook ();
-
- /* Copy the stream into the GDB_LASTERR buffer. */
- ui_file_rewind (gdb_lasterr);
- ui_file_put (stream, do_write, gdb_lasterr);
-
- /* Write the message plus any error_pre_print to gdb_stderr. */
- target_terminal_ours ();
- wrap_here (""); /* Force out any buffered output */
- gdb_flush (gdb_stdout);
- annotate_error_begin ();
- if (error_pre_print)
- fputs_filtered (error_pre_print, gdb_stderr);
- ui_file_put (stream, do_write, gdb_stderr);
- fprintf_filtered (gdb_stderr, "\n");
-
- throw_reason (reason);
-}
-
NORETURN void
error_stream (struct ui_file *stream)
{
- error_stream_1 (stream, RETURN_ERROR);
-}
-
-/* Get the last error message issued by gdb */
-
-char *
-error_last_message (void)
-{
long len;
- return ui_file_xstrdup (gdb_lasterr, &len);
-}
-
-/* This is to be called by main() at the very beginning */
-
-void
-error_init (void)
-{
- gdb_lasterr = mem_fileopen ();
+ char *message = ui_file_xstrdup (stream, &len);
+ make_cleanup (xfree, message);
+ error ("%s", message);
}
/* Print a message reporting an internal error/warning. Ask the user