aboutsummaryrefslogtreecommitdiff
path: root/gdb/tui/tui-io.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2020-09-27 20:30:30 -0600
committerTom Tromey <tom@tromey.com>2020-09-27 20:30:33 -0600
commit2c72d5e58a55d3e0f867ffd9421184852f051cb7 (patch)
tree30777c30b8de39921bc12251304c487961f7cef1 /gdb/tui/tui-io.c
parent35a982372fd63da7dd2811d6150b0c61236bbbb5 (diff)
downloadgdb-2c72d5e58a55d3e0f867ffd9421184852f051cb7.zip
gdb-2c72d5e58a55d3e0f867ffd9421184852f051cb7.tar.gz
gdb-2c72d5e58a55d3e0f867ffd9421184852f051cb7.tar.bz2
Rewrite tui_puts
This rewrites tui_puts. It now writes as many bytes as possible in a call to waddnstr, letting curses handle multi-byte sequences properly. Note that tui_puts_internal remains. It is needed to handle computing the start line of the readline prompt, which is difficult to do properly in the case where redisplaying can also cause the command window to scroll. This might be possible to implement by reverting to single "character" output, by using mbsrtowcs for its side effects to find character boundaries in the input. I have not attempted this. gdb/ChangeLog 2020-09-27 Tom Tromey <tom@tromey.com> PR tui/25342: * tui/tui-io.c (tui_puts): Rewrite. Move earlier.
Diffstat (limited to 'gdb/tui/tui-io.c')
-rw-r--r--gdb/tui/tui-io.c75
1 files changed, 63 insertions, 12 deletions
diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
index 7698d79..1a2764e 100644
--- a/gdb/tui/tui-io.c
+++ b/gdb/tui/tui-io.c
@@ -435,6 +435,69 @@ tui_write (const char *buf, size_t length)
tui_puts (copy.c_str ());
}
+/* Print a string in the curses command window. The output is
+ buffered. It is up to the caller to refresh the screen if
+ necessary. */
+
+void
+tui_puts (const char *string, WINDOW *w)
+{
+ if (w == nullptr)
+ w = TUI_CMD_WIN->handle.get ();
+
+ while (true)
+ {
+ const char *next = strpbrk (string, "\n\1\2\033\t");
+
+ /* Print the plain text prefix. */
+ size_t n_chars = next == nullptr ? strlen (string) : next - string;
+ if (n_chars > 0)
+ waddnstr (w, string, n_chars);
+
+ /* We finished. */
+ if (next == nullptr)
+ break;
+
+ char c = *next;
+ switch (c)
+ {
+ case '\1':
+ case '\2':
+ /* Ignore these, they are readline escape-marking
+ sequences. */
+ ++next;
+ break;
+
+ case '\n':
+ case '\t':
+ do_tui_putc (w, c);
+ ++next;
+ break;
+
+ case '\033':
+ {
+ size_t bytes_read = apply_ansi_escape (w, next);
+ if (bytes_read > 0)
+ next += bytes_read;
+ else
+ {
+ /* Just drop the escape. */
+ ++next;
+ }
+ }
+ break;
+
+ default:
+ gdb_assert_not_reached ("missing case in tui_puts");
+ }
+
+ string = next;
+ }
+
+ if (TUI_CMD_WIN != nullptr && w == TUI_CMD_WIN->handle.get ())
+ update_cmdwin_start_line ();
+}
+
static void
tui_puts_internal (WINDOW *w, const char *string, int *height)
{
@@ -480,18 +543,6 @@ tui_puts_internal (WINDOW *w, const char *string, int *height)
wrefresh (w);
}
-/* Print a string in the curses command window. The output is
- buffered. It is up to the caller to refresh the screen if
- necessary. */
-
-void
-tui_puts (const char *string, WINDOW *w)
-{
- if (w == nullptr)
- w = TUI_CMD_WIN->handle.get ();
- tui_puts_internal (w, string, nullptr);
-}
-
/* Readline callback.
Redisplay the command line with its prompt after readline has
changed the edited text. */