return m_stream->can_emit_style_escape ();
}
+ void emit_style_escape (const ui_file_style &style) override
+ {
+ if (can_emit_style_escape () && style != m_applied_style)
+ {
+ m_applied_style = style;
+ ui_file::emit_style_escape (style);
+ }
+ }
+
/* Flush the underlying output stream. */
void flush () override
{
/* The underlying output stream. */
ui_file *m_stream;
+
+ /* The currently applied style. */
+ ui_file_style m_applied_style;
};
/* Attaches and detaches buffers for each of the gdb_std* streams. */
}
void
-cli_ui_out::do_message (const ui_file_style &style,
+cli_ui_out::do_message (ui_file_style ¤t_style,
+ const ui_file_style &style,
const char *format, va_list args)
{
if (m_suppress_output)
return;
std::string str = string_vprintf (format, args);
- if (!str.empty ())
+ if (str.empty ())
+ return;
+
+ ui_file *stream = m_streams.back ();
+ if (current_style != style)
{
- ui_file *stream = m_streams.back ();
stream->emit_style_escape (style);
- stream->puts (str.c_str ());
- stream->emit_style_escape (ui_file_style ());
+ current_style = style;
}
+ stream->puts (str.c_str ());
}
void
return m_streams.back ()->can_emit_style_escape ();
}
+void
+cli_ui_out::emit_style_escape (const ui_file_style &style)
+{
+ m_streams.back ()->emit_style_escape (style);
+}
+
/* CLI interface to display tab-completion matches. */
/* CLI version of displayer.crlf. */
bool can_emit_style_escape () const override;
+ void emit_style_escape (const ui_file_style &style) override;
+
ui_file *current_stream () const override
{ return m_streams.back (); }
override ATTRIBUTE_PRINTF (7, 0);
virtual void do_spaces (int numspaces) override;
virtual void do_text (const char *string) override;
- virtual void do_message (const ui_file_style &style,
+ virtual void do_message (ui_file_style ¤t_style,
+ const ui_file_style &style,
const char *format, va_list args) override
- ATTRIBUTE_PRINTF (3,0);
+ ATTRIBUTE_PRINTF (4, 0);
virtual void do_wrap_hint (int indent) override;
virtual void do_flush () override;
virtual void do_redirect (struct ui_file *outstream) override;
}
void
-mi_ui_out::do_message (const ui_file_style &style,
+mi_ui_out::do_message (ui_file_style ¤t_style,
+ const ui_file_style &style,
const char *format, va_list args)
{
}
override ATTRIBUTE_PRINTF (7,0);
virtual void do_spaces (int numspaces) override;
virtual void do_text (const char *string) override;
- virtual void do_message (const ui_file_style &style,
+ virtual void do_message (ui_file_style ¤t_style,
+ const ui_file_style &style,
const char *format, va_list args) override
- ATTRIBUTE_PRINTF (3,0);
+ ATTRIBUTE_PRINTF (4, 0);
virtual void do_wrap_hint (int indent) override;
virtual void do_flush () override;
virtual void do_redirect (struct ui_file *outstream) override;
m_stream->puts_unfiltered (str);
}
+ void vprintf (const char *fmt, va_list args) override
+ ATTRIBUTE_PRINTF (2, 0);
+
private:
void prompt_for_continue ();
wrapping is not in effect. */
int m_wrap_column = 0;
+ /* The currently applied style. */
+ ui_file_style m_applied_style;
+
/* The style applied at the time that wrap_here was called. */
ui_file_style m_wrap_style;
void do_text (const char *string) override
{ }
- void do_message (const ui_file_style &style,
+ void do_message (ui_file_style ¤t_style,
+ const ui_file_style &style,
const char *format, va_list args)
- override ATTRIBUTE_PRINTF (3,0)
+ override ATTRIBUTE_PRINTF (4, 0)
{ }
void do_wrap_hint (int indent) override
# Two possible outputs, BASIC_RE, the unstyled output text, or
# STYLED_RE, the same things, but with styling applied.
set text "\"version\" style"
- set styled_text \
- [style "\"" version][style "version" version][style "\" style" version]
+ set styled_text [style $text version]
set basic_re "The $text foreground color is: \[^\r\n\]+"
set styled_re "The $styled_text foreground color is: \[^\r\n\]+"
ui_file::vprintf (const char *format, va_list args)
{
ui_out_flags flags = disallow_ui_out_field;
- cli_ui_out (this, flags).vmessage (m_applied_style, format, args);
+ cli_ui_out (this, flags).vmessage ({}, format, args);
}
/* See ui-file.h. */
void
ui_file::emit_style_escape (const ui_file_style &style)
{
- if (can_emit_style_escape () && style != m_applied_style)
- {
- m_applied_style = style;
- this->puts (style.to_ansi ().c_str ());
- }
+ if (can_emit_style_escape ())
+ this->puts (style.to_ansi ().c_str ());
}
/* See ui-file.h. */
void putc (int c);
- void vprintf (const char *, va_list) ATTRIBUTE_PRINTF (2, 0);
+ virtual void vprintf (const char *, va_list) ATTRIBUTE_PRINTF (2, 0);
/* Methods below are both public, and overridable by ui_file
subclasses. */
this->puts (str);
}
-protected:
-
- /* The currently applied style. */
- ui_file_style m_applied_style;
-
private:
/* Helper function for putstr and putstrn. Print the character C on
}
void
-ui_out::call_do_message (const ui_file_style &style, const char *format,
+ui_out::call_do_message (ui_file_style ¤t_style,
+ const ui_file_style &style, const char *format,
...)
{
va_list args;
to put a "format" attribute on call_do_message. */
DIAGNOSTIC_PUSH
DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
- do_message (style, format, args);
+ do_message (current_style, style, format, args);
DIAGNOSTIC_POP
va_end (args);
{
format_pieces fpieces (&format, true);
+ ui_file_style current_style = in_style;
ui_file_style style = in_style;
for (auto &&piece : fpieces)
switch (piece.n_int_args)
{
case 0:
- call_do_message (style, current_substring, str);
+ call_do_message (current_style, style, current_substring,
+ str);
break;
case 1:
- call_do_message (style, current_substring, intvals[0], str);
+ call_do_message (current_style, style, current_substring,
+ intvals[0], str);
break;
case 2:
- call_do_message (style, current_substring,
+ call_do_message (current_style, style, current_substring,
intvals[0], intvals[1], str);
break;
}
gdb_assert_not_reached ("wide_char_arg not supported in vmessage");
break;
case long_long_arg:
- call_do_message (style, current_substring, va_arg (args, long long));
+ call_do_message (current_style, style, current_substring,
+ va_arg (args, long long));
break;
case int_arg:
{
switch (piece.n_int_args)
{
case 0:
- call_do_message (style, current_substring, val);
+ call_do_message (current_style, style, current_substring,
+ val);
break;
case 1:
- call_do_message (style, current_substring, intvals[0], val);
+ call_do_message (current_style, style, current_substring,
+ intvals[0], val);
break;
case 2:
- call_do_message (style, current_substring,
+ call_do_message (current_style, style, current_substring,
intvals[0], intvals[1], val);
break;
}
switch (piece.n_int_args)
{
case 0:
- call_do_message (style, current_substring, val);
+ call_do_message (current_style, style, current_substring,
+ val);
break;
case 1:
- call_do_message (style, current_substring, intvals[0], val);
+ call_do_message (current_style, style, current_substring,
+ intvals[0], val);
break;
case 2:
- call_do_message (style, current_substring,
+ call_do_message (current_style, style, current_substring,
intvals[0], intvals[1], val);
break;
}
switch (piece.n_int_args)
{
case 0:
- call_do_message (style, current_substring, val);
+ call_do_message (current_style, style, current_substring,
+ val);
break;
case 1:
- call_do_message (style, current_substring, intvals[0], val);
+ call_do_message (current_style, style, current_substring,
+ intvals[0], val);
break;
case 2:
- call_do_message (style, current_substring,
+ call_do_message (current_style, style, current_substring,
intvals[0], intvals[1], val);
break;
}
switch (piece.n_int_args)
{
case 0:
- call_do_message (style, current_substring, val);
+ call_do_message (current_style, style, current_substring,
+ val);
break;
case 1:
- call_do_message (style, current_substring, intvals[0], val);
+ call_do_message (current_style, style, current_substring,
+ intvals[0], val);
break;
case 2:
- call_do_message (style, current_substring,
+ call_do_message (current_style, style, current_substring,
intvals[0], intvals[1], val);
break;
}
}
break;
case double_arg:
- call_do_message (style, current_substring, va_arg (args, double));
+ call_do_message (current_style, style, current_substring,
+ va_arg (args, double));
break;
case long_double_arg:
gdb_assert_not_reached ("long_double_arg not supported in vmessage");
case 's':
{
styled_string_s *ss = va_arg (args, styled_string_s *);
- call_do_message (ss->style, "%s", ss->str);
+ call_do_message (current_style, ss->style, "%s", ss->str);
}
break;
case '[':
}
break;
default:
- call_do_message (style, current_substring, va_arg (args, void *));
+ call_do_message (current_style, style, current_substring,
+ va_arg (args, void *));
break;
}
break;
because some platforms have modified GCC to include
-Wformat-security by default, which will warn here if
there is no argument. */
- call_do_message (style, current_substring, 0);
+ call_do_message (current_style, style, current_substring, 0);
break;
default:
internal_error (_("failed internal consistency check"));
}
}
+
+ ui_file_style plain;
+ if (can_emit_style_escape () && current_style != plain)
+ emit_style_escape (plain);
}
void
escapes. */
virtual bool can_emit_style_escape () const = 0;
+ /* Emit a style escape, if possible. */
+ virtual void emit_style_escape (const ui_file_style &style)
+ {
+ }
+
/* Return the ui_file currently used for output. */
virtual ui_file *current_stream () const = 0;
ATTRIBUTE_PRINTF (7, 0) = 0;
virtual void do_spaces (int numspaces) = 0;
virtual void do_text (const char *string) = 0;
- virtual void do_message (const ui_file_style &style,
+
+ /* A helper for vprintf and call_do_message. Formats a string and
+ then prints it using STYLE. This should take care to only change
+ the style when necessary (i.e., don't bother if the formatted
+ string is empty, or if the desired style is the same as
+ CURRENT_STYLE). Updates current_style if the style was
+ changed. */
+ virtual void do_message (ui_file_style ¤t_style,
+ const ui_file_style &style,
const char *format, va_list args)
- ATTRIBUTE_PRINTF (3,0) = 0;
+ ATTRIBUTE_PRINTF (4, 0) = 0;
virtual void do_wrap_hint (int indent) = 0;
virtual void do_flush () = 0;
virtual void do_redirect (struct ui_file *outstream) = 0;
{ return false; }
private:
- void call_do_message (const ui_file_style &style, const char *format,
+ /* A helper for vmessage that wraps a call to do_message. This will
+ update CURRENT_STYLE when needed. */
+ void call_do_message (ui_file_style ¤t_style,
+ const ui_file_style &style, const char *format,
...);
ui_out_flags m_flags;
}
}
+void
+pager_file::vprintf (const char *format, va_list args)
+{
+ ui_out_flags flags = disallow_ui_out_field;
+ cli_ui_out (this, flags).vmessage (m_applied_style, format, args);
+}
+
void
pager_file::puts (const char *linebuffer)
{