aboutsummaryrefslogtreecommitdiff
path: root/gdb/tui/tui-disasm.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2019-10-21 11:21:14 -0600
committerTom Tromey <tom@tromey.com>2019-11-05 15:23:36 -0700
commit1df2f9ef6cae23a08a50a3b2f33ce2664ce9ae9e (patch)
treea7b1c72b7e81c9e4179ea641fc5eb17fefe8e4bf /gdb/tui/tui-disasm.c
parent5d0510553eb447bf6861f4641b5ae3aaf9503a13 (diff)
downloadgdb-1df2f9ef6cae23a08a50a3b2f33ce2664ce9ae9e.zip
gdb-1df2f9ef6cae23a08a50a3b2f33ce2664ce9ae9e.tar.gz
gdb-1df2f9ef6cae23a08a50a3b2f33ce2664ce9ae9e.tar.bz2
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 <tom@tromey.com> * tui/tui-source.h (struct tui_source_window): Inline constructor. Remove destructor. <style_changed, m_observable>: Move to superclass. * tui/tui-winsource.h (tui_copy_source_line): Declare. (struct tui_source_window_base): Move private members to end. <style_changed, m_observable>: 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
Diffstat (limited to 'gdb/tui/tui-disasm.c')
-rw-r--r--gdb/tui/tui-disasm.c77
1 files changed, 51 insertions, 26 deletions
diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c
index 91c9845..7178326 100644
--- a/gdb/tui/tui-disasm.c
+++ b/gdb/tui/tui-disasm.c
@@ -39,6 +39,7 @@
#include "tui/tui-source.h"
#include "progspace.h"
#include "objfiles.h"
+#include "cli/cli-style.h"
#include "gdb_curses.h"
@@ -49,15 +50,47 @@ struct tui_asm_line
std::string insn;
};
+/* Helper function to find the number of characters in STR, skipping
+ any ANSI escape sequences. */
+static size_t
+len_without_escapes (const std::string &str)
+{
+ size_t len = 0;
+ const char *ptr = str.c_str ();
+ char c;
+
+ while ((c = *ptr++) != '\0')
+ {
+ if (c == '\033')
+ {
+ ui_file_style style;
+ size_t n_read;
+ if (style.parse (ptr, &n_read))
+ ptr += n_read;
+ else
+ {
+ /* Shouldn't happen, but just skip the ESC if it somehow
+ does. */
+ ++ptr;
+ }
+ }
+ else
+ ++len;
+ }
+ return len;
+}
+
/* Function to set the disassembly window's content.
Disassemble count lines starting at pc.
Return address of the count'th instruction after pc. */
static CORE_ADDR
tui_disassemble (struct gdbarch *gdbarch,
std::vector<tui_asm_line> &asm_lines,
- CORE_ADDR pc, int pos, int count)
+ CORE_ADDR pc, int pos, int count,
+ size_t *addr_size = nullptr)
{
- string_file gdb_dis_out;
+ bool term_out = source_styling && gdb_stdout->can_emit_style_escape ();
+ string_file gdb_dis_out (term_out);
/* Now construct each line. */
for (int i = 0; i < count; ++i)
@@ -68,6 +101,17 @@ tui_disassemble (struct gdbarch *gdbarch,
gdb_dis_out.clear ();
+ if (addr_size != nullptr)
+ {
+ size_t new_size;
+
+ if (term_out)
+ new_size = len_without_escapes (asm_lines[pos + i].addr_string);
+ else
+ new_size = asm_lines[pos + i].addr_string.size ();
+ *addr_size = std::max (*addr_size, new_size);
+ }
+
pc = pc + gdb_print_insn (gdbarch, pc, &gdb_dis_out, NULL);
asm_lines[pos + i].insn = std::move (gdb_dis_out.string ());
@@ -164,8 +208,7 @@ tui_disasm_window::set_contents (struct gdbarch *arch,
struct tui_locator_window *locator = tui_locator_win_info_ptr ();
int tab_len = tui_tab_width;
int insn_pos;
- int addr_size, insn_size;
-
+
gdb_assert (line_or_addr.loa == LOA_ADDRESS);
CORE_ADDR pc = line_or_addr.u.addr;
if (pc == 0)
@@ -182,23 +225,8 @@ tui_disasm_window::set_contents (struct gdbarch *arch,
/* Get temporary table that will hold all strings (addr & insn). */
std::vector<tui_asm_line> asm_lines (max_lines);
-
- tui_disassemble (gdbarch, asm_lines, pc, 0, max_lines);
-
- /* Determine maximum address- and instruction lengths. */
- addr_size = 0;
- insn_size = 0;
- for (i = 0; i < max_lines; i++)
- {
- size_t len = asm_lines[i].addr_string.size ();
-
- if (len > addr_size)
- addr_size = len;
-
- len = asm_lines[i].insn.size ();
- if (len > insn_size)
- insn_size = len;
- }
+ size_t addr_size = 0;
+ tui_disassemble (gdbarch, asm_lines, pc, 0, max_lines, &addr_size);
/* Align instructions to the same column. */
insn_pos = (1 + (addr_size / tab_len)) * tab_len;
@@ -215,11 +243,8 @@ tui_disasm_window::set_contents (struct gdbarch *arch,
- asm_lines[i].addr_string.size ())
+ asm_lines[i].insn);
- /* Now copy the line taking the offset into account. */
- if (line.size () > offset)
- src->line = line.substr (offset, line_width);
- else
- src->line.clear ();
+ const char *ptr = line.c_str ();
+ src->line = tui_copy_source_line (&ptr, -1, offset, line_width);
src->line_or_addr.loa = LOA_ADDRESS;
src->line_or_addr.u.addr = asm_lines[i].addr;