From 99bbb428d4412b79e59df321f9e83c13342e4612 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Tue, 12 Apr 2016 16:49:31 +0100 Subject: [PATCH] ada-lang.c: Introduce type_as_string and use it A couple wrong things here - We should not use target_terminal_ours when all we want is output. We should use target_terminal_ours_for_output instead, which preserves raw/cooked terminal modes, and SIGINT forwarding. - Most importantly, relying on stderr output immediately preceding the error/exception print isn't correct. The exception could be caught and handled, for example; MI frontends won't display the stderr part in an error dialog box. Etc. This commit introduces a type_as_string helper that allows building a full error string including type info. gdb/ChangeLog: 2016-04-12 Pedro Alves * ada-lang.c (type_as_string, type_as_string_and_cleanup): New functions. (ada_lookup_struct_elt_type): Use type_as_string_and_cleanup. --- gdb/ChangeLog | 6 ++++ gdb/ada-lang.c | 74 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 50 insertions(+), 30 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8fa4b02bfc..8fd8ea825e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2016-04-12 Pedro Alves + + * ada-lang.c (type_as_string, type_as_string_and_cleanup): New + functions. + (ada_lookup_struct_elt_type): Use type_as_string_and_cleanup. + 2016-04-12 Pedro Alves * ser-base.c (fd_event): Retry read_prim on EINTR. diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index d87412951e..7cdb693852 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -7576,6 +7576,39 @@ ada_value_struct_elt (struct value *arg, char *name, int no_err) "a value that is not a record.")); } +/* Return a string representation of type TYPE. Caller must free + result. */ + +static char * +type_as_string (struct type *type) +{ + struct ui_file *tmp_stream = mem_fileopen (); + struct cleanup *old_chain; + char *str; + + tmp_stream = mem_fileopen (); + old_chain = make_cleanup_ui_file_delete (tmp_stream); + + type_print (type, "", tmp_stream, -1); + str = ui_file_xstrdup (tmp_stream, NULL); + + do_cleanups (old_chain); + return str; +} + +/* Return a string representation of type TYPE, and install a cleanup + that releases it. */ + +static char * +type_as_string_and_cleanup (struct type *type) +{ + char *str; + + str = type_as_string (type); + make_cleanup (xfree, str); + return str; +} + /* Given a type TYPE, look up the type of the component of type named NAME. If DISPP is non-null, add its byte displacement from the beginning of a structure (pointed to by a value) of type TYPE to *DISPP (does not @@ -7616,22 +7649,15 @@ ada_lookup_struct_elt_type (struct type *type, char *name, int refok, || (TYPE_CODE (type) != TYPE_CODE_STRUCT && TYPE_CODE (type) != TYPE_CODE_UNION)) { + char *type_str; + if (noerr) return NULL; - else - { - target_terminal_ours (); - gdb_flush (gdb_stdout); - if (type == NULL) - error (_("Type (null) is not a structure or union type")); - else - { - /* XXX: type_sprint */ - fprintf_unfiltered (gdb_stderr, _("Type ")); - type_print (type, "", gdb_stderr, -1); - error (_(" is not a structure or union type")); - } - } + + type_str = (type != NULL + ? type_as_string_and_cleanup (type) + : _("(null)")); + error (_("Type %s is not a structure or union type"), type_str); } type = to_static_fixed_type (type); @@ -7701,22 +7727,10 @@ ada_lookup_struct_elt_type (struct type *type, char *name, int refok, BadName: if (!noerr) { - target_terminal_ours (); - gdb_flush (gdb_stdout); - if (name == NULL) - { - /* XXX: type_sprint */ - fprintf_unfiltered (gdb_stderr, _("Type ")); - type_print (type, "", gdb_stderr, -1); - error (_(" has no component named ")); - } - else - { - /* XXX: type_sprint */ - fprintf_unfiltered (gdb_stderr, _("Type ")); - type_print (type, "", gdb_stderr, -1); - error (_(" has no component named %s"), name); - } + char *name_str = name != NULL ? name : _(""); + + error (_("Type %s has no component named %s"), + type_as_string_and_cleanup (type), name_str); } return NULL;