aboutsummaryrefslogtreecommitdiff
path: root/gdb/cli
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/cli')
-rw-r--r--gdb/cli/cli-cmds.c74
-rw-r--r--gdb/cli/cli-cmds.h2
-rw-r--r--gdb/cli/cli-decode.c53
-rw-r--r--gdb/cli/cli-decode.h4
-rw-r--r--gdb/cli/cli-dump.c9
-rw-r--r--gdb/cli/cli-interp.c6
-rw-r--r--gdb/cli/cli-interp.h2
-rw-r--r--gdb/cli/cli-logging.c6
-rw-r--r--gdb/cli/cli-option.c6
-rw-r--r--gdb/cli/cli-option.h2
-rw-r--r--gdb/cli/cli-script.c76
-rw-r--r--gdb/cli/cli-script.h12
-rw-r--r--gdb/cli/cli-setshow.c17
-rw-r--r--gdb/cli/cli-setshow.h2
-rw-r--r--gdb/cli/cli-style.c118
-rw-r--r--gdb/cli/cli-style.h16
-rw-r--r--gdb/cli/cli-utils.c29
-rw-r--r--gdb/cli/cli-utils.h2
18 files changed, 325 insertions, 111 deletions
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 923b67b2..d353654 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -1,6 +1,6 @@
/* GDB CLI commands.
- Copyright (C) 2000-2024 Free Software Foundation, Inc.
+ Copyright (C) 2000-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -51,6 +51,7 @@
#include "cli/cli-cmds.h"
#include "cli/cli-style.h"
#include "cli/cli-utils.h"
+#include "terminal.h"
#include "extension.h"
#include "gdbsupport/pathstuff.h"
@@ -300,8 +301,8 @@ with_command_completer_1 (const char *set_cmd_prefix,
command as if it was a "set" command. */
if (delim == text
|| delim == nullptr
- || !isspace (delim[-1])
- || !(isspace (delim[2]) || delim[2] == '\0'))
+ || !c_isspace (delim[-1])
+ || !(c_isspace (delim[2]) || delim[2] == '\0'))
{
std::string new_text = std::string (set_cmd_prefix) + text;
tracker.advance_custom_word_point_by (-(int) strlen (set_cmd_prefix));
@@ -784,14 +785,14 @@ source_command (const char *args, int from_tty)
if (args[0] != '-')
break;
- if (args[1] == 'v' && isspace (args[2]))
+ if (args[1] == 'v' && c_isspace (args[2]))
{
source_verbose = 1;
/* Skip passed -v. */
args = &args[3];
}
- else if (args[1] == 's' && isspace (args[2]))
+ else if (args[1] == 's' && c_isspace (args[2]))
{
search_path = 1;
@@ -833,7 +834,7 @@ echo_command (const char *text, int from_tty)
gdb_printf ("%c", c);
}
- gdb_stdout->reset_style ();
+ gdb_stdout->emit_style_escape (ui_file_style ());
/* Force this output to appear now. */
gdb_flush (gdb_stdout);
@@ -949,9 +950,27 @@ shell_escape (const char *arg, int from_tty)
static void
shell_command (const char *arg, int from_tty)
{
+ scoped_gdb_ttystate save_restore_gdb_ttystate;
+ restore_initial_gdb_ttystate ();
+
shell_escape (arg, from_tty);
}
+/* Completion for the shell command. Currently, this just uses filename
+ completion, but we could, potentially, complete command names from $PATH
+ for the first word, which would make this even more shell like. */
+
+static void
+shell_command_completer (struct cmd_list_element *ignore,
+ completion_tracker &tracker,
+ const char *text, const char * /* word */)
+{
+ tracker.set_use_custom_word_point (true);
+ const char *word
+ = advance_to_filename_maybe_quoted_complete_word_point (tracker, text);
+ filename_maybe_quoted_completer (ignore, tracker, text, word);
+}
+
static void
edit_command (const char *arg, int from_tty)
{
@@ -1165,7 +1184,7 @@ pipe_command_completer (struct cmd_list_element *ignore,
delimiter = opts.delimiter.c_str ();
/* Check if we're past option values already. */
- if (text > org_text && !isspace (text[-1]))
+ if (text > org_text && !c_isspace (text[-1]))
return;
const char *delim = strstr (text, delimiter);
@@ -1178,8 +1197,32 @@ pipe_command_completer (struct cmd_list_element *ignore,
return;
}
- /* We're past the delimiter. What follows is a shell command, which
- we don't know how to complete. */
+ /* We're past the delimiter now, or at least, DELIM points to the
+ delimiter string. Update TEXT to point to the start of whatever
+ appears after the delimiter. */
+ text = skip_spaces (delim + strlen (delimiter));
+
+ /* We really are past the delimiter now, so offer completions. This is
+ like GDB's "shell" command, currently we only offer filename
+ completion, but in the future this could be improved by offering
+ completion of command names from $PATH.
+
+ What we don't do here is offer completions for the empty string. It
+ is assumed that the first word after the delimiter is going to be a
+ command name from $PATH, not a filename, so if the user has typed
+ nothing (yet) and tries to complete, there's no point offering a list
+ of files from the current directory.
+
+ Once the user has started to type something though, then we do start
+ offering filename completions. */
+ if (*text == '\0')
+ return;
+
+ tracker.set_use_custom_word_point (true);
+ tracker.advance_custom_word_point_by (text - org_text);
+ const char *word
+ = advance_to_filename_maybe_quoted_complete_word_point (tracker, text);
+ filename_maybe_quoted_completer (ignore, tracker, text, word);
}
/* Helper for the list_command function. Prints the lines around (and
@@ -1626,7 +1669,7 @@ disassemble_command (const char *arg, int from_tty)
if (*p == '\0')
error (_("Missing modifier."));
- while (*p && ! isspace (*p))
+ while (*p && ! c_isspace (*p))
{
switch (*p++)
{
@@ -1895,8 +1938,8 @@ alias_command_completer (struct cmd_list_element *ignore,
typing COMMAND DEFAULT-ARGS... */
if (delim != text
&& delim != nullptr
- && isspace (delim[-1])
- && (isspace (delim[1]) || delim[1] == '\0'))
+ && c_isspace (delim[-1])
+ && (c_isspace (delim[1]) || delim[1] == '\0'))
{
std::string new_text = std::string (delim + 1);
@@ -2578,9 +2621,7 @@ shell_internal_fn (struct gdbarch *gdbarch,
return value::allocate_optimized_out (int_type);
}
-void _initialize_cli_cmds ();
-void
-_initialize_cli_cmds ()
+INIT_GDB_FILE (cli_cmds)
{
struct cmd_list_element *c;
@@ -2803,7 +2844,7 @@ the previous command number shown."),
= add_com ("shell", class_support, shell_command, _("\
Execute the rest of the line as a shell command.\n\
With no arguments, run an inferior shell."));
- set_cmd_completer (shell_cmd, deprecated_filename_completer);
+ set_cmd_completer_handle_brkchars (shell_cmd, shell_command_completer);
add_com_alias ("!", shell_cmd, class_support, 0);
@@ -2861,6 +2902,7 @@ This can be changed using \"set listsize\", and the current value\n\
can be shown using \"show listsize\"."));
add_com_alias ("l", list_cmd, class_files, 1);
+ set_cmd_completer(list_cmd, location_completer);
c = add_com ("disassemble", class_vars, disassemble_command, _("\
Disassemble a specified section of memory.\n\
diff --git a/gdb/cli/cli-cmds.h b/gdb/cli/cli-cmds.h
index 6719ad7..33d13fb 100644
--- a/gdb/cli/cli-cmds.h
+++ b/gdb/cli/cli-cmds.h
@@ -1,5 +1,5 @@
/* Header file for GDB CLI command implementation library.
- Copyright (C) 2000-2024 Free Software Foundation, Inc.
+ Copyright (C) 2000-2025 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index 5008b48..2b30a6e 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -1,6 +1,6 @@
/* Handle lists of commands, their decoding and documentation, for GDB.
- Copyright (C) 1986-2024 Free Software Foundation, Inc.
+ Copyright (C) 1986-2025 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "symtab.h"
-#include <ctype.h>
#include "gdbsupport/gdb_regex.h"
#include "completer.h"
#include "ui-out.h"
@@ -2041,40 +2040,28 @@ void
print_doc_line (struct ui_file *stream, const char *str,
bool for_value_prefix)
{
- static char *line_buffer = 0;
- static int line_size;
- const char *p;
+ const char *p = strchr (str, '\n');
- if (!line_buffer)
- {
- line_size = 80;
- line_buffer = (char *) xmalloc (line_size);
- }
+ /* Only copy the input string if we really need to. */
+ std::optional<std::string> line_buffer;
+ if (p != nullptr)
+ line_buffer = std::string (str, p);
+ else if (for_value_prefix)
+ line_buffer = str;
- /* Searches for the first end of line or the end of STR. */
- p = str;
- while (*p && *p != '\n')
- p++;
- if (p - str > line_size - 1)
- {
- line_size = p - str + 1;
- xfree (line_buffer);
- line_buffer = (char *) xmalloc (line_size);
- }
- strncpy (line_buffer, str, p - str);
if (for_value_prefix)
{
- if (islower (line_buffer[0]))
- line_buffer[0] = toupper (line_buffer[0]);
- gdb_assert (p > str);
- if (line_buffer[p - str - 1] == '.')
- line_buffer[p - str - 1] = '\0';
- else
- line_buffer[p - str] = '\0';
+ char &c = (*line_buffer)[0];
+ if (c_islower (c))
+ c = c_toupper (c);
+ if (line_buffer->back () == '.')
+ line_buffer->pop_back ();
}
- else
- line_buffer[p - str] = '\0';
- gdb_puts (line_buffer, stream);
+
+ gdb_puts (line_buffer.has_value ()
+ ? line_buffer->c_str ()
+ : str,
+ stream);
}
/* Print one-line help for command C.
@@ -2239,7 +2226,7 @@ valid_cmd_char_p (int c)
/* Alas "42" is a legitimate user-defined command.
In the interests of not breaking anything we preserve that. */
- return isalnum (c) || c == '-' || c == '_' || c == '.';
+ return c_isalnum (c) || c == '-' || c == '_' || c == '.';
}
/* See command.h. */
@@ -2503,7 +2490,7 @@ lookup_cmd (const char **line, struct cmd_list_element *list,
}
else
{
- if (c->type == set_cmd && **line != '\0' && !isspace (**line))
+ if (c->type == set_cmd && **line != '\0' && !c_isspace (**line))
error (_("Argument must be preceded by space."));
/* We've got something. It may still not be what the caller
diff --git a/gdb/cli/cli-decode.h b/gdb/cli/cli-decode.h
index 85bd474..9be446f 100644
--- a/gdb/cli/cli-decode.h
+++ b/gdb/cli/cli-decode.h
@@ -1,6 +1,6 @@
/* Header file for GDB command decoding library.
- Copyright (C) 2000-2024 Free Software Foundation, Inc.
+ Copyright (C) 2000-2025 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -62,6 +62,8 @@ struct cmd_list_element
type (not_set_cmd),
doc (doc_)
{
+ gdb_assert (name != nullptr);
+ gdb_assert (doc != nullptr);
memset (&function, 0, sizeof (function));
}
diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c
index 2b9307e..3cdd9a3 100644
--- a/gdb/cli/cli-dump.c
+++ b/gdb/cli/cli-dump.c
@@ -1,6 +1,6 @@
/* Dump-to-file commands, for GDB, the GNU debugger.
- Copyright (C) 2002-2024 Free Software Foundation, Inc.
+ Copyright (C) 2002-2025 Free Software Foundation, Inc.
Contributed by Red Hat.
@@ -23,7 +23,6 @@
#include "cli/cli-cmds.h"
#include "value.h"
#include "completer.h"
-#include <ctype.h>
#include "target.h"
#include "readline/tilde.h"
#include "gdbcore.h"
@@ -397,7 +396,7 @@ restore_one_section (bfd *ibfd, asection *isec,
if (sec_end <= load_start
|| (load_end > 0 && sec_start >= load_end))
{
- /* No, no useable data in this section. */
+ /* No, no usable data in this section. */
gdb_printf (_("skipping section %s...\n"),
bfd_section_name (isec));
return;
@@ -564,9 +563,7 @@ restore_command (const char *args, int from_tty)
}
}
-void _initialize_cli_dump ();
-void
-_initialize_cli_dump ()
+INIT_GDB_FILE (cli_dump)
{
struct cmd_list_element *c;
diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index dbe2ed1..d7b73df 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -1,6 +1,6 @@
/* CLI Definitions for GDB, the GNU debugger.
- Copyright (C) 2002-2024 Free Software Foundation, Inc.
+ Copyright (C) 2002-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -321,9 +321,7 @@ cli_interp_factory (const char *name)
/* Standard gdb initialization hook. */
-void _initialize_cli_interp ();
-void
-_initialize_cli_interp ()
+INIT_GDB_FILE (cli_interp)
{
interp_factory_register (INTERP_CONSOLE, cli_interp_factory);
}
diff --git a/gdb/cli/cli-interp.h b/gdb/cli/cli-interp.h
index ed3d904..8f41725 100644
--- a/gdb/cli/cli-interp.h
+++ b/gdb/cli/cli-interp.h
@@ -1,6 +1,6 @@
/* CLI Definitions for GDB, the GNU debugger.
- Copyright (C) 2016-2024 Free Software Foundation, Inc.
+ Copyright (C) 2016-2025 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/gdb/cli/cli-logging.c b/gdb/cli/cli-logging.c
index 2c54cea..d6eb6c2 100644
--- a/gdb/cli/cli-logging.c
+++ b/gdb/cli/cli-logging.c
@@ -1,6 +1,6 @@
/* Command-line output logging for GDB, the GNU debugger.
- Copyright (C) 2003-2024 Free Software Foundation, Inc.
+ Copyright (C) 2003-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -202,9 +202,7 @@ show_logging_enabled (struct ui_file *file, int from_tty,
gdb_printf (file, _("off: Logging is disabled.\n"));
}
-void _initialize_cli_logging ();
-void
-_initialize_cli_logging ()
+INIT_GDB_FILE (cli_logging)
{
static struct cmd_list_element *set_logging_cmdlist, *show_logging_cmdlist;
diff --git a/gdb/cli/cli-option.c b/gdb/cli/cli-option.c
index 34ac164..5da8c73 100644
--- a/gdb/cli/cli-option.c
+++ b/gdb/cli/cli-option.c
@@ -1,6 +1,6 @@
/* CLI options framework, for GDB.
- Copyright (C) 2017-2024 Free Software Foundation, Inc.
+ Copyright (C) 2017-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -227,7 +227,7 @@ parse_option (gdb::array_view<const option_def_group> options_group,
match = &o;
match_ctx = grp.ctx;
- if ((isspace (arg[len]) || arg[len] == '\0')
+ if ((c_isspace (arg[len]) || arg[len] == '\0')
&& strlen (o.name) == len)
break; /* Exact match. */
}
@@ -635,7 +635,7 @@ complete_options (completion_tracker &tracker,
if (ov
&& !tracker.have_completions ()
&& **args == '\0'
- && *args > text && !isspace ((*args)[-1]))
+ && *args > text && !c_isspace ((*args)[-1]))
{
tracker.advance_custom_word_point_by
(*args - text);
diff --git a/gdb/cli/cli-option.h b/gdb/cli/cli-option.h
index 38dcd82..6a56d5a 100644
--- a/gdb/cli/cli-option.h
+++ b/gdb/cli/cli-option.h
@@ -1,6 +1,6 @@
/* CLI options framework, for GDB.
- Copyright (C) 2017-2024 Free Software Foundation, Inc.
+ Copyright (C) 2017-2025 Free Software Foundation, Inc.
This file is part of GDB.
diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
index 5decf3b..048d391 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -1,6 +1,6 @@
/* GDB CLI command scripting.
- Copyright (C) 1986-2024 Free Software Foundation, Inc.
+ Copyright (C) 1986-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -19,7 +19,6 @@
#include "event-top.h"
#include "value.h"
-#include <ctype.h>
#include "ui-out.h"
#include "top.h"
@@ -660,9 +659,13 @@ execute_control_command_1 (struct command_line *cmd, int from_tty)
}
case compile_control:
+#if defined(HAVE_COMPILE)
eval_compile_command (cmd, NULL, cmd->control_u.compile.scope,
cmd->control_u.compile.scope_data);
ret = simple_control;
+#else
+ error (_("compile support has not been compiled into gdb"));
+#endif
break;
case define_control:
@@ -825,7 +828,7 @@ locate_arg (const char *p)
while ((p = strchr (p, '$')))
{
if (startswith (p, "$arg")
- && (isdigit (p[4]) || p[4] == 'c'))
+ && (c_isdigit (p[4]) || p[4] == 'c'))
return p;
p++;
}
@@ -1320,9 +1323,9 @@ validate_comname (const char **comname)
/* Find the last word of the argument. */
p = *comname + strlen (*comname);
- while (p > *comname && isspace (p[-1]))
+ while (p > *comname && c_isspace (p[-1]))
p--;
- while (p > *comname && !isspace (p[-1]))
+ while (p > *comname && !c_isspace (p[-1]))
p--;
last_word = p;
@@ -1621,6 +1624,65 @@ define_prefix_command (const char *comname, int from_tty)
c->allow_unknown = c->user_commands.get () != nullptr;
}
+/* See cli/cli-script.h. */
+
+bool
+commands_equal (const command_line *a, const command_line *b)
+{
+ if ((a == nullptr) != (b == nullptr))
+ return false;
+
+ while (a != nullptr)
+ {
+ /* We are either at the end of both command lists, or there's
+ another command in both lists. */
+ if ((a->next == nullptr) != (b->next == nullptr))
+ return false;
+
+ /* There's a command line for both, or neither. */
+ if ((a->line == nullptr) != (b->line == nullptr))
+ return false;
+
+ /* Check control_type matches. */
+ if (a->control_type != b->control_type)
+ return false;
+
+ if (a->control_type == compile_control)
+ {
+ if (a->control_u.compile.scope != b->control_u.compile.scope)
+ return false;
+
+ /* This is where we "fail safe". The scope_data is a 'void *'
+ pointer which changes in meaning based on the value of
+ 'scope'. It is possible that two different 'void *' pointers
+ could point to the equal scope data, however, we just assume
+ that if the pointers are different, then the scope_data is
+ different. This could be improved in the future. */
+ if (a->control_u.compile.scope_data
+ != b->control_u.compile.scope_data)
+ return false;
+ }
+
+ /* Check lines are identical. */
+ if (a->line != nullptr && strcmp (a->line, b->line) != 0)
+ return false;
+
+ /* Check body_list_0. */
+ if (!commands_equal (a->body_list_0.get (), b->body_list_0.get ()))
+ return false;
+
+ /* Check body_list_1. */
+ if (!commands_equal (a->body_list_1.get (), b->body_list_1.get ()))
+ return false;
+
+ /* Move to the next element in each chain. */
+ a = a->next;
+ b = b->next;
+ }
+
+ return true;
+}
+
/* Used to implement source_command. */
@@ -1688,9 +1750,7 @@ show_user_1 (struct cmd_list_element *c, const char *prefix, const char *name,
}
-void _initialize_cli_script ();
-void
-_initialize_cli_script ()
+INIT_GDB_FILE (cli_script)
{
struct cmd_list_element *c;
diff --git a/gdb/cli/cli-script.h b/gdb/cli/cli-script.h
index df7316e..1ce0754 100644
--- a/gdb/cli/cli-script.h
+++ b/gdb/cli/cli-script.h
@@ -1,5 +1,5 @@
/* Header file for GDB CLI command implementation library.
- Copyright (C) 2000-2024 Free Software Foundation, Inc.
+ Copyright (C) 2000-2025 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -184,4 +184,14 @@ extern void print_command_trace (const char *cmd, ...)
extern void reset_command_nest_depth (void);
+/* Return true if A and B are identical. Some commands carry around a
+ 'void *' compilation context, in this case this function doesn't try to
+ validate if the context is actually the same or not, and will just
+ return false indicating the commands have changed. That is, a return
+ value of true is a guarantee that the commands are equal, a return
+ value of false means the commands are possibly different (and in most
+ cases are different). */
+
+extern bool commands_equal (const command_line *a, const command_line *b);
+
#endif /* GDB_CLI_CLI_SCRIPT_H */
diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c
index b438e98..d92d14e 100644
--- a/gdb/cli/cli-setshow.c
+++ b/gdb/cli/cli-setshow.c
@@ -1,6 +1,6 @@
/* Handle set and show GDB commands.
- Copyright (C) 2000-2024 Free Software Foundation, Inc.
+ Copyright (C) 2000-2025 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,7 +17,6 @@
#include "readline/tilde.h"
#include "value.h"
-#include <ctype.h>
#include "arch-utils.h"
#include "observable.h"
#include "interps.h"
@@ -49,7 +48,7 @@ parse_auto_binary_operation (const char *arg)
{
int length = strlen (arg);
- while (isspace (arg[length - 1]) && length > 0)
+ while (c_isspace (arg[length - 1]) && length > 0)
length--;
/* Note that "o" is ambiguous. */
@@ -119,7 +118,7 @@ parse_cli_boolean_value (const char *arg)
static void
-deprecated_show_value_hack (struct ui_file *ignore_file,
+deprecated_show_value_hack (struct ui_file *file,
int ignore_from_tty,
struct cmd_list_element *c,
const char *value)
@@ -130,7 +129,7 @@ deprecated_show_value_hack (struct ui_file *ignore_file,
/* Print doc minus "Show " at start. Tell print_doc_line that
this is for a 'show value' prefix. */
- print_doc_line (gdb_stdout, c->doc + 5, true);
+ print_doc_line (file, c->doc + 5, true);
gdb_assert (c->var.has_value ());
@@ -139,17 +138,17 @@ deprecated_show_value_hack (struct ui_file *ignore_file,
case var_string:
case var_string_noescape:
case var_enum:
- gdb_printf ((" is \"%s\".\n"), value);
+ gdb_printf (file, _(" is \"%s\".\n"), value);
break;
case var_optional_filename:
case var_filename:
- gdb_printf ((" is \"%ps\".\n"),
+ gdb_printf (file, _(" is \"%ps\".\n"),
styled_string (file_name_style.style (), value));
break;
default:
- gdb_printf ((" is %s.\n"), value);
+ gdb_printf (file, _(" is %s.\n"), value);
break;
}
}
@@ -748,5 +747,3 @@ cmd_show_list (struct cmd_list_element *list, int from_tty)
}
}
}
-
-
diff --git a/gdb/cli/cli-setshow.h b/gdb/cli/cli-setshow.h
index 9eac86f..886f89f 100644
--- a/gdb/cli/cli-setshow.h
+++ b/gdb/cli/cli-setshow.h
@@ -1,5 +1,5 @@
/* Header file for GDB CLI set and show commands implementation.
- Copyright (C) 2000-2024 Free Software Foundation, Inc.
+ Copyright (C) 2000-2025 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/gdb/cli/cli-style.c b/gdb/cli/cli-style.c
index b436275..d6829f0 100644
--- a/gdb/cli/cli-style.c
+++ b/gdb/cli/cli-style.c
@@ -1,6 +1,6 @@
/* CLI colorizing
- Copyright (C) 2018-2024 Free Software Foundation, Inc.
+ Copyright (C) 2018-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -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[] = {
@@ -372,7 +377,9 @@ set_style_enabled (const char *args, int from_tty, struct cmd_list_element *c)
warning ("The current terminal doesn't support styling. Styled output "
"might not appear as expected.");
- g_source_cache.clear ();
+ /* It is not necessary to flush the source cache here. The source cache
+ tracks whether entries are styled or not. */
+
gdb::observers::styling_changed.notify ();
}
@@ -408,9 +415,86 @@ show_style_disassembler (struct ui_file *file, int from_tty,
gdb_printf (file, _("Disassembler output styling is disabled.\n"));
}
-void _initialize_cli_style ();
+/* 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
-_initialize_cli_style ()
+no_emojis ()
+{
+ emoji_styling = AUTO_BOOLEAN_FALSE;
+}
+
+/* Emoji warning prefix. */
+static std::string warning_prefix = "⚠️ ";
+
+/* Implement 'show style 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 style 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);
+}
+
+INIT_GDB_FILE (cli_style)
{
add_setshow_prefix_cmd ("style", no_class,
_("\
@@ -429,6 +513,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."), _("\
@@ -625,4 +716,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 e94b48d..b1a950a 100644
--- a/gdb/cli/cli-style.h
+++ b/gdb/cli/cli-style.h
@@ -1,6 +1,6 @@
/* CLI stylizing
- Copyright (C) 2018-2024 Free Software Foundation, Inc.
+ Copyright (C) 2018-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -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/cli/cli-utils.c b/gdb/cli/cli-utils.c
index 152fee9..d0ca594 100644
--- a/gdb/cli/cli-utils.c
+++ b/gdb/cli/cli-utils.c
@@ -1,6 +1,6 @@
/* CLI utilities.
- Copyright (C) 2011-2024 Free Software Foundation, Inc.
+ Copyright (C) 2011-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -20,7 +20,6 @@
#include "cli/cli-utils.h"
#include "value.h"
-#include <ctype.h>
/* See documentation in cli-utils.h. */
@@ -46,7 +45,7 @@ get_ulongest (const char **pp, int trailer)
/* Internal variable. Make a copy of the name, so we can
null-terminate it to pass to lookup_internalvar(). */
const char *start = ++p;
- while (isalnum (*p) || *p == '_')
+ while (c_isalnum (*p) || *p == '_')
p++;
std::string varname (start, p - start);
if (!get_internalvar_integer (lookup_internalvar (varname.c_str ()),
@@ -67,7 +66,7 @@ get_ulongest (const char **pp, int trailer)
p = end;
}
- if (!(isspace (*p) || *p == '\0' || *p == trailer))
+ if (!(c_isspace (*p) || *p == '\0' || *p == trailer))
error (_("Trailing junk at: %s"), p);
p = skip_spaces (p);
*pp = p;
@@ -111,7 +110,7 @@ get_number_trailer (const char **pp, int trailer)
const char *start = ++p;
LONGEST longest_val;
- while (isalnum (*p) || *p == '_')
+ while (c_isalnum (*p) || *p == '_')
p++;
varname = (char *) alloca (p - start + 1);
strncpy (varname, start, p - start);
@@ -136,7 +135,7 @@ get_number_trailer (const char **pp, int trailer)
/* There is no number here. (e.g. "cond a == b"). */
{
/* Skip non-numeric token. */
- while (*p && !isspace((int) *p))
+ while (*p && !c_isspace((int) *p))
++p;
/* Return zero, which caller must interpret as error. */
retval = 0;
@@ -144,10 +143,10 @@ get_number_trailer (const char **pp, int trailer)
else
retval = atoi (p1);
}
- if (!(isspace (*p) || *p == '\0' || *p == trailer))
+ if (!(c_isspace (*p) || *p == '\0' || *p == trailer))
{
/* Trailing junk: return 0 and let caller print error msg. */
- while (!(isspace (*p) || *p == '\0' || *p == trailer))
+ while (!(c_isspace (*p) || *p == '\0' || *p == trailer))
++p;
retval = 0;
}
@@ -262,8 +261,8 @@ number_or_range_parser::get_number ()
option rather than an incomplete range, so check for end of
string as well. */
if (m_cur_tok[0] == '-'
- && !(isspace (m_cur_tok[-1])
- && (isalpha (m_cur_tok[1])
+ && !(c_isspace (m_cur_tok[-1])
+ && (c_isalpha (m_cur_tok[1])
|| m_cur_tok[1] == '-'
|| m_cur_tok[1] == '\0')))
{
@@ -293,7 +292,7 @@ number_or_range_parser::get_number ()
}
else
{
- if (isdigit (*(m_cur_tok + 1)))
+ if (c_isdigit (*(m_cur_tok + 1)))
error (_("negative value"));
if (*(m_cur_tok + 1) == '$')
{
@@ -330,9 +329,9 @@ number_or_range_parser::finished () const
integer, convenience var or negative convenience var. */
return (m_cur_tok == NULL || *m_cur_tok == '\0'
|| (!m_in_range
- && !(isdigit (*m_cur_tok) || *m_cur_tok == '$')
+ && !(c_isdigit (*m_cur_tok) || *m_cur_tok == '$')
&& !(*m_cur_tok == '-'
- && (isdigit (m_cur_tok[1]) || m_cur_tok[1] == '$'))));
+ && (c_isdigit (m_cur_tok[1]) || m_cur_tok[1] == '$'))));
}
/* Accept a number and a string-form list of numbers such as is
@@ -370,7 +369,7 @@ number_is_in_list (const char *list, int number)
const char *
remove_trailing_whitespace (const char *start, const char *s)
{
- while (s > start && isspace (*(s - 1)))
+ while (s > start && c_isspace (*(s - 1)))
--s;
return s;
@@ -420,7 +419,7 @@ int
check_for_argument (const char **str, const char *arg, int arg_len)
{
if (strncmp (*str, arg, arg_len) == 0
- && ((*str)[arg_len] == '\0' || isspace ((*str)[arg_len])))
+ && ((*str)[arg_len] == '\0' || c_isspace ((*str)[arg_len])))
{
*str += arg_len;
*str = skip_spaces (*str);
diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h
index 4832d01..f9b0123 100644
--- a/gdb/cli/cli-utils.h
+++ b/gdb/cli/cli-utils.h
@@ -1,6 +1,6 @@
/* CLI utilities.
- Copyright (C) 2011-2024 Free Software Foundation, Inc.
+ Copyright (C) 2011-2025 Free Software Foundation, Inc.
This file is part of GDB.