X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ftui%2Ftui-regs.c;h=12382cddb35710ce8efe030597af90ac7505f1dd;hb=63a33118e05a84fbae40cbe3ef955b52bad359a7;hp=7c0ebce665468e98f76bca551b567d545aeeaa8c;hpb=0043e6a5cce8d245bc331f567f2714b954731b20;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c index 7c0ebce665..12382cddb3 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 Free Software Foundation, Inc. + Copyright (C) 1998-2018 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,11 +244,10 @@ 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 - = (tui_win_content) TUI_DATA_WIN->generic.content; + display_info->regs_content = TUI_DATA_WIN->generic.content; display_info->regs_content_count = nr_regs; } @@ -273,17 +262,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 +283,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++; @@ -331,9 +319,9 @@ tui_display_registers_from (int start_element_no) char *p; int len; - 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_item_win + = &display_info->regs_content[i]->which_element.data_window; + data = &data_item_win->content[0]->which_element.data; len = 0; p = data->content; if (p != 0) @@ -375,8 +363,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 @@ -417,7 +404,8 @@ static void tui_display_reg_element_at_line (int start_element_no, int start_line_no) { - if (TUI_DATA_WIN->detail.data_display_info.regs_content != (tui_win_content) NULL + if (TUI_DATA_WIN->detail.data_display_info.regs_content + != (tui_win_content) NULL && TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0) { int element_no = start_element_no; @@ -427,7 +415,8 @@ tui_display_reg_element_at_line (int start_element_no, int last_line_no, first_line_on_last_page; last_line_no = tui_last_regs_line_no (); - first_line_on_last_page = last_line_no - (TUI_DATA_WIN->generic.height - 2); + first_line_on_last_page + = last_line_no - (TUI_DATA_WIN->generic.height - 2); if (first_line_on_last_page < 0) first_line_on_last_page = 0; @@ -437,7 +426,8 @@ tui_display_reg_element_at_line (int start_element_no, display at. */ if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0 && start_line_no > first_line_on_last_page) - element_no = tui_first_reg_element_no_inline (first_line_on_last_page); + element_no + = tui_first_reg_element_no_inline (first_line_on_last_page); } tui_display_registers_from (element_no); } @@ -475,7 +465,8 @@ tui_display_registers_from_line (int line_no, line = line_no; element_no = tui_first_reg_element_no_inline (line); - if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count) + if (element_no + < TUI_DATA_WIN->detail.data_display_info.regs_content_count) tui_display_reg_element_at_line (element_no, line); else line = (-1); @@ -514,8 +505,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, @@ -566,94 +556,146 @@ 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 (const 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) +tui_reggroup_completer (struct cmd_list_element *ignore, + completion_tracker &tracker, + 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); -} + static const char *extra[] = { "next", "prev", NULL }; + size_t len = strlen (word); + const char **tmp; + + reggroup_completer (ignore, tracker, text, word); -/* Provide a prototype to silence -Wmissing-prototypes. */ -extern initialize_file_ftype _initialize_tui_regs; + /* XXXX use complete_on_enum instead? */ + for (tmp = extra; *tmp != NULL; ++tmp) + { + if (strncmp (word, *tmp, len) == 0) + tracker.add_completion (gdb::unique_xmalloc_ptr (xstrdup (*tmp))); + } +} 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); } @@ -661,71 +703,30 @@ _initialize_tui_regs (void) ** STATIC LOCAL FUNCTIONS ** ******************************************/ -extern int pagination_enabled; - -static void -tui_restore_gdbout (void *ui) -{ - ui_file_delete (gdb_stdout); - gdb_stdout = (struct ui_file*) ui; - pagination_enabled = 1; -} +/* Get the register from the frame and return a printable + representation of it. */ -/* 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) +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); - - 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); - } - /* Save formatted output in the buffer. */ - p = tui_file_get_strbuf (stream); + string_file stream; + + scoped_restore save_pagination + = make_scoped_restore (&pagination_enabled, 0); + scoped_restore save_stdout + = make_scoped_restore (&gdb_stdout, &stream); + + gdbarch_print_registers_info (gdbarch, &stream, frame, regnum, 1); /* Remove the possible \n. */ - s = strrchr (p, '\n'); - if (s && s[1] == 0) - *s = 0; + std::string &str = stream.string (); + if (!str.empty () && str.back () == '\n') + str.resize (str.size () - 1); - xfree (data_element->content); - data_element->content = xstrdup (p); - do_cleanups (cleanups); + /* Expand tabs into spaces, since ncurses on MS-Windows doesn't. */ + return tui_expand_tabs (str.c_str (), 0); } /* Get the register value from the given frame and format it for the @@ -742,42 +743,17 @@ tui_get_register (struct frame_info *frame, *changedp = FALSE; if (target_has_registers) { - gdb_byte buf[MAX_REGISTER_SIZE]; - get_frame_register (frame, regnum, buf); + char *prev_content = data->content; - 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); -}