This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] printf support for DFP values


Thanks for reviewing Eli.

> If we can implement DFP printing in GDB, why should we also check for
> native DFP support and use that if available?  Are there any
> advantages in the native DFP printing, and if so, what are they?

Yes. With native DFP support we would have access to all the modifiers
(precision, width etc) available for printf, whereas, in the string
conversion solution we would just have a straight value-to-string
conversion mechanism without any additional capability.

> Also, if this patch is accepted, please submit also a suitable patch
> for the manual (doc/gdb.texinfo), where we describe the format
> conversions supported by the `printf' command (node "Output").

No problem. I'll supply that patch.

> A few questions/comments to the patch itself:
> 
> > -	double_arg, long_double_arg
> > +	double_arg, long_double_arg, decfloat_arg
> 
> You are using decfloat_arg unconditionally, but I don't see it defined
> anywhere in today's CVS.  Am I missing something?

decfloat_arg is being defined in an "enum" structure together with the
other values (double_arg, long_double_arg, int_arg etc). Is there a
different place you think it needs to be defined as well?

> +	      /* Replace %H, %D and %DD for %s's.  */
> Did you mean "Replace ... _with_ %s's"?
Fixed.

Regards,
Luis
2007-10-29  Luis Machado  <luisgpm@br.ibm.com>

  * printcmd.c: (printf_command): Add new DFP modifiers %H, %D and 
    %DD.
  * configure.ac: Add check for DECFLOAT printf support.
  * configure: Regenerated.

Index: git/gdb/printcmd.c
===================================================================
--- git.orig/gdb/printcmd.c	2007-10-26 17:43:36.000000000 -0700
+++ git/gdb/printcmd.c	2007-10-29 04:41:23.000000000 -0700
@@ -41,6 +41,7 @@
 #include "gdb_assert.h"
 #include "block.h"
 #include "disasm.h"
+#include "dfp.h"
 
 #ifdef TUI
 #include "tui/tui.h"		/* For tui_active et.al.   */
@@ -1819,7 +1820,7 @@
     enum argclass
       {
 	int_arg, long_arg, long_long_arg, ptr_arg, string_arg,
-	double_arg, long_double_arg
+	double_arg, long_double_arg, decfloat_arg
       };
     enum argclass *argclass;
     enum argclass this_argclass;
@@ -1928,6 +1929,31 @@
 		bad = 1;
 	      break;
 
+	    /* DFP Decimal32 types.  */
+	    case 'H':
+	      this_argclass = decfloat_arg;
+
+              if (lcount || seen_h || seen_big_l)
+                bad = 1;
+              if (seen_prec || seen_zero || seen_space || seen_plus)
+                bad = 1;
+	      break;
+
+	    /* DFP Decimal64 and Decimal128 types.  */
+	    case 'D':
+	      this_argclass = decfloat_arg;
+
+              if (lcount || seen_h || seen_big_l)
+                bad = 1;
+              if (seen_prec || seen_zero || seen_space || seen_plus)
+                bad = 1;
+
+	      if (*(++f) == 'D')
+		printf_unfiltered("\nDecimal 128\n");
+	      else
+		printf_unfiltered("\nDecimal 64\n");
+	      break;
+
 	    case 'c':
 	      this_argclass = int_arg;
 	      if (lcount || seen_h || seen_big_l)
@@ -2094,6 +2120,55 @@
 	      printf_filtered (current_substring, val);
 	      break;
 	    }
+
+	  /* Handles decimal floating point values.  */
+	  case decfloat_arg:
+	    {
+	      char *eos;
+	      char decstr[128];
+	      unsigned int dfp_len = TYPE_LENGTH (value_type (val_args[i]));
+	      uint8_t *dfp_value_ptr = (uint8_t *) value_contents_all (val_args[i])
+                                      + value_offset (val_args[i]);
+
+#if defined (PRINTF_HAS_DECFLOAT)
+	      printf_filtered(current_substring, dfp_value_ptr);
+#else
+	      if (TYPE_CODE (value_type (val_args[i])) != TYPE_CODE_DECFLOAT)
+		error (_("Cannot convert parameter to decfloat."));
+
+	      /* As a workaround until vasprintf has native support for DFP
+		 we convert the DFP values to string and print them using
+		 the %s format specifier.  */
+	      decimal_to_string (dfp_value_ptr, dfp_len, decstr);
+
+	      /* Points to the end of the string so that we can go back
+		 and check for DFP format specifiers.  */
+	      eos = current_substring + strlen(current_substring);
+
+	      /* Replace %H, %D and %DD with %s's.  */
+	      while(*--eos != '%')
+		if (*eos == 'D' && *(eos - 1) == 'D')
+		  {
+		    *(eos - 1) = 's';
+
+		    /* If we've found a %DD format specifier we need to go
+		       through the whole string pulling back one character
+		       since this format specifier has two chars.  */
+		    while (eos < last_arg)
+		      {
+			*eos = *(eos + 1);
+			eos++;
+		      }
+		  }
+		else if (*eos == 'D' || *eos == 'H')
+		  *eos = 's';
+
+	      /* Print the DFP value.  */
+	      printf_filtered(current_substring, decstr);
+	      break;
+#endif
+	    }
+
 	  case ptr_arg:
 	    {
 	      /* We avoid the host's %p because pointers are too
Index: git/gdb/configure.ac
===================================================================
--- git.orig/gdb/configure.ac	2007-10-26 17:43:36.000000000 -0700
+++ git/gdb/configure.ac	2007-10-26 17:52:25.000000000 -0700
@@ -927,6 +927,25 @@
             [Define to 1 if the "%ll" format works to print long longs.])
 fi
 
+# Check if the compiler and runtime support printing decfloats.
+
+AC_CACHE_CHECK([for decfloat support in printf],
+               gdb_cv_printf_has_decfloat,
+               [AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
+[[char buf[64];
+  _Decimal32 d32 = 1.2345df;
+  _Decimal64 d64 = 1.2345dd;
+  _Decimal128 d128 = 1.2345dl;
+  sprintf (buf, "Decimal32: %H\nDecimal64: %D\nDecimal128: %DD", d32, d64, d128);
+  return (strcmp ("Decimal32: 1.2345\nDecimal64: 1.2345\nDecimal128: 1.2345", buf));]])],
+                              gdb_cv_printf_has_decfloat=yes,
+                              gdb_cv_printf_has_decfloat=no,
+                              gdb_cv_printf_has_decfloat=no)])
+if test $gdb_cv_printf_has_decfloat = yes; then
+  AC_DEFINE(PRINTF_HAS_DECFLOAT, 1,
+            [Define to 1 if the "%H, %D and %DD" formats work to print decfloats.])
+fi
+
 # Check if the compiler supports the `long double' type.  We can't use
 # AC_C_LONG_DOUBLE because that one does additional checks on the
 # constants defined in <float.h> that fail on some systems,
Index: git/gdb/configure
===================================================================
--- git.orig/gdb/configure	2007-10-26 17:43:36.000000000 -0700
+++ git/gdb/configure	2007-10-26 17:59:22.000000000 -0700
@@ -21132,6 +21132,69 @@
 
 fi
 
+# Check if the compiler and runtime support printing decfloats.
+
+echo "$as_me:$LINENO: checking for decfloat support in printf" >&5
+echo $ECHO_N "checking for decfloat support in printf... $ECHO_C" >&6
+if test "${gdb_cv_printf_has_decfloat+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  gdb_cv_printf_has_decfloat=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[64];
+  _Decimal32 d32 = 1.2345df;
+  _Decimal64 d64 = 1.2345dd;
+  _Decimal128 d128 = 1.2345dl;
+  sprintf (buf, "Decimal32: %H\nDecimal64: %D\nDecimal128: %DD", d32, d64, d128);
+  return (strcmp ("Decimal32: 1.2345\nDecimal64: 1.2345\nDecimal128: 1.2345", buf));
+  ;
+  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_decfloat=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_decfloat=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_decfloat" >&5
+echo "${ECHO_T}$gdb_cv_printf_has_decfloat" >&6
+if test $gdb_cv_printf_has_decfloat = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define PRINTF_HAS_DECFLOAT 1
+_ACEOF
+
+fi
+
 # Check if the compiler supports the `long double' type.  We can't use
 # AC_C_LONG_DOUBLE because that one does additional checks on the
 # constants defined in <float.h> that fail on some systems,

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]