From 8a076db965ba49f891b959752db7c8bb0c524688 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Fri, 14 Jan 2005 18:55:33 +0000 Subject: [PATCH] 2005-01-13 Andrew Cagney * 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. --- gdb/ChangeLog | 11 ++++++++ gdb/cli/cli-interp.c | 9 ++++-- gdb/exceptions.c | 80 +++++++++++++++++++++++++++++++++++++++++----------- gdb/exceptions.h | 9 ++++++ gdb/mi/mi-main.c | 1 + 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 + * 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 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) { -- 2.7.4