aboutsummaryrefslogtreecommitdiff
path: root/gdb/tui
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-03-08 00:14:59 +0000
committerPedro Alves <palves@redhat.com>2017-03-08 00:14:59 +0000
commit9753a2f6d74dc92d2ad94993a5479ee0edbc6887 (patch)
tree8249537542c50a6d702920e67170e7c0f51bd770 /gdb/tui
parent1a4dd9ddae4ce51724b4e08c6304e7c64f8f916f (diff)
downloadgdb-9753a2f6d74dc92d2ad94993a5479ee0edbc6887.zip
gdb-9753a2f6d74dc92d2ad94993a5479ee0edbc6887.tar.gz
gdb-9753a2f6d74dc92d2ad94993a5479ee0edbc6887.tar.bz2
Fix PR tui/21216: TUI line breaks regression
Commit d7e747318f4d04 ("Eliminate make_cleanup_ui_file_delete / make ui_file a class hierarchy") regressed the TUI's command window. Newlines miss doing a "carriage return", resulting in output like: ~~~~~~~~~~~~~~~~~~ (gdb) helpList of classes of commands: aliases -- Aliases of other commands breakpoints -- Making program stop at certain points ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Before the commit mentioned above, the default ui_file->to_write implementation had a hack that would defer into the ui_file->to_fputs method. The TUI's ui_file did not implement the to_write method, so all writes would end up going to the ncurses window via tui_file_fputs -> tui_puts. After the commit above, the hack is gone, but the TUI's ui_file still does not implement the ui_file::write method. Since tui_file inherits from stdio_file, writing to a tui_file ends up doing fwrite on the FILE stream the TUI is "associated" with, via stdio_file::write, instead of writing to the ncurses window. The fix is to have tui_file override the "write" method. New test included. gdb/ChangeLog: 2017-03-08 Pedro Alves <palves@redhat.com> PR tui/21216 * tui/tui-file.c (tui_file::write): New. * tui/tui-file.h (tui_file): Override "write". * tui/tui-io.c (do_tui_putc, update_start_line): New functions, factored out from ... (tui_puts): ... here. (tui_putc): Use them. (tui_write): New function. * tui/tui-io.h (tui_write): Declare. gdb/testsuite/ChangeLog: 2017-03-08 Pedro Alves <palves@redhat.com> PR tui/21216 * gdb.tui/tui-nl-filtered-output.exp: New file.
Diffstat (limited to 'gdb/tui')
-rw-r--r--gdb/tui/tui-file.c10
-rw-r--r--gdb/tui/tui-file.h3
-rw-r--r--gdb/tui/tui-io.c114
-rw-r--r--gdb/tui/tui-io.h4
4 files changed, 91 insertions, 40 deletions
diff --git a/gdb/tui/tui-file.c b/gdb/tui/tui-file.c
index 2f895b7..80a31f8 100644
--- a/gdb/tui/tui-file.c
+++ b/gdb/tui/tui-file.c
@@ -44,6 +44,16 @@ tui_file::puts (const char *linebuffer)
}
void
+tui_file::write (const char *buf, long length_buf)
+{
+ tui_write (buf, length_buf);
+ /* gdb_stdout is buffered, and the caller must gdb_flush it at
+ appropriate times. Other streams are not so buffered. */
+ if (this != gdb_stdout)
+ tui_refresh_cmd_win ();
+}
+
+void
tui_file::flush ()
{
/* gdb_stdout is buffered. Other files are always flushed on
diff --git a/gdb/tui/tui-file.h b/gdb/tui/tui-file.h
index aceaab6..c426a83 100644
--- a/gdb/tui/tui-file.h
+++ b/gdb/tui/tui-file.h
@@ -28,8 +28,9 @@ class tui_file : public stdio_file
public:
explicit tui_file (FILE *stream);
- void flush () override;
+ void write (const char *buf, long length_buf) override;
void puts (const char *) override;
+ void flush () override;
};
#endif
diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
index 433762b..ba1ee9a 100644
--- a/gdb/tui/tui-io.c
+++ b/gdb/tui/tui-io.c
@@ -137,58 +137,94 @@ static int tui_readline_pipe[2];
This may be the main gdb prompt or a secondary prompt. */
static char *tui_rl_saved_prompt;
+/* Print a character in the curses command window. The output is
+ buffered. It is up to the caller to refresh the screen if
+ necessary. */
+
+static void
+do_tui_putc (WINDOW *w, char c)
+{
+ static int tui_skip_line = -1;
+
+ /* Catch annotation and discard them. We need two \032 and discard
+ until a \n is seen. */
+ if (c == '\032')
+ {
+ tui_skip_line++;
+ }
+ else if (tui_skip_line != 1)
+ {
+ tui_skip_line = -1;
+ /* Expand TABs, since ncurses on MS-Windows doesn't. */
+ if (c == '\t')
+ {
+ int col;
+
+ col = getcurx (w);
+ do
+ {
+ waddch (w, ' ');
+ col++;
+ }
+ while ((col % 8) != 0);
+ }
+ else
+ waddch (w, c);
+ }
+ else if (c == '\n')
+ tui_skip_line = -1;
+}
+
+/* Update the cached value of the command window's start line based on
+ the window's current Y coordinate. */
+
+static void
+update_cmdwin_start_line ()
+{
+ TUI_CMD_WIN->detail.command_info.start_line
+ = getcury (TUI_CMD_WIN->generic.handle);
+}
+
+/* Print a character in the curses command window. The output is
+ buffered. It is up to the caller to refresh the screen if
+ necessary. */
+
static void
tui_putc (char c)
{
- char buf[2];
+ WINDOW *w = TUI_CMD_WIN->generic.handle;
+
+ do_tui_putc (w, c);
+ update_cmdwin_start_line ();
+}
+
+/* Print LENGTH characters from the buffer pointed to by BUF to the
+ curses command window. The output is buffered. It is up to the
+ caller to refresh the screen if necessary. */
+
+void
+tui_write (const char *buf, size_t length)
+{
+ WINDOW *w = TUI_CMD_WIN->generic.handle;
- buf[0] = c;
- buf[1] = 0;
- tui_puts (buf);
+ for (size_t i = 0; i < length; i++)
+ do_tui_putc (w, buf[i]);
+ update_cmdwin_start_line ();
}
-/* Print the string in the curses command window.
- The output is buffered. It is up to the caller to refresh the screen
- if necessary. */
+/* 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)
{
- static int tui_skip_line = -1;
+ WINDOW *w = TUI_CMD_WIN->generic.handle;
char c;
- WINDOW *w;
- w = TUI_CMD_WIN->generic.handle;
while ((c = *string++) != 0)
- {
- /* Catch annotation and discard them. We need two \032 and
- discard until a \n is seen. */
- if (c == '\032')
- {
- tui_skip_line++;
- }
- else if (tui_skip_line != 1)
- {
- tui_skip_line = -1;
- /* Expand TABs, since ncurses on MS-Windows doesn't. */
- if (c == '\t')
- {
- int col;
-
- col = getcurx (w);
- do
- {
- waddch (w, ' ');
- col++;
- } while ((col % 8) != 0);
- }
- else
- waddch (w, c);
- }
- else if (c == '\n')
- tui_skip_line = -1;
- }
- TUI_CMD_WIN->detail.command_info.start_line = getcury (w);
+ do_tui_putc (w, c);
+ update_cmdwin_start_line ();
}
/* Readline callback.
diff --git a/gdb/tui/tui-io.h b/gdb/tui/tui-io.h
index e1d5f86..3bd465f 100644
--- a/gdb/tui/tui-io.h
+++ b/gdb/tui/tui-io.h
@@ -28,6 +28,10 @@ class cli_ui_out;
/* Print the string in the curses command window. */
extern void tui_puts (const char *);
+/* Print LENGTH characters from the buffer pointed to by BUF to the
+ curses command window. */
+extern void tui_write (const char *buf, size_t length);
+
/* Setup the IO for curses or non-curses mode. */
extern void tui_setup_io (int mode);