aboutsummaryrefslogtreecommitdiff
path: root/gdb/printcmd.c
diff options
context:
space:
mode:
authorgdb-2.8 <gdb@fsf.org>1988-09-03 08:00:00 +0100
committerPedro Alves <palves@redhat.com>2012-06-03 15:36:31 +0100
commit3bf57d210832b28e9361990830eb722a619f031b (patch)
treeba506d293bde0f6500d0cee3e643ebf8890d9cf7 /gdb/printcmd.c
parent7c75bab3d3ef344a6a0b13b9ab59ecd5855aceb5 (diff)
downloadgdb-3bf57d210832b28e9361990830eb722a619f031b.zip
gdb-3bf57d210832b28e9361990830eb722a619f031b.tar.gz
gdb-3bf57d210832b28e9361990830eb722a619f031b.tar.bz2
gdb-2.8
Diffstat (limited to 'gdb/printcmd.c')
-rw-r--r--gdb/printcmd.c415
1 files changed, 164 insertions, 251 deletions
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 04dda07..3fb12e4 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1,4 +1,4 @@
-/* Print values for GNU debugger gdb.
+/* Print values for GNU debugger GDB.
Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -54,8 +54,17 @@ static CORE_ADDR last_examine_address;
static value last_examine_value;
+/* Number of auto-display expression currently being displayed.
+ So that we can deleted it if we get an error or a signal within it.
+ -1 when not doing one. */
+
+int current_display_number;
+
+static void do_one_display ();
+
void do_displays ();
void print_address ();
+void print_scalar_formatted ();
START_FILE
@@ -123,25 +132,11 @@ print_formatted (val, format, size)
if (VALUE_LVAL (val) == lval_memory)
next_address = VALUE_ADDRESS (val) + len;
- if (format && format != 's')
- {
- val_long = value_as_long (val);
-
- /* If value is unsigned, truncate it in case negative. */
- if (format != 'd')
- {
- if (len == sizeof (char))
- val_long &= (1 << 8 * sizeof(char)) - 1;
- else if (len == sizeof (short))
- val_long &= (1 << 8 * sizeof(short)) - 1;
- }
- }
-
switch (format)
{
case 's':
next_address = VALUE_ADDRESS (val)
- + value_print (value_addr (val), stdout);
+ + value_print (value_addr (val), stdout, 0);
break;
case 'i':
@@ -149,6 +144,49 @@ print_formatted (val, format, size)
+ print_insn (VALUE_ADDRESS (val), stdout);
break;
+ default:
+ if (format == 0
+ || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_ARRAY
+ || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_STRUCT
+ || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_UNION)
+ value_print (val, stdout, format);
+ else
+ print_scalar_formatted (VALUE_CONTENTS (val), VALUE_TYPE (val),
+ format, size, stdout);
+ }
+}
+
+/* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR,
+ according to letters FORMAT and SIZE on STREAM.
+ FORMAT may not be zero. Formats s and i are not supported at this level.
+
+ This is how the elements of an array or structure are printed
+ with a format. */
+
+void
+print_scalar_formatted (valaddr, type, format, size, stream)
+ char *valaddr;
+ struct type *type;
+ char format;
+ int size;
+ FILE *stream;
+{
+ long val_long;
+ int len = TYPE_LENGTH (type);
+
+ val_long = unpack_long (type, valaddr);
+
+ /* If value is unsigned, truncate it in case negative. */
+ if (format != 'd')
+ {
+ if (len == sizeof (char))
+ val_long &= (1 << 8 * sizeof(char)) - 1;
+ else if (len == sizeof (short))
+ val_long &= (1 << 8 * sizeof(short)) - 1;
+ }
+
+ switch (format)
+ {
case 'x':
switch (size)
{
@@ -186,31 +224,30 @@ print_formatted (val, format, size)
break;
case 'a':
- print_address (val_long, stdout);
+ print_address (val_long, stream);
break;
case 'c':
- value_print (value_cast (builtin_type_char, val), stdout);
+ value_print (value_from_long (builtin_type_char, val_long), stream, 0);
break;
case 'f':
- if (TYPE_LENGTH (VALUE_TYPE (val)) == sizeof (float))
- VALUE_TYPE (val) = builtin_type_float;
- if (TYPE_LENGTH (VALUE_TYPE (val)) == sizeof (double))
- VALUE_TYPE (val) = builtin_type_double;
+ if (len == sizeof (float))
+ type = builtin_type_float;
+ if (len == sizeof (double))
+ type = builtin_type_double;
#ifdef IEEE_FLOAT
- if (is_nan (value_as_double (val)))
+ if (is_nan (unpack_double (type, valaddr)))
{
printf ("Nan");
break;
}
#endif
- printf ("%g", value_as_double (val));
+ printf ("%g", unpack_double (type, valaddr));
break;
case 0:
- value_print (val, stdout);
- break;
+ abort ();
default:
error ("Undefined output format \"%c\".", format);
@@ -364,7 +401,6 @@ print_command (exp)
else
val = access_value_history (0);
- if (!val) return; /* C++ */
histindex = record_latest_value (val);
printf ("$%d = ", histindex);
@@ -414,41 +450,17 @@ set_command (exp)
do_cleanups (old_chain);
}
-/* C++: Modified to give useful information about variable which
- hang off of `this'. */
static void
address_info (exp)
char *exp;
{
register struct symbol *sym;
register CORE_ADDR val;
- struct block *block, *get_selected_block ();
if (exp == 0)
error ("Argument required.");
- block = get_selected_block ();
- sym = lookup_symbol_1 (exp, block, VAR_NAMESPACE);
- if (! sym)
- {
- value v;
-
- /* C++: see if it hangs off of `this'. Must
- not inadvertently convert from a method call
- to data ref. */
- v = value_of_this (0);
- if (v)
- {
- val = check_field (v, exp);
- if (val)
- {
- printf ("Symbol \"%s\" is a field of the local class variable `this'\n", exp);
- return;
- }
- }
- else
- sym = lookup_symbol_2 (exp, 0, VAR_NAMESPACE);
- }
+ sym = lookup_symbol (exp, get_selected_block (), VAR_NAMESPACE);
if (sym == 0)
{
register int i;
@@ -572,12 +584,9 @@ whatis_command (exp)
else
val = access_value_history (0);
- if (val != 0)
- {
- printf ("type = ");
- type_print (VALUE_TYPE (val), "", stdout, 1);
- printf ("\n");
- }
+ printf ("type = ");
+ type_print (VALUE_TYPE (val), "", stdout, 1);
+ printf ("\n");
if (exp)
do_cleanups (old_chain);
@@ -639,143 +648,6 @@ ptype_command (typename)
type_print (type, "", stdout, 1);
printf ("\n");
}
-
-/* Print all the methods that correspond to the name METHOD.
- Can optionally qualify the method with a CLASSNAME, as
- in CLASSNAME :: METHODNAME. This routine does not call
- parse_c_expression, so the input must conform to one of
- these two forms. */
-
-static void
-pmethod_command (exp)
- char *exp;
-{
-# if 0
- struct expression *expr;
- register value val;
- register struct cleanup *old_chain;
- char *classname, *methodname;
-
- methodname = exp;
- while (*exp++ <= ' ') ; /* remove leading whitespace */
- if (exp[-1] == ':')
- if (*exp == ':')
- classname = (char *)1;
- else error ("Invalid syntax: \"%s\"", methodname);
- else
- {
- classname = exp-1;
- while (*exp++ != ':') ;
- exp[-1] = '\0';
- if (*exp == ':')
- {
- while (*exp++ <= ' ') ; /* remove leading 2nd whitespace */
- methodname = exp-1;
- while (((*exp | 0x20) >= 'a' && ((*exp | 0x20) <= 'z')) || *exp == '_')
- exp++;
- if (*exp)
- {
- *exp++ = '\0';
- while (*exp)
- if (*exp > ' ') error ("junk after method name");
- }
- }
- else error ("Invalid syntax: \"%s\"", methodname);
- }
- if (classname)
- {
- if (classname != (char *)1)
- classtype = lookup_typename (classname);
- else
- {
- register struct symtab *s;
- register struct blockvector *bv;
- struct blockvector *prev_bv = 0;
- register struct block *b;
- register int i, j;
- register struct symbol *sym;
- char *val;
- int found_in_file;
- static char *classnames[]
- = {"variable", "function", "type", "method"};
- int print_count = 0;
-
- if (regexp)
- if (val = (char *) re_comp (regexp))
- error ("Invalid regexp: %s", val);
-
- printf (regexp
- ? "All %ss matching regular expression \"%s\":\n"
- : "All defined %ss:\n",
- classnames[class],
- regexp);
-
- for (s = symtab_list; s; s = s->next)
- {
- found_in_file = 0;
- bv = BLOCKVECTOR (s);
- /* Often many files share a blockvector.
- Scan each blockvector only once so that
- we don't get every symbol many times.
- It happens that the first symtab in the list
- for any given blockvector is the main file. */
- if (bv != prev_bv)
- for (i = 0; i < 2; i++)
- {
- b = BLOCKVECTOR_BLOCK (bv, i);
- for (j = 0; j < BLOCK_NSYMS (b); j++)
- {
- QUIT;
- sym = BLOCK_SYM (b, j);
- if ((regexp == 0 || re_exec (SYMBOL_NAME (sym)))
- && ((class == 0 && SYMBOL_CLASS (sym) != LOC_TYPEDEF
- && SYMBOL_CLASS (sym) != LOC_BLOCK)
- || (class == 1 && SYMBOL_CLASS (sym) == LOC_BLOCK)
- || (class == 2 && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
- || (class == 3 && SYMBOL_CLASS (sym) == LOC_BLOCK)))
- {
- if (!found_in_file)
- {
- printf ("\nFile %s:\n", s->filename);
- print_count += 2;
- }
- found_in_file = 1;
- MORE;
- if (i == 1)
- printf ("static ");
-
- type_print (SYMBOL_TYPE (sym),
- (SYMBOL_CLASS (sym) == LOC_TYPEDEF
- ? "" : SYMBOL_NAME (sym)),
- stdout, 0);
- printf (";\n");
- }
- }
- }
- prev_bv = bv;
- }
- }
- }
- if (exp)
- {
- expr = parse_c_expression (exp);
- old_chain = make_cleanup (free_current_contents, &expr);
- val = evaluate_type (expr);
- }
- else
- val = access_value_history (0);
-
- if (val != 0)
- {
- printf ("type = ");
- type_print (VALUE_TYPE (val), "", stdout, 1);
- printf ("\n");
- }
-
- if (exp)
- do_cleanups (old_chain);
-# endif
-}
struct display
{
@@ -802,8 +674,9 @@ static int display_number;
Specify the expression. */
static void
-display_command (exp)
+display_command (exp, from_tty)
char *exp;
+ int from_tty;
{
struct format_data fmt;
register struct expression *expr;
@@ -841,6 +714,9 @@ display_command (exp)
new->format = fmt;
display_chain = new;
+ if (from_tty)
+ do_one_display (new);
+
dont_repeat ();
}
@@ -869,6 +745,38 @@ clear_displays ()
}
}
+/* Delete the auto-display number NUM. */
+
+void
+delete_display (num)
+ int num;
+{
+ register struct display *d1, *d;
+
+ if (!display_chain)
+ error ("No display number %d.", num);
+
+ if (display_chain->number == num)
+ {
+ d1 = display_chain;
+ display_chain = d1->next;
+ free_display (d1);
+ }
+ else
+ for (d = display_chain; ; d = d->next)
+ {
+ if (d->next == 0)
+ error ("No display number %d.", num);
+ if (d->next->number == num)
+ {
+ d1 = d->next;
+ d->next = d1->next;
+ free_display (d1);
+ break;
+ }
+ }
+}
+
/* Delete some values from the auto-display chain.
Specify the element numbers. */
@@ -898,25 +806,7 @@ undisplay_command (args)
num = atoi (p);
- if (display_chain->number == num)
- {
- d1 = display_chain;
- display_chain = d1->next;
- free_display (d1);
- }
- else
- for (d = display_chain; ; d = d->next)
- {
- if (d->next == 0)
- error ("No display number %d.", num);
- if (d->next->number == num)
- {
- d1 = d->next;
- d->next = d1->next;
- free_display (d1);
- break;
- }
- }
+ delete_display (num);
p = p1;
while (*p == ' ' || *p == '\t') p++;
@@ -924,6 +814,47 @@ undisplay_command (args)
dont_repeat ();
}
+/* Display a single auto-display. */
+
+static void
+do_one_display (d)
+ struct display *d;
+{
+ current_display_number = d->number;
+
+ printf ("%d: ", d->number);
+ if (d->format.size)
+ {
+ printf ("x/");
+ if (d->format.count != 1)
+ printf ("%d", d->format.count);
+ printf ("%c", d->format.format);
+ if (d->format.format != 'i' && d->format.format != 's')
+ printf ("%c", d->format.size);
+ printf (" ");
+ print_expression (d->exp, stdout);
+ if (d->format.count != 1)
+ printf ("\n");
+ else
+ printf (" ");
+ do_examine (d->format,
+ value_as_long (evaluate_expression (d->exp)));
+ }
+ else
+ {
+ if (d->format.format)
+ printf ("/%c ", d->format.format);
+ print_expression (d->exp, stdout);
+ printf (" = ");
+ print_formatted (evaluate_expression (d->exp),
+ d->format.format, d->format.size);
+ printf ("\n");
+ }
+
+ fflush (stdout);
+ current_display_number = -1;
+}
+
/* Display all of the values on the auto-display chain. */
void
@@ -932,37 +863,22 @@ do_displays ()
register struct display *d;
for (d = display_chain; d; d = d->next)
+ do_one_display (d);
+}
+
+/* Delete the auto-display which we were in the process of displaying.
+ This is done when there is an error or a signal. */
+
+void
+delete_current_display ()
+{
+ if (current_display_number >= 0)
{
- printf ("%d: ", d->number);
- if (d->format.size)
- {
- printf ("x/");
- if (d->format.count != 1)
- printf ("%d", d->format.count);
- printf ("%c", d->format.format);
- if (d->format.format != 'i' && d->format.format != 's')
- printf ("%c", d->format.size);
- printf (" ");
- print_expression (d->exp, stdout);
- if (d->format.count != 1)
- printf ("\n");
- else
- printf (" ");
- do_examine (d->format,
- value_as_long (evaluate_expression (d->exp)));
- }
- else
- {
- if (d->format.format)
- printf ("/%c ", d->format.format);
- print_expression (d->exp, stdout);
- printf (" = ");
- print_formatted (evaluate_expression (d->exp),
- d->format.format, d->format.size);
- printf ("\n");
- }
- fflush (stdout);
+ delete_display (current_display_number);
+ fprintf (stderr, "Deleting display %d to avoid infinite recursion.\n",
+ current_display_number);
}
+ current_display_number = -1;
}
static void
@@ -998,7 +914,7 @@ print_variable_value (var, frame, stream)
FILE *stream;
{
value val = read_var_value (var, frame);
- value_print (val, stream);
+ value_print (val, stream, 0);
}
/* Print the arguments of a stack frame, given the function FUNC
@@ -1057,7 +973,7 @@ print_frame_args (func, addr, num, stream)
if (! first)
fprintf (stream, ", ");
fprintf (stream, "%s=", SYMBOL_NAME (sym));
- value_print (val, stream);
+ value_print (val, stream, 0);
first = 0;
last_offset = SYMBOL_VALUE (sym) + TYPE_LENGTH (SYMBOL_TYPE (sym));
/* Round up address of next arg to multiple of size of int. */
@@ -1255,6 +1171,8 @@ printf_command (arg)
static
initialize ()
{
+ current_display_number = -1;
+
add_info ("address", address_info,
"Describe where variable VAR is stored.");
@@ -1281,11 +1199,6 @@ The selected stack frame's lexical context is used to look up the name.");
add_com ("whatis", class_vars, whatis_command,
"Print data type of expression EXP.");
- add_com ("pmethod", class_vars, pmethod_command,
- "Print definitions of method METHOD.\n\
-Argument must resolve to a method name within the containing scope.\n\
-All definitions found go into history array.");
-
add_info ("display", display_info,
"Expressions to display when program stops, with code numbers.");
add_com ("undisplay", class_vars, undisplay_command,