void _initialize_valprint (void);
-#define PRINT_MAX_DEFAULT 200 /* Start print_max off at this value. */
+#define PRINT_MAX_DEFAULT 200 /* Start print_max off at this value. */
struct value_print_options user_print_options =
{
/* 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. */
+ print routines. */
static void
show_repeat_count_threshold (struct ui_file *file, int from_tty,
value);
}
-/* If nonzero, stops printing of char arrays at first null. */
+/* If nonzero, stops printing of char arrays at first null. */
static void
show_stop_print_at_null (struct ui_file *file, int from_tty,
value);
}
-/* Controls pretty printing of structures. */
+/* Controls pretty printing of structures. */
static void
show_prettyprint_structs (struct ui_file *file, int from_tty,
}
/* If nonzero, causes unions inside structures or other unions to be
- printed. */
+ printed. */
static void
show_unionprint (struct ui_file *file, int from_tty,
value);
}
-/* If nonzero, causes machine addresses to be printed in certain contexts. */
+/* If nonzero, causes machine addresses to be printed in certain contexts. */
static void
show_addressprint (struct ui_file *file, int from_tty,
static int
valprint_check_validity (struct ui_file *stream,
struct type *type,
- int offset,
+ int embedded_offset,
const struct value *val)
{
CHECK_TYPEDEF (type);
&& TYPE_CODE (type) != TYPE_CODE_STRUCT
&& TYPE_CODE (type) != TYPE_CODE_ARRAY)
{
- if (! value_bits_valid (val, TARGET_CHAR_BIT * offset,
- TARGET_CHAR_BIT * TYPE_LENGTH (type)))
+ if (!value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset,
+ TARGET_CHAR_BIT * TYPE_LENGTH (type)))
{
- fprintf_filtered (stream, _("<value optimized out>"));
+ val_print_optimized_out (stream);
return 0;
}
- if (value_bits_synthetic_pointer (val, TARGET_CHAR_BIT * offset,
+ if (value_bits_synthetic_pointer (val, TARGET_CHAR_BIT * embedded_offset,
TARGET_CHAR_BIT * TYPE_LENGTH (type)))
{
fputs_filtered (_("<synthetic pointer>"), stream);
return 0;
}
+
+ if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
+ {
+ val_print_unavailable (stream);
+ return 0;
+ }
}
return 1;
}
-/* Print using the given LANGUAGE the data of type TYPE located at VALADDR
- (within GDB), which came from the inferior at address ADDRESS, onto
- stdio stream STREAM according to OPTIONS.
+void
+val_print_optimized_out (struct ui_file *stream)
+{
+ fprintf_filtered (stream, _("<optimized out>"));
+}
- If the data are a string pointer, returns the number of string characters
- printed.
+void
+val_print_unavailable (struct ui_file *stream)
+{
+ fprintf_filtered (stream, _("<unavailable>"));
+}
- FIXME: The data at VALADDR is in target byte order. If gdb is ever
- enhanced to be able to debug more than the single target it was compiled
- for (specific CPU type and thus specific target byte ordering), then
- either the print routines are going to have to take this into account,
- or the data is going to have to be passed into here already converted
- to the host byte ordering, whichever is more convenient. */
+void
+val_print_invalid_address (struct ui_file *stream)
+{
+ fprintf_filtered (stream, _("<invalid address>"));
+}
+/* Print using the given LANGUAGE the data of type TYPE located at
+ VALADDR + EMBEDDED_OFFSET (within GDB), which came from the
+ inferior at address ADDRESS + EMBEDDED_OFFSET, onto stdio stream
+ STREAM according to OPTIONS. VAL is the whole object that came
+ from ADDRESS. VALADDR must point to the head of VAL's contents
+ buffer.
+
+ The language printers will pass down an adjusted EMBEDDED_OFFSET to
+ further helper subroutines as subfields of TYPE are printed. In
+ such cases, VALADDR is passed down unadjusted, as well as VAL, so
+ that VAL can be queried for metadata about the contents data being
+ printed, using EMBEDDED_OFFSET as an offset into VAL's contents
+ buffer. For example: "has this field been optimized out", or "I'm
+ printing an object while inspecting a traceframe; has this
+ particular piece of data been collected?".
+
+ RECURSE indicates the amount of indentation to supply before
+ continuation lines; this amount is roughly twice the value of
+ RECURSE.
+
+ If the data is printed as a string, returns the number of string
+ characters printed. */
int
val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
if (value_entirely_optimized_out (val))
{
- fprintf_filtered (stream, _("<value optimized out>"));
+ val_print_optimized_out (stream);
return 0;
}
}
}
fputs_filtered ("]", stream);
+
+/* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR,
+ according to OPTIONS and SIZE on STREAM. Format i is not supported
+ at this level.
+
+ This is how the elements of an array or structure are printed
+ with a format. */
+}
+
+void
+val_print_scalar_formatted (struct type *type,
+ const gdb_byte *valaddr, int embedded_offset,
+ const struct value *val,
+ const struct value_print_options *options,
+ int size,
+ struct ui_file *stream)
+{
+ gdb_assert (val != NULL);
+ gdb_assert (valaddr == value_contents_for_printing_const (val));
+
+ /* If we get here with a string format, try again without it. Go
+ all the way back to the language printers, which may call us
+ again. */
+ if (options->format == 's')
+ {
+ struct value_print_options opts = *options;
+ opts.format = 0;
+ opts.deref_ref = 0;
+ val_print (type, valaddr, embedded_offset, 0, stream, 0, val, &opts,
+ current_language);
+ return;
+ }
+
+ /* A scalar object that does not have all bits available can't be
+ printed, because all bits contribute to its representation. */
+ if (!value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset,
+ TARGET_CHAR_BIT * TYPE_LENGTH (type)))
+ val_print_optimized_out (stream);
+ else if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
+ val_print_unavailable (stream);
+ else
+ print_scalar_formatted (valaddr + embedded_offset, type,
+ options, size, stream);
}
/* 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
+ 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.
+ 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
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. */
+ that capability. */
void
print_longest (struct ui_file *stream, int format, int use_c_format,
int
longest_to_int (LONGEST arg)
{
- /* Let the compiler do the work */
+ /* Let the compiler do the work. */
int rtnval = (int) arg;
- /* Check for overflows or underflows */
+ /* Check for overflows or underflows. */
if (sizeof (LONGEST) > sizeof (int))
{
if (rtnval != arg)
int b;
/* Declared "int" so it will be signed.
- * This ensures that right shift will shift in zeros.
- */
+ This ensures that right shift will shift in zeros. */
+
const int mask = 0x080;
/* FIXME: We should be not printing leading zeroes in most cases. */
p++)
{
/* Every byte has 8 binary characters; peel off
- * and print from the MSB end.
- */
+ and print from the MSB end. */
+
for (i = 0; i < (BITS_IN_BYTES * sizeof (*p)); i++)
{
if (*p & (mask >> i))
}
/* VALADDR points to an integer of LEN bytes.
- * Print it in octal on stream or format it in buf.
- */
+ Print it in octal on stream or format it in buf. */
+
void
print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
unsigned len, enum bfd_endian byte_order)
#define LOW_TWO 0007
/* For 32 we start in cycle 2, with two bits and one bit carry;
- * for 64 in cycle in cycle 1, with one bit and a two bit carry.
- */
+ for 64 in cycle in cycle 1, with one bit and a two bit carry. */
+
cycle = (len * BITS_IN_BYTES) % BITS_IN_OCTAL;
carry = 0;
switch (cycle)
{
case 0:
- /* No carry in, carry out two bits.
- */
+ /* No carry in, carry out two bits. */
+
octa1 = (HIGH_ZERO & *p) >> 5;
octa2 = (LOW_ZERO & *p) >> 2;
carry = (CARRY_ZERO & *p);
break;
case 1:
- /* Carry in two bits, carry out one bit.
- */
+ /* Carry in two bits, carry out one bit. */
+
octa1 = (carry << 1) | ((HIGH_ONE & *p) >> 7);
octa2 = (MID_ONE & *p) >> 4;
octa3 = (LOW_ONE & *p) >> 1;
break;
case 2:
- /* Carry in one bit, no carry out.
- */
+ /* Carry in one bit, no carry out. */
+
octa1 = (carry << 2) | ((HIGH_TWO & *p) >> 6);
octa2 = (MID_TWO & *p) >> 3;
octa3 = (LOW_TWO & *p);
{
case 0:
/* Carry out, no carry in */
+
octa1 = (HIGH_ZERO & *p) >> 5;
octa2 = (LOW_ZERO & *p) >> 2;
carry = (CARRY_ZERO & *p);
case 1:
/* Carry in, carry out */
+
octa1 = (carry << 1) | ((HIGH_ONE & *p) >> 7);
octa2 = (MID_ONE & *p) >> 4;
octa3 = (LOW_ONE & *p) >> 1;
case 2:
/* Carry in, no carry out */
+
octa1 = (carry << 2) | ((HIGH_TWO & *p) >> 6);
octa2 = (MID_TWO & *p) >> 3;
octa3 = (LOW_TWO & *p);
}
/* VALADDR points to an integer of LEN bytes.
- * Print it in decimal on stream or format it in buf.
- */
+ Print it in decimal on stream or format it in buf. */
+
void
print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
unsigned len, enum bfd_endian byte_order)
int flip;
/* Base-ten number is less than twice as many digits
- * as the base 16 number, which is 2 digits per byte.
- */
+ as the base 16 number, which is 2 digits per byte. */
+
decimal_len = len * 2 * 2;
digits = xmalloc (decimal_len);
* the nibbles by 16, add Y and re-decimalize. Repeat with Z.
*
* The trick is that "digits" holds a base-10 number, but sometimes
- * the individual digits are > 10.
+ * the individual digits are > 10.
*
* Outer loop is per nibble (hex digit) of input, from MSD end to
* LSD end.
*/
if (flip == 0)
{
- /* Take top nibble.
- */
+ /* Take top nibble. */
+
digits[0] += HIGH_NIBBLE (*p);
flip = 1;
}
else
{
- /* Take low nibble and bump our pointer "p".
- */
+ /* Take low nibble and bump our pointer "p". */
+
digits[0] += LOW_NIBBLE (*p);
if (byte_order == BFD_ENDIAN_BIG)
p++;
}
/* Ok, now "digits" is the decimal representation, with
- * the "decimal_digits" actual digits. Print!
- */
+ the "decimal_digits" actual digits. Print! */
+
for (i = decimal_digits - 1; i >= 0; i--)
{
fprintf_filtered (stream, "%1d", digits[i]);
}
/* VALADDR points to a char integer of LEN bytes.
- Print it out in appropriate language form on stream.
+ Print it out in appropriate language form on stream.
Omit any leading zero chars. */
void
(FIXME?) Assumes array element separator is a comma, which is correct
for all languages currently handled.
(FIXME?) Some languages have a notation for repeated array elements,
- perhaps we should try to use that notation when appropriate.
- */
+ perhaps we should try to use that notation when appropriate. */
void
-val_print_array_elements (struct type *type, const gdb_byte *valaddr,
+val_print_array_elements (struct type *type,
+ const gdb_byte *valaddr, int embedded_offset,
CORE_ADDR address, struct ui_file *stream,
int recurse,
const struct value *val,
rep1 = i + 1;
reps = 1;
- while ((rep1 < len) &&
- !memcmp (valaddr + i * eltlen, valaddr + rep1 * eltlen, eltlen))
+ while (rep1 < len
+ && value_available_contents_eq (val,
+ embedded_offset + i * eltlen,
+ val,
+ embedded_offset + rep1 * eltlen,
+ eltlen))
{
++reps;
++rep1;
if (reps > options->repeat_count_threshold)
{
- val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen,
- stream, recurse + 1, val, options, current_language);
+ val_print (elttype, valaddr, embedded_offset + i * eltlen,
+ address, stream, recurse + 1, val, options,
+ current_language);
annotate_elt_rep (reps);
fprintf_filtered (stream, " <repeats %u times>", reps);
annotate_elt_rep_end ();
}
else
{
- val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen,
+ val_print (elttype, valaddr, embedded_offset + i * eltlen,
+ address,
stream, recurse + 1, val, options, current_language);
annotate_elt ();
things_printed++;
/* Read LEN bytes of target memory at address MEMADDR, placing the
results in GDB's memory at MYADDR. Returns a count of the bytes
actually read, and optionally an errno value in the location
- pointed to by ERRNOPTR if ERRNOPTR is non-null. */
+ pointed to by ERRNOPTR if ERRNOPTR is non-null. */
/* FIXME: cagney/1999-10-14: Only used by val_print_string. Can this
function be eliminated. */
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. */
+ int nread; /* Number of bytes actually read. */
+ int errcode; /* Error from last read. */
- /* First try a complete read. */
+ /* First try a complete read. */
errcode = target_read_memory (memaddr, myaddr, len);
if (errcode == 0)
{
- /* Got it all. */
+ /* Got it all. */
nread = len;
}
else
{
- /* Loop, reading one byte at a time until we get as much as we can. */
+ /* Loop, reading one byte at a time until we get as much as we can. */
for (errcode = 0, nread = 0; len > 0 && errcode == 0; nread++, len--)
{
errcode = target_read_memory (memaddr++, myaddr++, 1);
}
- /* If an error, the last read was unsuccessful, so adjust count. */
+ /* If an error, the last read was unsuccessful, so adjust count. */
if (errcode != 0)
{
nread--;
Note: There was a FIXME asking to make this code use target_read_string,
but this function is more general (can read past null characters, up to
- given LEN). Besides, it is used much more often than target_read_string
+ given LEN). Besides, it is used much more often than target_read_string
so it is more tested. Perhaps callers of target_read_string should use
this function instead? */
{
int force_ellipsis = 0; /* Force ellipsis to be printed if nonzero. */
int errcode; /* Errno returned from bad reads. */
- int found_nul; /* Non-zero if we found the nul char */
+ int found_nul; /* Non-zero if we found the nul char. */
unsigned int fetchlimit; /* Maximum number of chars to print. */
int bytes_read;
gdb_byte *buffer = NULL; /* Dynamically growable fetch buffer. */
radix greater than 1, even if we don't have unique digits for every
value from 0 to radix-1, but in practice we lose on large radix values.
We should either fix the lossage or restrict the radix range more.
- (FIXME). */
+ (FIXME). */
if (radix < 2)
{
set_output_radix_1 (int from_tty, unsigned radix)
{
/* Validate the radix and disallow ones that we aren't prepared to
- handle correctly, leaving the radix unchanged. */
+ handle correctly, leaving the radix unchanged. */
switch (radix)
{
case 16:
It may be useful to have an unusual input radix. If the user wishes to
set an input radix that is not valid as an output radix, he needs to use
- the 'set input-radix' command. */
+ the 'set input-radix' command. */
static void
set_radix (char *arg, int from_tty)
}
}
-/* Show both the input and output radices. */
+/* Show both the input and output radices. */
static void
show_radix (char *arg, int from_tty)
_("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 */
+ /* Prefer set print to set prompt. */
add_alias_cmd ("pr", "print", no_class, 1, &setlist);
add_prefix_cmd ("print", no_class, show_print,
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. */
+ 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, _("\