From: Tom Tromey Date: Fri, 20 Dec 2024 21:00:39 +0000 (-0700) Subject: Use emoji to indicate errors and warnings X-Git-Tag: binutils-2_45~715 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a048980c4eb93f8a965b4addc7134e8a527874a2;p=thirdparty%2Fbinutils-gdb.git Use emoji to indicate errors and warnings This patch adds, at long last, some emoji output to gdb. In particular, warnings are indicated with the U+26A0 (WARNING SIGN), and errors with U+274C (CROSS MARK). There is a new setting to control whether emoji output can be used. It defaults to "auto", which means emoji will be used if the host charset is UTF-8. Note that disabling styling will also disable emoji, handy for traditionalists. I've refactored mingw console output a little, so that emoji will not be printed to the console. Note the previous code here was a bit strange in that it assumed that the first use of gdb_console_fputs would be to stdout. This version lets the user control the prefixes directly, so different emoji can be chosen if desired. Reviewed-By: Eli Zaretskii Reviewed-By: Keith Seitz Reviewed-By: Guinevere Larsen --- diff --git a/gdb/NEWS b/gdb/NEWS index 077d28a33e4..a82b7e3342c 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -65,6 +65,19 @@ show riscv numeric-register-names (e.g 'x1') or their abi names (e.g. 'ra'). Defaults to 'off', matching the old behaviour (abi names). +set style emoji on|off|auto +show style emoji + Controls whether GDB can display emoji. The default is "auto", + which means emoji will be displayed in some situations when + the host charset is UTF-8. + +set style warning-prefix STRING +set style error-prefix STRING + These commands control the prefix that is printed before warnings + and errors, respectively. This functionality is intended for use + with emoji display, and so the prefixes are only displayed if emoji + styling is enabled. + info linker-namespaces info linker-namespaces [[N]] Print information about the given linker namespace (identified as N), diff --git a/gdb/cli/cli-style.c b/gdb/cli/cli-style.c index 30c7afb5d3b..34592f079fb 100644 --- a/gdb/cli/cli-style.c +++ b/gdb/cli/cli-style.c @@ -23,6 +23,7 @@ #include "cli/cli-style.h" #include "source-cache.h" #include "observable.h" +#include "charset.h" /* True if styling is enabled. */ @@ -42,6 +43,10 @@ bool source_styling = true; bool disassembler_styling = true; +/* User-settable variable controlling emoji output. */ + +static auto_boolean emoji_styling = AUTO_BOOLEAN_AUTO; + /* Names of intensities; must correspond to ui_file_style::intensity. */ static const char * const cli_intensities[] = { @@ -410,6 +415,85 @@ show_style_disassembler (struct ui_file *file, int from_tty, gdb_printf (file, _("Disassembler output styling is disabled.\n")); } +/* Implement 'show style emoji'. */ + +static void +show_emoji_styling (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + if (emoji_styling == AUTO_BOOLEAN_TRUE) + gdb_printf (file, _("CLI emoji styling is enabled.\n")); + else if (emoji_styling == AUTO_BOOLEAN_FALSE) + gdb_printf (file, _("CLI emoji styling is disabled.\n")); + else + gdb_printf (file, _("CLI emoji styling is automatic (currently %s).\n"), + emojis_ok () ? _("enabled") : _("disabled")); +} + +/* See cli-style.h. */ + +bool +emojis_ok () +{ + if (!cli_styling || emoji_styling == AUTO_BOOLEAN_FALSE) + return false; + if (emoji_styling == AUTO_BOOLEAN_TRUE) + return true; + return strcmp (host_charset (), "UTF-8") == 0; +} + +/* See cli-style.h. */ + +void +no_emojis () +{ + emoji_styling = AUTO_BOOLEAN_FALSE; +} + +/* Emoji warning prefix. */ +static std::string warning_prefix = "⚠️ "; + +/* Implement 'show warning-prefix'. */ + +static void +show_warning_prefix (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + gdb_printf (file, _("Warning prefix is \"%s\".\n"), + warning_prefix.c_str ()); +} + +/* See cli-style.h. */ + +void +print_warning_prefix (ui_file *file) +{ + if (emojis_ok ()) + gdb_puts (warning_prefix.c_str (), file); +} + +/* Emoji error prefix. */ +static std::string error_prefix = "❌️ "; + +/* Implement 'show error-prefix'. */ + +static void +show_error_prefix (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + gdb_printf (file, _("Error prefix is \"%s\".\n"), + error_prefix.c_str ()); +} + +/* See cli-style.h. */ + +void +print_error_prefix (ui_file *file) +{ + if (emojis_ok ()) + gdb_puts (error_prefix.c_str (), file); +} + void _initialize_cli_style (); void _initialize_cli_style () @@ -431,6 +515,13 @@ If enabled, output to the terminal is styled."), set_style_enabled, show_style_enabled, &style_set_list, &style_show_list); + add_setshow_auto_boolean_cmd ("emoji", no_class, &emoji_styling, _("\ +Set whether emoji output is enabled."), _("\ +Show whether emoji output is enabled."), _("\ +If enabled, emojis may be displayed."), + nullptr, show_emoji_styling, + &style_set_list, &style_show_list); + add_setshow_boolean_cmd ("sources", no_class, &source_styling, _("\ Set whether source code styling is enabled."), _("\ Show whether source code styling is enabled."), _("\ @@ -627,4 +718,23 @@ coming from your source code."), &style_disasm_set_list); add_alias_cmd ("symbol", function_prefix_cmds.show, no_class, 0, &style_disasm_show_list); + + add_setshow_string_cmd ("warning-prefix", no_class, + &warning_prefix, + _("Set the warning prefix text."), + _("Show the warning prefix text."), + _("\ +The warning prefix text is displayed before any warning, when\n\ +emoji output is enabled."), + nullptr, show_warning_prefix, + &style_set_list, &style_show_list); + add_setshow_string_cmd ("error-prefix", no_class, + &error_prefix, + _("Set the error prefix text."), + _("Show the error prefix text."), + _("\ +The error prefix text is displayed before any error, when\n\ +emoji output is enabled."), + nullptr, show_error_prefix, + &style_set_list, &style_show_list); } diff --git a/gdb/cli/cli-style.h b/gdb/cli/cli-style.h index 77f4ac2ffc2..b1a950a539c 100644 --- a/gdb/cli/cli-style.h +++ b/gdb/cli/cli-style.h @@ -190,4 +190,18 @@ private: bool m_old_value; }; +/* Return true if emoji styling is allowed. */ +extern bool emojis_ok (); + +/* Disable emoji styling. This is here so that Windows can disable + emoji when the console is in use. It shouldn't be called + elsewhere. */ +extern void no_emojis (); + +/* Print the warning prefix, if desired. */ +extern void print_warning_prefix (ui_file *file); + +/* Print the error prefix, if desired. */ +extern void print_error_prefix (ui_file *file); + #endif /* GDB_CLI_CLI_STYLE_H */ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 9b4aa5b47b2..b9fc160a171 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -27974,6 +27974,19 @@ value, then @value{GDBN} will change this to @samp{off} at startup. @item show style enabled Show the current state of styling. +@item set style emoji @samp{auto|on|off} +Enable or disable the use of emoji. On most hosts, the default is +@samp{auto}, meaning that emoji will only be used if the host +character set is @samp{UTF-8}; however, on Windows the default is +@samp{off} when using the console. Note that disabling styling as a +whole will also prevent emoji display. + +Currently, emoji are printed whenever @value{GDBN} reports an error or +a warning. + +@item show style emoji +Show the current state of emoji output. + @item set style sources @samp{on|off} Enable or disable source code styling. This affects whether source code, such as the output of the @code{list} command, is styled. The @@ -27987,6 +28000,17 @@ is used. Otherwise, if @value{GDBN} was configured with Python scripting support, and if the Python Pygments package is available, then it will be used. +@item set style warning-prefix +@itemx show style warning-prefix +@itemx set style error-prefix +@itemx show style error-prefix + +These commands control the prefix that is printed before warnings and +errors, respectively. This functionality is intended for use with +emoji display, and so the prefixes are only displayed if emoji styling +is enabled. The defaults are the warning sign emoji for warnings, and +and the cross mark emoji for errors. + @item show style sources Show the current state of source code styling. diff --git a/gdb/exceptions.c b/gdb/exceptions.c index 6af3a7e379f..35400f3eb3d 100644 --- a/gdb/exceptions.c +++ b/gdb/exceptions.c @@ -25,6 +25,7 @@ #include "serial.h" #include "ui.h" #include +#include "cli/cli-style.h" static void print_flush (void) @@ -105,6 +106,7 @@ exception_print (struct ui_file *file, const struct gdb_exception &e) if (e.reason < 0 && e.message != NULL) { print_flush (); + print_error_prefix (file); print_exception (file, e); } } @@ -118,6 +120,7 @@ exception_fprintf (struct ui_file *file, const struct gdb_exception &e, va_list args; print_flush (); + print_error_prefix (file); /* Print the prefix. */ va_start (args, prefix); diff --git a/gdb/main.c b/gdb/main.c index 9220092d1e5..2dcb67d7ce8 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -672,6 +672,8 @@ captured_main_1 (struct captured_main_args *context) /* Ensure stderr is unbuffered. A Cygwin pty or pipe is implemented as a Windows pipe, and Windows buffers on pipes. */ setvbuf (stderr, NULL, _IONBF, BUFSIZ); + + windows_initialize_console (); #endif /* Note: `error' cannot be called before this point, because the diff --git a/gdb/main.h b/gdb/main.h index 4830b59d809..0f50b713b39 100644 --- a/gdb/main.h +++ b/gdb/main.h @@ -44,6 +44,9 @@ extern std::string interpreter_p; return value is in malloc'ed storage. */ extern char *windows_get_absolute_argv0 (const char *argv0); +/* Initialize Windows console settings. */ +extern void windows_initialize_console (); + extern void set_gdb_data_directory (const char *new_data_dir); #endif /* GDB_MAIN_H */ diff --git a/gdb/mingw-hdep.c b/gdb/mingw-hdep.c index dc7ca42fc7e..84a7b9f7a52 100644 --- a/gdb/mingw-hdep.c +++ b/gdb/mingw-hdep.c @@ -22,6 +22,7 @@ #include "gdbsupport/event-loop.h" #include "gdbsupport/gdb_select.h" #include "inferior.h" +#include "cli/cli-style.h" #include #include @@ -212,7 +213,30 @@ static int mingw_console_initialized; static HANDLE hstdout = INVALID_HANDLE_VALUE; /* Text attribute to use for normal text (the "none" pseudo-color). */ -static SHORT norm_attr; +static SHORT norm_attr; + +/* Initialize settings related to the console. */ + +void +windows_initialize_console () +{ + hstdout = (HANDLE)_get_osfhandle (fileno (stdout)); + DWORD cmode; + CONSOLE_SCREEN_BUFFER_INFO csbi; + + if (hstdout != INVALID_HANDLE_VALUE + && GetConsoleMode (hstdout, &cmode) != 0 + && GetConsoleScreenBufferInfo (hstdout, &csbi)) + { + norm_attr = csbi.wAttributes; + mingw_console_initialized = 1; + } + else if (hstdout != INVALID_HANDLE_VALUE) + mingw_console_initialized = -1; /* valid, but not a console device */ + + if (mingw_console_initialized > 0) + no_emojis (); +} /* The most recently applied style. */ static ui_file_style last_style; @@ -223,22 +247,6 @@ static ui_file_style last_style; int gdb_console_fputs (const char *linebuf, FILE *fstream) { - if (!mingw_console_initialized) - { - hstdout = (HANDLE)_get_osfhandle (fileno (fstream)); - DWORD cmode; - CONSOLE_SCREEN_BUFFER_INFO csbi; - - if (hstdout != INVALID_HANDLE_VALUE - && GetConsoleMode (hstdout, &cmode) != 0 - && GetConsoleScreenBufferInfo (hstdout, &csbi)) - { - norm_attr = csbi.wAttributes; - mingw_console_initialized = 1; - } - else if (hstdout != INVALID_HANDLE_VALUE) - mingw_console_initialized = -1; /* valid, but not a console device */ - } /* If our stdout is not a console device, let the default 'fputs' handle the task. */ if (mingw_console_initialized <= 0) diff --git a/gdb/testsuite/gdb.base/style.exp b/gdb/testsuite/gdb.base/style.exp index 59c93ee9837..c10be3bc12a 100644 --- a/gdb/testsuite/gdb.base/style.exp +++ b/gdb/testsuite/gdb.base/style.exp @@ -329,6 +329,18 @@ proc run_style_tests { } { "The \033\\\[38;2;254;210;16;48;5;255;22;27m.*\".*version.*\".*style.*\033\\\[m foreground color is: #FED210" \ "Version's TrueColor foreground style" } + + gdb_test_no_output "set host-charset UTF-8" + # Chosen since it will print an error. + gdb_test "maint translate-address" \ + "❌️ requires argument.*" \ + "emoji output" + + gdb_test_no_output "set style error-prefix abcd:" \ + "set the error prefix" + gdb_test "maint translate-address" \ + "abcd:requires argument.*" \ + "error prefix" } } diff --git a/gdb/utils.c b/gdb/utils.c index ce3c26ef140..6cdc3f48751 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -177,6 +177,7 @@ vwarning (const char *string, va_list args) target_terminal::ours_for_output (); } gdb_puts (warning_pre_print, gdb_stderr); + print_warning_prefix (gdb_stderr); gdb_puts (_("warning: "), gdb_stderr); gdb_vprintf (gdb_stderr, string, args); gdb_printf (gdb_stderr, "\n");