X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ftui%2Ftui-regs.c;h=834e692db1f0f9fe3a4b893158e1b02ff16b1682;hb=347dc1025db1c0acf616ab6520c3f36448f25e8b;hp=fb70e9d47aeea52b23f8d6a42c99573ac39f7ada;hpb=9a2b4c1ba76f3dff85f08faff0dd08849c2905fb;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c index fb70e9d47a..834e692db1 100644 --- a/gdb/tui/tui-regs.c +++ b/gdb/tui/tui-regs.c @@ -1,7 +1,6 @@ /* TUI display registers in window. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009, - 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1998-2016 Free Software Foundation, Inc. Contributed by Hewlett-Packard Company. @@ -31,15 +30,16 @@ #include "regcache.h" #include "inferior.h" #include "target.h" -#include "gdb_string.h" #include "tui/tui-layout.h" #include "tui/tui-win.h" #include "tui/tui-windata.h" #include "tui/tui-wingeneral.h" #include "tui/tui-file.h" #include "tui/tui-regs.h" +#include "tui/tui-io.h" #include "reggroups.h" #include "valprint.h" +#include "completer.h" #include "gdb_curses.h" @@ -59,12 +59,6 @@ static enum tui_status tui_get_register (struct frame_info *frame, struct tui_data_element *data, int regnum, int *changedp); -static void tui_register_format (struct frame_info *, - struct tui_data_element*, int); - -static void tui_scroll_regs_forward_command (char *, int); -static void tui_scroll_regs_backward_command (char *, int); - /***************************************** @@ -132,19 +126,6 @@ tui_first_reg_element_no_inline (int line_no) } -/* Answer the index of the last element in line_no. If line_no is - past the register area (-1) is returned. */ -int -tui_last_reg_element_no_in_line (int line_no) -{ - if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count) <= - TUI_DATA_WIN->detail.data_display_info.regs_content_count) - return ((line_no + 1) * - TUI_DATA_WIN->detail.data_display_info.regs_column_count) - 1; - else - return (-1); -} - /* Show the registers of the given group in the data window and refresh the window. */ void @@ -159,7 +140,7 @@ tui_show_registers (struct reggroup *group) /* Make sure the register window is visible. If not, select an appropriate layout. */ if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible) - tui_set_layout_for_display_command (DATA_NAME); + tui_set_layout_by_name (DATA_NAME); display_info = &TUI_DATA_WIN->detail.data_display_info; if (group == 0) @@ -171,7 +152,7 @@ tui_show_registers (struct reggroup *group) if (target_has_registers && target_has_stack && target_has_memory) { - ret = tui_show_register_group (group, get_current_frame (), + ret = tui_show_register_group (group, get_selected_frame (NULL), group == display_info->current_group); } if (ret == TUI_FAILURE) @@ -191,7 +172,7 @@ tui_show_registers (struct reggroup *group) data_item_win = &display_info->regs_content[i] ->which_element.data_window; - win = (struct tui_win_element *) data_item_win->content[0]; + win = data_item_win->content[0]; win->which_element.data.highlight = FALSE; } display_info->current_group = group; @@ -230,10 +211,19 @@ tui_show_register_group (struct reggroup *group, + gdbarch_num_pseudo_regs (gdbarch); regnum++) { - /* Must be in the group and have a name. */ - if (gdbarch_register_reggroup_p (gdbarch, regnum, group) - && gdbarch_register_name (gdbarch, regnum) != 0) - nr_regs++; + const char *name; + + /* Must be in the group. */ + if (!gdbarch_register_reggroup_p (gdbarch, regnum, group)) + continue; + + /* If the register name is empty, it is undefined for this + processor, so don't display anything. */ + name = gdbarch_register_name (gdbarch, regnum); + if (name == 0 || *name == '\0') + continue; + + nr_regs++; } if (display_info->regs_content_count > 0 && !refresh_values_only) @@ -254,7 +244,7 @@ tui_show_register_group (struct reggroup *group, { if (!refresh_values_only || allocated_here) { - TUI_DATA_WIN->generic.content = (void*) NULL; + TUI_DATA_WIN->generic.content = NULL; TUI_DATA_WIN->generic.content_size = 0; tui_add_content_elements (&TUI_DATA_WIN->generic, nr_regs); display_info->regs_content @@ -273,17 +263,19 @@ tui_show_register_group (struct reggroup *group, struct tui_data_element *data; const char *name; + /* Must be in the group. */ if (!gdbarch_register_reggroup_p (gdbarch, regnum, group)) continue; - name = gdbarch_register_name (gdbarch, regnum); - if (name == 0) - continue; + /* If the register name is empty, it is undefined for this + processor, so don't display anything. */ + name = gdbarch_register_name (gdbarch, regnum); + if (name == 0 || *name == '\0') + continue; data_item_win = &display_info->regs_content[pos]->which_element.data_window; - data = &((struct tui_win_element *) - data_item_win->content[0])->which_element.data; + data = &data_item_win->content[0]->which_element.data; if (data) { if (!refresh_values_only) @@ -292,9 +284,6 @@ tui_show_register_group (struct reggroup *group, data->name = name; data->highlight = FALSE; } - if (data->value == (void*) NULL) - data->value = (void*) xmalloc (MAX_REGISTER_SIZE); - tui_get_register (frame, data, regnum, 0); } pos++; @@ -333,8 +322,7 @@ tui_display_registers_from (int start_element_no) data_item_win = &display_info->regs_content[i]->which_element.data_window; - data = &((struct tui_win_element *) - data_item_win->content[0])->which_element.data; + data = &data_item_win->content[0]->which_element.data; len = 0; p = data->content; if (p != 0) @@ -376,8 +364,7 @@ tui_display_registers_from (int start_element_no) /* Create the window if necessary. */ data_item_win = &display_info->regs_content[i] ->which_element.data_window; - data_element_ptr = &((struct tui_win_element *) - data_item_win->content[0])->which_element.data; + data_element_ptr = &data_item_win->content[0]->which_element.data; if (data_item_win->handle != (WINDOW*) NULL && (data_item_win->height != 1 || data_item_win->width != item_win_width @@ -519,8 +506,7 @@ tui_check_register_values (struct frame_info *frame) data_item_win_ptr = &display_info->regs_content[i]-> which_element.data_window; - data = &((struct tui_win_element *) - data_item_win_ptr->content[0])->which_element.data; + data = &data_item_win_ptr->content[0]->which_element.data; was_hilighted = data->highlight; tui_get_register (frame, data, @@ -571,51 +557,135 @@ tui_display_register (struct tui_data_element *data, } } -static void -tui_reg_next_command (char *arg, int from_tty) +/* Helper for "tui reg next", wraps a call to REGGROUP_NEXT, but adds wrap + around behaviour. Returns the next register group, or NULL if the + register window is not currently being displayed. */ + +static struct reggroup * +tui_reg_next (struct gdbarch *gdbarch) { - struct gdbarch *gdbarch = get_current_arch (); + struct reggroup *group = NULL; - if (TUI_DATA_WIN != 0) + if (TUI_DATA_WIN != NULL) { - struct reggroup *group - = TUI_DATA_WIN->detail.data_display_info.current_group; - + group = TUI_DATA_WIN->detail.data_display_info.current_group; group = reggroup_next (gdbarch, group); - if (group == 0) - group = reggroup_next (gdbarch, 0); - - if (group) - tui_show_registers (group); + if (group == NULL) + group = reggroup_next (gdbarch, NULL); } + return group; } -static void -tui_reg_float_command (char *arg, int from_tty) -{ - tui_show_registers (float_reggroup); -} +/* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap + around behaviour. Returns the previous register group, or NULL if the + register window is not currently being displayed. */ -static void -tui_reg_general_command (char *arg, int from_tty) +static struct reggroup * +tui_reg_prev (struct gdbarch *gdbarch) { - tui_show_registers (general_reggroup); + struct reggroup *group = NULL; + + if (TUI_DATA_WIN != NULL) + { + group = TUI_DATA_WIN->detail.data_display_info.current_group; + group = reggroup_prev (gdbarch, group); + if (group == NULL) + group = reggroup_prev (gdbarch, NULL); + } + return group; } +/* Implement the 'tui reg' command. Changes the register group displayed + in the tui register window. Displays the tui register window if it is + not already on display. */ + static void -tui_reg_system_command (char *arg, int from_tty) +tui_reg_command (char *args, int from_tty) { - tui_show_registers (system_reggroup); + struct gdbarch *gdbarch = get_current_arch (); + + if (args != NULL) + { + struct reggroup *group, *match = NULL; + size_t len = strlen (args); + + /* Make sure the curses mode is enabled. */ + tui_enable (); + + /* Make sure the register window is visible. If not, select an + appropriate layout. We need to do this before trying to run the + 'next' or 'prev' commands. */ + if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible) + tui_set_layout_by_name (DATA_NAME); + + if (strncmp (args, "next", len) == 0) + match = tui_reg_next (gdbarch); + else if (strncmp (args, "prev", len) == 0) + match = tui_reg_prev (gdbarch); + + /* This loop matches on the initial part of a register group + name. If this initial part in ARGS matches only one register + group then the switch is made. */ + for (group = reggroup_next (gdbarch, NULL); + group != NULL; + group = reggroup_next (gdbarch, group)) + { + if (strncmp (reggroup_name (group), args, len) == 0) + { + if (match != NULL) + error (_("ambiguous register group name '%s'"), args); + match = group; + } + } + + if (match == NULL) + error (_("unknown register group '%s'"), args); + + tui_show_registers (match); + } + else + { + struct reggroup *group; + int first; + + printf_unfiltered (_("\"tui reg\" must be followed by the name of " + "either a register group,\nor one of 'next' " + "or 'prev'. Known register groups are:\n")); + + for (first = 1, group = reggroup_next (gdbarch, NULL); + group != NULL; + first = 0, group = reggroup_next (gdbarch, group)) + { + if (!first) + printf_unfiltered (", "); + printf_unfiltered ("%s", reggroup_name (group)); + } + + printf_unfiltered ("\n"); + } } -static struct cmd_list_element *tuireglist; +/* Complete names of register groups, and add the special "prev" and "next" + names. */ -static void -tui_reg_command (char *args, int from_tty) +static VEC (char_ptr) * +tui_reggroup_completer (struct cmd_list_element *ignore, + const char *text, const char *word) { - printf_unfiltered (_("\"tui reg\" must be followed by the name of a " - "tui reg command.\n")); - help_list (tuireglist, "tui reg ", -1, gdb_stdout); + VEC (char_ptr) *result = NULL; + static const char *extra[] = { "next", "prev", NULL }; + size_t len = strlen (word); + const char **tmp; + + result = reggroup_completer (ignore, text, word); + + for (tmp = extra; *tmp != NULL; ++tmp) + { + if (strncmp (word, *tmp, len) == 0) + VEC_safe_push (char_ptr, result, xstrdup (*tmp)); + } + + return result; } /* Provide a prototype to silence -Wmissing-prototypes. */ @@ -624,41 +694,13 @@ extern initialize_file_ftype _initialize_tui_regs; void _initialize_tui_regs (void) { - struct cmd_list_element **tuicmd; + struct cmd_list_element **tuicmd, *cmd; tuicmd = tui_get_cmd_list (); - add_prefix_cmd ("reg", class_tui, tui_reg_command, - _("TUI commands to control the register window."), - &tuireglist, "tui reg ", 0, - tuicmd); - - add_cmd ("float", class_tui, tui_reg_float_command, - _("Display only floating point registers."), - &tuireglist); - add_cmd ("general", class_tui, tui_reg_general_command, - _("Display only general registers."), - &tuireglist); - add_cmd ("system", class_tui, tui_reg_system_command, - _("Display only system registers."), - &tuireglist); - add_cmd ("next", class_tui, tui_reg_next_command, - _("Display next register group."), - &tuireglist); - - if (xdb_commands) - { - add_com ("fr", class_tui, tui_reg_float_command, - _("Display only floating point registers\n")); - add_com ("gr", class_tui, tui_reg_general_command, - _("Display only general registers\n")); - add_com ("sr", class_tui, tui_reg_system_command, - _("Display only special registers\n")); - add_com ("+r", class_tui, tui_scroll_regs_forward_command, - _("Scroll the registers window forward\n")); - add_com ("-r", class_tui, tui_scroll_regs_backward_command, - _("Scroll the register window backward\n")); - } + cmd = add_cmd ("reg", class_tui, tui_reg_command, _("\ +TUI command to control the register window."), tuicmd); + set_cmd_completer (cmd, tui_reggroup_completer); } @@ -666,8 +708,6 @@ _initialize_tui_regs (void) ** STATIC LOCAL FUNCTIONS ** ******************************************/ -extern int pagination_enabled; - static void tui_restore_gdbout (void *ui) { @@ -676,49 +716,25 @@ tui_restore_gdbout (void *ui) pagination_enabled = 1; } -/* Get the register from the frame and make a printable representation - of it in the data element. */ -static void -tui_register_format (struct frame_info *frame, - struct tui_data_element *data_element, - int regnum) +/* Get the register from the frame and return a printable + representation of it. */ + +static char * +tui_register_format (struct frame_info *frame, int regnum) { struct gdbarch *gdbarch = get_frame_arch (frame); struct ui_file *stream; struct ui_file *old_stdout; - const char *name; struct cleanup *cleanups; char *p, *s; - struct type *type = register_type (gdbarch, regnum); + char *ret; - name = gdbarch_register_name (gdbarch, regnum); - if (name == 0) - { - return; - } - pagination_enabled = 0; old_stdout = gdb_stdout; stream = tui_sfileopen (256); gdb_stdout = stream; cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout); - if (TYPE_VECTOR (type) != 0 && 0) - { - gdb_byte buf[MAX_REGISTER_SIZE]; - int len; - struct value_print_options opts; - - len = register_size (gdbarch, regnum); - fprintf_filtered (stream, "%-14s ", name); - get_frame_register (frame, regnum, buf); - get_formatted_print_options (&opts, 'f'); - print_scalar_formatted (buf, type, &opts, len, stream); - } - else - { - gdbarch_print_registers_info (gdbarch, stream, - frame, regnum, 1); - } + gdbarch_print_registers_info (gdbarch, stream, frame, regnum, 1); /* Save formatted output in the buffer. */ p = tui_file_get_strbuf (stream); @@ -728,9 +744,12 @@ tui_register_format (struct frame_info *frame, if (s && s[1] == 0) *s = 0; - xfree (data_element->content); - data_element->content = xstrdup (p); + /* Expand tabs into spaces, since ncurses on MS-Windows doesn't. */ + ret = tui_expand_tabs (p, 0); + do_cleanups (cleanups); + + return ret; } /* Get the register value from the given frame and format it for the @@ -747,42 +766,17 @@ tui_get_register (struct frame_info *frame, *changedp = FALSE; if (target_has_registers) { - gdb_byte buf[MAX_REGISTER_SIZE]; + char *prev_content = data->content; - get_frame_register (frame, regnum, buf); - if (changedp) - { - struct gdbarch *gdbarch = get_frame_arch (frame); - int size = register_size (gdbarch, regnum); - char *old = (char*) data->value; - int i; + data->content = tui_register_format (frame, regnum); - for (i = 0; i < size; i++) - if (buf[i] != old[i]) - { - *changedp = TRUE; - old[i] = buf[i]; - } - } + if (changedp != NULL + && strcmp (prev_content, data->content) != 0) + *changedp = 1; - /* Reformat the data content if the value changed. */ - if (changedp == 0 || *changedp == TRUE) - tui_register_format (frame, data, regnum); + xfree (prev_content); ret = TUI_SUCCESS; } return ret; } - -static void -tui_scroll_regs_forward_command (char *arg, int from_tty) -{ - tui_scroll (FORWARD_SCROLL, TUI_DATA_WIN, 1); -} - - -static void -tui_scroll_regs_backward_command (char *arg, int from_tty) -{ - tui_scroll (BACKWARD_SCROLL, TUI_DATA_WIN, 1); -}