From 2025a643ef7edd04df5027888c2d4a030edfcd81 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Tue, 4 Sep 2007 14:18:47 +0000 Subject: [PATCH] * printcmd.c (printf_command): Handle ptr_arg. Correct typo in internal error message. * gdb.base/display.exp: Add tests for printf %p. --- gdb/ChangeLog | 5 +++ gdb/printcmd.c | 61 +++++++++++++++++++++++++++++- gdb/testsuite/ChangeLog | 4 ++ gdb/testsuite/gdb.base/display.exp | 2 + 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d8eca3ad187..af3cf2fc864 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2007-09-04 Daniel Jacobowitz + + * printcmd.c (printf_command): Handle ptr_arg. Correct typo + in internal error message. + 2007-09-04 Pedro Alves Daniel Jacobowitz diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 9fc716b8820..019a4a62703 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -2079,9 +2079,68 @@ printf_command (char *arg, int from_tty) printf_filtered (current_substring, val); break; } + case ptr_arg: + { + /* We avoid the host's %p because pointers are too + likely to be the wrong size. The only interesting + modifier for %p is a width; extract that, and then + handle %p as glibc would: %#x or a literal "(nil)". */ + + char *p, *fmt, *fmt_p; +#if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG) + long long val = value_as_long (val_args[i]); +#else + long val = value_as_long (val_args[i]); +#endif + + fmt = alloca (strlen (current_substring) + 5); + + /* Copy up to the leading %. */ + p = current_substring; + fmt_p = fmt; + while (*p) + { + int is_percent = (*p == '%'); + *fmt_p++ = *p++; + if (is_percent) + { + if (*p == '%') + *fmt_p++ = *p++; + else + break; + } + } + + if (val != 0) + *fmt_p++ = '#'; + + /* Copy any width. */ + while (*p >= '0' && *p < '9') + *fmt_p++ = *p++; + + gdb_assert (*p == 'p' && *(p + 1) == '\0'); + if (val != 0) + { +#if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG) + *fmt_p++ = 'l'; +#endif + *fmt_p++ = 'l'; + *fmt_p++ = 'x'; + *fmt_p++ = '\0'; + printf_filtered (fmt, val); + } + else + { + *fmt_p++ = 's'; + *fmt_p++ = '\0'; + printf_filtered (fmt, "(nil)"); + } + + break; + } default: internal_error (__FILE__, __LINE__, - _("failed internal consitency check")); + _("failed internal consistency check")); } /* Skip to the next substring. */ current_substring += strlen (current_substring) + 1; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index ea169285963..c453ab26200 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-09-04 Daniel Jacobowitz + + * gdb.base/display.exp: Add tests for printf %p. + 2007-09-03 Pedro Alves * gdb.base/unload.c (dlopen, dlsym): Use the TEXT macro to convert diff --git a/gdb/testsuite/gdb.base/display.exp b/gdb/testsuite/gdb.base/display.exp index 653b5d9cc0d..254c4313db9 100644 --- a/gdb/testsuite/gdb.base/display.exp +++ b/gdb/testsuite/gdb.base/display.exp @@ -178,6 +178,8 @@ gdb_test "printf \"\\\\!\\a\\f\\r\\t\\v\\b\\n\"" ".*!.*" gdb_test "printf \"\"" ".*" "re-set term" gdb_test "printf \"\\w\"" ".*Unrecognized escape character.*" gdb_test "printf \"%d\" j" ".*Invalid argument syntax.*" +gdb_test "printf \"%p\\n\", 0" "\\(nil\\)" +gdb_test "printf \"%p\\n\", 1" "0x1" # play with "print", too # -- 2.30.2