From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6235 invoked by alias); 23 Feb 2007 16:15:17 -0000 Received: (qmail 6220 invoked by uid 22791); 23 Feb 2007 16:15:14 -0000 X-Spam-Check-By: sourceware.org Received: from 195.22.55.53.adsl.nextra.cz (HELO host0.dyn.jankratochvil.net) (195.22.55.53) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 23 Feb 2007 16:15:01 +0000 Received: from host0.dyn.jankratochvil.net (localhost [127.0.0.1]) by host0.dyn.jankratochvil.net (8.14.0/8.13.8) with ESMTP id l1NGEs3n004127 for ; Fri, 23 Feb 2007 17:14:54 +0100 Received: (from jkratoch@localhost) by host0.dyn.jankratochvil.net (8.14.0/8.14.0/Submit) id l1NGEriM004126 for gdb-patches@sourceware.org; Fri, 23 Feb 2007 17:14:53 +0100 Date: Fri, 23 Feb 2007 16:15:00 -0000 From: Jan Kratochvil To: gdb-patches@sourceware.org Subject: Re: [RFC] print/x of a float/double should printf ("%a") Message-ID: <20070223161453.GA479@host0.dyn.jankratochvil.net> References: <20070218153705.GA25940@host0.dyn.jankratochvil.net> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="BXVAT5kNtrzKuDFl" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.13 (2007-02-12) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-02/txt/msg00289.txt.bz2 --BXVAT5kNtrzKuDFl Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1190 On Sun, 18 Feb 2007 21:25:54 +0100, Eli Zaretskii wrote: > > Date: Sun, 18 Feb 2007 16:37:06 +0100 > > From: Jan Kratochvil > > > > currently "print/x (float) a" does an integer "print/x (long) a". > > > > Ulrich Drepper requested to use instead printf ("%a") (man excerpt below): ... > . Please submit an appropriate change for the manual. Attached. > > Systems not supporting "%a" will print the value as > > print (float) a > > which differs from the current way there: > > print/x (long) a > > This makes this an incompatible change. For this reason, I'd prefer a > new format letter, like Andreas suggested. I believe this change is to make the most common default action more valid. Also some hardly noticeable changes are what separate GDB stable release are for, aren't they? If someone has very specific printing needs s/he still can use the GDB function `printf' (instead of `print') or even to use `call printf' with the right format strings and parameters casting. As I did not find general consensus here I just updated the patch by the doc part and also implemented a forgotten "%a"/"%A" for the GDB `printf' command. Regards, Jan --BXVAT5kNtrzKuDFl Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="gdb-printf-x-2.patch" Content-length: 17295 2007-02-23 Jan Kratochvil * configure.ac (PRINTF_HAS_HEX_DOUBLE): Test for printf ("%a"). * configure, config.in: Regenerate. * printcmd.c (printf_command): Support "%a"/"%A" formatting. (print_scalar_formatted): Print TYPE_CODE_FLT/x by print_floating (format='x'). * valprint.c (print_floating): Add FORMAT parameter. * value.h (print_floating): Update prototype. * ada-valprint.c (ada_print_floating): Callers changed. * c-valprint.c (c_val_print): Likewise. * f-valprint.c (f_val_print): Likewise. * m2-valprint.c (m2_val_print): Likewise. * p-valprint.c (pascal_val_print): Likewise. 2007-02-23 Jan Kratochvil * gdb.texinfo (Output formats): Described hexadecimal floats printing. 2007-02-18 Jan Kratochvil * gdb.arch/i386-sse.exp: Check $xmm.v4_float and $xmm.v2_double printing in hexadecimal format. * gdb.base/gdb1821.exp: Update the DOUBLE/x print check. Index: gdb/configure.ac =================================================================== RCS file: /cvs/src/src/gdb/configure.ac,v retrieving revision 1.42 diff -u -p -r1.42 configure.ac --- gdb/configure.ac 2 Feb 2007 22:54:09 -0000 1.42 +++ gdb/configure.ac 18 Feb 2007 04:35:38 -0000 @@ -955,6 +955,23 @@ aix*) ;; esac +# Check if the compiler and runtime support printing doubles in hex. + +AC_CACHE_CHECK([for hex double support in printf], + gdb_cv_printf_has_hex_double, + [AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], +[[char buf[16]; + double f = 3.141592653; + sprintf (buf, "%a", f); + return (strncmp ("0x1.921fb", buf, 9));]])], + gdb_cv_printf_has_hex_double=yes, + gdb_cv_printf_has_hex_double=no, + gdb_cv_printf_has_hex_double=no)]) +if test $gdb_cv_printf_has_hex_double = yes; then + AC_DEFINE(PRINTF_HAS_HEX_DOUBLE, 1, + [Define to 1 if the "%a" format works to print doubles in hex.]) +fi + dnl For certain native configurations, we need to check whether thread dnl support can be built in or not. Index: gdb/ada-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/ada-valprint.c,v retrieving revision 1.30 diff -u -p -r1.30 ada-valprint.c --- gdb/ada-valprint.c 9 Jan 2007 17:58:49 -0000 1.30 +++ gdb/ada-valprint.c 18 Feb 2007 04:35:32 -0000 @@ -308,7 +308,7 @@ ada_print_floating (const gdb_byte *vala struct ui_file *tmp_stream = mem_fileopen (); struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_stream); - print_floating (valaddr, type, tmp_stream); + print_floating (valaddr, type, tmp_stream, 0); ui_file_put (tmp_stream, ui_memcpy, buffer); do_cleanups (cleanups); Index: gdb/c-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/c-valprint.c,v retrieving revision 1.42 diff -u -p -r1.42 c-valprint.c --- gdb/c-valprint.c 26 Jan 2007 20:54:16 -0000 1.42 +++ gdb/c-valprint.c 18 Feb 2007 04:35:32 -0000 @@ -432,7 +432,7 @@ c_val_print (struct type *type, const gd } else { - print_floating (valaddr + embedded_offset, type, stream); + print_floating (valaddr + embedded_offset, type, stream, 0); } break; @@ -458,7 +458,7 @@ c_val_print (struct type *type, const gd format, 0, stream); else print_floating (valaddr + embedded_offset, TYPE_TARGET_TYPE (type), - stream); + stream, 0); fprintf_filtered (stream, " + "); if (format) print_scalar_formatted (valaddr + embedded_offset @@ -469,7 +469,7 @@ c_val_print (struct type *type, const gd print_floating (valaddr + embedded_offset + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), TYPE_TARGET_TYPE (type), - stream); + stream, 0); fprintf_filtered (stream, " * I"); break; Index: gdb/f-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/f-valprint.c,v retrieving revision 1.34 diff -u -p -r1.34 f-valprint.c --- gdb/f-valprint.c 9 Jan 2007 17:58:50 -0000 1.34 +++ gdb/f-valprint.c 18 Feb 2007 04:35:38 -0000 @@ -495,7 +495,7 @@ f_val_print (struct type *type, const gd if (format) print_scalar_formatted (valaddr, type, format, 0, stream); else - print_floating (valaddr, type, stream); + print_floating (valaddr, type, stream, 0); break; case TYPE_CODE_VOID: @@ -571,9 +571,9 @@ f_val_print (struct type *type, const gd error (_("Cannot print out complex*%d variables"), TYPE_LENGTH (type)); } fputs_filtered ("(", stream); - print_floating (valaddr, type, stream); + print_floating (valaddr, type, stream, 0); fputs_filtered (",", stream); - print_floating (valaddr + TYPE_LENGTH (type), type, stream); + print_floating (valaddr + TYPE_LENGTH (type), type, stream, 0); fputs_filtered (")", stream); break; Index: gdb/m2-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/m2-valprint.c,v retrieving revision 1.12 diff -u -p -r1.12 m2-valprint.c --- gdb/m2-valprint.c 9 Jan 2007 17:58:51 -0000 1.12 +++ gdb/m2-valprint.c 18 Feb 2007 04:35:38 -0000 @@ -479,7 +479,7 @@ m2_val_print (struct type *type, const g print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); else - print_floating (valaddr + embedded_offset, type, stream); + print_floating (valaddr + embedded_offset, type, stream, 0); break; case TYPE_CODE_METHOD: Index: gdb/p-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/p-valprint.c,v retrieving revision 1.47 diff -u -p -r1.47 p-valprint.c --- gdb/p-valprint.c 8 Feb 2007 14:20:56 -0000 1.47 +++ gdb/p-valprint.c 18 Feb 2007 04:35:38 -0000 @@ -426,7 +426,7 @@ pascal_val_print (struct type *type, con } else { - print_floating (valaddr + embedded_offset, type, stream); + print_floating (valaddr + embedded_offset, type, stream, 0); } break; Index: gdb/printcmd.c =================================================================== RCS file: /cvs/src/src/gdb/printcmd.c,v retrieving revision 1.100 diff -u -p -r1.100 printcmd.c --- gdb/printcmd.c 9 Jan 2007 17:58:56 -0000 1.100 +++ gdb/printcmd.c 18 Feb 2007 04:35:38 -0000 @@ -362,23 +362,36 @@ print_scalar_formatted (const void *vala switch (format) { case 'x': - if (!size) - { - /* No size specified, like in print. Print varying # of digits. */ - print_longest (stream, 'x', 1, val_long); - } - else - switch (size) - { - case 'b': - case 'h': - case 'w': - case 'g': - print_longest (stream, size, 1, val_long); - break; - default: - error (_("Undefined output size \"%c\"."), size); - } + /* TYPE_CODE_FLT gets printed in hex by print_floating() below. */ + if (TYPE_CODE (type) != TYPE_CODE_FLT) + { + if (!size) + { + /* No size specified, like in print. Print varying # of digits. */ + print_longest (stream, 'x', 1, val_long); + } + else + switch (size) + { + case 'b': + case 'h': + case 'w': + case 'g': + print_longest (stream, size, 1, val_long); + break; + default: + error (_("Undefined output size \"%c\"."), size); + } + break; + } + case 'f': + if (len == TYPE_LENGTH (builtin_type_float)) + type = builtin_type_float; + else if (len == TYPE_LENGTH (builtin_type_double)) + type = builtin_type_double; + else if (len == TYPE_LENGTH (builtin_type_long_double)) + type = builtin_type_long_double; + print_floating (valaddr, type, stream, format); break; case 'd': @@ -408,16 +421,6 @@ print_scalar_formatted (const void *vala stream, 0, Val_pretty_default); break; - case 'f': - if (len == TYPE_LENGTH (builtin_type_float)) - type = builtin_type_float; - else if (len == TYPE_LENGTH (builtin_type_double)) - type = builtin_type_double; - else if (len == TYPE_LENGTH (builtin_type_long_double)) - type = builtin_type_long_double; - print_floating (valaddr, type, stream); - break; - case 0: internal_error (__FILE__, __LINE__, _("failed internal consistency check")); @@ -1940,6 +1943,10 @@ printf_command (char *arg, int from_tty) bad = 1; break; +#ifdef PRINTF_HAS_HEX_DOUBLE + case 'a': + case 'A': +#endif case 'e': case 'f': case 'g': Index: gdb/valprint.c =================================================================== RCS file: /cvs/src/src/gdb/valprint.c,v retrieving revision 1.64 diff -u -p -r1.64 valprint.c --- gdb/valprint.c 9 Jan 2007 17:58:59 -0000 1.64 +++ gdb/valprint.c 18 Feb 2007 04:35:45 -0000 @@ -432,16 +432,18 @@ longest_to_int (LONGEST arg) } /* Print a floating point value of type TYPE (not always a - TYPE_CODE_FLT), pointed to in GDB by VALADDR, on STREAM. */ + TYPE_CODE_FLT), pointed to in GDB by VALADDR, on STREAM. + Print in hex if supported on host and requested by FORMAT 'x'. */ void print_floating (const gdb_byte *valaddr, struct type *type, - struct ui_file *stream) + struct ui_file *stream, int format) { DOUBLEST doub; int inv; const struct floatformat *fmt = NULL; unsigned len = TYPE_LENGTH (type); + const char *format_string; /* If it is a floating-point, check for obvious problems. */ if (TYPE_CODE (type) == TYPE_CODE_FLT) @@ -481,17 +483,32 @@ print_floating (const gdb_byte *valaddr, instead uses the type's length to determine the precision of the floating-point value being printed. */ + /* Do not use a format string variable to permit arguments checking. */ +#define FORMAT_PREFIX "%.*" +#ifdef PRINTF_HAS_LONG_DOUBLE +# define FORMAT_LONG FORMAT_PREFIX "L" +#else +# define FORMAT_LONG FORMAT_PREFIX +#endif +#ifdef PRINTF_HAS_HEX_DOUBLE +# define FORMAT_MAY_HEX (format == 'x' ? FORMAT_PREFIX "a" : FORMAT_PREFIX "g") +# define FORMAT_LONG_MAY_HEX (format == 'x' ? FORMAT_LONG "a" : FORMAT_LONG "g") +#else +# define FORMAT_MAY_HEX FORMAT_PREFIX "g" +# define FORMAT_LONG_MAY_HEX FORMAT_LONG "g" +#endif + if (len < sizeof (double)) - fprintf_filtered (stream, "%.9g", (double) doub); + fprintf_filtered (stream, FORMAT_MAY_HEX, 9, (double) doub); else if (len == sizeof (double)) - fprintf_filtered (stream, "%.17g", (double) doub); + fprintf_filtered (stream, FORMAT_MAY_HEX, 17, (double) doub); else #ifdef PRINTF_HAS_LONG_DOUBLE - fprintf_filtered (stream, "%.35Lg", doub); + fprintf_filtered (stream, FORMAT_LONG_MAY_HEX, 35, doub); #else /* This at least wins with values that are representable as doubles. */ - fprintf_filtered (stream, "%.17g", (double) doub); + fprintf_filtered (stream, FORMAT_MAY_HEX, 17, (double) doub); #endif } Index: gdb/value.h =================================================================== RCS file: /cvs/src/src/gdb/value.h,v retrieving revision 1.96 diff -u -p -r1.96 value.h --- gdb/value.h 9 Jan 2007 17:58:59 -0000 1.96 +++ gdb/value.h 18 Feb 2007 04:35:45 -0000 @@ -480,7 +480,7 @@ extern void print_longest (struct ui_fil int use_local, LONGEST val); extern void print_floating (const gdb_byte *valaddr, struct type *type, - struct ui_file *stream); + struct ui_file *stream, int format); extern int value_print (struct value *val, struct ui_file *stream, int format, enum val_prettyprint pretty); Index: gdb/testsuite/gdb.arch/i386-sse.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.arch/i386-sse.exp,v retrieving revision 1.6 diff -u -p -r1.6 i386-sse.exp --- gdb/testsuite/gdb.arch/i386-sse.exp 26 Jan 2007 20:53:15 -0000 1.6 +++ gdb/testsuite/gdb.arch/i386-sse.exp 18 Feb 2007 04:35:45 -0000 @@ -87,6 +87,12 @@ foreach r {0 1 2 3 4 5 6 7} { gdb_test "print \$xmm$r.v16_int8" \ ".. = \\{(-?\[0-9\]+ '.*', ){15}-?\[0-9\]+ '.*'\\}.*" \ "check int8 contents of %xmm$r" + gdb_test "print/x \$xmm$r.v4_float" \ + ".. = \\{(-?0x\[0-9a-f\]+\[.\]\[0-9a-f\]+p\[+-\]\[0-9\]+, ){3}-?0x\[0-9a-f\]+\[.\]\[0-9a-f\]+p\[+-\]\[0-9\]+\\}.*" \ + "check hex float contents of %xmm$r" + gdb_test "print/x \$xmm$r.v2_double" \ + ".. = \\{-?0x\[0-9a-f\]+\[.\]\[0-9a-f\]+p\[+-\]\[0-9\]+, -?0x\[0-9a-f\]+\[.\]\[0-9a-f\]+p\[+-\]\[0-9\]+\\}.*" \ + "check hex double contents of %xmm$r" } foreach r {0 1 2 3 4 5 6 7} { Index: gdb/testsuite/gdb.base/gdb1821.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gdb1821.exp,v retrieving revision 1.2 diff -u -p -r1.2 gdb1821.exp --- gdb/testsuite/gdb.base/gdb1821.exp 9 Jan 2007 17:59:11 -0000 1.2 +++ gdb/testsuite/gdb.base/gdb1821.exp 18 Feb 2007 13:04:13 -0000 @@ -39,5 +39,4 @@ if ![runto_main] then { perror "couldn't run to breakpoint" continue } -gdb_test "print /x bar" "{x__0 = 0x0, y__0 = 0x0, z__1 = 0x0}" - +gdb_test "print /x bar" "{x__0 = 0x0.0+p\\+0, y__0 = 0x0.0+p\\+0, z__1 = 0x0.0+p\\+0}" Index: gdb/configure =================================================================== RCS file: /cvs/src/src/gdb/configure,v retrieving revision 1.221 diff -u -p -r1.221 configure --- gdb/configure 2 Feb 2007 22:55:54 -0000 1.221 +++ gdb/configure 18 Feb 2007 12:52:56 -0000 @@ -20858,6 +20858,67 @@ echo "${ECHO_T}$gdb_cv_bigtoc" >&6 ;; esac +# Check if the compiler and runtime support printing doubles in hex. + +echo "$as_me:$LINENO: checking for hex double support in printf" >&5 +echo $ECHO_N "checking for hex double support in printf... $ECHO_C" >&6 +if test "${gdb_cv_printf_has_hex_double+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + gdb_cv_printf_has_hex_double=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +char buf[16]; + double f = 3.141592653; + sprintf (buf, "%a", f); + return (strncmp ("0x1.921fb", buf, 9)); + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + gdb_cv_printf_has_hex_double=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +gdb_cv_printf_has_hex_double=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $gdb_cv_printf_has_hex_double" >&5 +echo "${ECHO_T}$gdb_cv_printf_has_hex_double" >&6 +if test $gdb_cv_printf_has_hex_double = yes; then + +cat >>confdefs.h <<\_ACEOF +#define PRINTF_HAS_HEX_DOUBLE 1 +_ACEOF + +fi + if test ${build} = ${host} -a ${host} = ${target} ; then Index: gdb/config.in =================================================================== RCS file: /cvs/src/src/gdb/config.in,v retrieving revision 1.88 diff -u -p -r1.88 config.in --- gdb/config.in 2 Feb 2007 22:54:46 -0000 1.88 +++ gdb/config.in 18 Feb 2007 04:35:33 -0000 @@ -497,6 +497,9 @@ /* Define if the prfpregset_t type is broken. */ #undef PRFPREGSET_T_BROKEN +/* Define to 1 if the "%a" format works to print doubles in hex. */ +#undef PRINTF_HAS_HEX_DOUBLE + /* Define to 1 if the "%Lg" format works to print long doubles. */ #undef PRINTF_HAS_LONG_DOUBLE Index: gdb/doc/gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.387 diff -u -p -r1.387 gdb.texinfo --- gdb/doc/gdb.texinfo 18 Feb 2007 08:04:35 -0000 1.387 +++ gdb/doc/gdb.texinfo 23 Feb 2007 15:59:22 -0000 @@ -5744,7 +5744,8 @@ letters supported are: @table @code @item x Regard the bits of the value as an integer, and print the integer in -hexadecimal. +hexadecimal. Floating point numbers get printed in floating point hexadecimal +format. @item d Print as integer in signed decimal. @@ -5798,6 +5799,22 @@ p/x $pc Note that no space is required before the slash; this is because command names in @value{GDBN} cannot contain a slash. +Structured content gets printed recursively, applying the specified format to +each of its elements as during + +@smallexample +struct s + { + int i; + float fl; + double dbl; + }; +(gdb) p s +$1 = {i = 4, fl = 5.5999999, dbl = 7.7999999999999998} +(gdb) p/x s +$2 = {i = 0x4, fl = 0x1.666666000p+2, dbl = 0x1.f3333333333330000p+2} +@end smallexample + To reprint the last value in the value history with a different format, you can use the @code{print} command with just a format and no expression. For example, @samp{p/x} reprints the last value in hex. --BXVAT5kNtrzKuDFl--