From 1df2f9ef6cae23a08a50a3b2f33ce2664ce9ae9e Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 21 Oct 2019 11:21:14 -0600 Subject: Style disassembly in the TUI This patch changes the TUI disassembly window to style its contents. The styling should be identical to what is seen in the CLI. This involved a bit of rearrangement, so that the source and disassembly windows could share both the copy_source_line utility function, and the ability to react to changes in "set style enabled". This version introduces a new function to strip the styling from the address string when computing the length. As a byproduct, it also removes the unused "insn_size" computation from tui_disasm_window::set_contents. gdb/ChangeLog 2019-11-05 Tom Tromey * tui/tui-source.h (struct tui_source_window): Inline constructor. Remove destructor. : Move to superclass. * tui/tui-winsource.h (tui_copy_source_line): Declare. (struct tui_source_window_base): Move private members to end. : Move from tui_source_window. * tui/tui-winsource.c (tui_copy_source_line): Move from tui-source.c. Rename from copy_source_line. Add special handling for negative line number. (tui_source_window_base::style_changed): Move from tui_source_window. (tui_source_window_base): Register observer. (~tui_source_window_base): New. * tui/tui-source.c (copy_source_line): Move to tui-winsource.c; rename. (tui_source_window::set_contents): Use tui_copy_source_line. (tui_source_window::tui_source_window): Move to tui-source.h. (tui_source_window::~tui_source_window): Remove. (tui_source_window::style_changed): Move to superclass. * tui/tui-disasm.c (tui_disassemble): Create string file with styling, when possible. Add "addr_size" parameter. (tui_disasm_window::set_contents): Use tui_copy_source_line. Don't compute maximum size. (len_without_escapes): New function Change-Id: I8722635eeecbbb1633d943a65b856404c2d467b0 --- gdb/tui/tui-winsource.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) (limited to 'gdb/tui/tui-winsource.c') diff --git a/gdb/tui/tui-winsource.c b/gdb/tui/tui-winsource.c index 5d0bcb4..3ca723c 100644 --- a/gdb/tui/tui-winsource.c +++ b/gdb/tui/tui-winsource.c @@ -65,7 +65,98 @@ tui_display_main () } } +/* See tui-winsource.h. */ + +std::string +tui_copy_source_line (const char **ptr, int line_no, int first_col, + int line_width) +{ + const char *lineptr = *ptr; + + /* Init the line with the line number. */ + std::string result; + + if (line_no > 0) + { + result = string_printf ("%-6d", line_no); + int len = result.size (); + len = len - ((len / tui_tab_width) * tui_tab_width); + result.append (len, ' '); + } + + int column = 0; + char c; + do + { + int skip_bytes; + + c = *lineptr; + if (c == '\033' && skip_ansi_escape (lineptr, &skip_bytes)) + { + /* We always have to preserve escapes. */ + result.append (lineptr, lineptr + skip_bytes); + lineptr += skip_bytes; + continue; + } + + ++lineptr; + ++column; + + auto process_tab = [&] () + { + int max_tab_len = tui_tab_width; + + --column; + for (int j = column % max_tab_len; + j < max_tab_len && column < first_col + line_width; + column++, j++) + if (column >= first_col) + result.push_back (' '); + }; + + /* We have to process all the text in order to pick up all the + escapes. */ + if (column <= first_col || column > first_col + line_width) + { + if (c == '\t') + process_tab (); + continue; + } + + if (c == '\n' || c == '\r' || c == '\0') + { + /* Nothing. */ + } + else if (c < 040 && c != '\t') + { + result.push_back ('^'); + result.push_back (c + 0100); + } + else if (c == 0177) + { + result.push_back ('^'); + result.push_back ('?'); + } + else if (c == '\t') + process_tab (); + else + result.push_back (c); + } + while (c != '\0' && c != '\n' && c != '\r'); + + if (c == '\r' && *lineptr == '\n') + ++lineptr; + *ptr = lineptr; + return result; +} + +void +tui_source_window_base::style_changed () +{ + if (tui_active && is_visible ()) + refill (); +} /* Function to display source in the source window. This function initializes the horizontal scroll to 0. */ @@ -253,8 +344,16 @@ tui_source_window_base::tui_source_window_base (enum tui_win_type type) gdb_assert (type == SRC_WIN || type == DISASSEM_WIN); start_line_or_addr.loa = LOA_ADDRESS; start_line_or_addr.u.addr = 0; + + gdb::observers::source_styling_changed.attach + (std::bind (&tui_source_window::style_changed, this), + m_observable); } +tui_source_window_base::~tui_source_window_base () +{ + gdb::observers::source_styling_changed.detach (m_observable); +} /* See tui-data.h. */ -- cgit v1.1