From 2a3c1174c3c0db1140180fb3fc56ac324d1c0a7c Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 5 Jun 2019 09:17:16 +0100 Subject: Introduce gdb-specific %p format suffixes This introduces a few gdb-specific %p format suffixes. This is useful for emitting gdb-specific output in an ergonomic way. It also yields code that is more i18n-friendly. The comment before ui_out::message explains the details. Note that the tests had to change a little. When using one of the gdb printf functions with styling, there can be spurious style changes emitted to the output. This did not seem worthwhile to fix, as the low-level output functions are rather spaghetti-ish already, and I didn't want to make them even worse. This change also necessitated adding support for "*" as precision and width in format_pieces. These are used in various spots in gdb, and it seemed better to me to implement them than to remove the uses. gdb/ChangeLog 2019-10-01 Pedro Alves Tom Tromey * unittests/format_pieces-selftests.c: Add gdb_format parameter. (test_gdb_formats): New function. (run_tests): Call it. (test_format_specifier): Update. * utils.h (fputs_filtered): Update comment. (vfprintf_styled, vfprintf_styled_no_gdbfmt) (fputs_styled_unfiltered): Declare. * utils.c (fputs_styled_unfiltered): New function. (vfprintf_maybe_filtered): Add gdbfmt parameter. (vfprintf_filtered): Update. (vfprintf_unfiltered, vprintf_filtered): Update. (vfprintf_styled, vfprintf_styled_no_gdbfmt): New functions. * ui-out.h (enum ui_out_flag) : New constants. (enum class field_kind): New. (struct base_field_s, struct signed_field_s): New. (signed_field): New function. (struct string_field_s): New. (string_field): New function. (struct styled_string_s): New. (styled_string): New function. (class ui_out) : Add comment. : New methods. : Add style parameter. * ui-out.c (ui_out::call_do_message, ui_out::vmessage): New methods. (ui_out::message): Rewrite. * mi/mi-out.h (class mi_ui_out) : Add style parameter. * mi/mi-out.c (mi_ui_out::do_message): Add style parameter. * gdbsupport/format.h (class format_pieces) : Add gdb_extensions parameter. (class format_piece): Add parameter to constructor. (n_int_args): New field. * gdbsupport/format.c (format_pieces::format_pieces): Add gdb_extensions parameter. Handle '*'. * cli-out.h (class cli_ui_out) : Add style parameter. * cli-out.c (cli_ui_out::do_message): Add style parameter. Call vfprintf_styled_no_gdbfmt. (cli_ui_out::do_field_string, cli_ui_out::do_spaces) (cli_ui_out::do_text, cli_ui_out::field_separator): Allow unfiltered output. * ui-style.h (struct ui_file_style) : New method. gdb/testsuite/ChangeLog 2019-10-01 Tom Tromey * gdb.base/style.exp: Update tests. --- gdb/utils.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 11 deletions(-) (limited to 'gdb/utils.c') diff --git a/gdb/utils.c b/gdb/utils.c index b7d3800..e685cc2 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -73,13 +73,15 @@ #include "cli/cli-style.h" #include "gdbsupport/scope-exit.h" #include "gdbarch.h" +#include "cli-out.h" void (*deprecated_error_begin_hook) (void); /* Prototypes for local functions */ static void vfprintf_maybe_filtered (struct ui_file *, const char *, - va_list, int) ATTRIBUTE_PRINTF (2, 0); + va_list, bool, bool) + ATTRIBUTE_PRINTF (2, 0); static void fputs_maybe_filtered (const char *, struct ui_file *, int); @@ -1855,6 +1857,24 @@ fputs_styled (const char *linebuffer, const ui_file_style &style, /* See utils.h. */ void +fputs_styled_unfiltered (const char *linebuffer, const ui_file_style &style, + struct ui_file *stream) +{ + /* This just makes it so we emit somewhat fewer escape + sequences. */ + if (style.is_default ()) + fputs_maybe_filtered (linebuffer, stream, 0); + else + { + set_output_style (stream, style); + fputs_maybe_filtered (linebuffer, stream, 0); + set_output_style (stream, ui_file_style ()); + } +} + +/* See utils.h. */ + +void fputs_highlighted (const char *str, const compiled_regex &highlight, struct ui_file *stream) { @@ -2021,34 +2041,46 @@ puts_debug (char *prefix, char *string, char *suffix) We implement three variants, vfprintf (takes a vararg list and stream), fprintf (takes a stream to write on), and printf (the usual). - Note also that a longjmp to top level may occur in this routine - (since prompt_for_continue may do so) so this routine should not be - called when cleanups are not in place. */ + Note also that this may throw a quit (since prompt_for_continue may + do so). */ static void vfprintf_maybe_filtered (struct ui_file *stream, const char *format, - va_list args, int filter) + va_list args, bool filter, bool gdbfmt) { - std::string linebuffer = string_vprintf (format, args); - fputs_maybe_filtered (linebuffer.c_str (), stream, filter); + if (gdbfmt) + { + ui_out_flags flags = disallow_ui_out_field; + if (!filter) + flags |= unfiltered_output; + cli_ui_out (stream, flags).vmessage (applied_style, format, args); + } + else + { + std::string str = string_vprintf (format, args); + fputs_maybe_filtered (str.c_str (), stream, filter); + } } void vfprintf_filtered (struct ui_file *stream, const char *format, va_list args) { - vfprintf_maybe_filtered (stream, format, args, 1); + vfprintf_maybe_filtered (stream, format, args, true, true); } void vfprintf_unfiltered (struct ui_file *stream, const char *format, va_list args) { - std::string linebuffer = string_vprintf (format, args); if (debug_timestamp && stream == gdb_stdlog) { using namespace std::chrono; int len, need_nl; + string_file sfile; + cli_ui_out (&sfile, 0).vmessage (ui_file_style (), format, args); + std::string linebuffer = std::move (sfile.string ()); + steady_clock::time_point now = steady_clock::now (); seconds s = duration_cast (now.time_since_epoch ()); microseconds us = duration_cast (now.time_since_epoch () - s); @@ -2064,13 +2096,13 @@ vfprintf_unfiltered (struct ui_file *stream, const char *format, va_list args) fputs_unfiltered (timestamp.c_str (), stream); } else - fputs_unfiltered (linebuffer.c_str (), stream); + vfprintf_maybe_filtered (stream, format, args, false, true); } void vprintf_filtered (const char *format, va_list args) { - vfprintf_maybe_filtered (gdb_stdout, format, args, 1); + vfprintf_maybe_filtered (gdb_stdout, format, args, true, false); } void @@ -2130,6 +2162,33 @@ fprintf_styled (struct ui_file *stream, const ui_file_style &style, set_output_style (stream, ui_file_style ()); } +/* See utils.h. */ + +void +vfprintf_styled (struct ui_file *stream, const ui_file_style &style, + const char *format, va_list args) +{ + set_output_style (stream, style); + vfprintf_filtered (stream, format, args); + set_output_style (stream, ui_file_style ()); +} + +/* See utils.h. */ + +void +vfprintf_styled_no_gdbfmt (struct ui_file *stream, const ui_file_style &style, + bool filter, const char *format, va_list args) +{ + std::string str = string_vprintf (format, args); + if (!str.empty ()) + { + if (!style.is_default ()) + set_output_style (stream, style); + fputs_maybe_filtered (str.c_str (), stream, filter); + if (!style.is_default ()) + set_output_style (stream, ui_file_style ()); + } +} void printf_filtered (const char *format, ...) -- cgit v1.1