X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Ftui%2Ftui-regs.c;h=d33f0aadef8253fd15f88b705bd000d246686c0c;hb=283be8bfa4c19c60f81abbbb43e41b6ccfdff4a9;hp=bb8d545c47b579e94a5ead35a6f6238d9fcb50bf;hpb=65962b20b6df7e8961ec4002179dbd51a33a627f;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c index bb8d545c47..d33f0aadef 100644 --- a/gdb/tui/tui-regs.c +++ b/gdb/tui/tui-regs.c @@ -1,6 +1,6 @@ /* TUI display registers in window. - Copyright (C) 1998-2019 Free Software Foundation, Inc. + Copyright (C) 1998-2020 Free Software Foundation, Inc. Contributed by Hewlett-Packard Company. @@ -42,24 +42,53 @@ #include "gdb_curses.h" -static void tui_display_register (struct tui_data_item_window *data); +/* Get the register from the frame and return a printable + representation of it. */ -static void tui_show_register_group (tui_data_window *win_info, - struct reggroup *group, - struct frame_info *frame, - int refresh_values_only); +static gdb::unique_xmalloc_ptr +tui_register_format (struct frame_info *frame, int regnum) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); -static void tui_get_register (struct frame_info *frame, - struct tui_data_item_window *data, - int regnum, bool *changedp); + string_file stream; + scoped_restore save_pagination + = make_scoped_restore (&pagination_enabled, 0); + scoped_restore save_stdout + = make_scoped_restore (&gdb_stdout, &stream); -/* See tui-regs.h. */ + gdbarch_print_registers_info (gdbarch, &stream, frame, regnum, 1); + + /* Remove the possible \n. */ + std::string &str = stream.string (); + if (!str.empty () && str.back () == '\n') + str.resize (str.size () - 1); -tui_data_item_window::~tui_data_item_window () + /* Expand tabs into spaces, since ncurses on MS-Windows doesn't. */ + return tui_expand_tabs (str.c_str ()); +} + +/* Get the register value from the given frame and format it for the + display. When changep is set, check if the new register value has + changed with respect to the previous call. */ +static void +tui_get_register (struct frame_info *frame, + struct tui_data_item_window *data, + int regnum, bool *changedp) { - xfree (value); - xfree (content); + if (changedp) + *changedp = false; + if (target_has_registers) + { + gdb::unique_xmalloc_ptr new_content + = tui_register_format (frame, regnum); + + if (changedp != NULL + && strcmp (data->content.get (), new_content.get ()) != 0) + *changedp = true; + + data->content = std::move (new_content); + } } /* See tui-regs.h. */ @@ -67,14 +96,9 @@ tui_data_item_window::~tui_data_item_window () int tui_data_window::last_regs_line_no () const { - int num_lines = (-1); - - if (!regs_content.empty ()) - { - num_lines = regs_content.size () / regs_column_count; - if (regs_content.size () % regs_column_count) - num_lines++; - } + int num_lines = m_regs_content.size () / m_regs_column_count; + if (m_regs_content.size () % m_regs_column_count) + num_lines++; return num_lines; } @@ -83,14 +107,14 @@ tui_data_window::last_regs_line_no () const int tui_data_window::line_from_reg_element_no (int element_no) const { - if (element_no < regs_content.size ()) + if (element_no < m_regs_content.size ()) { int i, line = (-1); i = 1; while (line == (-1)) { - if (element_no < regs_column_count * i) + if (element_no < m_regs_column_count * i) line = i - 1; else i++; @@ -107,89 +131,55 @@ tui_data_window::line_from_reg_element_no (int element_no) const int tui_data_window::first_reg_element_no_inline (int line_no) const { - if (line_no * regs_column_count <= regs_content.size ()) - return ((line_no + 1) * regs_column_count) - regs_column_count; + if (line_no * m_regs_column_count <= m_regs_content.size ()) + return ((line_no + 1) * m_regs_column_count) - m_regs_column_count; else return (-1); } -/* A helper function to display the register window in the appropriate - way. */ - -static void -tui_reg_layout () -{ - enum tui_layout_type cur_layout = tui_current_layout (); - enum tui_layout_type new_layout; - if (cur_layout == SRC_COMMAND || cur_layout == SRC_DATA_COMMAND) - new_layout = SRC_DATA_COMMAND; - else - new_layout = DISASSEM_DATA_COMMAND; - tui_set_layout (new_layout); -} - /* Show the registers of the given group in the data window and refresh the window. */ void -tui_show_registers (struct reggroup *group) +tui_data_window::show_registers (struct reggroup *group) { - /* 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->is_visible) - tui_reg_layout (); - if (group == 0) group = general_reggroup; - /* Say that registers should be displayed, even if there is a - problem. */ - TUI_DATA_WIN->display_regs = true; - if (target_has_registers && target_has_stack && target_has_memory) { - tui_show_register_group (TUI_DATA_WIN, group, get_selected_frame (NULL), - group == TUI_DATA_WIN->current_group); + show_register_group (group, get_selected_frame (NULL), + group == m_current_group); /* Clear all notation of changed values. */ - for (auto &&data_item_win : TUI_DATA_WIN->regs_content) - { - if (data_item_win != nullptr) - data_item_win->highlight = false; - } - TUI_DATA_WIN->current_group = group; - TUI_DATA_WIN->display_all_data (); + for (auto &&data_item_win : m_regs_content) + data_item_win.highlight = false; + m_current_group = group; } else { - TUI_DATA_WIN->current_group = 0; - TUI_DATA_WIN->erase_data_content (NO_REGS_STRING); + m_current_group = 0; + m_regs_content.clear (); } + + rerender (); } /* Set the data window to display the registers of the register group using the given frame. Values are refreshed only when - refresh_values_only is TRUE. */ + refresh_values_only is true. */ -static void -tui_show_register_group (tui_data_window *win_info, - struct reggroup *group, - struct frame_info *frame, - int refresh_values_only) +void +tui_data_window::show_register_group (struct reggroup *group, + struct frame_info *frame, + bool refresh_values_only) { struct gdbarch *gdbarch = get_frame_arch (frame); int nr_regs; int regnum, pos; - char title[80]; /* Make a new title showing which group we display. */ - snprintf (title, sizeof (title) - 1, "Register group: %s", - reggroup_name (group)); - xfree (win_info->title); - win_info->title = xstrdup (title); + title = string_printf ("Register group: %s", reggroup_name (group)); /* See how many registers must be displayed. */ nr_regs = 0; @@ -210,16 +200,7 @@ tui_show_register_group (tui_data_window *win_info, nr_regs++; } - if (!refresh_values_only) - win_info->regs_content.clear (); - - if (nr_regs < win_info->regs_content.size ()) - win_info->regs_content.resize (nr_regs); - else - { - for (int i = win_info->regs_content.size (); i < nr_regs; ++i) - win_info->regs_content.emplace_back (new tui_data_item_window ()); - } + m_regs_content.resize (nr_regs); /* Now set the register names and values. */ pos = 0; @@ -238,7 +219,7 @@ tui_show_register_group (tui_data_window *win_info, if (name == 0 || *name == '\0') continue; - data_item_win = win_info->regs_content[pos].get (); + data_item_win = &m_regs_content[pos]; if (data_item_win) { if (!refresh_values_only) @@ -258,80 +239,45 @@ tui_show_register_group (tui_data_window *win_info, void tui_data_window::display_registers_from (int start_element_no) { - if (!regs_content.empty ()) + int j, item_win_width, cur_y; + + int max_len = 0; + for (auto &&data_item_win : m_regs_content) + { + const char *p; + int len; + + len = 0; + p = data_item_win.content.get (); + if (p != 0) + len = strlen (p); + + if (len > max_len) + max_len = len; + } + item_win_width = max_len + 1; + int i = start_element_no; + + m_regs_column_count = (width - 2) / item_win_width; + if (m_regs_column_count == 0) + m_regs_column_count = 1; + item_win_width = (width - 2) / m_regs_column_count; + + /* Now create each data "sub" window, and write the display into + it. */ + cur_y = 1; + while (i < m_regs_content.size () && cur_y <= height - 2) { - int j, item_win_width, cur_y; - - int max_len = 0; - for (auto &&data_item_win : regs_content) - { - char *p; - int len; - - len = 0; - p = data_item_win->content; - if (p != 0) - while (*p) - { - if (*p++ == '\t') - len = 8 * ((len / 8) + 1); - else - len++; - } - - if (len > max_len) - max_len = len; - } - item_win_width = max_len + 1; - int i = start_element_no; - - regs_column_count = (width - 2) / item_win_width; - if (regs_column_count == 0) - regs_column_count = 1; - item_win_width = (width - 2) / regs_column_count; - - /* Now create each data "sub" window, and write the display into - it. */ - cur_y = 1; - while (i < regs_content.size () - && cur_y <= viewport_height) + for (j = 0; + j < m_regs_column_count && i < m_regs_content.size (); + j++) { - for (j = 0; - j < regs_column_count && i < regs_content.size (); - j++) - { - struct tui_data_item_window *data_item_win; - - /* Create the window if necessary. */ - data_item_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 - || data_item_win->origin.y != cur_y)) - { - tui_delete_win (data_item_win->handle); - data_item_win->handle = 0; - } - - 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; - data_item_win->origin.y = cur_y; - tui_make_window (data_item_win); - scrollok (data_item_win->handle, FALSE); - } - touchwin (data_item_win->handle); - - /* Get the printable representation of the register - and display it. */ - tui_display_register (data_item_win); - i++; /* Next register. */ - } - cur_y++; /* Next row. */ + /* Create the window if necessary. */ + m_regs_content[i].resize (1, item_win_width, + x + (item_win_width * j) + 1, y + cur_y); + i++; /* Next register. */ } + cur_y++; /* Next row. */ } } @@ -341,27 +287,24 @@ void tui_data_window::display_reg_element_at_line (int start_element_no, int start_line_no) { - if (!regs_content.empty ()) - { - int element_no = start_element_no; + int element_no = start_element_no; - if (start_element_no != 0 && start_line_no != 0) - { - int last_line_no, first_line_on_last_page; - - last_line_no = last_regs_line_no (); - first_line_on_last_page = last_line_no - (height - 2); - if (first_line_on_last_page < 0) - first_line_on_last_page = 0; - - /* If the element_no causes us to scroll past the end of the - registers, adjust what element to really start the - display at. */ - if (start_line_no > first_line_on_last_page) - element_no = first_reg_element_no_inline (first_line_on_last_page); - } - display_registers_from (element_no); + if (start_element_no != 0 && start_line_no != 0) + { + int last_line_no, first_line_on_last_page; + + last_line_no = last_regs_line_no (); + first_line_on_last_page = last_line_no - (height - 2); + if (first_line_on_last_page < 0) + first_line_on_last_page = 0; + + /* If the element_no causes us to scroll past the end of the + registers, adjust what element to really start the + display at. */ + if (start_line_no > first_line_on_last_page) + element_no = first_reg_element_no_inline (first_line_on_last_page); } + display_registers_from (element_no); } /* See tui-regs.h. */ @@ -369,35 +312,29 @@ tui_data_window::display_reg_element_at_line (int start_element_no, int tui_data_window::display_registers_from_line (int line_no) { - check_and_display_highlight_if_needed (); - if (!regs_content.empty ()) - { - int element_no; + int element_no; - if (line_no < 0) - line_no = 0; - else + if (line_no < 0) + line_no = 0; + else + { + /* Make sure that we don't display off the end of the + registers. */ + if (line_no >= last_regs_line_no ()) { - /* Make sure that we don't display off the end of the - registers. */ - if (line_no >= last_regs_line_no ()) - { - line_no = line_from_reg_element_no (regs_content.size () - 1); - if (line_no < 0) - line_no = 0; - } + line_no = line_from_reg_element_no (m_regs_content.size () - 1); + if (line_no < 0) + line_no = 0; } - - element_no = first_reg_element_no_inline (line_no); - if (element_no < regs_content.size ()) - display_reg_element_at_line (element_no, line_no); - else - line_no = (-1); - - return line_no; } - return (-1); /* Nothing was displayed. */ + element_no = first_reg_element_no_inline (line_no); + if (element_no < m_regs_content.size ()) + display_reg_element_at_line (element_no, line_no); + else + line_no = (-1); + + return line_no; } @@ -406,12 +343,12 @@ tui_data_window::display_registers_from_line (int line_no) int tui_data_window::first_data_item_displayed () { - for (int i = 0; i < regs_content.size (); i++) + for (int i = 0; i < m_regs_content.size (); i++) { struct tui_gen_win_info *data_item_win; - data_item_win = regs_content[i].get (); - if (data_item_win->handle != NULL && data_item_win->is_visible) + data_item_win = &m_regs_content[i]; + if (data_item_win->is_visible ()) return i; } @@ -423,19 +360,15 @@ tui_data_window::first_data_item_displayed () void tui_data_window::delete_data_content_windows () { - for (auto &&win : regs_content) - { - tui_delete_win (win->handle); - win->handle = NULL; - win->is_visible = false; - } + for (auto &&win : m_regs_content) + win.handle.reset (nullptr); } void tui_data_window::erase_data_content (const char *prompt) { - werase (handle); + werase (handle.get ()); check_and_display_highlight_if_needed (); if (prompt != NULL) { @@ -446,54 +379,27 @@ tui_data_window::erase_data_content (const char *prompt) x_pos = 1; else x_pos = half_width - strlen (prompt); - mvwaddstr (handle, (height / 2), x_pos, (char *) prompt); + mvwaddstr (handle.get (), (height / 2), x_pos, (char *) prompt); } - wrefresh (handle); + tui_wrefresh (handle.get ()); } /* See tui-regs.h. */ void -tui_data_window::display_all_data () +tui_data_window::rerender () { - if (regs_content.empty ()) - erase_data_content (NO_DATA_STRING); + if (m_regs_content.empty ()) + erase_data_content (_("[ Register Values Unavailable ]")); else { erase_data_content (NULL); delete_data_content_windows (); - check_and_display_highlight_if_needed (); display_registers_from (0); } } -/* Function to redisplay the contents of the data window. */ -void -tui_data_window::refresh_all () -{ - erase_data_content (NULL); - if (!regs_content.empty ()) - { - int first_element = first_data_item_displayed (); - - if (first_element >= 0) /* Re-use existing windows. */ - { - int first_line = (-1); - - if (first_element < regs_content.size ()) - first_line = line_from_reg_element_no (first_element); - - if (first_line >= 0) - { - erase_data_content (NULL); - display_registers_from_line (first_line); - } - } - } -} - - /* Scroll the data window vertically forward or backward. */ void tui_data_window::do_scroll_vertical (int num_to_scroll) @@ -502,7 +408,7 @@ tui_data_window::do_scroll_vertical (int num_to_scroll) int first_line = (-1); first_element_no = first_data_item_displayed (); - if (first_element_no < regs_content.size ()) + if (first_element_no < m_regs_content.size ()) first_line = line_from_reg_element_no (first_element_no); else { /* Calculate the first line from the element number which is in @@ -521,100 +427,90 @@ tui_data_window::do_scroll_vertical (int num_to_scroll) /* See tui-regs.h. */ void -tui_data_window::set_new_height (int height) -{ - /* Delete all data item windows. */ - for (auto &&win : regs_content) - { - tui_delete_win (win->handle); - win->handle = NULL; - } -} - -/* See tui-regs.h. */ - -void -tui_data_window::do_make_visible_with_new_height () +tui_data_window::refresh_window () { - display_all_data (); + tui_gen_win_info::refresh_window (); + for (auto &&win : m_regs_content) + win.refresh_window (); } -/* See tui-regs.h. */ - void -tui_data_window::refresh_window () +tui_data_window::no_refresh () { - tui_gen_win_info::refresh_window (); - for (auto &&win : regs_content) - { - if (win != NULL) - win->refresh_window (); - } + tui_gen_win_info::no_refresh (); + for (auto &&win : m_regs_content) + win.no_refresh (); } /* This function check all displayed registers for changes in values, given a particular frame. If the values have changed, they are updated with the new value and highlighted. */ void -tui_check_register_values (struct frame_info *frame) +tui_data_window::check_register_values (struct frame_info *frame) { - if (TUI_DATA_WIN != NULL - && TUI_DATA_WIN->is_visible) + if (m_regs_content.empty ()) + show_registers (m_current_group); + else { - if (TUI_DATA_WIN->regs_content.empty () - && TUI_DATA_WIN->display_regs) - tui_show_registers (TUI_DATA_WIN->current_group); - else + for (auto &&data_item_win : m_regs_content) { - for (auto &&data_item_win_ptr : TUI_DATA_WIN->regs_content) - { - int was_hilighted; + int was_hilighted; - was_hilighted = data_item_win_ptr->highlight; + was_hilighted = data_item_win.highlight; - tui_get_register (frame, data_item_win_ptr.get (), - data_item_win_ptr->item_no, - &data_item_win_ptr->highlight); + tui_get_register (frame, &data_item_win, + data_item_win.item_no, + &data_item_win.highlight); - if (data_item_win_ptr->highlight || was_hilighted) - tui_display_register (data_item_win_ptr.get ()); - } + if (data_item_win.highlight || was_hilighted) + data_item_win.rerender (); } } } /* 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_item_window *data) +void +tui_data_item_window::rerender () { - if (data->handle != NULL) - { - int i; - - if (data->highlight) - /* We ignore the return value, casting it to void in order to avoid - a compiler warning. The warning itself was introduced by a patch - 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 (data->handle); + int i; + + scrollok (handle.get (), FALSE); + if (highlight) + /* We ignore the return value, casting it to void in order to avoid + a compiler warning. The warning itself was introduced by a patch + 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 (handle.get ()); - wmove (data->handle, 0, 0); - for (i = 1; i < data->width; i++) - waddch (data->handle, ' '); - wmove (data->handle, 0, 0); - if (data->content) - waddstr (data->handle, data->content); - - if (data->highlight) - /* We ignore the return value, casting it to void in order to avoid - a compiler warning. The warning itself was introduced by a patch - 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 (data->handle); - data->refresh_window (); + wmove (handle.get (), 0, 0); + for (i = 1; i < width; i++) + waddch (handle.get (), ' '); + wmove (handle.get (), 0, 0); + if (content) + waddstr (handle.get (), content.get ()); + + if (highlight) + /* We ignore the return value, casting it to void in order to avoid + a compiler warning. The warning itself was introduced by a patch + 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 (handle.get ()); + refresh_window (); +} + +void +tui_data_item_window::refresh_window () +{ + if (handle != nullptr) + { + /* This seems to be needed because the data items are nested + windows, which according to the ncurses man pages aren't well + supported. */ + touchwin (handle.get ()); + tui_wrefresh (handle.get ()); } } @@ -671,15 +567,15 @@ tui_reg_command (const char *args, int from_tty) /* Make sure the curses mode is enabled. */ tui_enable (); + tui_suppress_output suppress; + /* 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_reg_layout (); + if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->is_visible ()) + tui_regs_layout (); - struct reggroup *current_group = NULL; - if (TUI_DATA_WIN != NULL) - current_group = TUI_DATA_WIN->current_group; + struct reggroup *current_group = TUI_DATA_WIN->get_current_group (); if (strncmp (args, "next", len) == 0) match = tui_reg_next (current_group, gdbarch); else if (strncmp (args, "prev", len) == 0) @@ -703,7 +599,7 @@ tui_reg_command (const char *args, int from_tty) if (match == NULL) error (_("unknown register group '%s'"), args); - tui_show_registers (match); + TUI_DATA_WIN->show_registers (match); } else { @@ -749,64 +645,17 @@ tui_reggroup_completer (struct cmd_list_element *ignore, } } -/* 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); - - 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. */ - std::string &str = stream.string (); - if (!str.empty () && str.back () == '\n') - str.resize (str.size () - 1); - - /* 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 - display. When changep is set, check if the new register value has - changed with respect to the previous call. */ -static void -tui_get_register (struct frame_info *frame, - struct tui_data_item_window *data, - int regnum, bool *changedp) -{ - if (changedp) - *changedp = false; - if (target_has_registers) - { - char *prev_content = data->content; - - data->content = tui_register_format (frame, regnum); - - if (changedp != NULL - && strcmp (prev_content, data->content) != 0) - *changedp = true; - - xfree (prev_content); - } -} - +void _initialize_tui_regs (); void -_initialize_tui_regs (void) +_initialize_tui_regs () { struct cmd_list_element **tuicmd, *cmd; tuicmd = tui_get_cmd_list (); cmd = add_cmd ("reg", class_tui, tui_reg_command, _("\ -TUI command to control the register window."), tuicmd); +TUI command to control the register window.\n\ +Usage: tui reg NAME\n\ +NAME is the name of the register group to display"), tuicmd); set_cmd_completer (cmd, tui_reggroup_completer); }