/* Print values for GDB, the GNU debugger.
- Copyright 1986, 1988, 1989, 1991-1994, 1998, 2000
+
+ Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
#include "gdb_string.h"
#include "gdbcore.h"
#include "gdbcmd.h"
#include "target.h"
-#include "obstack.h"
#include "language.h"
-#include "demangle.h"
#include "annotate.h"
#include "valprint.h"
+#include "floatformat.h"
+#include "doublest.h"
+#include "exceptions.h"
#include <errno.h>
/* Prototypes for local functions */
-static int partial_memory_read (CORE_ADDR memaddr, char *myaddr,
+static int partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
int len, int *errnoptr);
-static void print_hex_chars (struct ui_file *, unsigned char *,
- unsigned int);
-
static void show_print (char *, int);
static void set_print (char *, int);
unsigned int print_max;
#define PRINT_MAX_DEFAULT 200 /* Start print_max off at this value. */
+static void
+show_print_max (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Limit on string chars or array elements to print is %s.\n"),
+ value);
+}
+
/* Default input and output radixes, and output format letter. */
unsigned input_radix = 10;
+static void
+show_input_radix (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Default input radix for entering numbers is %s.\n"),
+ value);
+}
+
unsigned output_radix = 10;
+static void
+show_output_radix (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Default output radix for printing of values is %s.\n"),
+ value);
+}
int output_format = 0;
+/* By default we print arrays without printing the index of each element in
+ the array. This behavior can be changed by setting PRINT_ARRAY_INDEXES. */
+
+static int print_array_indexes = 0;
+static void
+show_print_array_indexes (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Printing of array indexes is %s.\n"), value);
+}
+
/* Print repeat counts if there are more than this many repetitions of an
element in an array. Referenced by the low level language dependent
print routines. */
unsigned int repeat_count_threshold = 10;
+static void
+show_repeat_count_threshold (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Threshold for repeated print elements is %s.\n"),
+ value);
+}
/* If nonzero, stops printing of char arrays at first null. */
int stop_print_at_null;
+static void
+show_stop_print_at_null (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Printing of char arrays to stop at first null char is %s.\n"),
+ value);
+}
/* Controls pretty printing of structures. */
int prettyprint_structs;
+static void
+show_prettyprint_structs (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Prettyprinting of structures is %s.\n"), value);
+}
/* Controls pretty printing of arrays. */
int prettyprint_arrays;
+static void
+show_prettyprint_arrays (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Prettyprinting of arrays is %s.\n"), value);
+}
/* If nonzero, causes unions inside structures or other unions to be
printed. */
int unionprint; /* Controls printing of nested unions. */
+static void
+show_unionprint (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Printing of unions interior to structures is %s.\n"),
+ value);
+}
/* If nonzero, causes machine addresses to be printed in certain contexts. */
int addressprint; /* Controls printing of machine addresses */
+static void
+show_addressprint (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Printing of addresses is %s.\n"), value);
+}
\f
/* Print data of type TYPE located at VALADDR (within GDB), which came from
int
-val_print (struct type *type, char *valaddr, int embedded_offset,
- CORE_ADDR address, struct ui_file *stream, int format, int deref_ref,
- int recurse, enum val_prettyprint pretty)
+val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
+ CORE_ADDR address, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
{
+ volatile struct gdb_exception except;
+ volatile enum val_prettyprint real_pretty = pretty;
+ int ret = 0;
+
struct type *real_type = check_typedef (type);
if (pretty == Val_pretty_default)
- {
- pretty = prettyprint_structs ? Val_prettyprint : Val_no_prettyprint;
- }
+ real_pretty = prettyprint_structs ? Val_prettyprint : Val_no_prettyprint;
QUIT;
only a stub and we can't find and substitute its complete type, then
print appropriate string and return. */
- if (TYPE_FLAGS (real_type) & TYPE_FLAG_STUB)
+ if (TYPE_STUB (real_type))
{
fprintf_filtered (stream, "<incomplete type>");
gdb_flush (stream);
return (0);
}
- return (LA_VAL_PRINT (type, valaddr, embedded_offset, address,
- stream, format, deref_ref, recurse, pretty));
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ ret = LA_VAL_PRINT (type, valaddr, embedded_offset, address,
+ stream, format, deref_ref, recurse, real_pretty);
+ }
+ if (except.reason < 0)
+ fprintf_filtered (stream, _("<error reading variable>"));
+
+ return ret;
}
-/* Print the value VAL in C-ish syntax on stream STREAM.
- FORMAT is a format-letter, or 0 for print in natural format of data type.
- If the object printed is a string pointer, returns
- the number of string bytes printed. */
+/* Check whether the value VAL is printable. Return 1 if it is;
+ return 0 and print an appropriate error message to STREAM if it
+ is not. */
-int
-value_print (value_ptr val, struct ui_file *stream, int format,
- enum val_prettyprint pretty)
+static int
+value_check_printable (struct value *val, struct ui_file *stream)
{
if (val == 0)
{
- printf_filtered ("<address of value unknown>");
+ fprintf_filtered (stream, _("<address of value unknown>"));
return 0;
}
- if (VALUE_OPTIMIZED_OUT (val))
+
+ if (value_optimized_out (val))
{
- printf_filtered ("<value optimized out>");
+ fprintf_filtered (stream, _("<value optimized out>"));
return 0;
}
+
+ return 1;
+}
+
+/* Print the value VAL onto stream STREAM according to FORMAT (a
+ letter, or 0 for natural format using TYPE).
+
+ If DEREF_REF is nonzero, then dereference references, otherwise just print
+ them like pointers.
+
+ The PRETTY parameter controls prettyprinting.
+
+ If the data are a string pointer, returns the number of string characters
+ printed.
+
+ This is a preferable interface to val_print, above, because it uses
+ GDB's value mechanism. */
+
+int
+common_val_print (struct value *val, struct ui_file *stream, int format,
+ int deref_ref, int recurse, enum val_prettyprint pretty)
+{
+ if (!value_check_printable (val, stream))
+ return 0;
+
+ return val_print (value_type (val), value_contents_all (val),
+ value_embedded_offset (val), VALUE_ADDRESS (val),
+ stream, format, deref_ref, recurse, pretty);
+}
+
+/* Print the value VAL in C-ish syntax on stream STREAM.
+ FORMAT is a format-letter, or 0 for print in natural format of data type.
+ If the object printed is a string pointer, returns
+ the number of string bytes printed. */
+
+int
+value_print (struct value *val, struct ui_file *stream, int format,
+ enum val_prettyprint pretty)
+{
+ if (!value_check_printable (val, stream))
+ return 0;
+
return LA_VALUE_PRINT (val, stream, format, pretty);
}
value. STREAM is where to print the value. */
void
-val_print_type_code_int (struct type *type, char *valaddr,
+val_print_type_code_int (struct type *type, const gdb_byte *valaddr,
struct ui_file *stream)
{
if (TYPE_LENGTH (type) > sizeof (LONGEST))
}
else
{
-#ifdef PRINT_TYPELESS_INTEGER
- PRINT_TYPELESS_INTEGER (stream, type, unpack_long (type, valaddr));
-#else
print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0,
unpack_long (type, valaddr));
-#endif
- }
-}
-
-/* Print a number according to FORMAT which is one of d,u,x,o,b,h,w,g.
- The raison d'etre of this function is to consolidate printing of
- LONG_LONG's into this one function. Some platforms have long longs but
- don't have a printf() that supports "ll" in the format string. We handle
- these by seeing if the number is representable as either a signed or
- unsigned long, depending upon what format is desired, and if not we just
- bail out and print the number in hex.
-
- The format chars b,h,w,g are from print_scalar_formatted(). If USE_LOCAL,
- format it according to the current language (this should be used for most
- integers which GDB prints, the exception is things like protocols where
- the format of the integer is a protocol thing, not a user-visible thing).
- */
-
-#if defined (CC_HAS_LONG_LONG) && !defined (PRINTF_HAS_LONG_LONG)
-static void print_decimal (struct ui_file * stream, char *sign,
- int use_local, ULONGEST val_ulong);
-static void
-print_decimal (struct ui_file *stream, char *sign, int use_local,
- ULONGEST val_ulong)
-{
- unsigned long temp[3];
- int i = 0;
- do
- {
- temp[i] = val_ulong % (1000 * 1000 * 1000);
- val_ulong /= (1000 * 1000 * 1000);
- i++;
- }
- while (val_ulong != 0 && i < (sizeof (temp) / sizeof (temp[0])));
- switch (i)
- {
- case 1:
- fprintf_filtered (stream, "%s%lu",
- sign, temp[0]);
- break;
- case 2:
- fprintf_filtered (stream, "%s%lu%09lu",
- sign, temp[1], temp[0]);
- break;
- case 3:
- fprintf_filtered (stream, "%s%lu%09lu%09lu",
- sign, temp[2], temp[1], temp[0]);
- break;
- default:
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
}
- return;
}
-#endif
void
-print_longest (struct ui_file *stream, int format, int use_local,
- LONGEST val_long)
+val_print_type_code_flags (struct type *type, const gdb_byte *valaddr,
+ struct ui_file *stream)
{
-#if defined (CC_HAS_LONG_LONG) && !defined (PRINTF_HAS_LONG_LONG)
- if (sizeof (long) < sizeof (LONGEST))
+ ULONGEST val = unpack_long (type, valaddr);
+ int bitpos, nfields = TYPE_NFIELDS (type);
+
+ fputs_filtered ("[ ", stream);
+ for (bitpos = 0; bitpos < nfields; bitpos++)
{
- switch (format)
+ if (TYPE_FIELD_BITPOS (type, bitpos) != -1
+ && (val & ((ULONGEST)1 << bitpos)))
{
- case 'd':
- {
- /* Print a signed value, that doesn't fit in a long */
- if ((long) val_long != val_long)
- {
- if (val_long < 0)
- print_decimal (stream, "-", use_local, -val_long);
- else
- print_decimal (stream, "", use_local, val_long);
- return;
- }
- break;
- }
- case 'u':
- {
- /* Print an unsigned value, that doesn't fit in a long */
- if ((unsigned long) val_long != (ULONGEST) val_long)
- {
- print_decimal (stream, "", use_local, val_long);
- return;
- }
- break;
- }
- case 'x':
- case 'o':
- case 'b':
- case 'h':
- case 'w':
- case 'g':
- /* Print as unsigned value, must fit completely in unsigned long */
- {
- unsigned long temp = val_long;
- if (temp != val_long)
- {
- /* Urk, can't represent value in long so print in hex.
- Do shift in two operations so that if sizeof (long)
- == sizeof (LONGEST) we can avoid warnings from
- picky compilers about shifts >= the size of the
- shiftee in bits */
- unsigned long vbot = (unsigned long) val_long;
- LONGEST temp = (val_long >> (sizeof (long) * HOST_CHAR_BIT - 1));
- unsigned long vtop = temp >> 1;
- fprintf_filtered (stream, "0x%lx%08lx", vtop, vbot);
- return;
- }
- break;
- }
+ if (TYPE_FIELD_NAME (type, bitpos))
+ fprintf_filtered (stream, "%s ", TYPE_FIELD_NAME (type, bitpos));
+ else
+ fprintf_filtered (stream, "#%d ", bitpos);
}
}
-#endif
-
-#if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG)
- switch (format)
- {
- case 'd':
- fprintf_filtered (stream,
- use_local ? local_decimal_format_custom ("ll")
- : "%lld",
- val_long);
- break;
- case 'u':
- fprintf_filtered (stream, "%llu", val_long);
- break;
- case 'x':
- fprintf_filtered (stream,
- use_local ? local_hex_format_custom ("ll")
- : "%llx",
- val_long);
- break;
- case 'o':
- fprintf_filtered (stream,
- use_local ? local_octal_format_custom ("ll")
- : "%llo",
- val_long);
- break;
- case 'b':
- fprintf_filtered (stream, local_hex_format_custom ("02ll"), val_long);
- break;
- case 'h':
- fprintf_filtered (stream, local_hex_format_custom ("04ll"), val_long);
- break;
- case 'w':
- fprintf_filtered (stream, local_hex_format_custom ("08ll"), val_long);
- break;
- case 'g':
- fprintf_filtered (stream, local_hex_format_custom ("016ll"), val_long);
- break;
- default:
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
- }
-#else /* !CC_HAS_LONG_LONG || !PRINTF_HAS_LONG_LONG */
- /* In the following it is important to coerce (val_long) to a long. It does
- nothing if !LONG_LONG, but it will chop off the top half (which we know
- we can ignore) if the host supports long longs. */
-
- switch (format)
- {
- case 'd':
- fprintf_filtered (stream,
- use_local ? local_decimal_format_custom ("l")
- : "%ld",
- (long) val_long);
- break;
- case 'u':
- fprintf_filtered (stream, "%lu", (unsigned long) val_long);
- break;
- case 'x':
- fprintf_filtered (stream,
- use_local ? local_hex_format_custom ("l")
- : "%lx",
- (unsigned long) val_long);
- break;
- case 'o':
- fprintf_filtered (stream,
- use_local ? local_octal_format_custom ("l")
- : "%lo",
- (unsigned long) val_long);
- break;
- case 'b':
- fprintf_filtered (stream, local_hex_format_custom ("02l"),
- (unsigned long) val_long);
- break;
- case 'h':
- fprintf_filtered (stream, local_hex_format_custom ("04l"),
- (unsigned long) val_long);
- break;
- case 'w':
- fprintf_filtered (stream, local_hex_format_custom ("08l"),
- (unsigned long) val_long);
- break;
- case 'g':
- fprintf_filtered (stream, local_hex_format_custom ("016l"),
- (unsigned long) val_long);
- break;
- default:
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
- }
-#endif /* CC_HAS_LONG_LONG || PRINTF_HAS_LONG_LONG */
+ fputs_filtered ("]", stream);
}
-#if 0
+/* Print a number according to FORMAT which is one of d,u,x,o,b,h,w,g.
+ The raison d'etre of this function is to consolidate printing of
+ LONG_LONG's into this one function. The format chars b,h,w,g are
+ from print_scalar_formatted(). Numbers are printed using C
+ format.
+
+ USE_C_FORMAT means to use C format in all cases. Without it,
+ 'o' and 'x' format do not include the standard C radix prefix
+ (leading 0 or 0x).
+
+ Hilfinger/2004-09-09: USE_C_FORMAT was originally called USE_LOCAL
+ and was intended to request formating according to the current
+ language and would be used for most integers that GDB prints. The
+ exceptional cases were things like protocols where the format of
+ the integer is a protocol thing, not a user-visible thing). The
+ parameter remains to preserve the information of what things might
+ be printed with language-specific format, should we ever resurrect
+ that capability. */
+
void
-strcat_longest (int format, int use_local, LONGEST val_long, char *buf,
- int buflen)
+print_longest (struct ui_file *stream, int format, int use_c_format,
+ LONGEST val_long)
{
-/* FIXME: Use buflen to avoid buffer overflow. */
-#if defined (CC_HAS_LONG_LONG) && !defined (PRINTF_HAS_LONG_LONG)
- long vtop, vbot;
-
- vtop = val_long >> (sizeof (long) * HOST_CHAR_BIT);
- vbot = (long) val_long;
-
- if ((format == 'd' && (val_long < INT_MIN || val_long > INT_MAX))
- || ((format == 'u' || format == 'x') && (unsigned long long) val_long > UINT_MAX))
- {
- sprintf (buf, "0x%lx%08lx", vtop, vbot);
- return;
- }
-#endif
+ const char *val;
-#ifdef PRINTF_HAS_LONG_LONG
switch (format)
{
case 'd':
- sprintf (buf,
- (use_local ? local_decimal_format_custom ("ll") : "%lld"),
- val_long);
- break;
+ val = int_string (val_long, 10, 1, 0, 1); break;
case 'u':
- sprintf (buf, "%llu", val_long);
- break;
+ val = int_string (val_long, 10, 0, 0, 1); break;
case 'x':
- sprintf (buf,
- (use_local ? local_hex_format_custom ("ll") : "%llx"),
-
- val_long);
- break;
- case 'o':
- sprintf (buf,
- (use_local ? local_octal_format_custom ("ll") : "%llo"),
- val_long);
- break;
+ val = int_string (val_long, 16, 0, 0, use_c_format); break;
case 'b':
- sprintf (buf, local_hex_format_custom ("02ll"), val_long);
- break;
+ val = int_string (val_long, 16, 0, 2, 1); break;
case 'h':
- sprintf (buf, local_hex_format_custom ("04ll"), val_long);
- break;
+ val = int_string (val_long, 16, 0, 4, 1); break;
case 'w':
- sprintf (buf, local_hex_format_custom ("08ll"), val_long);
- break;
+ val = int_string (val_long, 16, 0, 8, 1); break;
case 'g':
- sprintf (buf, local_hex_format_custom ("016ll"), val_long);
- break;
- default:
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
- }
-#else /* !PRINTF_HAS_LONG_LONG */
- /* In the following it is important to coerce (val_long) to a long. It does
- nothing if !LONG_LONG, but it will chop off the top half (which we know
- we can ignore) if the host supports long longs. */
-
- switch (format)
- {
- case 'd':
- sprintf (buf, (use_local ? local_decimal_format_custom ("l") : "%ld"),
- ((long) val_long));
- break;
- case 'u':
- sprintf (buf, "%lu", ((unsigned long) val_long));
- break;
- case 'x':
- sprintf (buf, (use_local ? local_hex_format_custom ("l") : "%lx"),
- ((long) val_long));
+ val = int_string (val_long, 16, 0, 16, 1); break;
break;
case 'o':
- sprintf (buf, (use_local ? local_octal_format_custom ("l") : "%lo"),
- ((long) val_long));
- break;
- case 'b':
- sprintf (buf, local_hex_format_custom ("02l"),
- ((long) val_long));
- break;
- case 'h':
- sprintf (buf, local_hex_format_custom ("04l"),
- ((long) val_long));
- break;
- case 'w':
- sprintf (buf, local_hex_format_custom ("08l"),
- ((long) val_long));
- break;
- case 'g':
- sprintf (buf, local_hex_format_custom ("016l"),
- ((long) val_long));
- break;
+ val = int_string (val_long, 8, 0, 0, use_c_format); break;
default:
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
- }
-
-#endif /* !PRINTF_HAS_LONG_LONG */
+ internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
+ }
+ fputs_filtered (val, stream);
}
-#endif
/* This used to be a macro, but I don't think it is called often enough
to merit such treatment. */
{
if (rtnval != arg)
{
- error ("Value out of range.");
+ error (_("Value out of range."));
}
}
return (rtnval);
}
-
-/* Print a floating point value of type TYPE, pointed to in GDB by VALADDR,
- on STREAM. */
+/* Print a floating point value of type TYPE (not always a
+ TYPE_CODE_FLT), pointed to in GDB by VALADDR, on STREAM. */
void
-print_floating (char *valaddr, struct type *type, struct ui_file *stream)
+print_floating (const gdb_byte *valaddr, struct type *type,
+ struct ui_file *stream)
{
DOUBLEST doub;
int inv;
+ const struct floatformat *fmt = NULL;
unsigned len = TYPE_LENGTH (type);
+ enum float_kind kind;
- /* Check for NaN's. Note that this code does not depend on us being
- on an IEEE conforming system. It only depends on the target
- machine using IEEE representation. This means (a)
- cross-debugging works right, and (2) IEEE_FLOAT can (and should)
- be non-zero for systems like the 68881, which uses IEEE
- representation, but is not IEEE conforming. */
- if (IEEE_FLOAT)
+ /* If it is a floating-point, check for obvious problems. */
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ fmt = floatformat_from_type (type);
+ if (fmt != NULL)
{
- unsigned long low, high;
- /* Is the sign bit 0? */
- int nonnegative;
- /* Is it is a NaN (i.e. the exponent is all ones and
- the fraction is nonzero)? */
- int is_nan;
-
- /* For lint, initialize these two variables to suppress warning: */
- low = high = nonnegative = 0;
- if (len == 4)
- {
- /* It's single precision. */
- /* Assume that floating point byte order is the same as
- integer byte order. */
- low = extract_unsigned_integer (valaddr, 4);
- nonnegative = ((low & 0x80000000) == 0);
- is_nan = ((((low >> 23) & 0xFF) == 0xFF)
- && 0 != (low & 0x7FFFFF));
- low &= 0x7fffff;
- high = 0;
- }
- else if (len == 8)
+ kind = floatformat_classify (fmt, valaddr);
+ if (kind == float_nan)
{
- /* It's double precision. Get the high and low words. */
-
- /* Assume that floating point byte order is the same as
- integer byte order. */
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
- {
- low = extract_unsigned_integer (valaddr + 4, 4);
- high = extract_unsigned_integer (valaddr, 4);
- }
- else
- {
- low = extract_unsigned_integer (valaddr, 4);
- high = extract_unsigned_integer (valaddr + 4, 4);
- }
- nonnegative = ((high & 0x80000000) == 0);
- is_nan = (((high >> 20) & 0x7ff) == 0x7ff
- && !((((high & 0xfffff) == 0)) && (low == 0)));
- high &= 0xfffff;
- }
- else
- {
-#ifdef TARGET_ANALYZE_FLOATING
- TARGET_ANALYZE_FLOATING;
-#else
- /* Extended. We can't detect extended NaNs for this target.
- Also note that currently extendeds get nuked to double in
- REGISTER_CONVERTIBLE. */
- is_nan = 0;
-#endif
+ if (floatformat_is_negative (fmt, valaddr))
+ fprintf_filtered (stream, "-");
+ fprintf_filtered (stream, "nan(");
+ fputs_filtered ("0x", stream);
+ fputs_filtered (floatformat_mantissa (fmt, valaddr), stream);
+ fprintf_filtered (stream, ")");
+ return;
}
-
- if (is_nan)
+ else if (kind == float_infinite)
{
- /* The meaning of the sign and fraction is not defined by IEEE.
- But the user might know what they mean. For example, they
- (in an implementation-defined manner) distinguish between
- signaling and quiet NaN's. */
- if (high)
- fprintf_filtered (stream, "-NaN(0x%lx%.8lx)" + !!nonnegative,
- high, low);
- else
- fprintf_filtered (stream, "-NaN(0x%lx)" + nonnegative, low);
+ if (floatformat_is_negative (fmt, valaddr))
+ fputs_filtered ("-", stream);
+ fputs_filtered ("inf", stream);
return;
}
}
+ /* NOTE: cagney/2002-01-15: The TYPE passed into print_floating()
+ isn't necessarily a TYPE_CODE_FLT. Consequently, unpack_double
+ needs to be used as that takes care of any necessary type
+ conversions. Such conversions are of course direct to DOUBLEST
+ and disregard any possible target floating point limitations.
+ For instance, a u64 would be converted and displayed exactly on a
+ host with 80 bit DOUBLEST but with loss of information on a host
+ with 64 bit DOUBLEST. */
+
doub = unpack_double (type, valaddr, &inv);
if (inv)
{
return;
}
+ /* FIXME: kettenis/2001-01-20: The following code makes too much
+ assumptions about the host and target floating point format. */
+
+ /* NOTE: cagney/2002-02-03: Since the TYPE of what was passed in may
+ not necessarily be a TYPE_CODE_FLT, the below ignores that and
+ instead uses the type's length to determine the precision of the
+ floating-point value being printed. */
+
if (len < sizeof (double))
fprintf_filtered (stream, "%.9g", (double) doub);
else if (len == sizeof (double))
#ifdef PRINTF_HAS_LONG_DOUBLE
fprintf_filtered (stream, "%.35Lg", doub);
#else
- /* This at least wins with values that are representable as doubles */
+ /* This at least wins with values that are representable as
+ doubles. */
fprintf_filtered (stream, "%.17g", (double) doub);
#endif
}
void
-print_binary_chars (struct ui_file *stream, unsigned char *valaddr,
+print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr,
unsigned len)
{
#define BITS_IN_BYTES 8
- unsigned char *p;
+ const gdb_byte *p;
unsigned int i;
int b;
/* FIXME: We should be not printing leading zeroes in most cases. */
- fprintf_filtered (stream, local_binary_format_prefix ());
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
{
for (p = valaddr;
p < valaddr + len;
}
}
}
- fprintf_filtered (stream, local_binary_format_suffix ());
}
/* VALADDR points to an integer of LEN bytes.
* Print it in octal on stream or format it in buf.
*/
void
-print_octal_chars (struct ui_file *stream, unsigned char *valaddr, unsigned len)
+print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
+ unsigned len)
{
- unsigned char *p;
+ const gdb_byte *p;
unsigned char octa1, octa2, octa3, carry;
int cycle;
cycle = (len * BITS_IN_BYTES) % BITS_IN_OCTAL;
carry = 0;
- fprintf_filtered (stream, local_octal_format_prefix ());
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ fputs_filtered ("0", stream);
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
{
for (p = valaddr;
p < valaddr + len;
break;
default:
- error ("Internal error in octal conversion;");
+ error (_("Internal error in octal conversion;"));
}
cycle++;
break;
default:
- error ("Internal error in octal conversion;");
+ error (_("Internal error in octal conversion;"));
}
cycle++;
}
}
- fprintf_filtered (stream, local_octal_format_suffix ());
}
/* VALADDR points to an integer of LEN bytes.
* Print it in decimal on stream or format it in buf.
*/
void
-print_decimal_chars (struct ui_file *stream, unsigned char *valaddr,
+print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
unsigned len)
{
#define TEN 10
#define CARRY_LEFT( x ) ((x) % TEN)
#define SHIFT( x ) ((x) << 4)
#define START_P \
- ((TARGET_BYTE_ORDER == BIG_ENDIAN) ? valaddr : valaddr + len - 1)
+ ((gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) ? valaddr : valaddr + len - 1)
#define NOT_END_P \
- ((TARGET_BYTE_ORDER == BIG_ENDIAN) ? (p < valaddr + len) : (p >= valaddr))
+ ((gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) ? (p < valaddr + len) : (p >= valaddr))
#define NEXT_P \
- ((TARGET_BYTE_ORDER == BIG_ENDIAN) ? p++ : p-- )
+ ((gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) ? p++ : p-- )
#define LOW_NIBBLE( x ) ( (x) & 0x00F)
#define HIGH_NIBBLE( x ) (((x) & 0x0F0) >> 4)
- unsigned char *p;
+ const gdb_byte *p;
unsigned char *digits;
int carry;
int decimal_len;
* as the base 16 number, which is 2 digits per byte.
*/
decimal_len = len * 2 * 2;
- digits = (unsigned char *) malloc (decimal_len);
- if (digits == NULL)
- error ("Can't allocate memory for conversion to decimal.");
+ digits = xmalloc (decimal_len);
for (i = 0; i < decimal_len; i++)
{
digits[i] = 0;
}
- fprintf_filtered (stream, local_decimal_format_prefix ());
-
/* Ok, we have an unknown number of bytes of data to be printed in
* decimal.
*
fprintf_filtered (stream, "%1d", digits[i]);
}
xfree (digits);
-
- fprintf_filtered (stream, local_decimal_format_suffix ());
}
/* VALADDR points to an integer of LEN bytes. Print it in hex on stream. */
-static void
-print_hex_chars (struct ui_file *stream, unsigned char *valaddr, unsigned len)
+void
+print_hex_chars (struct ui_file *stream, const gdb_byte *valaddr,
+ unsigned len)
{
- unsigned char *p;
+ const gdb_byte *p;
/* FIXME: We should be not printing leading zeroes in most cases. */
- fprintf_filtered (stream, local_hex_format_prefix ());
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ fputs_filtered ("0x", stream);
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
{
for (p = valaddr;
p < valaddr + len;
fprintf_filtered (stream, "%02x", *p);
}
}
- fprintf_filtered (stream, local_hex_format_suffix ());
}
+/* VALADDR points to a char integer of LEN bytes. Print it out in appropriate language form on stream.
+ Omit any leading zero chars. */
+
+void
+print_char_chars (struct ui_file *stream, const gdb_byte *valaddr,
+ unsigned len)
+{
+ const gdb_byte *p;
+
+ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+ {
+ p = valaddr;
+ while (p < valaddr + len - 1 && *p == 0)
+ ++p;
+
+ while (p < valaddr + len)
+ {
+ LA_EMIT_CHAR (*p, stream, '\'');
+ ++p;
+ }
+ }
+ else
+ {
+ p = valaddr + len - 1;
+ while (p > valaddr && *p == 0)
+ --p;
+
+ while (p >= valaddr)
+ {
+ LA_EMIT_CHAR (*p, stream, '\'');
+ --p;
+ }
+ }
+}
+
+/* Return non-zero if the debugger should print the index of each element
+ when printing array values. */
+
+int
+print_array_indexes_p (void)
+{
+ return print_array_indexes;
+}
+
+/* Assuming TYPE is a simple, non-empty array type, compute its lower bound.
+ Save it into LOW_BOUND if not NULL.
+
+ Return 1 if the operation was successful. Return zero otherwise,
+ in which case the value of LOW_BOUND is unmodified.
+
+ Computing the array lower bound is pretty easy, but this function
+ does some additional verifications before returning the low bound.
+ If something incorrect is detected, it is better to return a status
+ rather than throwing an error, making it easier for the caller to
+ implement an error-recovery plan. For instance, it may decide to
+ warn the user that the bound was not found and then use a default
+ value instead. */
+
+int
+get_array_low_bound (struct type *type, long *low_bound)
+{
+ struct type *index = TYPE_INDEX_TYPE (type);
+ long low = 0;
+
+ if (index == NULL)
+ return 0;
+
+ if (TYPE_CODE (index) != TYPE_CODE_RANGE
+ && TYPE_CODE (index) != TYPE_CODE_ENUM)
+ return 0;
+
+ low = TYPE_LOW_BOUND (index);
+ if (low > TYPE_HIGH_BOUND (index))
+ return 0;
+
+ if (low_bound)
+ *low_bound = low;
+
+ return 1;
+}
+
+/* Print on STREAM using the given FORMAT the index for the element
+ at INDEX of an array whose index type is INDEX_TYPE. */
+
+void
+maybe_print_array_index (struct type *index_type, LONGEST index,
+ struct ui_file *stream, int format,
+ enum val_prettyprint pretty)
+{
+ struct value *index_value;
+
+ if (!print_array_indexes)
+ return;
+
+ index_value = value_from_longest (index_type, index);
+
+ LA_PRINT_ARRAY_INDEX (index_value, stream, format, pretty);
+}
+
/* Called by various <lang>_val_print routines to print elements of an
array in the form "<elem1>, <elem2>, <elem3>, ...".
*/
void
-val_print_array_elements (struct type *type, char *valaddr, CORE_ADDR address,
- struct ui_file *stream, int format, int deref_ref,
+val_print_array_elements (struct type *type, const gdb_byte *valaddr,
+ CORE_ADDR address, struct ui_file *stream,
+ int format, int deref_ref,
int recurse, enum val_prettyprint pretty,
unsigned int i)
{
unsigned int things_printed = 0;
unsigned len;
- struct type *elttype;
+ struct type *elttype, *index_type;
unsigned eltlen;
/* Position of the array element we are examining to see
whether it is repeated. */
unsigned int rep1;
/* Number of repetitions we have detected so far. */
unsigned int reps;
+ long low_bound_index = 0;
elttype = TYPE_TARGET_TYPE (type);
eltlen = TYPE_LENGTH (check_typedef (elttype));
len = TYPE_LENGTH (type) / eltlen;
+ index_type = TYPE_INDEX_TYPE (type);
+
+ /* Get the array low bound. This only makes sense if the array
+ has one or more element in it. */
+ if (len > 0 && !get_array_low_bound (type, &low_bound_index))
+ {
+ warning ("unable to get low bound of array, using zero as default");
+ low_bound_index = 0;
+ }
annotate_array_section_begin (i, elttype);
}
}
wrap_here (n_spaces (2 + 2 * recurse));
+ maybe_print_array_index (index_type, i + low_bound_index,
+ stream, format, pretty);
rep1 = i + 1;
reps = 1;
function be eliminated. */
static int
-partial_memory_read (CORE_ADDR memaddr, char *myaddr, int len, int *errnoptr)
+partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int *errnoptr)
{
int nread; /* Number of bytes actually read. */
int errcode; /* Error from last read. */
unsigned int fetchlimit; /* Maximum number of chars to print. */
unsigned int nfetch; /* Chars to fetch / chars fetched. */
unsigned int chunksize; /* Size of each fetch, in chars. */
- char *buffer = NULL; /* Dynamically growable fetch buffer. */
- char *bufptr; /* Pointer to next available byte in buffer. */
- char *limit; /* First location past end of fetch buffer. */
+ gdb_byte *buffer = NULL; /* Dynamically growable fetch buffer. */
+ gdb_byte *bufptr; /* Pointer to next available byte in buffer. */
+ gdb_byte *limit; /* First location past end of fetch buffer. */
struct cleanup *old_chain = NULL; /* Top of the old cleanup chain. */
int found_nul; /* Non-zero if we found the nul char */
if (len > 0)
{
- buffer = (char *) xmalloc (len * width);
+ buffer = (gdb_byte *) xmalloc (len * width);
bufptr = buffer;
old_chain = make_cleanup (xfree, buffer);
nfetch = min (chunksize, fetchlimit - bufsize);
if (buffer == NULL)
- buffer = (char *) xmalloc (nfetch * width);
+ buffer = (gdb_byte *) xmalloc (nfetch * width);
else
{
discard_cleanups (old_chain);
- buffer = (char *) xrealloc (buffer, (nfetch + bufsize) * width);
+ buffer = (gdb_byte *) xrealloc (buffer, (nfetch + bufsize) * width);
}
old_chain = make_cleanup (xfree, buffer);
if (len == -1 && !found_nul)
{
- char *peekbuf;
+ gdb_byte *peekbuf;
/* We didn't find a null terminator we were looking for. Attempt
to peek at the next character. If not successful, or it is not
a null byte, then force ellipsis to be printed. */
- peekbuf = (char *) alloca (width);
+ peekbuf = (gdb_byte *) alloca (width);
if (target_read_memory (addr, peekbuf, width) == 0
&& extract_unsigned_integer (peekbuf, width) != 0)
if (errcode == EIO)
{
fprintf_filtered (stream, " <Address ");
- print_address_numeric (addr, 1, stream);
+ deprecated_print_address_numeric (addr, 1, stream);
fprintf_filtered (stream, " out of bounds>");
}
else
{
fprintf_filtered (stream, " <Error reading address ");
- print_address_numeric (addr, 1, stream);
+ deprecated_print_address_numeric (addr, 1, stream);
fprintf_filtered (stream, ": %s>", safe_strerror (errcode));
}
}
knows what they really did here. Radix setting is confusing, e.g.
setting the input radix to "10" never changes it! */
-/* ARGSUSED */
static void
set_input_radix (char *args, int from_tty, struct cmd_list_element *c)
{
- set_input_radix_1 (from_tty, *(unsigned *) c->var);
+ set_input_radix_1 (from_tty, input_radix);
}
-/* ARGSUSED */
static void
set_input_radix_1 (int from_tty, unsigned radix)
{
if (radix < 2)
{
- error ("Nonsense input radix ``decimal %u''; input radix unchanged.",
+ /* FIXME: cagney/2002-03-17: This needs to revert the bad radix
+ value. */
+ error (_("Nonsense input radix ``decimal %u''; input radix unchanged."),
radix);
}
input_radix = radix;
if (from_tty)
{
- printf_filtered ("Input radix now set to decimal %u, hex %x, octal %o.\n",
+ printf_filtered (_("Input radix now set to decimal %u, hex %x, octal %o.\n"),
radix, radix, radix);
}
}
-/* ARGSUSED */
static void
set_output_radix (char *args, int from_tty, struct cmd_list_element *c)
{
- set_output_radix_1 (from_tty, *(unsigned *) c->var);
+ set_output_radix_1 (from_tty, output_radix);
}
static void
output_format = 'o'; /* octal */
break;
default:
- error ("Unsupported output radix ``decimal %u''; output radix unchanged.",
+ /* FIXME: cagney/2002-03-17: This needs to revert the bad radix
+ value. */
+ error (_("Unsupported output radix ``decimal %u''; output radix unchanged."),
radix);
}
output_radix = radix;
if (from_tty)
{
- printf_filtered ("Output radix now set to decimal %u, hex %x, octal %o.\n",
+ printf_filtered (_("Output radix now set to decimal %u, hex %x, octal %o.\n"),
radix, radix, radix);
}
}
set_input_radix_1 (0, radix);
if (from_tty)
{
- printf_filtered ("Input and output radices now set to decimal %u, hex %x, octal %o.\n",
+ printf_filtered (_("Input and output radices now set to decimal %u, hex %x, octal %o.\n"),
radix, radix, radix);
}
}
/* Show both the input and output radices. */
-/*ARGSUSED */
static void
show_radix (char *arg, int from_tty)
{
{
if (input_radix == output_radix)
{
- printf_filtered ("Input and output radices set to decimal %u, hex %x, octal %o.\n",
+ printf_filtered (_("Input and output radices set to decimal %u, hex %x, octal %o.\n"),
input_radix, input_radix, input_radix);
}
else
{
- printf_filtered ("Input radix set to decimal %u, hex %x, octal %o.\n",
+ printf_filtered (_("Input radix set to decimal %u, hex %x, octal %o.\n"),
input_radix, input_radix, input_radix);
- printf_filtered ("Output radix set to decimal %u, hex %x, octal %o.\n",
+ printf_filtered (_("Output radix set to decimal %u, hex %x, octal %o.\n"),
output_radix, output_radix, output_radix);
}
}
}
\f
-/*ARGSUSED */
static void
set_print (char *arg, int from_tty)
{
help_list (setprintlist, "set print ", -1, gdb_stdout);
}
-/*ARGSUSED */
static void
show_print (char *args, int from_tty)
{
struct cmd_list_element *c;
add_prefix_cmd ("print", no_class, set_print,
- "Generic command for setting how things print.",
+ _("Generic command for setting how things print."),
&setprintlist, "set print ", 0, &setlist);
add_alias_cmd ("p", "print", no_class, 1, &setlist);
/* prefer set print to set prompt */
add_alias_cmd ("pr", "print", no_class, 1, &setlist);
add_prefix_cmd ("print", no_class, show_print,
- "Generic command for showing print settings.",
+ _("Generic command for showing print settings."),
&showprintlist, "show print ", 0, &showlist);
add_alias_cmd ("p", "print", no_class, 1, &showlist);
add_alias_cmd ("pr", "print", no_class, 1, &showlist);
- add_show_from_set
- (add_set_cmd ("elements", no_class, var_uinteger, (char *) &print_max,
- "Set limit on string chars or array elements to print.\n\
-\"set print elements 0\" causes there to be no limit.",
- &setprintlist),
- &showprintlist);
-
- add_show_from_set
- (add_set_cmd ("null-stop", no_class, var_boolean,
- (char *) &stop_print_at_null,
- "Set printing of char arrays to stop at first null char.",
- &setprintlist),
- &showprintlist);
-
- add_show_from_set
- (add_set_cmd ("repeats", no_class, var_uinteger,
- (char *) &repeat_count_threshold,
- "Set threshold for repeated print elements.\n\
-\"set print repeats 0\" causes all elements to be individually printed.",
- &setprintlist),
- &showprintlist);
-
- add_show_from_set
- (add_set_cmd ("pretty", class_support, var_boolean,
- (char *) &prettyprint_structs,
- "Set prettyprinting of structures.",
- &setprintlist),
- &showprintlist);
-
- add_show_from_set
- (add_set_cmd ("union", class_support, var_boolean, (char *) &unionprint,
- "Set printing of unions interior to structures.",
- &setprintlist),
- &showprintlist);
-
- add_show_from_set
- (add_set_cmd ("array", class_support, var_boolean,
- (char *) &prettyprint_arrays,
- "Set prettyprinting of arrays.",
- &setprintlist),
- &showprintlist);
-
- add_show_from_set
- (add_set_cmd ("address", class_support, var_boolean, (char *) &addressprint,
- "Set printing of addresses.",
- &setprintlist),
- &showprintlist);
-
- c = add_set_cmd ("input-radix", class_support, var_uinteger,
- (char *) &input_radix,
- "Set default input radix for entering numbers.",
- &setlist);
- add_show_from_set (c, &showlist);
- c->function.sfunc = set_input_radix;
-
- c = add_set_cmd ("output-radix", class_support, var_uinteger,
- (char *) &output_radix,
- "Set default output radix for printing of values.",
- &setlist);
- add_show_from_set (c, &showlist);
- c->function.sfunc = set_output_radix;
-
- /* The "set radix" and "show radix" commands are special in that they are
- like normal set and show commands but allow two normally independent
- variables to be either set or shown with a single command. So the
- usual add_set_cmd() and add_show_from_set() commands aren't really
- appropriate. */
- add_cmd ("radix", class_support, set_radix,
- "Set default input and output number radices.\n\
+ add_setshow_uinteger_cmd ("elements", no_class, &print_max, _("\
+Set limit on string chars or array elements to print."), _("\
+Show limit on string chars or array elements to print."), _("\
+\"set print elements 0\" causes there to be no limit."),
+ NULL,
+ show_print_max,
+ &setprintlist, &showprintlist);
+
+ add_setshow_boolean_cmd ("null-stop", no_class, &stop_print_at_null, _("\
+Set printing of char arrays to stop at first null char."), _("\
+Show printing of char arrays to stop at first null char."), NULL,
+ NULL,
+ show_stop_print_at_null,
+ &setprintlist, &showprintlist);
+
+ add_setshow_uinteger_cmd ("repeats", no_class,
+ &repeat_count_threshold, _("\
+Set threshold for repeated print elements."), _("\
+Show threshold for repeated print elements."), _("\
+\"set print repeats 0\" causes all elements to be individually printed."),
+ NULL,
+ show_repeat_count_threshold,
+ &setprintlist, &showprintlist);
+
+ add_setshow_boolean_cmd ("pretty", class_support, &prettyprint_structs, _("\
+Set prettyprinting of structures."), _("\
+Show prettyprinting of structures."), NULL,
+ NULL,
+ show_prettyprint_structs,
+ &setprintlist, &showprintlist);
+
+ add_setshow_boolean_cmd ("union", class_support, &unionprint, _("\
+Set printing of unions interior to structures."), _("\
+Show printing of unions interior to structures."), NULL,
+ NULL,
+ show_unionprint,
+ &setprintlist, &showprintlist);
+
+ add_setshow_boolean_cmd ("array", class_support, &prettyprint_arrays, _("\
+Set prettyprinting of arrays."), _("\
+Show prettyprinting of arrays."), NULL,
+ NULL,
+ show_prettyprint_arrays,
+ &setprintlist, &showprintlist);
+
+ add_setshow_boolean_cmd ("address", class_support, &addressprint, _("\
+Set printing of addresses."), _("\
+Show printing of addresses."), NULL,
+ NULL,
+ show_addressprint,
+ &setprintlist, &showprintlist);
+
+ add_setshow_uinteger_cmd ("input-radix", class_support, &input_radix, _("\
+Set default input radix for entering numbers."), _("\
+Show default input radix for entering numbers."), NULL,
+ set_input_radix,
+ show_input_radix,
+ &setlist, &showlist);
+
+ add_setshow_uinteger_cmd ("output-radix", class_support, &output_radix, _("\
+Set default output radix for printing of values."), _("\
+Show default output radix for printing of values."), NULL,
+ set_output_radix,
+ show_output_radix,
+ &setlist, &showlist);
+
+ /* The "set radix" and "show radix" commands are special in that
+ they are like normal set and show commands but allow two normally
+ independent variables to be either set or shown with a single
+ command. So the usual deprecated_add_set_cmd() and [deleted]
+ add_show_from_set() commands aren't really appropriate. */
+ /* FIXME: i18n: With the new add_setshow_integer command, that is no
+ longer true - show can display anything. */
+ add_cmd ("radix", class_support, set_radix, _("\
+Set default input and output number radices.\n\
Use 'set input-radix' or 'set output-radix' to independently set each.\n\
-Without an argument, sets both radices back to the default value of 10.",
+Without an argument, sets both radices back to the default value of 10."),
&setlist);
- add_cmd ("radix", class_support, show_radix,
- "Show the default input and output number radices.\n\
-Use 'show input-radix' or 'show output-radix' to independently show each.",
+ add_cmd ("radix", class_support, show_radix, _("\
+Show the default input and output number radices.\n\
+Use 'show input-radix' or 'show output-radix' to independently show each."),
&showlist);
+ add_setshow_boolean_cmd ("array-indexes", class_support,
+ &print_array_indexes, _("\
+Set printing of array indexes."), _("\
+Show printing of array indexes"), NULL, NULL, show_print_array_indexes,
+ &setprintlist, &showprintlist);
+
/* Give people the defaults which they are used to. */
prettyprint_structs = 0;
prettyprint_arrays = 0;