diff options
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/printcmd.c | 61 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/display.exp | 2 |
4 files changed, 71 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d8eca3a..af3cf2f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2007-09-04 Daniel Jacobowitz <dan@codesourcery.com> + + * printcmd.c (printf_command): Handle ptr_arg. Correct typo + in internal error message. + 2007-09-04 Pedro Alves <pedro_alves@portugalmail.pt> Daniel Jacobowitz <dan@codesourcery.com> diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 9fc716b..019a4a6 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 ea16928..c453ab2 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-09-04 Daniel Jacobowitz <dan@codesourcery.com> + + * gdb.base/display.exp: Add tests for printf %p. + 2007-09-03 Pedro Alves <pedro_alves@portugalmail.pt> * 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 653b5d9..254c431 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 # |