* printcmd.c (printf_command): Add seen_big_h, seen_big_d and

seen_double_big_d, treat the new H, D, and DD modifiers as length
	modifiers.
	* doc/gdb.texinfo (Output): Update documentation on using printf with DFP
	types.
	* testsuite/gdb.base/printcmds.exp (test_printf_with_dfp): Update
	printf calls with required float modifiers.
This commit is contained in:
Luis Machado 2008-01-09 13:47:59 +00:00
parent d2e2e64908
commit 0aea4bf354
6 changed files with 157 additions and 94 deletions

View File

@ -1,3 +1,9 @@
2008-01-09 Luis Machado <luisgpm@br.ibm.com>
* printcmd.c (printf_command): Add seen_big_h, seen_big_d and
seen_double_big_d, treat the new H, D, and DD modifiers as length
modifiers.
2008-01-08 Joel Brobecker <brobecker@adacore.com>
* dwarf2read.c (read_enumeration_type): Add comment.

View File

@ -1,3 +1,8 @@
2008-01-09 Luis Machado <luisgpm@br.ibm.com>
* gdb.texinfo (Output): Update documentation on using printf with DFP
types.
2008-01-07 Thiago Jung Bauermann <bauerman@br.ibm.com>
* gdb.texinfo (C and C++): Add Decimal Floating Point format

View File

@ -16693,7 +16693,8 @@ single character. Octal and hexadecimal escape sequences are not
supported.
Additionally, @code{printf} supports conversion specifications for DFP
(@dfn{Decimal Floating Point}) types using the following conversion
(@dfn{Decimal Floating Point}) types using the following length modifiers
together with a floating point specifier.
letters:
@itemize @bullet
@ -16708,7 +16709,7 @@ letters:
@end itemize
If the underlying @code{C} implementation used to build @value{GDBN} has
support for the three conversion letters for DFP types, other modifiers
support for the three length modifiers for DFP types, other modifiers
such as width and precision will also be available for @value{GDBN} to use.
In case there is no such @code{C} support, no additional modifiers will be
@ -16716,7 +16717,7 @@ available and the value will be printed in the standard way.
Here's an example of printing DFP types using the above conversion letters:
@smallexample
printf "D32: %H - D64: %D - D128: %DD\n",1.2345df,1.2E10dd,1.2E1dl
printf "D32: %Hf - D64: %Df - D128: %DDf\n",1.2345df,1.2E10dd,1.2E1dl
@end smallexample
@end table

View File

@ -1837,7 +1837,8 @@ printf_command (char *arg, int from_tty)
{
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;
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
@ -1901,6 +1902,26 @@ printf_command (char *arg, int from_tty)
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)
{
@ -1929,34 +1950,6 @@ printf_command (char *arg, int from_tty)
bad = 1;
break;
/* DFP Decimal32 types. */
case 'H':
this_argclass = decfloat_arg;
#ifndef PRINTF_HAS_DECFLOAT
if (lcount || seen_h || seen_big_l)
bad = 1;
if (seen_prec || seen_zero || seen_space || seen_plus)
bad = 1;
#endif
break;
/* DFP Decimal64 and Decimal128 types. */
case 'D':
this_argclass = decfloat_arg;
#ifndef PRINTF_HAS_DECFLOAT
if (lcount || seen_h || seen_big_l)
bad = 1;
if (seen_prec || seen_zero || seen_space || seen_plus)
bad = 1;
#endif
/* Check for a Decimal128. */
if (*(f + 1) == 'D')
f++;
break;
case 'c':
this_argclass = int_arg;
if (lcount || seen_h || seen_big_l)
@ -1986,7 +1979,9 @@ printf_command (char *arg, int from_tty)
case 'g':
case 'E':
case 'G':
if (seen_big_l)
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;
@ -2124,50 +2119,101 @@ printf_command (char *arg, int from_tty)
break;
}
/* Handles decimal floating point values. */
case decfloat_arg:
/* Handles decimal floating values. */
case decfloat_arg:
{
char *eos;
char decstr[MAX_DECIMAL_STRING];
unsigned int dfp_len = TYPE_LENGTH (value_type (val_args[i]));
unsigned char *dfp_value_ptr = (unsigned char *) value_contents_all (val_args[i])
+ value_offset (val_args[i]);
const gdb_byte *param_ptr = value_contents (val_args[i]);
#if defined (PRINTF_HAS_DECFLOAT)
printf_filtered (current_substring, dfp_value_ptr);
/* If we have native support for Decimal floating
printing, handle it here. */
printf_filtered (current_substring, param_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);
we convert the DFP values to string and print them using
the %s format specifier. */
char *eos, *sos;
int nnull_chars = 0;
/* Parameter data. */
struct type *param_type = value_type (val_args[i]);
unsigned int param_len = TYPE_LENGTH (param_type);
/* DFP output data. */
struct value *dfp_value = NULL;
gdb_byte *dfp_ptr;
int dfp_len = 16;
gdb_byte dec[16];
struct type *dfp_type = NULL;
char decstr[MAX_DECIMAL_STRING];
/* Points to the end of the string so that we can go back
and check for DFP format specifiers. */
and check for DFP length modifiers. */
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';
/* Look for the float/double format specifier. */
while (*eos != 'f' && *eos != 'e' && *eos != 'E'
&& *eos != 'g' && *eos != 'G')
eos--;
/* 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';
sos = eos;
/* Search for the '%' char and extract the size and type of
the output decimal value based on its modifiers
(%Hf, %Df, %DDf). */
while (*--sos != '%')
{
if (*sos == 'H')
{
dfp_len = 4;
dfp_type = builtin_type (current_gdbarch)->builtin_decfloat;
}
else if (*sos == 'D' && *(sos - 1) == 'D')
{
dfp_len = 16;
dfp_type = builtin_type (current_gdbarch)->builtin_declong;
sos--;
}
else
{
dfp_len = 8;
dfp_type = builtin_type (current_gdbarch)->builtin_decdouble;
}
}
/* Replace %Hf, %Df and %DDf with %s's. */
*++sos = 's';
/* Go through the whole format string and pull the correct
number of chars back to compensate for the change in the
format specifier. */
while (nnull_chars < nargs - i)
{
if (*eos == '\0')
nnull_chars++;
*++sos = *++eos;
}
/* Conversion between different DFP types. */
if (TYPE_CODE (param_type) == TYPE_CODE_DECFLOAT)
decimal_convert (param_ptr, param_len, dec, dfp_len);
else
/* If this is a non-trivial conversion, just output 0.
A correct converted value can be displayed by explicitly
casting to a DFP type. */
decimal_from_string (dec, dfp_len, "0");
dfp_value = value_from_decfloat (dfp_type, dec);
dfp_ptr = (gdb_byte *) value_contents (dfp_value);
decimal_to_string (dfp_ptr, dfp_len, decstr);
/* Print the DFP value. */
printf_filtered (current_substring, decstr);
break;
#endif
}

View File

@ -1,3 +1,8 @@
2008-01-09 Luis Machado <luisgpm@br.ibm.com>
* gdb.base/printcmds.exp (test_printf_with_dfp): Update printf calls
with required float modifiers.
2008-01-08 Joel Brobecker <brobecker@adacore.com>
* gdb.ada/funcall_param: New test program.

View File

@ -674,49 +674,49 @@ proc test_printf_with_dfp {} {
# Test various dfp values, covering 32-bit, 64-bit and 128-bit ones
# _Decimal32 constants, which can support up to 7 digits
gdb_test "printf \"%H\\n\",1.2df" "1.2"
gdb_test "printf \"%H\\n\",-1.2df" "-1.2"
gdb_test "printf \"%H\\n\",1.234567df" "1.234567"
gdb_test "printf \"%H\\n\",-1.234567df" "-1.234567"
gdb_test "printf \"%H\\n\",1234567.df" "1234567"
gdb_test "printf \"%H\\n\",-1234567.df" "-1234567"
gdb_test "printf \"%Hf\\n\",1.2df" "1.2"
gdb_test "printf \"%Hf\\n\",-1.2df" "-1.2"
gdb_test "printf \"%Hf\\n\",1.234567df" "1.234567"
gdb_test "printf \"%Hf\\n\",-1.234567df" "-1.234567"
gdb_test "printf \"%Hf\\n\",1234567.df" "1234567"
gdb_test "printf \"%Hf\\n\",-1234567.df" "-1234567"
gdb_test "printf \"%H\\n\",1.2E1df" "12"
gdb_test "printf \"%H\\n\",1.2E10df" "1.2E\\+10"
gdb_test "printf \"%H\\n\",1.2E-10df" "1.2E-10"
gdb_test "printf \"%Hf\\n\",1.2E1df" "12"
gdb_test "printf \"%Hf\\n\",1.2E10df" "1.2E\\+10"
gdb_test "printf \"%Hf\\n\",1.2E-10df" "1.2E-10"
# The largest exponent for 32-bit dfp value is 96.
gdb_test "printf \"%H\\n\",1.2E96df" "1.200000E\\+96"
gdb_test "printf \"%Hf\\n\",1.2E96df" "1.200000E\\+96"
# _Decimal64 constants, which can support up to 16 digits
gdb_test "printf \"%D\\n\",1.2dd" "1.2"
gdb_test "printf \"%D\\n\",-1.2dd" "-1.2"
gdb_test "printf \"%D\\n\",1.234567890123456dd" "1.234567890123456"
gdb_test "printf \"%D\\n\",-1.234567890123456dd" "-1.234567890123456"
gdb_test "printf \"%D\\n\",1234567890123456.dd" "1234567890123456"
gdb_test "printf \"%D\\n\",-1234567890123456.dd" "-1234567890123456"
gdb_test "printf \"%Df\\n\",1.2dd" "1.2"
gdb_test "printf \"%Df\\n\",-1.2dd" "-1.2"
gdb_test "printf \"%Df\\n\",1.234567890123456dd" "1.234567890123456"
gdb_test "printf \"%Df\\n\",-1.234567890123456dd" "-1.234567890123456"
gdb_test "printf \"%Df\\n\",1234567890123456.dd" "1234567890123456"
gdb_test "printf \"%Df\\n\",-1234567890123456.dd" "-1234567890123456"
gdb_test "printf \"%D\\n\",1.2E1dd" "12"
gdb_test "printf \"%D\\n\",1.2E10dd" "1.2E\\+10"
gdb_test "printf \"%D\\n\",1.2E-10dd" "1.2E-10"
gdb_test "printf \"%Df\\n\",1.2E1dd" "12"
gdb_test "printf \"%Df\\n\",1.2E10dd" "1.2E\\+10"
gdb_test "printf \"%Df\\n\",1.2E-10dd" "1.2E-10"
# The largest exponent for 64-bit dfp value is 384.
gdb_test "printf \"%D\\n\",1.2E384dd" "1.200000000000000E\\+384"
gdb_test "printf \"%Df\\n\",1.2E384dd" "1.200000000000000E\\+384"
# _Decimal128 constants, which can support up to 34 digits
gdb_test "printf \"%DD\\n\",1.2dl" "1.2"
gdb_test "printf \"%DD\\n\",-1.2dl" "-1.2"
gdb_test "printf \"%DD\\n\",1.234567890123456789012345678901234dl" "1.234567890123456789012345678901234"
gdb_test "printf \"%DD\\n\",-1.234567890123456789012345678901234dl" "-1.234567890123456789012345678901234"
gdb_test "printf \"%DD\\n\",1234567890123456789012345678901234.dl" "1234567890123456789012345678901234"
gdb_test "printf \"%DD\\n\",-1234567890123456789012345678901234.dl" "-1234567890123456789012345678901234"
gdb_test "printf \"%DDf\\n\",1.2dl" "1.2"
gdb_test "printf \"%DDf\\n\",-1.2dl" "-1.2"
gdb_test "printf \"%DDf\\n\",1.234567890123456789012345678901234dl" "1.234567890123456789012345678901234"
gdb_test "printf \"%DDf\\n\",-1.234567890123456789012345678901234dl" "-1.234567890123456789012345678901234"
gdb_test "printf \"%DDf\\n\",1234567890123456789012345678901234.dl" "1234567890123456789012345678901234"
gdb_test "printf \"%DDf\\n\",-1234567890123456789012345678901234.dl" "-1234567890123456789012345678901234"
gdb_test "printf \"%DD\\n\",1.2E1dl" "12"
gdb_test "printf \"%DD\\n\",1.2E10dl" "1.2E\\+10"
gdb_test "printf \"%DD\\n\",1.2E-10dl" "1.2E-10"
gdb_test "printf \"%DDf\\n\",1.2E1dl" "12"
gdb_test "printf \"%DDf\\n\",1.2E10dl" "1.2E\\+10"
gdb_test "printf \"%DDf\\n\",1.2E-10dl" "1.2E-10"
# The largest exponent for 128-bit dfp value is 6144.
gdb_test "printf \"%DD\\n\",1.2E6144dl" "1.200000000000000000000000000000000E\\+6144"
gdb_test "printf \"%DDf\\n\",1.2E6144dl" "1.200000000000000000000000000000000E\\+6144"
}
# Escape a left curly brace to prevent it from being interpreted as