aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/cli/cli-interp.c9
-rw-r--r--gdb/exceptions.c80
-rw-r--r--gdb/exceptions.h9
-rw-r--r--gdb/mi/mi-main.c1
5 files changed, 91 insertions, 19 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b77c67f..b0a3a4e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,16 @@
2005-01-14 Andrew Cagney <cagney@gnu.org>
+ * mi/mi-main.c (mi_execute_command): Print the exception.
+ * cli/cli-interp.c (safe_execute_command): Print the exception.
+ * exceptions.h (exception_print): Declare.
+ * exceptions.c (struct catcher): Add field print_message.
+ (catcher_init): Add parameter print_message, store in the catcher
+ struct.
+ (print_and_throw): Only print the message when print_message.
+ (catch_exceptions_with_msg, catch_errors): Pass print_message=1 to
+ catcher_init.
+ (catch_exception): Pass print_message=0 to catcher_init.
+
* varobj.c (varobj_create): Add missing \n.
2005-01-13 Michael Snyder <msnyder@redhat.com>
diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index cb447e3..ac905b2 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -125,11 +125,16 @@ do_captured_execute_command (struct ui_out *uiout, void *data)
static struct exception
safe_execute_command (struct ui_out *uiout, char *command, int from_tty)
{
+ struct exception e;
struct captured_execute_command_args args;
args.command = command;
args.from_tty = from_tty;
- return catch_exception (uiout, do_captured_execute_command, &args,
- RETURN_MASK_ALL);
+ e = catch_exception (uiout, do_captured_execute_command, &args,
+ RETURN_MASK_ALL);
+ /* FIXME: cagney/2005-01-13: This shouldn't be needed. Instead the
+ caller should print the exception. */
+ exception_print (gdb_stderr, NULL, e);
+ return e;
}
diff --git a/gdb/exceptions.c b/gdb/exceptions.c
index dab5d9b..781864b 100644
--- a/gdb/exceptions.c
+++ b/gdb/exceptions.c
@@ -69,8 +69,13 @@ struct catcher
enum catcher_state state;
/* Jump buffer pointing back at the exception handler. */
SIGJMP_BUF buf;
- /* Status buffer belonging to that exception handler. */
+ /* Status buffer belonging to the exception handler. */
volatile struct exception *exception;
+ /* Should the error / quit message be printed? Old code assumes
+ that this file prints the error/quit message when first reported.
+ New code instead directly handles the printing of error/quit
+ messages. */
+ int print_message;
/* Saved/current state. */
int mask;
char *saved_error_pre_print;
@@ -88,7 +93,8 @@ static SIGJMP_BUF *
catcher_init (struct ui_out *func_uiout,
char *errstring,
volatile struct exception *exception,
- return_mask mask)
+ return_mask mask,
+ int print_message)
{
struct catcher *new_catcher = XZALLOC (struct catcher);
@@ -99,6 +105,7 @@ catcher_init (struct ui_out *func_uiout,
new_catcher->exception = exception;
new_catcher->mask = mask;
+ new_catcher->print_message = print_message;
/* Override error/quit messages during FUNC. */
new_catcher->saved_error_pre_print = error_pre_print;
@@ -295,6 +302,40 @@ do_write (void *data, const char *buffer, long length_buffer)
}
+void
+exception_print (struct ui_file *file, const char *pre_print,
+ struct exception e)
+{
+ if (e.reason < 0 && e.message != NULL)
+ {
+ target_terminal_ours ();
+ wrap_here (""); /* Force out any buffered output */
+ gdb_flush (file);
+ annotate_error_begin ();
+ if (pre_print)
+ fputs_filtered (pre_print, file);
+
+ /* KLUGE: cagney/2005-01-13: Write the string out one line at a
+ time as that way the MI's behavior is preserved. */
+ {
+ const char *start;
+ const char *end;
+ for (start = e.message; start != NULL; start = end)
+ {
+ end = strchr (start, '\n');
+ if (end == NULL)
+ fputs_filtered (start, file);
+ else
+ {
+ end++;
+ ui_file_write (file, start, end - start);
+ }
+ }
+ }
+ fprintf_filtered (file, "\n");
+ }
+}
+
NORETURN static void
print_and_throw (enum return_reason reason, enum errors error,
const char *prefix, const char *fmt,
@@ -322,18 +363,23 @@ print_and_throw (enum return_reason reason, enum errors error,
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");
+ /* Print the mesage to stderr, but only if the catcher isn't going
+ to handle/print it locally. */
+ if (current_catcher->print_message)
+ {
+ 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;
@@ -417,7 +463,7 @@ catch_exception (struct ui_out *uiout,
{
volatile struct exception exception;
SIGJMP_BUF *catch;
- catch = catcher_init (uiout, NULL, &exception, mask);
+ catch = catcher_init (uiout, NULL, &exception, mask, 0);
for (SIGSETJMP ((*catch));
catcher_state_machine (CATCH_ITER);)
(*func) (uiout, func_args);
@@ -434,7 +480,7 @@ catch_exceptions_with_msg (struct ui_out *uiout,
{
volatile struct exception exception;
volatile int val = 0;
- SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask);
+ SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask, 1);
for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
val = (*func) (uiout, func_args);
gdb_assert (val >= 0);
@@ -462,7 +508,7 @@ 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, errstring, &exception, mask);
+ SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask, 1);
/* 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". */
diff --git a/gdb/exceptions.h b/gdb/exceptions.h
index e062b18..919738a 100644
--- a/gdb/exceptions.h
+++ b/gdb/exceptions.h
@@ -65,6 +65,11 @@ struct exception
/* A pre-defined non-exception. */
extern const struct exception exception_none;
+/* If E is an exception, print it's error message on the specified
+ stream. */
+extern void exception_print (struct ui_file *file, const char *pre_print,
+ struct exception e);
+
/* Throw an exception (as described by "struct exception"). Will
execute a LONG JUMP to the inner most containing exception handler
established using catch_exceptions() (or similar).
@@ -121,6 +126,10 @@ extern int catch_exceptions_with_msg (struct ui_out *uiout,
void *func_args,
char *errstring, char **gdberrmsg,
return_mask mask);
+
+/* This function, in addition, suppresses the printing of the captured
+ error message. It's up to the client to print it. */
+
extern struct exception catch_exception (struct ui_out *uiout,
catch_exception_ftype *func,
void *func_args,
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 7df1569..bd45cd5 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -1156,6 +1156,7 @@ mi_execute_command (char *cmd, int from_tty)
args.command = command;
result = catch_exception (uiout, captured_mi_execute_command, &args,
RETURN_MASK_ALL);
+ exception_print (gdb_stderr, NULL, result);
if (args.action == EXECUTE_COMMAND_SUPRESS_PROMPT)
{