Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Unified Diff: gdb/printcmd.c

Issue 11969036: Merge GDB 7.5.1 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@master
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gdb/ppcobsd-tdep.c ('k') | gdb/probe.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gdb/printcmd.c
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index bee8a85090439e9738d78e5db98a49cac24e6d17..d5b5b63122a7d99f7c53e8cf187544eb3927aee0 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -49,18 +49,12 @@
#include "charset.h"
#include "arch-utils.h"
#include "cli/cli-utils.h"
+#include "format.h"
#ifdef TUI
#include "tui/tui.h" /* For tui_active et al. */
#endif
-#if defined(__MINGW32__) && !defined(PRINTF_HAS_LONG_LONG)
-# define USE_PRINTF_I64 1
-# define PRINTF_HAS_LONG_LONG
-#else
-# define USE_PRINTF_I64 0
-#endif
-
struct format_data
{
int count;
@@ -568,9 +562,10 @@ set_next_address (struct gdbarch *gdbarch, CORE_ADDR addr)
DO_DEMANGLE controls whether to print a symbol in its native "raw" form,
or to interpret it as a possible C++ name and convert it back to source
form. However note that DO_DEMANGLE can be overridden by the specific
- settings of the demangle and asm_demangle variables. */
+ settings of the demangle and asm_demangle variables. Returns
+ non-zero if anything was printed; zero otherwise. */
-void
+int
print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
struct ui_file *stream,
int do_demangle, char *leadin)
@@ -589,7 +584,7 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
&filename, &line, &unmapped))
{
do_cleanups (cleanup_chain);
- return;
+ return 0;
}
fputs_filtered (leadin, stream);
@@ -616,6 +611,7 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
fputs_filtered (">", stream);
do_cleanups (cleanup_chain);
+ return 1;
}
/* Given an address ADDR return all the elements needed to print the
@@ -638,7 +634,7 @@ build_address_symbolic (struct gdbarch *gdbarch,
struct symbol *symbol;
CORE_ADDR name_location = 0;
struct obj_section *section = NULL;
- char *name_temp = "";
+ const char *name_temp = "";
/* Let's say it is mapped (not unmapped). */
*unmapped = 0;
@@ -683,6 +679,13 @@ build_address_symbolic (struct gdbarch *gdbarch,
name_temp = SYMBOL_LINKAGE_NAME (symbol);
}
+ if (msymbol != NULL
+ && MSYMBOL_SIZE (msymbol) == 0
+ && MSYMBOL_TYPE (msymbol) != mst_text
+ && MSYMBOL_TYPE (msymbol) != mst_text_gnu_ifunc
+ && MSYMBOL_TYPE (msymbol) != mst_file_text)
+ msymbol = NULL;
+
if (msymbol != NULL)
{
if (SYMBOL_VALUE_ADDRESS (msymbol) > name_location || symbol == NULL)
@@ -763,29 +766,23 @@ pc_prefix (CORE_ADDR addr)
/* Print address ADDR symbolically on STREAM. Parameter DEMANGLE
controls whether to print the symbolic name "raw" or demangled.
- Global setting "addressprint" controls whether to print hex address
- or not. */
+ Return non-zero if anything was printed; zero otherwise. */
-void
-print_address_demangle (struct gdbarch *gdbarch, CORE_ADDR addr,
+int
+print_address_demangle (const struct value_print_options *opts,
+ struct gdbarch *gdbarch, CORE_ADDR addr,
struct ui_file *stream, int do_demangle)
{
- struct value_print_options opts;
-
- get_user_print_options (&opts);
- if (addr == 0)
- {
- fprintf_filtered (stream, "0");
- }
- else if (opts.addressprint)
+ if (opts->addressprint)
{
fputs_filtered (paddress (gdbarch, addr), stream);
print_address_symbolic (gdbarch, addr, stream, do_demangle, " ");
}
else
{
- print_address_symbolic (gdbarch, addr, stream, do_demangle, "");
+ return print_address_symbolic (gdbarch, addr, stream, do_demangle, "");
}
+ return 1;
}
@@ -1080,6 +1077,22 @@ set_command (char *exp, int from_tty)
struct cleanup *old_chain =
make_cleanup (free_current_contents, &expr);
+ if (expr->nelts >= 1)
+ switch (expr->elts[0].opcode)
+ {
+ case UNOP_PREINCREMENT:
+ case UNOP_POSTINCREMENT:
+ case UNOP_PREDECREMENT:
+ case UNOP_POSTDECREMENT:
+ case BINOP_ASSIGN:
+ case BINOP_ASSIGN_MODIFY:
+ case BINOP_COMMA:
+ break;
+ default:
+ warning
+ (_("Expression is not an assignment (and might have no effect)"));
+ }
+
evaluate_expression (expr);
do_cleanups (old_chain);
}
@@ -1594,7 +1607,6 @@ map_display_numbers (char *args,
void *data)
{
struct get_number_or_range_state state;
- struct display *b, *tmp;
int num;
if (args == NULL)
@@ -1637,9 +1649,6 @@ do_delete_display (struct display *d, void *data)
static void
undisplay_command (char *args, int from_tty)
{
- int num;
- struct get_number_or_range_state state;
-
if (args == NULL)
{
if (query (_("Delete all auto-display expressions? ")))
@@ -1952,7 +1961,9 @@ clear_dangling_display_expressions (struct so_list *solib)
struct symbol. NAME is the name to print; if NULL then VAR's print
name will be used. STREAM is the ui_file on which to print the
value. INDENT specifies the number of indent levels to print
- before printing the variable name. */
+ before printing the variable name.
+
+ This function invalidates FRAME. */
void
print_variable_and_value (const char *name, struct symbol *var,
@@ -1974,6 +1985,10 @@ print_variable_and_value (const char *name, struct symbol *var,
get_user_print_options (&opts);
opts.deref_ref = 1;
common_val_print (val, stream, indent, &opts, current_language);
+
+ /* common_val_print invalidates FRAME when a pretty printer calls inferior
+ function. */
+ frame = NULL;
}
if (except.reason < 0)
fprintf_filtered(stream, "<error reading variable %s (%s)>", name,
@@ -1986,13 +2001,9 @@ print_variable_and_value (const char *name, struct symbol *var,
static void
ui_printf (char *arg, struct ui_file *stream)
{
- char *f = NULL;
+ struct format_piece *fpieces;
char *s = arg;
- char *string = NULL;
struct value **val_args;
- char *substrings;
- char *current_substring;
- int nargs = 0;
int allocated_args = 20;
struct cleanup *old_cleanups;
@@ -2008,64 +2019,13 @@ ui_printf (char *arg, struct ui_file *stream)
if (*s++ != '"')
error (_("Bad format string, missing '\"'."));
- /* Parse the format-control string and copy it into the string STRING,
- processing some kinds of escape sequence. */
-
- f = string = (char *) alloca (strlen (s) + 1);
-
- while (*s != '"')
- {
- int c = *s++;
- switch (c)
- {
- case '\0':
- error (_("Bad format string, non-terminated '\"'."));
-
- case '\\':
- switch (c = *s++)
- {
- case '\\':
- *f++ = '\\';
- break;
- case 'a':
- *f++ = '\a';
- break;
- case 'b':
- *f++ = '\b';
- break;
- case 'f':
- *f++ = '\f';
- break;
- case 'n':
- *f++ = '\n';
- break;
- case 'r':
- *f++ = '\r';
- break;
- case 't':
- *f++ = '\t';
- break;
- case 'v':
- *f++ = '\v';
- break;
- case '"':
- *f++ = '"';
- break;
- default:
- /* ??? TODO: handle other escape sequences. */
- error (_("Unrecognized escape character \\%c in format string."),
- c);
- }
- break;
+ fpieces = parse_format_string (&s);
- default:
- *f++ = c;
- }
- }
+ make_cleanup (free_format_pieces_cleanup, &fpieces);
- /* Skip over " and following space and comma. */
- s++;
- *f++ = '\0';
+ if (*s++ != '"')
+ error (_("Bad format string, non-terminated '\"'."));
+
s = skip_spaces (s);
if (*s != ',' && *s != 0)
@@ -2075,240 +2035,16 @@ ui_printf (char *arg, struct ui_file *stream)
s++;
s = skip_spaces (s);
- /* Need extra space for the '\0's. Doubling the size is sufficient. */
- substrings = alloca (strlen (string) * 2);
- current_substring = substrings;
-
{
- /* Now scan the string for %-specs and see what kinds of args they want.
- argclass[I] classifies the %-specs so we can give printf_filtered
- something of the right size. */
-
- enum argclass
- {
- int_arg, long_arg, long_long_arg, ptr_arg,
- string_arg, wide_string_arg, wide_char_arg,
- double_arg, long_double_arg, decfloat_arg
- };
- enum argclass *argclass;
- enum argclass this_argclass;
- char *last_arg;
+ int nargs = 0;
int nargs_wanted;
- int i;
+ int i, fr;
+ char *current_substring;
- argclass = (enum argclass *) alloca (strlen (s) * sizeof *argclass);
nargs_wanted = 0;
- f = string;
- last_arg = string;
- while (*f)
- if (*f++ == '%')
- {
- int seen_hash = 0, seen_zero = 0, lcount = 0, seen_prec = 0;
- int seen_space = 0, seen_plus = 0;
- int seen_big_l = 0, seen_h = 0, seen_big_h = 0;
- int seen_big_d = 0, seen_double_big_d = 0;
- int bad = 0;
-
- /* Check the validity of the format specifier, and work
- out what argument it expects. We only accept C89
- format strings, with the exception of long long (which
- we autoconf for). */
-
- /* Skip over "%%". */
- if (*f == '%')
- {
- f++;
- continue;
- }
-
- /* The first part of a format specifier is a set of flag
- characters. */
- while (strchr ("0-+ #", *f))
- {
- if (*f == '#')
- seen_hash = 1;
- else if (*f == '0')
- seen_zero = 1;
- else if (*f == ' ')
- seen_space = 1;
- else if (*f == '+')
- seen_plus = 1;
- f++;
- }
-
- /* The next part of a format specifier is a width. */
- while (strchr ("0123456789", *f))
- f++;
-
- /* The next part of a format specifier is a precision. */
- if (*f == '.')
- {
- seen_prec = 1;
- f++;
- while (strchr ("0123456789", *f))
- f++;
- }
-
- /* The next part of a format specifier is a length modifier. */
- if (*f == 'h')
- {
- seen_h = 1;
- f++;
- }
- else if (*f == 'l')
- {
- f++;
- lcount++;
- if (*f == 'l')
- {
- f++;
- lcount++;
- }
- }
- else if (*f == 'L')
- {
- seen_big_l = 1;
- f++;
- }
- /* Decimal32 modifier. */
- else if (*f == 'H')
- {
- seen_big_h = 1;
- f++;
- }
- /* Decimal64 and Decimal128 modifiers. */
- else if (*f == 'D')
- {
- f++;
-
- /* Check for a Decimal128. */
- if (*f == 'D')
- {
- f++;
- seen_double_big_d = 1;
- }
- else
- seen_big_d = 1;
- }
-
- switch (*f)
- {
- case 'u':
- if (seen_hash)
- bad = 1;
- /* FALLTHROUGH */
-
- case 'o':
- case 'x':
- case 'X':
- if (seen_space || seen_plus)
- bad = 1;
- /* FALLTHROUGH */
-
- case 'd':
- case 'i':
- if (lcount == 0)
- this_argclass = int_arg;
- else if (lcount == 1)
- this_argclass = long_arg;
- else
- this_argclass = long_long_arg;
-
- if (seen_big_l)
- bad = 1;
- break;
-
- case 'c':
- this_argclass = lcount == 0 ? int_arg : wide_char_arg;
- if (lcount > 1 || seen_h || seen_big_l)
- bad = 1;
- if (seen_prec || seen_zero || seen_space || seen_plus)
- bad = 1;
- break;
-
- case 'p':
- this_argclass = ptr_arg;
- if (lcount || seen_h || seen_big_l)
- bad = 1;
- if (seen_prec || seen_zero || seen_space || seen_plus)
- bad = 1;
- break;
-
- case 's':
- this_argclass = lcount == 0 ? string_arg : wide_string_arg;
- if (lcount > 1 || seen_h || seen_big_l)
- bad = 1;
- if (seen_zero || seen_space || seen_plus)
- bad = 1;
- break;
-
- case 'e':
- case 'f':
- case 'g':
- case 'E':
- case 'G':
- if (seen_big_h || seen_big_d || seen_double_big_d)
- this_argclass = decfloat_arg;
- else if (seen_big_l)
- this_argclass = long_double_arg;
- else
- this_argclass = double_arg;
-
- if (lcount || seen_h)
- bad = 1;
- break;
-
- case '*':
- error (_("`*' not supported for precision or width in printf"));
-
- case 'n':
- error (_("Format specifier `n' not supported in printf"));
-
- case '\0':
- error (_("Incomplete format specifier at end of format string"));
-
- default:
- error (_("Unrecognized format specifier '%c' in printf"), *f);
- }
-
- if (bad)
- error (_("Inappropriate modifiers to "
- "format specifier '%c' in printf"),
- *f);
-
- f++;
-
- if (lcount > 1 && USE_PRINTF_I64)
- {
- /* Windows' printf does support long long, but not the usual way.
- Convert %lld to %I64d. */
- int length_before_ll = f - last_arg - 1 - lcount;
-
- strncpy (current_substring, last_arg, length_before_ll);
- strcpy (current_substring + length_before_ll, "I64");
- current_substring[length_before_ll + 3] =
- last_arg[length_before_ll + lcount];
- current_substring += length_before_ll + 4;
- }
- else if (this_argclass == wide_string_arg
- || this_argclass == wide_char_arg)
- {
- /* Convert %ls or %lc to %s. */
- int length_before_ls = f - last_arg - 2;
-
- strncpy (current_substring, last_arg, length_before_ls);
- strcpy (current_substring + length_before_ls, "s");
- current_substring += length_before_ls + 2;
- }
- else
- {
- strncpy (current_substring, last_arg, f - last_arg);
- current_substring += f - last_arg;
- }
- *current_substring++ = '\0';
- last_arg = f;
- argclass[nargs_wanted++] = this_argclass;
- }
+ for (fr = 0; fpieces[fr].string != NULL; fr++)
+ if (fpieces[fr].argclass != literal_piece)
+ ++nargs_wanted;
/* Now, parse all arguments and evaluate them.
Store the VALUEs in VAL_ARGS. */
@@ -2334,10 +2070,11 @@ ui_printf (char *arg, struct ui_file *stream)
error (_("Wrong number of arguments for specified format-string"));
/* Now actually print them. */
- current_substring = substrings;
- for (i = 0; i < nargs; i++)
+ i = 0;
+ for (fr = 0; fpieces[fr].string != NULL; fr++)
{
- switch (argclass[i])
+ current_substring = fpieces[fr].string;
+ switch (fpieces[fr].argclass)
{
case string_arg:
{
@@ -2672,20 +2409,25 @@ ui_printf (char *arg, struct ui_file *stream)
break;
}
+ case literal_piece:
+ /* Print a portion of the format string that has no
+ directives. Note that this will not include any
+ ordinary %-specs, but it might include "%%". That is
+ why we use printf_filtered and not puts_filtered here.
+ Also, we pass a dummy argument because some platforms
+ have modified GCC to include -Wformat-security by
+ default, which will warn here if there is no
+ argument. */
+ fprintf_filtered (stream, current_substring, 0);
+ break;
default:
internal_error (__FILE__, __LINE__,
_("failed internal consistency check"));
}
- /* Skip to the next substring. */
- current_substring += strlen (current_substring) + 1;
+ /* Maybe advance to the next argument. */
+ if (fpieces[fr].argclass != literal_piece)
+ ++i;
}
- /* Print the portion of the format string after the last argument.
- Note that this will not include any ordinary %-specs, but it
- might include "%%". That is why we use printf_filtered and not
- puts_filtered here. Also, we pass a dummy argument because
- some platforms have modified GCC to include -Wformat-security
- by default, which will warn here if there is no argument. */
- fprintf_filtered (stream, last_arg, 0);
}
do_cleanups (old_cleanups);
}
« no previous file with comments | « gdb/ppcobsd-tdep.c ('k') | gdb/probe.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698