}
/* Number of auto-display expression currently being displayed.
- So that we can disable it if we get an error or a signal within it.
+ So that we can disable it if we get a signal within it.
-1 when not doing one. */
int current_display_number;
static int display_number;
-/* Walk the following statement or block through all displays. */
+/* Walk the following statement or block through all displays.
+ ALL_DISPLAYS_SAFE does so even if the statement deletes the current
+ display. */
#define ALL_DISPLAYS(B) \
for (B = display_chain; B; B = B->next)
+#define ALL_DISPLAYS_SAFE(B,TMP) \
+ for (B = display_chain; \
+ B ? (TMP = B->next, 1): 0; \
+ B = TMP)
+
/* Prototypes for exported functions. */
void output_command (char *, int);
CORE_ADDR pc;
frame = get_selected_frame (NULL);
- pc = get_frame_pc (frame);
-
- if (pc == addr)
+ if (get_frame_pc_if_available (frame, &pc) && pc == addr)
return "=> ";
}
return " ";
free_display (display);
}
-/* Delete some values from the auto-display chain.
- Specify the element numbers. */
+/* Call FUNCTION on each of the displays whose numbers are given in
+ ARGS. DATA is passed unmodified to FUNCTION. */
static void
-undisplay_command (char *args, int from_tty)
+map_display_numbers (char *args,
+ void (*function) (struct display *,
+ void *),
+ void *data)
{
- int num;
struct get_number_or_range_state state;
+ struct display *b, *tmp;
+ int num;
- if (args == 0)
- {
- if (query (_("Delete all auto-display expressions? ")))
- clear_displays ();
- dont_repeat ();
- return;
- }
+ if (args == NULL)
+ error_no_arg (_("one or more display numbers"));
init_number_or_range (&state, args);
+
while (!state.finished)
{
char *p = state.string;
warning (_("bad display number at or near '%s'"), p);
else
{
- struct display *d;
+ struct display *d, *tmp;
- ALL_DISPLAYS (d)
+ ALL_DISPLAYS_SAFE (d, tmp)
if (d->number == num)
break;
if (d == NULL)
printf_unfiltered (_("No display number %d.\n"), num);
else
- delete_display (d);
+ function (d, data);
}
}
+}
+
+/* Callback for map_display_numbers, that deletes a display. */
+
+static void
+do_delete_display (struct display *d, void *data)
+{
+ delete_display (d);
+}
+
+/* "undisplay" command. */
+
+static void
+undisplay_command (char *args, int from_tty)
+{
+ int num;
+ struct get_number_or_range_state state;
+
+ if (args == NULL)
+ {
+ if (query (_("Delete all auto-display expressions? ")))
+ clear_displays ();
+ dont_repeat ();
+ return;
+ }
+
+ map_display_numbers (args, do_delete_display, NULL);
dont_repeat ();
}
static void
do_one_display (struct display *d)
{
+ struct cleanup *old_chain;
int within_current_scope;
if (d->enabled_p == 0)
if (!within_current_scope)
return;
+ old_chain = make_cleanup_restore_integer (¤t_display_number);
current_display_number = d->number;
annotate_display_begin ();
printf_filtered (": ");
if (d->format.size)
{
- CORE_ADDR addr;
- struct value *val;
+ volatile struct gdb_exception ex;
annotate_display_format ();
else
printf_filtered (" ");
- val = evaluate_expression (d->exp);
- addr = value_as_address (val);
- if (d->format.format == 'i')
- addr = gdbarch_addr_bits_remove (d->exp->gdbarch, addr);
-
annotate_display_value ();
- do_examine (d->format, d->exp->gdbarch, addr);
+ TRY_CATCH (ex, RETURN_MASK_ERROR)
+ {
+ struct value *val;
+ CORE_ADDR addr;
+
+ val = evaluate_expression (d->exp);
+ addr = value_as_address (val);
+ if (d->format.format == 'i')
+ addr = gdbarch_addr_bits_remove (d->exp->gdbarch, addr);
+ do_examine (d->format, d->exp->gdbarch, addr);
+ }
+ if (ex.reason < 0)
+ fprintf_filtered (gdb_stdout, _("<error: %s>\n"), ex.message);
}
else
{
struct value_print_options opts;
+ volatile struct gdb_exception ex;
annotate_display_format ();
get_formatted_print_options (&opts, d->format.format);
opts.raw = d->format.raw;
- print_formatted (evaluate_expression (d->exp),
- d->format.size, &opts, gdb_stdout);
+
+ TRY_CATCH (ex, RETURN_MASK_ERROR)
+ {
+ struct value *val;
+
+ val = evaluate_expression (d->exp);
+ print_formatted (val, d->format.size, &opts, gdb_stdout);
+ }
+ if (ex.reason < 0)
+ fprintf_filtered (gdb_stdout, _("<error: %s>"), ex.message);
printf_filtered ("\n");
}
annotate_display_end ();
gdb_flush (gdb_stdout);
- current_display_number = -1;
+ do_cleanups (old_chain);
}
/* Display all of the values on the auto-display chain which can be
}
}
+/* Callback fo map_display_numbers, that enables or disables the
+ passed in display D. */
+
static void
-enable_display (char *args, int from_tty)
+do_enable_disable_display (struct display *d, void *data)
{
- char *p = args;
- char *p1;
- int num;
- struct display *d;
+ d->enabled_p = *(int *) data;
+}
+
+/* Implamentation of both the "disable display" and "enable display"
+ commands. ENABLE decides what to do. */
- if (p == 0)
+static void
+enable_disable_display_command (char *args, int from_tty, int enable)
+{
+ if (args == NULL)
{
- for (d = display_chain; d; d = d->next)
- d->enabled_p = 1;
- }
- else
- while (*p)
- {
- p1 = p;
- while (*p1 >= '0' && *p1 <= '9')
- p1++;
- if (*p1 && *p1 != ' ' && *p1 != '\t')
- error (_("Arguments must be display numbers."));
+ struct display *d;
- num = atoi (p);
+ ALL_DISPLAYS (d)
+ d->enabled_p = enable;
+ return;
+ }
- for (d = display_chain; d; d = d->next)
- if (d->number == num)
- {
- d->enabled_p = 1;
- goto win;
- }
- printf_unfiltered (_("No display number %d.\n"), num);
- win:
- p = p1;
- while (*p == ' ' || *p == '\t')
- p++;
- }
+ map_display_numbers (args, do_enable_disable_display, &enable);
}
+/* The "enable display" command. */
+
static void
-disable_display_command (char *args, int from_tty)
+enable_display_command (char *args, int from_tty)
{
- char *p = args;
- char *p1;
- struct display *d;
-
- if (p == 0)
- {
- for (d = display_chain; d; d = d->next)
- d->enabled_p = 0;
- }
- else
- while (*p)
- {
- p1 = p;
- while (*p1 >= '0' && *p1 <= '9')
- p1++;
- if (*p1 && *p1 != ' ' && *p1 != '\t')
- error (_("Arguments must be display numbers."));
+ enable_disable_display_command (args, from_tty, 1);
+}
- disable_display (atoi (p));
+/* The "disable display" command. */
- p = p1;
- while (*p == ' ' || *p == '\t')
- p++;
- }
+static void
+disable_display_command (char *args, int from_tty)
+{
+ enable_disable_display_command (args, from_tty, 0);
}
/* display_chain items point to blocks and expressions. Some expressions in
With no argument, display all currently requested auto-display expressions.\n\
Use \"undisplay\" to cancel display requests previously made."));
- add_cmd ("display", class_vars, enable_display, _("\
+ add_cmd ("display", class_vars, enable_display_command, _("\
Enable some expressions to be displayed when program stops.\n\
Arguments are the code numbers of the expressions to resume displaying.\n\
No argument means enable all automatic-display expressions.\n\