aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog19
-rw-r--r--gdb/ada-lang.c48
-rw-r--r--gdb/source.c62
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.base/page.exp14
-rw-r--r--gdb/testsuite/gdb.base/style.exp18
-rw-r--r--gdb/ui-style.h10
-rw-r--r--gdb/utils.c92
8 files changed, 193 insertions, 75 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 326113a..eb3bc0b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,22 @@
+2019-02-17 Tom Tromey <tom@tromey.com>
+
+ * ada-lang.c (user_select_syms): Use filtered printing.
+ * utils.c (wrap_style): New global.
+ (desired_style): Remove.
+ (emit_style_escape): Add stream parameter.
+ (set_output_style, reset_terminal_style, prompt_for_continue):
+ Update.
+ (flush_wrap_buffer): Only flush gdb_stdout.
+ (wrap_here): Set wrap_style.
+ (fputs_maybe_filtered): Clear the wrap buffer on exception. Don't
+ treat escape sequences as a character. Change when wrap buffer is
+ flushed.
+ (fputs_styled): Do not set the output style when the default is
+ requested.
+ * ui-style.h (struct ui_file_style) <is_default>: New method.
+ * source.c (print_source_lines_base): Emit escape sequences in one
+ piece.
+
2019-02-17 Joel Brobecker <brobecker@adacore.com>
* gdbtypes.c (type_align): Handle TYPE_CODE_RANGE the same as
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 66df1d1..a6fadc8 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -3903,16 +3903,16 @@ user_select_syms (struct block_symbol *syms, int nsyms, int max_results)
error (_("\
canceled because the command is ambiguous\n\
See set/show multiple-symbol."));
-
+
/* If select_mode is "all", then return all possible symbols.
Only do that if more than one symbol can be selected, of course.
Otherwise, display the menu as usual. */
if (select_mode == multiple_symbols_all && max_results > 1)
return nsyms;
- printf_unfiltered (_("[0] cancel\n"));
+ printf_filtered (_("[0] cancel\n"));
if (max_results > 1)
- printf_unfiltered (_("[1] all\n"));
+ printf_filtered (_("[1] all\n"));
sort_choices (syms, nsyms);
@@ -3926,16 +3926,16 @@ See set/show multiple-symbol."));
struct symtab_and_line sal =
find_function_start_sal (syms[i].symbol, 1);
- printf_unfiltered ("[%d] ", i + first_choice);
+ printf_filtered ("[%d] ", i + first_choice);
ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
&type_print_raw_options);
if (sal.symtab == NULL)
- printf_unfiltered (_(" at <no source file available>:%d\n"),
- sal.line);
+ printf_filtered (_(" at <no source file available>:%d\n"),
+ sal.line);
else
- printf_unfiltered (_(" at %s:%d\n"),
- symtab_to_filename_for_display (sal.symtab),
- sal.line);
+ printf_filtered (_(" at %s:%d\n"),
+ symtab_to_filename_for_display (sal.symtab),
+ sal.line);
continue;
}
else
@@ -3951,37 +3951,37 @@ See set/show multiple-symbol."));
if (SYMBOL_LINE (syms[i].symbol) != 0 && symtab != NULL)
{
- printf_unfiltered ("[%d] ", i + first_choice);
+ printf_filtered ("[%d] ", i + first_choice);
ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
&type_print_raw_options);
- printf_unfiltered (_(" at %s:%d\n"),
- symtab_to_filename_for_display (symtab),
- SYMBOL_LINE (syms[i].symbol));
+ printf_filtered (_(" at %s:%d\n"),
+ symtab_to_filename_for_display (symtab),
+ SYMBOL_LINE (syms[i].symbol));
}
else if (is_enumeral
&& TYPE_NAME (SYMBOL_TYPE (syms[i].symbol)) != NULL)
{
- printf_unfiltered (("[%d] "), i + first_choice);
+ printf_filtered (("[%d] "), i + first_choice);
ada_print_type (SYMBOL_TYPE (syms[i].symbol), NULL,
gdb_stdout, -1, 0, &type_print_raw_options);
- printf_unfiltered (_("'(%s) (enumeral)\n"),
- SYMBOL_PRINT_NAME (syms[i].symbol));
+ printf_filtered (_("'(%s) (enumeral)\n"),
+ SYMBOL_PRINT_NAME (syms[i].symbol));
}
else
{
- printf_unfiltered ("[%d] ", i + first_choice);
+ printf_filtered ("[%d] ", i + first_choice);
ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
&type_print_raw_options);
if (symtab != NULL)
- printf_unfiltered (is_enumeral
- ? _(" in %s (enumeral)\n")
- : _(" at %s:?\n"),
- symtab_to_filename_for_display (symtab));
+ printf_filtered (is_enumeral
+ ? _(" in %s (enumeral)\n")
+ : _(" at %s:?\n"),
+ symtab_to_filename_for_display (symtab));
else
- printf_unfiltered (is_enumeral
- ? _(" (enumeral)\n")
- : _(" at ?\n"));
+ printf_filtered (is_enumeral
+ ? _(" (enumeral)\n")
+ : _(" at ?\n"));
}
}
}
diff --git a/gdb/source.c b/gdb/source.c
index c32b7c6..f99215f 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -1249,7 +1249,6 @@ static void
print_source_lines_base (struct symtab *s, int line, int stopline,
print_source_lines_flags flags)
{
- int c;
scoped_fd desc;
int noprint = 0;
int nlines = stopline - line;
@@ -1343,13 +1342,10 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
line, symtab_to_filename_for_display (s), s->nlines);
const char *iter = lines.c_str ();
- while (nlines-- > 0)
+ while (nlines-- > 0 && *iter != '\0')
{
char buf[20];
- c = *iter++;
- if (c == '\0')
- break;
last_line_listed = current_source_line;
if (flags & PRINT_SOURCE_LINES_FILENAME)
{
@@ -1358,33 +1354,55 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
}
xsnprintf (buf, sizeof (buf), "%d\t", current_source_line++);
uiout->text (buf);
- do
+
+ while (*iter != '\0')
{
- if (c < 040 && c != '\t' && c != '\n' && c != '\r' && c != '\033')
+ /* Find a run of characters that can be emitted at once.
+ This is done so that escape sequences are kept
+ together. */
+ const char *start = iter;
+ while (true)
{
- xsnprintf (buf, sizeof (buf), "^%c", c + 0100);
- uiout->text (buf);
+ int skip_bytes;
+
+ char c = *iter;
+ if (c == '\033' && skip_ansi_escape (iter, &skip_bytes))
+ iter += skip_bytes;
+ else if (c < 040 && c != '\t')
+ break;
+ else if (c == 0177)
+ break;
+ else
+ ++iter;
}
- else if (c == 0177)
- uiout->text ("^?");
- else if (c == '\r')
+ if (iter > start)
{
- /* Skip a \r character, but only before a \n. */
- if (*iter != '\n')
- printf_filtered ("^%c", c + 0100);
+ std::string text (start, iter);
+ uiout->text (text.c_str ());
}
- else
+ if (*iter == '\r')
{
- xsnprintf (buf, sizeof (buf), "%c", c);
+ /* Treat either \r or \r\n as a single newline. */
+ ++iter;
+ if (*iter == '\n')
+ ++iter;
+ break;
+ }
+ else if (*iter == '\n')
+ {
+ ++iter;
+ break;
+ }
+ else if (*iter > 0 && *iter < 040)
+ {
+ xsnprintf (buf, sizeof (buf), "^%c", *iter + 0100);
uiout->text (buf);
}
+ else if (*iter == 0177)
+ uiout->text ("^?");
}
- while (c != '\n' && (c = *iter++) != '\0');
- if (c == '\0')
- break;
+ uiout->text ("\n");
}
- if (!lines.empty() && lines.back () != '\n')
- uiout->text ("\n");
}
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index ee8c4d3..88c6a6c 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-02-17 Tom Tromey <tom@tromey.com>
+
+ * gdb.base/style.exp: Add line-wrapping tests.
+ * gdb.base/page.exp: Add test for quitting during pagination.
+
2019-02-17 Joel Brobecker <brobecker@adacore.com>
* gdb.ada/big_packed_array: New testcase.
diff --git a/gdb/testsuite/gdb.base/page.exp b/gdb/testsuite/gdb.base/page.exp
index 7461591..10ebf0d 100644
--- a/gdb/testsuite/gdb.base/page.exp
+++ b/gdb/testsuite/gdb.base/page.exp
@@ -80,6 +80,20 @@ gdb_expect_list "paged count remainder" "${gdb_prompt} " {
11
}
+set fours [string repeat 4 40]
+set str "1\\n2\\n3\\n$fours\\n5\\n"
+
+# Avoid some confusing output from readline.
+gdb_test_no_output "set editing off"
+
+gdb_test_no_output "set width 30"
+send_gdb "printf \"$str\"\n"
+gdb_expect_list "paged count for interrupt" \
+ ".*$pagination_prompt" \
+ [list 1\r\n 2\r\n 3\r\n 444444444444444444444444444444]
+
+gdb_test "q" "Quit" "quit while paging"
+
gdb_exit
return 0
diff --git a/gdb/testsuite/gdb.base/style.exp b/gdb/testsuite/gdb.base/style.exp
index 78d04b0..010d959 100644
--- a/gdb/testsuite/gdb.base/style.exp
+++ b/gdb/testsuite/gdb.base/style.exp
@@ -45,6 +45,24 @@ save_vars { env(TERM) } {
gdb_test "print &main" " = .* \033\\\[34m$hex\033\\\[m <$main_expr>"
+ # Regression test for a bug where line-wrapping would occur at the
+ # wrong spot with styling. There were different bugs at different
+ # widths, so try two.
+ foreach width {20 30} {
+ gdb_test_no_output "set width $width"
+ # There was also a bug where the styling could be wrong in the
+ # line listing; this is why the words from the source code are
+ # spelled out in the final result line of the test.
+ gdb_test "frame" \
+ [multi_line \
+ "#0 *$main_expr.*$arg_expr.*" \
+ ".*$arg_expr.*" \
+ ".* at .*$file_expr.*" \
+ "\[0-9\]+.*return.* break here .*"
+ ] \
+ "frame when width=$width"
+ }
+
gdb_exit
gdb_spawn
diff --git a/gdb/ui-style.h b/gdb/ui-style.h
index d719438..04a1d44 100644
--- a/gdb/ui-style.h
+++ b/gdb/ui-style.h
@@ -163,6 +163,16 @@ struct ui_file_style
/* Return the ANSI escape sequence for this style. */
std::string to_ansi () const;
+ /* Return true if this style is the default style; false
+ otherwise. */
+ bool is_default () const
+ {
+ return (m_foreground == NONE
+ && m_background == NONE
+ && m_intensity == NORMAL
+ && !m_reverse);
+ }
+
/* Return true if this style specified reverse display; false
otherwise. */
bool is_reverse () const
diff --git a/gdb/utils.c b/gdb/utils.c
index 6fb5736..ec26196 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -72,6 +72,7 @@
#include <algorithm>
#include "common/pathstuff.h"
#include "cli/cli-style.h"
+#include "common/scope-exit.h"
void (*deprecated_error_begin_hook) (void);
@@ -1282,6 +1283,9 @@ static const char *wrap_indent;
/* Column number on the screen where wrap_buffer begins, or 0 if wrapping
is not in effect. */
static int wrap_column;
+
+/* The style applied at the time that wrap_here was called. */
+static ui_file_style wrap_style;
/* Initialize the number of lines per page and chars per line. */
@@ -1427,21 +1431,19 @@ set_screen_width_and_height (int width, int height)
static ui_file_style applied_style;
-/* The currently desired style. This can differ from the applied
- style when showing the pagination prompt. */
-
-static ui_file_style desired_style;
-
-/* Emit an ANSI style escape for STYLE to the wrap buffer. */
+/* Emit an ANSI style escape for STYLE. If STREAM is nullptr, emit to
+ the wrap buffer; otherwise emit to STREAM. */
static void
-emit_style_escape (const ui_file_style &style)
+emit_style_escape (const ui_file_style &style,
+ struct ui_file *stream = nullptr)
{
- if (applied_style == style)
- return;
applied_style = style;
- wrap_buffer.append (style.to_ansi ());
+ if (stream == nullptr)
+ wrap_buffer.append (style.to_ansi ());
+ else
+ fputs_unfiltered (style.to_ansi ().c_str (), stream);
}
/* See utils.h. */
@@ -1465,11 +1467,11 @@ can_emit_style_escape (struct ui_file *stream)
static void
set_output_style (struct ui_file *stream, const ui_file_style &style)
{
- if (!can_emit_style_escape (stream)
- || style == desired_style)
+ if (!can_emit_style_escape (stream))
return;
- desired_style = style;
+ /* Note that we don't pass STREAM here, because we want to emit to
+ the wrap buffer, not directly to STREAM. */
emit_style_escape (style);
}
@@ -1482,9 +1484,8 @@ reset_terminal_style (struct ui_file *stream)
{
/* Force the setting, regardless of what we think the setting
might already be. */
- desired_style = ui_file_style ();
- applied_style = desired_style;
- wrap_buffer.append (desired_style.to_ansi ());
+ applied_style = ui_file_style ();
+ wrap_buffer.append (applied_style.to_ansi ());
}
}
@@ -1504,7 +1505,8 @@ prompt_for_continue (void)
bool disable_pagination = pagination_disabled_for_command;
/* Clear the current styling. */
- emit_style_escape (ui_file_style ());
+ if (can_emit_style_escape (gdb_stdout))
+ emit_style_escape (ui_file_style (), gdb_stdout);
if (annotation_level > 1)
printf_unfiltered (("\n\032\032pre-prompt-for-continue\n"));
@@ -1551,7 +1553,8 @@ prompt_for_continue (void)
pagination_disabled_for_command = disable_pagination;
/* Restore the current styling. */
- emit_style_escape (desired_style);
+ if (can_emit_style_escape (gdb_stdout))
+ emit_style_escape (applied_style);
dont_repeat (); /* Forget prev cmd -- CR won't repeat it. */
}
@@ -1589,7 +1592,7 @@ reinitialize_more_filter (void)
static void
flush_wrap_buffer (struct ui_file *stream)
{
- if (!wrap_buffer.empty ())
+ if (stream == gdb_stdout && !wrap_buffer.empty ())
{
fputs_unfiltered (wrap_buffer.c_str (), stream);
wrap_buffer.clear ();
@@ -1644,6 +1647,7 @@ wrap_here (const char *indent)
wrap_indent = "";
else
wrap_indent = indent;
+ wrap_style = applied_style;
}
}
@@ -1743,6 +1747,14 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
return;
}
+ auto buffer_clearer
+ = make_scope_exit ([&] ()
+ {
+ wrap_buffer.clear ();
+ wrap_column = 0;
+ wrap_indent = "";
+ });
+
/* Go through and output each character. Show line extension
when this is necessary; prompt user for new page when this is
necessary. */
@@ -1759,6 +1771,8 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
while (*lineptr && *lineptr != '\n')
{
+ int skip_bytes;
+
/* Print a single line. */
if (*lineptr == '\t')
{
@@ -1769,6 +1783,14 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
chars_printed = ((chars_printed >> 3) + 1) << 3;
lineptr++;
}
+ else if (*lineptr == '\033'
+ && skip_ansi_escape (lineptr, &skip_bytes))
+ {
+ wrap_buffer.append (lineptr, skip_bytes);
+ /* Note that we don't consider this a character, so we
+ don't increment chars_printed here. */
+ lineptr += skip_bytes;
+ }
else
{
wrap_buffer.push_back (*lineptr);
@@ -1782,15 +1804,18 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
chars_printed = 0;
lines_printed++;
- /* If we aren't actually wrapping, don't output newline --
- if chars_per_line is right, we probably just overflowed
- anyway; if it's wrong, let us keep going. */
if (wrap_column)
{
- emit_style_escape (ui_file_style ());
- flush_wrap_buffer (stream);
+ if (can_emit_style_escape (stream))
+ emit_style_escape (ui_file_style (), stream);
+ /* If we aren't actually wrapping, don't output
+ newline -- if chars_per_line is right, we
+ probably just overflowed anyway; if it's wrong,
+ let us keep going. */
fputc_unfiltered ('\n', stream);
}
+ else
+ flush_wrap_buffer (stream);
/* Possible new page. Note that
PAGINATION_DISABLED_FOR_COMMAND might be set during
@@ -1803,8 +1828,8 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
if (wrap_column)
{
fputs_unfiltered (wrap_indent, stream);
- emit_style_escape (desired_style);
- flush_wrap_buffer (stream);
+ if (can_emit_style_escape (stream))
+ emit_style_escape (wrap_style, stream);
/* FIXME, this strlen is what prevents wrap_indent from
containing tabs. However, if we recurse to print it
and count its chars, we risk trouble if wrap_indent is
@@ -1828,6 +1853,8 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
lineptr++;
}
}
+
+ buffer_clearer.release ();
}
void
@@ -1842,9 +1869,16 @@ void
fputs_styled (const char *linebuffer, const ui_file_style &style,
struct ui_file *stream)
{
- set_output_style (stream, style);
- fputs_maybe_filtered (linebuffer, stream, 1);
- set_output_style (stream, ui_file_style ());
+ /* This just makes it so we emit somewhat fewer escape
+ sequences. */
+ if (style.is_default ())
+ fputs_maybe_filtered (linebuffer, stream, 1);
+ else
+ {
+ set_output_style (stream, style);
+ fputs_maybe_filtered (linebuffer, stream, 1);
+ set_output_style (stream, ui_file_style ());
+ }
}
int