X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ftui%2Ftui-regs.c;h=32e82b23482e0d72d8213de8f095a5b7def97f05;hb=268a13a5a3f7c6b9b6ffc5ac2d1b24eb41f3fbdc;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..32e82b2348 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-2019 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" @@ -47,23 +47,15 @@ /***************************************** ** STATIC LOCAL FUNCTIONS FORWARD DECLS ** ******************************************/ -static void -tui_display_register (struct tui_data_element *data, - struct tui_gen_win_info *win_info); +static void tui_display_register (struct tui_data_item_window *data); -static enum tui_status tui_show_register_group (struct reggroup *group, - struct frame_info *frame, - int refresh_values_only); +static void tui_show_register_group (struct reggroup *group, + struct frame_info *frame, + int refresh_values_only); 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); + struct tui_data_item_window *data, + int regnum, bool *changedp); @@ -78,12 +70,11 @@ tui_last_regs_line_no (void) { int num_lines = (-1); - if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0) + if (!TUI_DATA_WIN->regs_content.empty ()) { - num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count / - TUI_DATA_WIN->detail.data_display_info.regs_column_count); - if (TUI_DATA_WIN->detail.data_display_info.regs_content_count % - TUI_DATA_WIN->detail.data_display_info.regs_column_count) + num_lines = (TUI_DATA_WIN->regs_content.size () + / TUI_DATA_WIN->regs_column_count); + if (TUI_DATA_WIN->regs_content.size () % TUI_DATA_WIN->regs_column_count) num_lines++; } return num_lines; @@ -96,15 +87,14 @@ tui_last_regs_line_no (void) int tui_line_from_reg_element_no (int element_no) { - if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count) + if (element_no < TUI_DATA_WIN->regs_content.size ()) { int i, line = (-1); i = 1; while (line == (-1)) { - if (element_no < - (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i)) + if (element_no < TUI_DATA_WIN->regs_column_count * i) line = i - 1; else i++; @@ -122,79 +112,57 @@ tui_line_from_reg_element_no (int element_no) int tui_first_reg_element_no_inline (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) - - TUI_DATA_WIN->detail.data_display_info.regs_column_count; + if ((line_no * TUI_DATA_WIN->regs_column_count) + <= TUI_DATA_WIN->regs_content.size ()) + return (((line_no + 1) * TUI_DATA_WIN->regs_column_count) + - TUI_DATA_WIN->regs_column_count); else return (-1); } -/* 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 tui_show_registers (struct reggroup *group) { enum tui_status ret = TUI_FAILURE; - struct tui_data_info *display_info; /* Make sure the curses mode is enabled. */ tui_enable (); /* 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); + if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->is_visible) + tui_set_layout_by_name (DATA_NAME); - display_info = &TUI_DATA_WIN->detail.data_display_info; if (group == 0) group = general_reggroup; /* Say that registers should be displayed, even if there is a problem. */ - display_info->display_regs = TRUE; + TUI_DATA_WIN->display_regs = true; if (target_has_registers && target_has_stack && target_has_memory) { - ret = tui_show_register_group (group, get_current_frame (), - group == display_info->current_group); + tui_show_register_group (group, get_selected_frame (NULL), + group == TUI_DATA_WIN->current_group); + ret = TUI_SUCCESS; } if (ret == TUI_FAILURE) { - display_info->current_group = 0; + TUI_DATA_WIN->current_group = 0; tui_erase_data_content (NO_REGS_STRING); } else { - int i; - /* Clear all notation of changed values. */ - for (i = 0; i < display_info->regs_content_count; i++) + for (auto &&data_item_win : TUI_DATA_WIN->regs_content) { - struct tui_gen_win_info *data_item_win; - struct tui_win_element *win; - - data_item_win = &display_info->regs_content[i] - ->which_element.data_window; - win = (struct tui_win_element *) data_item_win->content[0]; - win->which_element.data.highlight = FALSE; + if (data_item_win != nullptr) + data_item_win->highlight = false; } - display_info->current_group = group; + TUI_DATA_WIN->current_group = group; tui_display_all_data (); } } @@ -204,108 +172,82 @@ tui_show_registers (struct reggroup *group) using the given frame. Values are refreshed only when refresh_values_only is TRUE. */ -static enum tui_status +static void tui_show_register_group (struct reggroup *group, struct frame_info *frame, int refresh_values_only) { struct gdbarch *gdbarch = get_frame_arch (frame); - enum tui_status ret = TUI_FAILURE; int nr_regs; - int allocated_here = FALSE; int regnum, pos; char title[80]; - struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info; /* Make a new title showing which group we display. */ snprintf (title, sizeof (title) - 1, "Register group: %s", reggroup_name (group)); - xfree (TUI_DATA_WIN->generic.title); - TUI_DATA_WIN->generic.title = xstrdup (title); + xfree (TUI_DATA_WIN->title); + TUI_DATA_WIN->title = xstrdup (title); /* See how many registers must be displayed. */ nr_regs = 0; - for (regnum = 0; - regnum < gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch); - regnum++) + for (regnum = 0; regnum < gdbarch_num_cooked_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; - if (display_info->regs_content_count > 0 && !refresh_values_only) - { - tui_free_data_content (display_info->regs_content, - display_info->regs_content_count); - display_info->regs_content_count = 0; + /* 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) + if (!refresh_values_only) + TUI_DATA_WIN->regs_content.clear (); + + if (nr_regs < TUI_DATA_WIN->regs_content.size ()) + TUI_DATA_WIN->regs_content.resize (nr_regs); + else { - display_info->regs_content = tui_alloc_content (nr_regs, DATA_WIN); - allocated_here = TRUE; - refresh_values_only = FALSE; + for (int i = TUI_DATA_WIN->regs_content.size (); i < nr_regs; ++i) + TUI_DATA_WIN->regs_content.emplace_back (new tui_data_item_window ()); } - if (display_info->regs_content != (tui_win_content) NULL) + /* Now set the register names and values. */ + pos = 0; + for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++) { - if (!refresh_values_only || allocated_here) - { - TUI_DATA_WIN->generic.content = (void*) 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_count = nr_regs; - } + struct tui_data_item_window *data_item_win; + const char *name; - /* Now set the register names and values. */ - pos = 0; - for (regnum = 0; - regnum < gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch); - regnum++) - { - struct tui_gen_win_info *data_item_win; - struct tui_data_element *data; - const char *name; - - if (!gdbarch_register_reggroup_p (gdbarch, regnum, group)) - continue; - - name = gdbarch_register_name (gdbarch, regnum); - if (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; - if (data) - { - if (!refresh_values_only) - { - data->item_no = regnum; - data->name = name; - data->highlight = FALSE; - } - if (data->value == (void*) NULL) - data->value = (void*) xmalloc (MAX_REGISTER_SIZE); + /* Must be in the group. */ + if (!gdbarch_register_reggroup_p (gdbarch, regnum, group)) + continue; - tui_get_register (frame, data, regnum, 0); - } - pos++; - } + /* 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; - TUI_DATA_WIN->generic.content_size = - display_info->regs_content_count + display_info->data_content_count; - ret = TUI_SUCCESS; + data_item_win = TUI_DATA_WIN->regs_content[pos].get (); + if (data_item_win) + { + if (!refresh_values_only) + { + data_item_win->item_no = regnum; + data_item_win->name = name; + data_item_win->highlight = false; + } + tui_get_register (frame, data_item_win, regnum, 0); + } + pos++; } - - return ret; } /* Function to display the registers in the content from @@ -315,27 +257,18 @@ tui_show_register_group (struct reggroup *group, void tui_display_registers_from (int start_element_no) { - struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info; - - if (display_info->regs_content != (tui_win_content) NULL - && display_info->regs_content_count > 0) + if (!TUI_DATA_WIN->regs_content.empty ()) { - int i = start_element_no; int j, item_win_width, cur_y; int max_len = 0; - for (i = 0; i < display_info->regs_content_count; i++) + for (auto &&data_item_win : TUI_DATA_WIN->regs_content) { - struct tui_data_element *data; - struct tui_gen_win_info *data_item_win; 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; len = 0; - p = data->content; + p = data_item_win->content; if (p != 0) while (*p) { @@ -349,35 +282,31 @@ tui_display_registers_from (int start_element_no) max_len = len; } item_win_width = max_len + 1; - i = start_element_no; + int i = start_element_no; - display_info->regs_column_count = - (TUI_DATA_WIN->generic.width - 2) / item_win_width; - if (display_info->regs_column_count == 0) - display_info->regs_column_count = 1; + TUI_DATA_WIN->regs_column_count = + (TUI_DATA_WIN->width - 2) / item_win_width; + if (TUI_DATA_WIN->regs_column_count == 0) + TUI_DATA_WIN->regs_column_count = 1; item_win_width = - (TUI_DATA_WIN->generic.width - 2) / display_info->regs_column_count; + (TUI_DATA_WIN->width - 2) / TUI_DATA_WIN->regs_column_count; /* Now create each data "sub" window, and write the display into it. */ cur_y = 1; - while (i < display_info->regs_content_count - && cur_y <= TUI_DATA_WIN->generic.viewport_height) + while (i < TUI_DATA_WIN->regs_content.size () + && cur_y <= TUI_DATA_WIN->viewport_height) { for (j = 0; - j < display_info->regs_column_count - && i < display_info->regs_content_count; + j < TUI_DATA_WIN->regs_column_count + && i < TUI_DATA_WIN->regs_content.size (); j++) { - struct tui_gen_win_info *data_item_win; - struct tui_data_element *data_element_ptr; + struct tui_data_item_window *data_item_win; /* 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; - if (data_item_win->handle != (WINDOW*) NULL + data_item_win = TUI_DATA_WIN->regs_content[i].get (); + if (data_item_win->handle != NULL && (data_item_win->height != 1 || data_item_win->width != item_win_width || data_item_win->origin.x != (item_win_width * j) + 1 @@ -387,7 +316,7 @@ tui_display_registers_from (int start_element_no) data_item_win->handle = 0; } - if (data_item_win->handle == (WINDOW *) NULL) + if (data_item_win->handle == NULL) { data_item_win->height = 1; data_item_win->width = item_win_width; @@ -400,7 +329,7 @@ tui_display_registers_from (int start_element_no) /* Get the printable representation of the register and display it. */ - tui_display_register (data_element_ptr, data_item_win); + tui_display_register (data_item_win); i++; /* Next register. */ } cur_y++; /* Next row. */ @@ -417,8 +346,7 @@ 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 - && TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0) + if (!TUI_DATA_WIN->regs_content.empty ()) { int element_no = start_element_no; @@ -427,17 +355,17 @@ 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->height - 2); if (first_line_on_last_page < 0) first_line_on_last_page = 0; - /* If there is no other data displayed except registers, and - the element_no causes us to scroll past the end of the + /* If the element_no causes us to scroll past the end of the registers, adjust what element to really start the 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); + if (start_line_no > first_line_on_last_page) + element_no + = tui_first_reg_element_no_inline (first_line_on_last_page); } tui_display_registers_from (element_no); } @@ -452,7 +380,7 @@ int tui_display_registers_from_line (int line_no, int force_display) { - if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0) + if (!TUI_DATA_WIN->regs_content.empty ()) { int line, element_no; @@ -465,7 +393,7 @@ tui_display_registers_from_line (int line_no, if (line_no >= tui_last_regs_line_no ()) { if ((line = tui_line_from_reg_element_no ( - TUI_DATA_WIN->detail.data_display_info.regs_content_count - 1)) < 0) + TUI_DATA_WIN->regs_content.size () - 1)) < 0) line = 0; } else @@ -475,7 +403,7 @@ 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->regs_content.size ()) tui_display_reg_element_at_line (element_no, line); else line = (-1); @@ -494,37 +422,25 @@ void tui_check_register_values (struct frame_info *frame) { if (TUI_DATA_WIN != NULL - && TUI_DATA_WIN->generic.is_visible) + && TUI_DATA_WIN->is_visible) { - struct tui_data_info *display_info - = &TUI_DATA_WIN->detail.data_display_info; - - if (display_info->regs_content_count <= 0 - && display_info->display_regs) - tui_show_registers (display_info->current_group); + if (TUI_DATA_WIN->regs_content.empty () + && TUI_DATA_WIN->display_regs) + tui_show_registers (TUI_DATA_WIN->current_group); else { - int i; - - for (i = 0; (i < display_info->regs_content_count); i++) + for (auto &&data_item_win_ptr : TUI_DATA_WIN->regs_content) { - struct tui_data_element *data; - struct tui_gen_win_info *data_item_win_ptr; int was_hilighted; - 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; - was_hilighted = data->highlight; + was_hilighted = data_item_win_ptr->highlight; - tui_get_register (frame, data, - data->item_no, &data->highlight); + tui_get_register (frame, data_item_win_ptr.get (), + data_item_win_ptr->item_no, + &data_item_win_ptr->highlight); - if (data->highlight || was_hilighted) - { - tui_display_register (data, data_item_win_ptr); - } + if (data_item_win_ptr->highlight || was_hilighted) + tui_display_register (data_item_win_ptr.get ()); } } } @@ -533,10 +449,9 @@ tui_check_register_values (struct frame_info *frame) /* Display a register in a window. If hilite is TRUE, then the value will be displayed in reverse video. */ static void -tui_display_register (struct tui_data_element *data, - struct tui_gen_win_info *win_info) +tui_display_register (struct tui_data_item_window *data) { - if (win_info->handle != (WINDOW *) NULL) + if (data->handle != NULL) { int i; @@ -546,14 +461,14 @@ tui_display_register (struct tui_data_element *data, to ncurses 5.7 dated 2009-08-29, changing this macro to expand to code that causes the compiler to generate an unused-value warning. */ - (void) wstandout (win_info->handle); + (void) wstandout (data->handle); - wmove (win_info->handle, 0, 0); - for (i = 1; i < win_info->width; i++) - waddch (win_info->handle, ' '); - wmove (win_info->handle, 0, 0); + wmove (data->handle, 0, 0); + for (i = 1; i < data->width; i++) + waddch (data->handle, ' '); + wmove (data->handle, 0, 0); if (data->content) - waddstr (win_info->handle, data->content); + waddstr (data->handle, data->content); if (data->highlight) /* We ignore the return value, casting it to void in order to avoid @@ -561,99 +476,151 @@ tui_display_register (struct tui_data_element *data, to ncurses 5.7 dated 2009-08-29, changing this macro to expand to code that causes the compiler to generate an unused-value warning. */ - (void) wstandend (win_info->handle); - tui_refresh_win (win_info); + (void) wstandend (data->handle); + data->refresh_window (); } } -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->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->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->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; -/* Provide a prototype to silence -Wmissing-prototypes. */ -extern initialize_file_ftype _initialize_tui_regs; + reggroup_completer (ignore, tracker, text, word); + + /* XXXX use complete_on_enum instead? */ + for (tmp = extra; *tmp != NULL; ++tmp) + { + if (strncmp (word, *tmp, len) == 0) + tracker.add_completion (make_unique_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 +628,30 @@ _initialize_tui_regs (void) ** STATIC LOCAL FUNCTIONS ** ******************************************/ -extern int pagination_enabled; +/* Get the register from the frame and return a printable + representation of it. */ -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 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 @@ -733,51 +659,26 @@ tui_register_format (struct frame_info *frame, changed with respect to the previous call. */ static enum tui_status tui_get_register (struct frame_info *frame, - struct tui_data_element *data, - int regnum, int *changedp) + struct tui_data_item_window *data, + int regnum, bool *changedp) { enum tui_status ret = TUI_FAILURE; if (changedp) - *changedp = FALSE; + *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; - - for (i = 0; i < size; i++) - if (buf[i] != old[i]) - { - *changedp = TRUE; - old[i] = buf[i]; - } - } + data->content = tui_register_format (frame, regnum); + + if (changedp != NULL + && strcmp (prev_content, data->content) != 0) + *changedp = true; - /* 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); -}