forked from Imagelibrary/binutils-gdb
Compare commits
7 Commits
binutils-2
...
users/palv
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc0a76bef5 | ||
|
|
2d3081ce81 | ||
|
|
4b4de9f875 | ||
|
|
47f969f4d9 | ||
|
|
03c6774d01 | ||
|
|
67f57a9be2 | ||
|
|
9507d5238b |
20
gdb/NEWS
20
gdb/NEWS
@@ -46,6 +46,21 @@ pipe -d DELIM COMMAND DELIM SHELL_COMMAND
|
|||||||
With no COMMAND, repeat the last executed command
|
With no COMMAND, repeat the last executed command
|
||||||
and send its output to SHELL_COMMAND.
|
and send its output to SHELL_COMMAND.
|
||||||
|
|
||||||
|
with SETTING [VALUE] [-- COMMAND]
|
||||||
|
w SETTING [VALUE] [-- COMMAND]
|
||||||
|
Temporarily set SETTING, run COMMAND, and restore SETTING.
|
||||||
|
Usage: with SETTING -- COMMAND
|
||||||
|
With no COMMAND, repeats the last executed command.
|
||||||
|
SETTING is any GDB setting you can change with the "set"
|
||||||
|
subcommands. For example, 'with language c -- print someobj'
|
||||||
|
temporarily switches to the C language in order to print someobj.
|
||||||
|
Settings can be combined: 'w lang c -- w print elements unlimited --
|
||||||
|
usercmd' switches to the C language and runs usercmd with no limit
|
||||||
|
of array elements to print.
|
||||||
|
|
||||||
|
maint with SETTING [VALUE] [-- COMMAND]
|
||||||
|
Like "with", but works with "maintenance set" settings.
|
||||||
|
|
||||||
set may-call-functions [on|off]
|
set may-call-functions [on|off]
|
||||||
show may-call-functions
|
show may-call-functions
|
||||||
This controls whether GDB will attempt to call functions in
|
This controls whether GDB will attempt to call functions in
|
||||||
@@ -84,7 +99,8 @@ set style highlight background COLOR
|
|||||||
set style highlight intensity VALUE
|
set style highlight intensity VALUE
|
||||||
Control the styling of highlightings.
|
Control the styling of highlightings.
|
||||||
|
|
||||||
maint test-settings KIND
|
maint set test-settings KIND
|
||||||
|
maint show test-settings KIND
|
||||||
A set of commands used by the testsuite for exercising the settings
|
A set of commands used by the testsuite for exercising the settings
|
||||||
infrastructure.
|
infrastructure.
|
||||||
|
|
||||||
@@ -194,6 +210,8 @@ maint show test-options-completion-result
|
|||||||
"taas" commands, and their "-ascending" option can now be
|
"taas" commands, and their "-ascending" option can now be
|
||||||
abbreviated.
|
abbreviated.
|
||||||
|
|
||||||
|
** GDB can now complete the options of the "info threads" command.
|
||||||
|
|
||||||
** GDB can now complete the options of the "compile file" and
|
** GDB can now complete the options of the "compile file" and
|
||||||
"compile code" commands. The "compile file" command now
|
"compile code" commands. The "compile file" command now
|
||||||
completes on filenames.
|
completes on filenames.
|
||||||
|
|||||||
@@ -211,6 +211,116 @@ show_command (const char *arg, int from_tty)
|
|||||||
cmd_show_list (showlist, from_tty, "");
|
cmd_show_list (showlist, from_tty, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See cli/cli-cmds.h. */
|
||||||
|
|
||||||
|
void
|
||||||
|
with_command_1 (const char *set_cmd_prefix,
|
||||||
|
cmd_list_element *setlist, const char *args, int from_tty)
|
||||||
|
{
|
||||||
|
const char *delim = strstr (args, "--");
|
||||||
|
const char *nested_cmd = nullptr;
|
||||||
|
|
||||||
|
if (delim == args)
|
||||||
|
error (_("Missing setting before '--' delimiter"));
|
||||||
|
|
||||||
|
if (delim == nullptr || *skip_spaces (&delim[2]) == '\0')
|
||||||
|
nested_cmd = repeat_previous ();
|
||||||
|
|
||||||
|
cmd_list_element *set_cmd = lookup_cmd (&args, setlist, set_cmd_prefix,
|
||||||
|
/*allow_unknown=*/ 0,
|
||||||
|
/*ignore_help_classes=*/ 1);
|
||||||
|
gdb_assert (set_cmd != nullptr);
|
||||||
|
|
||||||
|
if (set_cmd->var == nullptr)
|
||||||
|
error (_("Cannot use this setting with the \"with\" command"));
|
||||||
|
|
||||||
|
std::string temp_value
|
||||||
|
= (delim == nullptr ? args : std::string (args, delim - args));
|
||||||
|
|
||||||
|
if (nested_cmd == nullptr)
|
||||||
|
nested_cmd = skip_spaces (delim + 2);
|
||||||
|
|
||||||
|
std::string org_value = get_setshow_command_value_string (set_cmd);
|
||||||
|
|
||||||
|
/* Tweak the setting to the new temporary value. */
|
||||||
|
do_set_command (temp_value.c_str (), from_tty, set_cmd);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
|
||||||
|
|
||||||
|
/* Execute the nested command. */
|
||||||
|
execute_command (nested_cmd, from_tty);
|
||||||
|
}
|
||||||
|
catch (const gdb_exception &ex)
|
||||||
|
{
|
||||||
|
/* Restore the setting and rethrow. If restoring the setting
|
||||||
|
throws, swallow the new exception and warn. There's nothing
|
||||||
|
else we can reasonably do. */
|
||||||
|
try
|
||||||
|
{
|
||||||
|
do_set_command (org_value.c_str (), from_tty, set_cmd);
|
||||||
|
}
|
||||||
|
catch (const gdb_exception &ex2)
|
||||||
|
{
|
||||||
|
warning (_("Couldn't restore setting: %s"), ex2.what ());
|
||||||
|
}
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore the setting. */
|
||||||
|
do_set_command (org_value.c_str (), from_tty, set_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See cli/cli-cmds.h. */
|
||||||
|
|
||||||
|
void
|
||||||
|
with_command_completer_1 (const char *set_cmd_prefix,
|
||||||
|
completion_tracker &tracker,
|
||||||
|
const char *text)
|
||||||
|
{
|
||||||
|
tracker.set_use_custom_word_point (true);
|
||||||
|
|
||||||
|
const char *delim = strstr (text, "--");
|
||||||
|
|
||||||
|
/* If we're still not past the "--" delimiter, complete the "with"
|
||||||
|
command as if it was a "set" command. */
|
||||||
|
if (delim == text
|
||||||
|
|| delim == nullptr
|
||||||
|
|| !isspace (delim[-1])
|
||||||
|
|| !(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));
|
||||||
|
complete_nested_command_line (tracker, new_text.c_str ());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're past the "--" delimiter. Complete on the sub command. */
|
||||||
|
const char *nested_cmd = skip_spaces (delim + 2);
|
||||||
|
tracker.advance_custom_word_point_by (nested_cmd - text);
|
||||||
|
complete_nested_command_line (tracker, nested_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The "with" command. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
with_command (const char *args, int from_tty)
|
||||||
|
{
|
||||||
|
with_command_1 ("set ", setlist, args, from_tty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "with" command completer. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
with_command_completer (struct cmd_list_element *ignore,
|
||||||
|
completion_tracker &tracker,
|
||||||
|
const char *text, const char * /*word*/)
|
||||||
|
{
|
||||||
|
with_command_completer_1 ("set ", tracker, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Provide documentation on command or list given by COMMAND. FROM_TTY
|
/* Provide documentation on command or list given by COMMAND. FROM_TTY
|
||||||
is ignored. */
|
is ignored. */
|
||||||
@@ -850,40 +960,71 @@ edit_command (const char *arg, int from_tty)
|
|||||||
xfree (p);
|
xfree (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The options for the "pipe" command. */
|
||||||
|
|
||||||
|
struct pipe_cmd_opts
|
||||||
|
{
|
||||||
|
/* For "-d". */
|
||||||
|
char *delimiter = nullptr;
|
||||||
|
|
||||||
|
~pipe_cmd_opts ()
|
||||||
|
{
|
||||||
|
xfree (delimiter);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const gdb::option::option_def pipe_cmd_option_defs[] = {
|
||||||
|
|
||||||
|
gdb::option::string_option_def<pipe_cmd_opts> {
|
||||||
|
"d",
|
||||||
|
[] (pipe_cmd_opts *opts) { return &opts->delimiter; },
|
||||||
|
nullptr,
|
||||||
|
N_("Indicates to use the specified delimiter string to separate\n\
|
||||||
|
COMMAND from SHELL_COMMAND, in alternative to |. This is useful in\n\
|
||||||
|
case COMMAND contains a | character."),
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Create an option_def_group for the "pipe" command's options, with
|
||||||
|
OPTS as context. */
|
||||||
|
|
||||||
|
static inline gdb::option::option_def_group
|
||||||
|
make_pipe_cmd_options_def_group (pipe_cmd_opts *opts)
|
||||||
|
{
|
||||||
|
return {{pipe_cmd_option_defs}, opts};
|
||||||
|
}
|
||||||
|
|
||||||
/* Implementation of the "pipe" command. */
|
/* Implementation of the "pipe" command. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pipe_command (const char *arg, int from_tty)
|
pipe_command (const char *arg, int from_tty)
|
||||||
{
|
{
|
||||||
std::string delim ("|");
|
pipe_cmd_opts opts;
|
||||||
|
|
||||||
if (arg != nullptr && check_for_argument (&arg, "-d", 2))
|
auto grp = make_pipe_cmd_options_def_group (&opts);
|
||||||
{
|
gdb::option::process_options
|
||||||
delim = extract_arg (&arg);
|
(&arg, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
|
||||||
if (delim.empty ())
|
|
||||||
error (_("Missing delimiter DELIM after -d"));
|
const char *delim = "|";
|
||||||
}
|
if (opts.delimiter != nullptr)
|
||||||
|
delim = opts.delimiter;
|
||||||
|
|
||||||
const char *command = arg;
|
const char *command = arg;
|
||||||
if (command == nullptr)
|
if (command == nullptr)
|
||||||
error (_("Missing COMMAND"));
|
error (_("Missing COMMAND"));
|
||||||
|
|
||||||
arg = strstr (arg, delim.c_str ());
|
arg = strstr (arg, delim);
|
||||||
|
|
||||||
if (arg == nullptr)
|
if (arg == nullptr)
|
||||||
error (_("Missing delimiter before SHELL_COMMAND"));
|
error (_("Missing delimiter before SHELL_COMMAND"));
|
||||||
|
|
||||||
std::string gdb_cmd (command, arg - command);
|
std::string gdb_cmd (command, arg - command);
|
||||||
|
|
||||||
arg += delim.length (); /* Skip the delimiter. */
|
arg += strlen (delim); /* Skip the delimiter. */
|
||||||
|
|
||||||
if (gdb_cmd.empty ())
|
if (gdb_cmd.empty ())
|
||||||
{
|
gdb_cmd = repeat_previous ();
|
||||||
repeat_previous ();
|
|
||||||
gdb_cmd = skip_spaces (get_saved_command_line ());
|
|
||||||
if (gdb_cmd.empty ())
|
|
||||||
error (_("No previous command to relaunch"));
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *shell_command = skip_spaces (arg);
|
const char *shell_command = skip_spaces (arg);
|
||||||
if (*shell_command == '\0')
|
if (*shell_command == '\0')
|
||||||
@@ -914,6 +1055,43 @@ pipe_command (const char *arg, int from_tty)
|
|||||||
exit_status_set_internal_vars (exit_status);
|
exit_status_set_internal_vars (exit_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Completer for the pipe command. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
pipe_command_completer (struct cmd_list_element *ignore,
|
||||||
|
completion_tracker &tracker,
|
||||||
|
const char *text, const char *word_ignored)
|
||||||
|
{
|
||||||
|
pipe_cmd_opts opts;
|
||||||
|
|
||||||
|
const char *org_text = text;
|
||||||
|
auto grp = make_pipe_cmd_options_def_group (&opts);
|
||||||
|
if (gdb::option::complete_options
|
||||||
|
(tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char *delimiter = "|";
|
||||||
|
if (opts.delimiter != nullptr)
|
||||||
|
delimiter = opts.delimiter;
|
||||||
|
|
||||||
|
/* Check if we're past option values already. */
|
||||||
|
if (text > org_text && !isspace (text[-1]))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char *delim = strstr (text, delimiter);
|
||||||
|
|
||||||
|
/* If we're still not past the delimiter, complete the gdb
|
||||||
|
command. */
|
||||||
|
if (delim == nullptr || delim == text)
|
||||||
|
{
|
||||||
|
complete_nested_command_line (tracker, text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're past the delimiter. What follows is a shell command, which
|
||||||
|
we don't know how to complete. */
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
list_command (const char *arg, int from_tty)
|
list_command (const char *arg, int from_tty)
|
||||||
{
|
{
|
||||||
@@ -1849,6 +2027,23 @@ Generic command for showing things about the debugger."),
|
|||||||
/* Another way to get at the same thing. */
|
/* Another way to get at the same thing. */
|
||||||
add_info ("set", show_command, _("Show all GDB settings."));
|
add_info ("set", show_command, _("Show all GDB settings."));
|
||||||
|
|
||||||
|
c = add_com ("with", class_vars, with_command, _("\
|
||||||
|
Temporarily set SETTING to VALUE, run COMMAND, and restore SETTING.\n\
|
||||||
|
Usage: with SETTING [VALUE] [-- COMMAND]\n\
|
||||||
|
Usage: w SETTING [VALUE] [-- COMMAND]\n\
|
||||||
|
With no COMMAND, repeats the last executed command.\n\
|
||||||
|
\n\
|
||||||
|
SETTING is any setting you can change with the \"set\" subcommands.\n\
|
||||||
|
E.g.:\n\
|
||||||
|
with language pascal -- print obj\n\
|
||||||
|
with print elements unlimited -- print obj\n\
|
||||||
|
\n\
|
||||||
|
You can change multiple settings using nested with, and use\n\
|
||||||
|
abbreviations for commands and/or values. E.g.:\n\
|
||||||
|
w la p -- w p el u -- p obj"));
|
||||||
|
set_cmd_completer_handle_brkchars (c, with_command_completer);
|
||||||
|
add_com_alias ("w", "with", class_vars, 1);
|
||||||
|
|
||||||
add_cmd ("commands", no_set_class, show_commands, _("\
|
add_cmd ("commands", no_set_class, show_commands, _("\
|
||||||
Show the history of commands you typed.\n\
|
Show the history of commands you typed.\n\
|
||||||
You can supply a command number to start with, or a `+' to start after\n\
|
You can supply a command number to start with, or a `+' to start after\n\
|
||||||
@@ -1907,7 +2102,10 @@ Uses EDITOR environment variable contents as editor (or ex as default)."));
|
|||||||
|
|
||||||
c->completer = location_completer;
|
c->completer = location_completer;
|
||||||
|
|
||||||
c = add_com ("pipe", class_support, pipe_command, _("\
|
const auto pipe_cmd_opts = make_pipe_cmd_options_def_group (nullptr);
|
||||||
|
|
||||||
|
static std::string pipe_cmd_help
|
||||||
|
= gdb::option::build_help (_("\
|
||||||
Send the output of a gdb command to a shell command.\n\
|
Send the output of a gdb command to a shell command.\n\
|
||||||
Usage: | [COMMAND] | SHELL_COMMAND\n\
|
Usage: | [COMMAND] | SHELL_COMMAND\n\
|
||||||
Usage: | -d DELIM COMMAND DELIM SHELL_COMMAND\n\
|
Usage: | -d DELIM COMMAND DELIM SHELL_COMMAND\n\
|
||||||
@@ -1916,12 +2114,15 @@ Usage: pipe -d DELIM COMMAND DELIM SHELL_COMMAND\n\
|
|||||||
\n\
|
\n\
|
||||||
Executes COMMAND and sends its output to SHELL_COMMAND.\n\
|
Executes COMMAND and sends its output to SHELL_COMMAND.\n\
|
||||||
\n\
|
\n\
|
||||||
The -d option indicates to use the string DELIM to separate COMMAND\n\
|
Options:\n\
|
||||||
from SHELL_COMMAND, in alternative to |. This is useful in\n\
|
%OPTIONS%\
|
||||||
case COMMAND contains a | character.\n\
|
|
||||||
\n\
|
|
||||||
With no COMMAND, repeat the last executed command\n\
|
With no COMMAND, repeat the last executed command\n\
|
||||||
and send its output to SHELL_COMMAND."));
|
and send its output to SHELL_COMMAND."),
|
||||||
|
pipe_cmd_opts);
|
||||||
|
|
||||||
|
c = add_com ("pipe", class_support, pipe_command,
|
||||||
|
pipe_cmd_help.c_str ());
|
||||||
|
set_cmd_completer_handle_brkchars (c, pipe_command_completer);
|
||||||
add_com_alias ("|", "pipe", class_support, 0);
|
add_com_alias ("|", "pipe", class_support, 0);
|
||||||
|
|
||||||
add_com ("list", class_files, list_command, _("\
|
add_com ("list", class_files, list_command, _("\
|
||||||
|
|||||||
@@ -142,4 +142,19 @@ extern gdb::optional<open_script>
|
|||||||
extern int source_verbose;
|
extern int source_verbose;
|
||||||
extern int trace_commands;
|
extern int trace_commands;
|
||||||
|
|
||||||
|
/* Common code for the "with" and "maintenance with" commands.
|
||||||
|
SET_CMD_PREFIX is the spelling of the corresponding "set" command
|
||||||
|
prefix: i.e., "set " or "maintenance set ". SETLIST is the command
|
||||||
|
element for the same "set" command prefix. */
|
||||||
|
extern void with_command_1 (const char *set_cmd_prefix,
|
||||||
|
cmd_list_element *setlist,
|
||||||
|
const char *args, int from_tty);
|
||||||
|
|
||||||
|
/* Common code for the completers of the "with" and "maintenance with"
|
||||||
|
commands. SET_CMD_PREFIX is the spelling of the corresponding
|
||||||
|
"set" command prefix: i.e., "set " or "maintenance set ". */
|
||||||
|
extern void with_command_completer_1 (const char *set_cmd_prefix,
|
||||||
|
completion_tracker &tracker,
|
||||||
|
const char *text);
|
||||||
|
|
||||||
#endif /* CLI_CLI_CMDS_H */
|
#endif /* CLI_CLI_CMDS_H */
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ union option_value
|
|||||||
|
|
||||||
/* For var_enum options. */
|
/* For var_enum options. */
|
||||||
const char *enumeration;
|
const char *enumeration;
|
||||||
|
|
||||||
|
/* For var_string options. This is malloc-allocated. */
|
||||||
|
char *string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Holds an options definition and its value. */
|
/* Holds an options definition and its value. */
|
||||||
@@ -56,8 +59,57 @@ struct option_def_and_value
|
|||||||
|
|
||||||
/* The option's value, if any. */
|
/* The option's value, if any. */
|
||||||
gdb::optional<option_value> value;
|
gdb::optional<option_value> value;
|
||||||
|
|
||||||
|
option_def_and_value (const option_def &option_, void *ctx_,
|
||||||
|
gdb::optional<option_value> &&value_)
|
||||||
|
: option (option_),
|
||||||
|
ctx (ctx_),
|
||||||
|
value (std::move (value_))
|
||||||
|
{
|
||||||
|
clear_value (option_, value_);
|
||||||
|
}
|
||||||
|
|
||||||
|
option_def_and_value (const option_def &option_, void *ctx_)
|
||||||
|
: option (option_),
|
||||||
|
ctx (ctx_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
option_def_and_value (option_def_and_value &&rval)
|
||||||
|
: option (rval.option),
|
||||||
|
ctx (rval.ctx),
|
||||||
|
value (std::move (rval.value))
|
||||||
|
{
|
||||||
|
clear_value (rval.option, rval.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
~option_def_and_value ()
|
||||||
|
{
|
||||||
|
if (value.has_value ())
|
||||||
|
{
|
||||||
|
if (option.type == var_string)
|
||||||
|
xfree (value->string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/* Clear the option_value, without releasing it. This is used after
|
||||||
|
the value has been moved to some other option_def_and_value
|
||||||
|
instance. */
|
||||||
|
static void clear_value (const option_def &option,
|
||||||
|
gdb::optional<option_value> &value)
|
||||||
|
{
|
||||||
|
if (value.has_value ())
|
||||||
|
{
|
||||||
|
if (option.type == var_string)
|
||||||
|
value->string = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void save_option_value_in_ctx (gdb::optional<option_def_and_value> &ov);
|
||||||
|
|
||||||
/* Info passed around when handling completion. */
|
/* Info passed around when handling completion. */
|
||||||
struct parse_option_completion_info
|
struct parse_option_completion_info
|
||||||
{
|
{
|
||||||
@@ -370,6 +422,25 @@ parse_option (gdb::array_view<const option_def_group> options_group,
|
|||||||
val.enumeration = parse_cli_var_enum (args, match->enums);
|
val.enumeration = parse_cli_var_enum (args, match->enums);
|
||||||
return option_def_and_value {*match, match_ctx, val};
|
return option_def_and_value {*match, match_ctx, val};
|
||||||
}
|
}
|
||||||
|
case var_string:
|
||||||
|
{
|
||||||
|
if (check_for_argument (args, "--"))
|
||||||
|
{
|
||||||
|
/* Treat e.g., "pipe -d --" as if there was no argument
|
||||||
|
after "-d". */
|
||||||
|
error (_("-%s requires an argument"), match->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *arg_start = *args;
|
||||||
|
*args = skip_to_space (*args);
|
||||||
|
|
||||||
|
if (*args == arg_start)
|
||||||
|
error (_("-%s requires an argument"), match->name);
|
||||||
|
|
||||||
|
option_value val;
|
||||||
|
val.string = savestring (arg_start, *args - arg_start);
|
||||||
|
return option_def_and_value {*match, match_ctx, val};
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Not yet. */
|
/* Not yet. */
|
||||||
@@ -456,6 +527,11 @@ complete_options (completion_tracker &tracker,
|
|||||||
(*args - text);
|
(*args - text);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the caller passed in a context, then it is
|
||||||
|
interested in the option argument values. */
|
||||||
|
if (ov && ov->ctx != nullptr)
|
||||||
|
save_option_value_in_ctx (ov);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -499,6 +575,41 @@ complete_options (completion_tracker &tracker,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save the parsed value in the option's context. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
save_option_value_in_ctx (gdb::optional<option_def_and_value> &ov)
|
||||||
|
{
|
||||||
|
switch (ov->option.type)
|
||||||
|
{
|
||||||
|
case var_boolean:
|
||||||
|
{
|
||||||
|
bool value = ov->value.has_value () ? ov->value->boolean : true;
|
||||||
|
*ov->option.var_address.boolean (ov->option, ov->ctx) = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case var_uinteger:
|
||||||
|
*ov->option.var_address.uinteger (ov->option, ov->ctx)
|
||||||
|
= ov->value->uinteger;
|
||||||
|
break;
|
||||||
|
case var_zuinteger_unlimited:
|
||||||
|
*ov->option.var_address.integer (ov->option, ov->ctx)
|
||||||
|
= ov->value->integer;
|
||||||
|
break;
|
||||||
|
case var_enum:
|
||||||
|
*ov->option.var_address.enumeration (ov->option, ov->ctx)
|
||||||
|
= ov->value->enumeration;
|
||||||
|
break;
|
||||||
|
case var_string:
|
||||||
|
*ov->option.var_address.string (ov->option, ov->ctx)
|
||||||
|
= ov->value->string;
|
||||||
|
ov->value->string = nullptr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
gdb_assert_not_reached ("unhandled option type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* See cli-option.h. */
|
/* See cli-option.h. */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -534,29 +645,7 @@ process_options (const char **args,
|
|||||||
|
|
||||||
processed_any = true;
|
processed_any = true;
|
||||||
|
|
||||||
switch (ov->option.type)
|
save_option_value_in_ctx (ov);
|
||||||
{
|
|
||||||
case var_boolean:
|
|
||||||
{
|
|
||||||
bool value = ov->value.has_value () ? ov->value->boolean : true;
|
|
||||||
*ov->option.var_address.boolean (ov->option, ov->ctx) = value;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case var_uinteger:
|
|
||||||
*ov->option.var_address.uinteger (ov->option, ov->ctx)
|
|
||||||
= ov->value->uinteger;
|
|
||||||
break;
|
|
||||||
case var_zuinteger_unlimited:
|
|
||||||
*ov->option.var_address.integer (ov->option, ov->ctx)
|
|
||||||
= ov->value->integer;
|
|
||||||
break;
|
|
||||||
case var_enum:
|
|
||||||
*ov->option.var_address.enumeration (ov->option, ov->ctx)
|
|
||||||
= ov->value->enumeration;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
gdb_assert_not_reached ("unhandled option type");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,6 +677,8 @@ get_val_type_str (const option_def &opt, std::string &buffer)
|
|||||||
}
|
}
|
||||||
return buffer.c_str ();
|
return buffer.c_str ();
|
||||||
}
|
}
|
||||||
|
case var_string:
|
||||||
|
return "STRING";
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -715,6 +806,15 @@ add_setshow_cmds_for_options (command_class cmd_class,
|
|||||||
nullptr, option.show_cmd_cb,
|
nullptr, option.show_cmd_cb,
|
||||||
set_list, show_list);
|
set_list, show_list);
|
||||||
}
|
}
|
||||||
|
else if (option.type == var_string)
|
||||||
|
{
|
||||||
|
add_setshow_string_cmd (option.name, cmd_class,
|
||||||
|
option.var_address.string (option, data),
|
||||||
|
option.set_doc, option.show_doc,
|
||||||
|
option.help_doc,
|
||||||
|
nullptr, option.show_cmd_cb,
|
||||||
|
set_list, show_list);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
gdb_assert_not_reached (_("option type not handled"));
|
gdb_assert_not_reached (_("option type not handled"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ public:
|
|||||||
unsigned int *(*uinteger) (const option_def &, void *ctx);
|
unsigned int *(*uinteger) (const option_def &, void *ctx);
|
||||||
int *(*integer) (const option_def &, void *ctx);
|
int *(*integer) (const option_def &, void *ctx);
|
||||||
const char **(*enumeration) (const option_def &, void *ctx);
|
const char **(*enumeration) (const option_def &, void *ctx);
|
||||||
|
char **(*string) (const option_def &, void *ctx);
|
||||||
}
|
}
|
||||||
var_address;
|
var_address;
|
||||||
|
|
||||||
@@ -261,6 +262,26 @@ struct enum_option_def : option_def
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* An var_string command line option. */
|
||||||
|
|
||||||
|
template<typename Context>
|
||||||
|
struct string_option_def : option_def
|
||||||
|
{
|
||||||
|
string_option_def (const char *long_option_,
|
||||||
|
char **(*get_var_address_cb_) (Context *),
|
||||||
|
show_value_ftype *show_cmd_cb_,
|
||||||
|
const char *set_doc_,
|
||||||
|
const char *show_doc_ = nullptr,
|
||||||
|
const char *help_doc_ = nullptr)
|
||||||
|
: option_def (long_option_, var_string,
|
||||||
|
(erased_get_var_address_ftype *) get_var_address_cb_,
|
||||||
|
show_cmd_cb_,
|
||||||
|
set_doc_, show_doc_, help_doc_)
|
||||||
|
{
|
||||||
|
var_address.enumeration = detail::get_var_address<const char *, Context>;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* A group of options that all share the same context pointer to pass
|
/* A group of options that all share the same context pointer to pass
|
||||||
to the options' get-current-value callbacks. */
|
to the options' get-current-value callbacks. */
|
||||||
struct option_def_group
|
struct option_def_group
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ parse_cli_var_uinteger (var_types var_type, const char **arg,
|
|||||||
{
|
{
|
||||||
LONGEST val;
|
LONGEST val;
|
||||||
|
|
||||||
if (*arg == nullptr)
|
if (*arg == nullptr || **arg == '\0')
|
||||||
{
|
{
|
||||||
if (var_type == var_uinteger)
|
if (var_type == var_uinteger)
|
||||||
error_no_arg (_("integer to set it to, or \"unlimited\"."));
|
error_no_arg (_("integer to set it to, or \"unlimited\"."));
|
||||||
@@ -225,7 +225,7 @@ parse_cli_var_zuinteger_unlimited (const char **arg, bool expression)
|
|||||||
{
|
{
|
||||||
LONGEST val;
|
LONGEST val;
|
||||||
|
|
||||||
if (*arg == nullptr)
|
if (*arg == nullptr || **arg == '\0')
|
||||||
error_no_arg (_("integer to set it to, or \"unlimited\"."));
|
error_no_arg (_("integer to set it to, or \"unlimited\"."));
|
||||||
|
|
||||||
if (is_unlimited_literal (arg, expression))
|
if (is_unlimited_literal (arg, expression))
|
||||||
@@ -308,6 +308,9 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
|||||||
|
|
||||||
gdb_assert (c->type == set_cmd);
|
gdb_assert (c->type == set_cmd);
|
||||||
|
|
||||||
|
if (arg == NULL)
|
||||||
|
arg = "";
|
||||||
|
|
||||||
switch (c->var_type)
|
switch (c->var_type)
|
||||||
{
|
{
|
||||||
case var_string:
|
case var_string:
|
||||||
@@ -317,8 +320,6 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
|||||||
char *q;
|
char *q;
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
if (arg == NULL)
|
|
||||||
arg = "";
|
|
||||||
newobj = (char *) xmalloc (strlen (arg) + 2);
|
newobj = (char *) xmalloc (strlen (arg) + 2);
|
||||||
p = arg;
|
p = arg;
|
||||||
q = newobj;
|
q = newobj;
|
||||||
@@ -364,9 +365,6 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case var_string_noescape:
|
case var_string_noescape:
|
||||||
if (arg == NULL)
|
|
||||||
arg = "";
|
|
||||||
|
|
||||||
if (*(char **) c->var == NULL || strcmp (*(char **) c->var, arg) != 0)
|
if (*(char **) c->var == NULL || strcmp (*(char **) c->var, arg) != 0)
|
||||||
{
|
{
|
||||||
xfree (*(char **) c->var);
|
xfree (*(char **) c->var);
|
||||||
@@ -376,14 +374,14 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case var_filename:
|
case var_filename:
|
||||||
if (arg == NULL)
|
if (*arg == '\0')
|
||||||
error_no_arg (_("filename to set it to."));
|
error_no_arg (_("filename to set it to."));
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case var_optional_filename:
|
case var_optional_filename:
|
||||||
{
|
{
|
||||||
char *val = NULL;
|
char *val = NULL;
|
||||||
|
|
||||||
if (arg != NULL)
|
if (*arg != '\0')
|
||||||
{
|
{
|
||||||
/* Clear trailing whitespace of filename. */
|
/* Clear trailing whitespace of filename. */
|
||||||
const char *ptr = arg + strlen (arg) - 1;
|
const char *ptr = arg + strlen (arg) - 1;
|
||||||
@@ -455,7 +453,7 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
|||||||
{
|
{
|
||||||
LONGEST val;
|
LONGEST val;
|
||||||
|
|
||||||
if (arg == NULL)
|
if (*arg == '\0')
|
||||||
{
|
{
|
||||||
if (c->var_type == var_integer)
|
if (c->var_type == var_integer)
|
||||||
error_no_arg (_("integer to set it to, or \"unlimited\"."));
|
error_no_arg (_("integer to set it to, or \"unlimited\"."));
|
||||||
@@ -625,24 +623,13 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do a "show" command. ARG is NULL if no argument, or the
|
/* See cli/cli-setshow.h. */
|
||||||
text of the argument, and FROM_TTY is nonzero if this command is
|
|
||||||
being entered directly by the user (i.e. these are just like any
|
|
||||||
other command). C is the command list element for the command. */
|
|
||||||
|
|
||||||
void
|
std::string
|
||||||
do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
get_setshow_command_value_string (cmd_list_element *c)
|
||||||
{
|
{
|
||||||
struct ui_out *uiout = current_uiout;
|
|
||||||
|
|
||||||
gdb_assert (c->type == show_cmd);
|
|
||||||
|
|
||||||
string_file stb;
|
string_file stb;
|
||||||
|
|
||||||
/* Possibly call the pre hook. */
|
|
||||||
if (c->pre_show_hook)
|
|
||||||
(c->pre_show_hook) (c);
|
|
||||||
|
|
||||||
switch (c->var_type)
|
switch (c->var_type)
|
||||||
{
|
{
|
||||||
case var_string:
|
case var_string:
|
||||||
@@ -672,9 +659,7 @@ do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
|||||||
stb.puts ("auto");
|
stb.puts ("auto");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
internal_error (__FILE__, __LINE__,
|
gdb_assert_not_reached ("invalid var_auto_boolean");
|
||||||
_("do_show_command: "
|
|
||||||
"invalid var_auto_boolean"));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -703,23 +688,42 @@ do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error (_("gdb internal error: bad var_type in do_show_command"));
|
gdb_assert_not_reached ("bad var_type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return std::move (stb.string ());
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: cagney/2005-02-10: Need to split this in half: code to
|
|
||||||
convert the value into a string (esentially the above); and
|
/* Do a "show" command. ARG is NULL if no argument, or the
|
||||||
code to print the value out. For the latter there should be
|
text of the argument, and FROM_TTY is nonzero if this command is
|
||||||
MI and CLI specific versions. */
|
being entered directly by the user (i.e. these are just like any
|
||||||
|
other command). C is the command list element for the command. */
|
||||||
|
|
||||||
|
void
|
||||||
|
do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
||||||
|
{
|
||||||
|
struct ui_out *uiout = current_uiout;
|
||||||
|
|
||||||
|
gdb_assert (c->type == show_cmd);
|
||||||
|
|
||||||
|
/* Possibly call the pre hook. */
|
||||||
|
if (c->pre_show_hook)
|
||||||
|
(c->pre_show_hook) (c);
|
||||||
|
|
||||||
|
std::string val = get_setshow_command_value_string (c);
|
||||||
|
|
||||||
|
/* FIXME: cagney/2005-02-10: There should be MI and CLI specific
|
||||||
|
versions of code to print the value out. */
|
||||||
|
|
||||||
if (uiout->is_mi_like_p ())
|
if (uiout->is_mi_like_p ())
|
||||||
uiout->field_stream ("value", stb);
|
uiout->field_string ("value", val.c_str ());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (c->show_value_func != NULL)
|
if (c->show_value_func != NULL)
|
||||||
c->show_value_func (gdb_stdout, from_tty, c, stb.c_str ());
|
c->show_value_func (gdb_stdout, from_tty, c, val.c_str ());
|
||||||
else
|
else
|
||||||
deprecated_show_value_hack (gdb_stdout, from_tty, c, stb.c_str ());
|
deprecated_show_value_hack (gdb_stdout, from_tty, c, val.c_str ());
|
||||||
}
|
}
|
||||||
|
|
||||||
c->func (c, NULL, from_tty);
|
c->func (c, NULL, from_tty);
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
#ifndef CLI_CLI_SETSHOW_H
|
#ifndef CLI_CLI_SETSHOW_H
|
||||||
#define CLI_CLI_SETSHOW_H
|
#define CLI_CLI_SETSHOW_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
struct cmd_list_element;
|
struct cmd_list_element;
|
||||||
|
|
||||||
/* Parse ARG, an option to a boolean variable.
|
/* Parse ARG, an option to a boolean variable.
|
||||||
@@ -55,6 +57,9 @@ extern void do_set_command (const char *arg, int from_tty,
|
|||||||
extern void do_show_command (const char *arg, int from_tty,
|
extern void do_show_command (const char *arg, int from_tty,
|
||||||
struct cmd_list_element *c);
|
struct cmd_list_element *c);
|
||||||
|
|
||||||
|
/* Get a string version of C's current value. */
|
||||||
|
extern std::string get_setshow_command_value_string (cmd_list_element *c);
|
||||||
|
|
||||||
extern void cmd_show_list (struct cmd_list_element *list, int from_tty,
|
extern void cmd_show_list (struct cmd_list_element *list, int from_tty,
|
||||||
const char *prefix);
|
const char *prefix);
|
||||||
|
|
||||||
|
|||||||
@@ -461,14 +461,17 @@ extern void error_no_arg (const char *) ATTRIBUTE_NORETURN;
|
|||||||
|
|
||||||
extern void dont_repeat ();
|
extern void dont_repeat ();
|
||||||
|
|
||||||
/* Commands call repeat_previous if they want to repeat the previous command.
|
/* Commands call repeat_previous if they want to repeat the previous
|
||||||
Such commands that repeat the previous command must indicate
|
command. Such commands that repeat the previous command must
|
||||||
to not repeat themselves, to avoid recursive repeat.
|
indicate to not repeat themselves, to avoid recursive repeat.
|
||||||
repeat_previous will mark the current command as not repeating,
|
repeat_previous marks the current command as not repeating, and
|
||||||
and will ensure get_saved_command_line returns the previous command,
|
ensures get_saved_command_line returns the previous command, so
|
||||||
so that the currently executing command can repeat it. */
|
that the currently executing command can repeat it. If there's no
|
||||||
|
previous command, throws an error. Otherwise, returns the result
|
||||||
|
of get_saved_command_line, which now points at the command to
|
||||||
|
repeat. */
|
||||||
|
|
||||||
extern void repeat_previous ();
|
extern const char *repeat_previous ();
|
||||||
|
|
||||||
/* Prevent dont_repeat from working, and return a cleanup that
|
/* Prevent dont_repeat from working, and return a cleanup that
|
||||||
restores the previous state. */
|
restores the previous state. */
|
||||||
|
|||||||
@@ -1560,6 +1560,7 @@ show you the alternatives available, if there is more than one possibility).
|
|||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Command Syntax:: How to give commands to @value{GDBN}
|
* Command Syntax:: How to give commands to @value{GDBN}
|
||||||
|
* Command Settings:: How to change default behavior of commands
|
||||||
* Completion:: Command completion
|
* Completion:: Command completion
|
||||||
* Command Options:: Command options
|
* Command Options:: Command options
|
||||||
* Help:: How to ask @value{GDBN} for help
|
* Help:: How to ask @value{GDBN} for help
|
||||||
@@ -1616,6 +1617,98 @@ commands. This command accepts the current line, like @key{RET}, and
|
|||||||
then fetches the next line relative to the current line from the history
|
then fetches the next line relative to the current line from the history
|
||||||
for editing.
|
for editing.
|
||||||
|
|
||||||
|
|
||||||
|
@node Command Settings
|
||||||
|
@section Command Settings
|
||||||
|
@cindex default behavior of commands, changing
|
||||||
|
@cindex default settings, changing
|
||||||
|
|
||||||
|
Many commands change their behavior according to command-specific
|
||||||
|
variables or settings. These settings can be changed with the
|
||||||
|
@code{set} subcommands. For example, the @code{print} command
|
||||||
|
(@pxref{Data, ,Examining Data}) prints arrays differently depending on
|
||||||
|
settings changeable with the commands @code{set print elements
|
||||||
|
NUMBER-OF-ELEMENTS} and @code{set print array-indexes}, among others.
|
||||||
|
|
||||||
|
You can change these settings to your preference in the gdbinit files
|
||||||
|
loaded at @value{GDBN} startup. @xref{Startup}.
|
||||||
|
|
||||||
|
The settings can also be changed interactively during the debugging
|
||||||
|
session. For example, to change the limit of array elements to print,
|
||||||
|
you can do the following:
|
||||||
|
@smallexample
|
||||||
|
(@value{GDBN}) set print elements 10
|
||||||
|
(@value{GDBN}) print some_array
|
||||||
|
$1 = @{0, 10, 20, 30, 40, 50, 60, 70, 80, 90...@}
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
The above @code{set print elements 10} command changes the number of
|
||||||
|
elements to print from the default of 200 to 10. If you only intend
|
||||||
|
this limit of 10 to be used for printing @code{some_array}, then you
|
||||||
|
must restore the limit back to 200, with @code{set print elements
|
||||||
|
200}.
|
||||||
|
|
||||||
|
Some commands allow overriding settings with command options. For
|
||||||
|
example, the @code{print} command supports a number of options that
|
||||||
|
allow overriding relevant global print settings as set by @code{set
|
||||||
|
print} subcommands. @xref{print options}. The example above could be
|
||||||
|
rewritten as:
|
||||||
|
@smallexample
|
||||||
|
(@value{GDBN}) print -elements 10 -- some_array
|
||||||
|
$1 = @{0, 10, 20, 30, 40, 50, 60, 70, 80, 90...@}
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
Alternatively, you can use the @code{with} command to change a setting
|
||||||
|
temporarily, for the duration of a command invocation.
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@kindex with command
|
||||||
|
@kindex w @r{(@code{with})}
|
||||||
|
@cindex settings
|
||||||
|
@cindex temporarily change settings
|
||||||
|
@item with @var{setting} [@var{value}] [-- @var{command}]
|
||||||
|
@itemx w @var{setting} [@var{value}] [-- @var{command}]
|
||||||
|
Temporarily set @var{setting} to @var{value} for the duration of
|
||||||
|
@var{command}.
|
||||||
|
|
||||||
|
@var{setting} is any setting you can change with the @code{set}
|
||||||
|
subcommands. @var{value} is the value to assign to @code{setting}
|
||||||
|
while running @code{command}.
|
||||||
|
|
||||||
|
If no @var{command} is provided, the last command executed is
|
||||||
|
repeated.
|
||||||
|
|
||||||
|
If a @var{command} is provided, it must be preceded by a double dash
|
||||||
|
(@code{--}) separator. This is required because some settings accept
|
||||||
|
free-form arguments, such as expressions or filenames.
|
||||||
|
|
||||||
|
For example, the command
|
||||||
|
@smallexample
|
||||||
|
(@value{GDBN}) with print array on -- print some_array
|
||||||
|
@end smallexample
|
||||||
|
@noindent
|
||||||
|
is equivalent to the following 3 commands:
|
||||||
|
@smallexample
|
||||||
|
(@value{GDBN}) set print array on
|
||||||
|
(@value{GDBN}) print some_array
|
||||||
|
(@value{GDBN}) set print array off
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
The @code{with} command is particularly useful when you want to
|
||||||
|
override a setting while running user-defined commands, or commands
|
||||||
|
defined in Python or Guile. @xref{Extending GDB,, Extending GDB}.
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
(@value{GDBN}) with print pretty on -- my_complex_command
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
To change several settings for the same command, you can nest
|
||||||
|
@code{with} commands. For example, @code{with language ada -- with
|
||||||
|
print elements 10} temporarily changes the language to Ada and sets a
|
||||||
|
limit of 10 elements to print for arrays and strings.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
@node Completion
|
@node Completion
|
||||||
@section Command Completion
|
@section Command Completion
|
||||||
|
|
||||||
@@ -37626,12 +37719,20 @@ Shows the result of completing the @code{maint test-options}
|
|||||||
subcommands. This is used by the testsuite to validate completion
|
subcommands. This is used by the testsuite to validate completion
|
||||||
support in the command options framework.
|
support in the command options framework.
|
||||||
|
|
||||||
@kindex maint test-settings
|
@kindex maint set test-settings
|
||||||
@item maint test-settings set @var{kind}
|
@kindex maint show test-settings
|
||||||
@itemx maint test-settings show @var{kind}
|
@item maint set test-settings @var{kind}
|
||||||
|
@itemx maint show test-settings @var{kind}
|
||||||
These are representative commands for each @var{kind} of setting type
|
These are representative commands for each @var{kind} of setting type
|
||||||
@value{GDBN} supports. They are used by the testsuite for exercising
|
@value{GDBN} supports. They are used by the testsuite for exercising
|
||||||
the settings infrastructure.
|
the settings infrastructure.
|
||||||
|
|
||||||
|
@kindex maint with
|
||||||
|
@item maint with @var{setting} [@var{value}] [-- @var{command}]
|
||||||
|
Like the @code{with} command, but works with @code{maintenance set}
|
||||||
|
variables. This is used by the testsuite to exercise the @code{with}
|
||||||
|
command's infrastructure.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
The following command is useful for non-interactive invocations of
|
The following command is useful for non-interactive invocations of
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Support for GDB maintenance commands.
|
/* Maintenance commands for testing the settings framework.
|
||||||
|
|
||||||
Copyright (C) 2019 Free Software Foundation, Inc.
|
Copyright (C) 2019 Free Software Foundation, Inc.
|
||||||
|
|
||||||
@@ -21,46 +21,33 @@
|
|||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "gdbcmd.h"
|
#include "gdbcmd.h"
|
||||||
|
|
||||||
/* Command list for "maint test-settings". */
|
/* Command list for "maint set test-settings". */
|
||||||
static cmd_list_element *maintenance_test_settings_list;
|
static cmd_list_element *maintenance_set_test_settings_list;
|
||||||
|
|
||||||
/* Command list for "maint test-settings set/show". */
|
/* Command list for "maint show test-settings". */
|
||||||
static cmd_list_element *maintenance_test_settings_set_list;
|
static cmd_list_element *maintenance_show_test_settings_list;
|
||||||
static cmd_list_element *maintenance_test_settings_show_list;
|
|
||||||
|
|
||||||
/* The "maintenance test-options" prefix command. */
|
/* The "maintenance set test-settings" prefix command. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
maintenance_test_settings_cmd (const char *arg, int from_tty)
|
maintenance_set_test_settings_cmd (const char *args, int from_tty)
|
||||||
{
|
{
|
||||||
printf_unfiltered
|
printf_unfiltered (_("\"maintenance set test-settings\" must be followed "
|
||||||
(_("\"maintenance test-settings\" must be followed "
|
|
||||||
"by the name of a subcommand.\n"));
|
|
||||||
help_list (maintenance_test_settings_list, "maintenance test-settings ",
|
|
||||||
all_commands, gdb_stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The "maintenance test-options set" prefix command. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
maintenance_test_settings_set_cmd (const char *args, int from_tty)
|
|
||||||
{
|
|
||||||
printf_unfiltered (_("\"maintenance test-settings set\" must be followed "
|
|
||||||
"by the name of a set command.\n"));
|
"by the name of a set command.\n"));
|
||||||
help_list (maintenance_test_settings_set_list,
|
help_list (maintenance_set_test_settings_list,
|
||||||
"maintenance test-settings set ",
|
"maintenance set test-settings ",
|
||||||
all_commands, gdb_stdout);
|
all_commands, gdb_stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The "maintenance test-options show" prefix command. */
|
/* The "maintenance show test-settings" prefix command. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
maintenance_test_settings_show_cmd (const char *args, int from_tty)
|
maintenance_show_test_settings_cmd (const char *args, int from_tty)
|
||||||
{
|
{
|
||||||
cmd_show_list (maintenance_test_settings_show_list, from_tty, "");
|
cmd_show_list (maintenance_show_test_settings_list, from_tty, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Control variables for all the "maintenance test-options set/show
|
/* Control variables for all the "maintenance set/show test-settings
|
||||||
xxx" commands. */
|
xxx" commands. */
|
||||||
|
|
||||||
static int maintenance_test_settings_boolean;
|
static int maintenance_test_settings_boolean;
|
||||||
@@ -85,18 +72,26 @@ static char *maintenance_test_settings_optional_filename;
|
|||||||
|
|
||||||
static char *maintenance_test_settings_filename;
|
static char *maintenance_test_settings_filename;
|
||||||
|
|
||||||
static const char *maintenance_test_settings_enum;
|
/* Enum values for the "maintenance set/show test-settings boolean"
|
||||||
|
|
||||||
/* Enum values for the "maintenance test-settings set/show boolean"
|
|
||||||
commands. */
|
commands. */
|
||||||
|
static const char maintenance_test_settings_xxx[] = "xxx";
|
||||||
|
static const char maintenance_test_settings_yyy[] = "yyy";
|
||||||
|
static const char maintenance_test_settings_zzz[] = "zzz";
|
||||||
|
|
||||||
static const char *const maintenance_test_settings_enums[] = {
|
static const char *const maintenance_test_settings_enums[] = {
|
||||||
"xxx", "yyy", "zzz", nullptr
|
maintenance_test_settings_xxx,
|
||||||
|
maintenance_test_settings_yyy,
|
||||||
|
maintenance_test_settings_zzz,
|
||||||
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The "maintenance test-options show xxx" commands. */
|
static const char *maintenance_test_settings_enum
|
||||||
|
= maintenance_test_settings_xxx;
|
||||||
|
|
||||||
|
/* The "maintenance show test-settings xxx" commands. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
maintenance_test_settings_show_value_cmd
|
maintenance_show_test_settings_value_cmd
|
||||||
(struct ui_file *file, int from_tty,
|
(struct ui_file *file, int from_tty,
|
||||||
struct cmd_list_element *c, const char *value)
|
struct cmd_list_element *c, const char *value)
|
||||||
{
|
{
|
||||||
@@ -107,29 +102,23 @@ maintenance_test_settings_show_value_cmd
|
|||||||
void
|
void
|
||||||
_initialize_maint_test_settings (void)
|
_initialize_maint_test_settings (void)
|
||||||
{
|
{
|
||||||
add_prefix_cmd ("test-settings", no_class,
|
maintenance_test_settings_filename = xstrdup ("/foo/bar");
|
||||||
maintenance_test_settings_cmd,
|
|
||||||
_("\
|
|
||||||
Generic command for testing the settings infrastructure."),
|
|
||||||
&maintenance_test_settings_list,
|
|
||||||
"maintenance test-settings ", 0,
|
|
||||||
&maintenancelist);
|
|
||||||
|
|
||||||
add_prefix_cmd ("set", class_maintenance,
|
add_prefix_cmd ("test-settings", class_maintenance,
|
||||||
maintenance_test_settings_set_cmd, _("\
|
maintenance_set_test_settings_cmd, _("\
|
||||||
Set GDB internal variables used for set/show command infrastructure testing."),
|
Set GDB internal variables used for set/show command infrastructure testing."),
|
||||||
&maintenance_test_settings_set_list,
|
&maintenance_set_test_settings_list,
|
||||||
"maintenance test-settings set ",
|
"maintenance set test-settings ",
|
||||||
0/*allow-unknown*/,
|
0/*allow-unknown*/,
|
||||||
&maintenance_test_settings_list);
|
&maintenance_set_cmdlist);
|
||||||
|
|
||||||
add_prefix_cmd ("show", class_maintenance,
|
add_prefix_cmd ("test-settings", class_maintenance,
|
||||||
maintenance_test_settings_show_cmd, _("\
|
maintenance_show_test_settings_cmd, _("\
|
||||||
Show GDB internal variables used for set/show command infrastructure testing."),
|
Show GDB internal variables used for set/show command infrastructure testing."),
|
||||||
&maintenance_test_settings_show_list,
|
&maintenance_show_test_settings_list,
|
||||||
"maintenance test-settings show ",
|
"maintenance show test-settings ",
|
||||||
0/*allow-unknown*/,
|
0/*allow-unknown*/,
|
||||||
&maintenance_test_settings_list);
|
&maintenance_show_cmdlist);
|
||||||
|
|
||||||
add_setshow_boolean_cmd ("boolean", class_maintenance,
|
add_setshow_boolean_cmd ("boolean", class_maintenance,
|
||||||
&maintenance_test_settings_boolean, _("\
|
&maintenance_test_settings_boolean, _("\
|
||||||
@@ -137,9 +126,9 @@ command used for internal testing"), _("\
|
|||||||
command used for internal testing"),
|
command used for internal testing"),
|
||||||
nullptr, /* help_doc */
|
nullptr, /* help_doc */
|
||||||
nullptr, /* set_cmd */
|
nullptr, /* set_cmd */
|
||||||
maintenance_test_settings_show_value_cmd,
|
maintenance_show_test_settings_value_cmd,
|
||||||
&maintenance_test_settings_set_list,
|
&maintenance_set_test_settings_list,
|
||||||
&maintenance_test_settings_show_list);
|
&maintenance_show_test_settings_list);
|
||||||
|
|
||||||
add_setshow_auto_boolean_cmd ("auto-boolean", class_maintenance,
|
add_setshow_auto_boolean_cmd ("auto-boolean", class_maintenance,
|
||||||
&maintenance_test_settings_auto_boolean, _("\
|
&maintenance_test_settings_auto_boolean, _("\
|
||||||
@@ -147,19 +136,19 @@ command used for internal testing"), _("\
|
|||||||
command used for internal testing"),
|
command used for internal testing"),
|
||||||
nullptr, /* help_doc */
|
nullptr, /* help_doc */
|
||||||
nullptr, /* set_cmd */
|
nullptr, /* set_cmd */
|
||||||
maintenance_test_settings_show_value_cmd,
|
maintenance_show_test_settings_value_cmd,
|
||||||
&maintenance_test_settings_set_list,
|
&maintenance_set_test_settings_list,
|
||||||
&maintenance_test_settings_show_list);
|
&maintenance_show_test_settings_list);
|
||||||
|
|
||||||
add_setshow_uinteger_cmd ("uinteger", class_maintenance,
|
add_setshow_uinteger_cmd ("uinteger", class_maintenance,
|
||||||
&maintenance_test_settings_uinteger, _("\
|
&maintenance_test_settings_uinteger, _("\
|
||||||
command used for internal testing"), _("\
|
command used for internal testing"), _("\
|
||||||
command used for internal testing"),
|
command used for internal testing"),
|
||||||
nullptr, /* help_doc */
|
nullptr, /* help_doc */
|
||||||
nullptr, /* set_cmd */
|
nullptr, /* set_cmd */
|
||||||
maintenance_test_settings_show_value_cmd,
|
maintenance_show_test_settings_value_cmd,
|
||||||
&maintenance_test_settings_set_list,
|
&maintenance_set_test_settings_list,
|
||||||
&maintenance_test_settings_show_list);
|
&maintenance_show_test_settings_list);
|
||||||
|
|
||||||
add_setshow_integer_cmd ("integer", class_maintenance,
|
add_setshow_integer_cmd ("integer", class_maintenance,
|
||||||
&maintenance_test_settings_integer, _("\
|
&maintenance_test_settings_integer, _("\
|
||||||
@@ -167,9 +156,9 @@ command used for internal testing"), _("\
|
|||||||
command used for internal testing"),
|
command used for internal testing"),
|
||||||
nullptr, /* help_doc */
|
nullptr, /* help_doc */
|
||||||
nullptr, /* set_cmd */
|
nullptr, /* set_cmd */
|
||||||
maintenance_test_settings_show_value_cmd,
|
maintenance_show_test_settings_value_cmd,
|
||||||
&maintenance_test_settings_set_list,
|
&maintenance_set_test_settings_list,
|
||||||
&maintenance_test_settings_show_list);
|
&maintenance_show_test_settings_list);
|
||||||
|
|
||||||
add_setshow_string_cmd ("string", class_maintenance,
|
add_setshow_string_cmd ("string", class_maintenance,
|
||||||
&maintenance_test_settings_string, _("\
|
&maintenance_test_settings_string, _("\
|
||||||
@@ -177,9 +166,9 @@ command used for internal testing"), _("\
|
|||||||
command used for internal testing"),
|
command used for internal testing"),
|
||||||
nullptr, /* help_doc */
|
nullptr, /* help_doc */
|
||||||
nullptr, /* set_cmd */
|
nullptr, /* set_cmd */
|
||||||
maintenance_test_settings_show_value_cmd,
|
maintenance_show_test_settings_value_cmd,
|
||||||
&maintenance_test_settings_set_list,
|
&maintenance_set_test_settings_list,
|
||||||
&maintenance_test_settings_show_list);
|
&maintenance_show_test_settings_list);
|
||||||
|
|
||||||
add_setshow_string_noescape_cmd
|
add_setshow_string_noescape_cmd
|
||||||
("string-noescape", class_maintenance,
|
("string-noescape", class_maintenance,
|
||||||
@@ -188,9 +177,9 @@ command used for internal testing"), _("\
|
|||||||
command used for internal testing"),
|
command used for internal testing"),
|
||||||
nullptr, /* help_doc */
|
nullptr, /* help_doc */
|
||||||
nullptr, /* set_cmd */
|
nullptr, /* set_cmd */
|
||||||
maintenance_test_settings_show_value_cmd,
|
maintenance_show_test_settings_value_cmd,
|
||||||
&maintenance_test_settings_set_list,
|
&maintenance_set_test_settings_list,
|
||||||
&maintenance_test_settings_show_list);
|
&maintenance_show_test_settings_list);
|
||||||
|
|
||||||
add_setshow_optional_filename_cmd
|
add_setshow_optional_filename_cmd
|
||||||
("optional-filename", class_maintenance,
|
("optional-filename", class_maintenance,
|
||||||
@@ -199,9 +188,9 @@ command used for internal testing"), _("\
|
|||||||
command used for internal testing"),
|
command used for internal testing"),
|
||||||
nullptr, /* help_doc */
|
nullptr, /* help_doc */
|
||||||
nullptr, /* set_cmd */
|
nullptr, /* set_cmd */
|
||||||
maintenance_test_settings_show_value_cmd,
|
maintenance_show_test_settings_value_cmd,
|
||||||
&maintenance_test_settings_set_list,
|
&maintenance_set_test_settings_list,
|
||||||
&maintenance_test_settings_show_list);
|
&maintenance_show_test_settings_list);
|
||||||
|
|
||||||
add_setshow_filename_cmd ("filename", class_maintenance,
|
add_setshow_filename_cmd ("filename", class_maintenance,
|
||||||
&maintenance_test_settings_filename, _("\
|
&maintenance_test_settings_filename, _("\
|
||||||
@@ -209,9 +198,9 @@ command used for internal testing"), _("\
|
|||||||
command used for internal testing"),
|
command used for internal testing"),
|
||||||
nullptr, /* help_doc */
|
nullptr, /* help_doc */
|
||||||
nullptr, /* set_cmd */
|
nullptr, /* set_cmd */
|
||||||
maintenance_test_settings_show_value_cmd,
|
maintenance_show_test_settings_value_cmd,
|
||||||
&maintenance_test_settings_set_list,
|
&maintenance_set_test_settings_list,
|
||||||
&maintenance_test_settings_show_list);
|
&maintenance_show_test_settings_list);
|
||||||
|
|
||||||
add_setshow_zinteger_cmd ("zinteger", class_maintenance,
|
add_setshow_zinteger_cmd ("zinteger", class_maintenance,
|
||||||
&maintenance_test_settings_zinteger, _("\
|
&maintenance_test_settings_zinteger, _("\
|
||||||
@@ -219,9 +208,9 @@ command used for internal testing"), _("\
|
|||||||
command used for internal testing"),
|
command used for internal testing"),
|
||||||
nullptr, /* help_doc */
|
nullptr, /* help_doc */
|
||||||
nullptr, /* set_cmd */
|
nullptr, /* set_cmd */
|
||||||
maintenance_test_settings_show_value_cmd,
|
maintenance_show_test_settings_value_cmd,
|
||||||
&maintenance_test_settings_set_list,
|
&maintenance_set_test_settings_list,
|
||||||
&maintenance_test_settings_show_list);
|
&maintenance_show_test_settings_list);
|
||||||
|
|
||||||
add_setshow_zuinteger_cmd ("zuinteger", class_maintenance,
|
add_setshow_zuinteger_cmd ("zuinteger", class_maintenance,
|
||||||
&maintenance_test_settings_zuinteger, _("\
|
&maintenance_test_settings_zuinteger, _("\
|
||||||
@@ -229,9 +218,9 @@ command used for internal testing"), _("\
|
|||||||
command used for internal testing"),
|
command used for internal testing"),
|
||||||
nullptr, /* help_doc */
|
nullptr, /* help_doc */
|
||||||
nullptr, /* set_cmd */
|
nullptr, /* set_cmd */
|
||||||
maintenance_test_settings_show_value_cmd,
|
maintenance_show_test_settings_value_cmd,
|
||||||
&maintenance_test_settings_set_list,
|
&maintenance_set_test_settings_list,
|
||||||
&maintenance_test_settings_show_list);
|
&maintenance_show_test_settings_list);
|
||||||
|
|
||||||
add_setshow_zuinteger_unlimited_cmd
|
add_setshow_zuinteger_unlimited_cmd
|
||||||
("zuinteger-unlimited", class_maintenance,
|
("zuinteger-unlimited", class_maintenance,
|
||||||
@@ -240,9 +229,9 @@ command used for internal testing"), _("\
|
|||||||
command used for internal testing"),
|
command used for internal testing"),
|
||||||
nullptr, /* help_doc */
|
nullptr, /* help_doc */
|
||||||
nullptr, /* set_cmd */
|
nullptr, /* set_cmd */
|
||||||
maintenance_test_settings_show_value_cmd,
|
maintenance_show_test_settings_value_cmd,
|
||||||
&maintenance_test_settings_set_list,
|
&maintenance_set_test_settings_list,
|
||||||
&maintenance_test_settings_show_list);
|
&maintenance_show_test_settings_list);
|
||||||
|
|
||||||
add_setshow_enum_cmd ("enum", class_maintenance,
|
add_setshow_enum_cmd ("enum", class_maintenance,
|
||||||
maintenance_test_settings_enums,
|
maintenance_test_settings_enums,
|
||||||
@@ -251,7 +240,7 @@ command used for internal testing"), _("\
|
|||||||
command used for internal testing"),
|
command used for internal testing"),
|
||||||
nullptr, /* help_doc */
|
nullptr, /* help_doc */
|
||||||
nullptr, /* set_cmd */
|
nullptr, /* set_cmd */
|
||||||
maintenance_test_settings_show_value_cmd,
|
maintenance_show_test_settings_value_cmd,
|
||||||
&maintenance_test_settings_set_list,
|
&maintenance_set_test_settings_list,
|
||||||
&maintenance_test_settings_show_list);
|
&maintenance_show_test_settings_list);
|
||||||
}
|
}
|
||||||
|
|||||||
28
gdb/maint.c
28
gdb/maint.c
@@ -43,6 +43,7 @@
|
|||||||
#include "cli/cli-decode.h"
|
#include "cli/cli-decode.h"
|
||||||
#include "cli/cli-utils.h"
|
#include "cli/cli-utils.h"
|
||||||
#include "cli/cli-setshow.h"
|
#include "cli/cli-setshow.h"
|
||||||
|
#include "cli/cli-cmds.h"
|
||||||
|
|
||||||
static void maintenance_do_deprecate (const char *, int);
|
static void maintenance_do_deprecate (const char *, int);
|
||||||
|
|
||||||
@@ -634,6 +635,24 @@ maintenance_show_cmd (const char *args, int from_tty)
|
|||||||
cmd_show_list (maintenance_show_cmdlist, from_tty, "");
|
cmd_show_list (maintenance_show_cmdlist, from_tty, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* "maintenance with" command. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
maintenance_with_cmd (const char *args, int from_tty)
|
||||||
|
{
|
||||||
|
with_command_1 ("maintenance set ", maintenance_set_cmdlist, args, from_tty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "maintenance with" command completer. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
maintenance_with_cmd_completer (struct cmd_list_element *ignore,
|
||||||
|
completion_tracker &tracker,
|
||||||
|
const char *text, const char * /*word*/)
|
||||||
|
{
|
||||||
|
with_command_completer_1 ("maintenance set ", tracker, text);
|
||||||
|
}
|
||||||
|
|
||||||
/* Profiling support. */
|
/* Profiling support. */
|
||||||
|
|
||||||
static int maintenance_profile_p;
|
static int maintenance_profile_p;
|
||||||
@@ -1023,6 +1042,15 @@ Configure variables internal to GDB that aid in GDB's maintenance"),
|
|||||||
0/*allow-unknown*/,
|
0/*allow-unknown*/,
|
||||||
&maintenancelist);
|
&maintenancelist);
|
||||||
|
|
||||||
|
cmd = add_cmd ("with", class_maintenance, maintenance_with_cmd, _("\
|
||||||
|
Like \"with\", but works with \"maintenance set\" variables.\n\
|
||||||
|
Usage: maintenance with SETTING [VALUE] [-- COMMAND]\n\
|
||||||
|
With no COMMAND, repeats the last executed command.\n\
|
||||||
|
SETTING is any setting you can change with the \"maintenance set\"\n\
|
||||||
|
subcommands."),
|
||||||
|
&maintenancelist);
|
||||||
|
set_cmd_completer_handle_brkchars (cmd, maintenance_with_cmd_completer);
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
add_cmd ("dump-me", class_maintenance, maintenance_dump_me, _("\
|
add_cmd ("dump-me", class_maintenance, maintenance_dump_me, _("\
|
||||||
Get fatal error; make debugger dump its core.\n\
|
Get fatal error; make debugger dump its core.\n\
|
||||||
|
|||||||
@@ -454,6 +454,21 @@ proc_with_prefix test-thread-apply {} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Basic option-machinery + "info threads" command integration tests.
|
||||||
|
proc_with_prefix test-info-threads {} {
|
||||||
|
test_gdb_complete_multiple "info threads " "" "" {
|
||||||
|
"-gid"
|
||||||
|
"ID"
|
||||||
|
}
|
||||||
|
|
||||||
|
test_gdb_complete_unique \
|
||||||
|
"info threads -" \
|
||||||
|
"info threads -gid"
|
||||||
|
|
||||||
|
# "ID" isn't really something the user can type.
|
||||||
|
test_gdb_complete_none "info threads I"
|
||||||
|
}
|
||||||
|
|
||||||
# Miscellaneous tests.
|
# Miscellaneous tests.
|
||||||
proc_with_prefix test-misc {variant} {
|
proc_with_prefix test-misc {variant} {
|
||||||
global all_options
|
global all_options
|
||||||
@@ -921,3 +936,6 @@ test-frame-apply
|
|||||||
|
|
||||||
# Basic "thread apply" integration tests.
|
# Basic "thread apply" integration tests.
|
||||||
test-thread-apply
|
test-thread-apply
|
||||||
|
|
||||||
|
# Basic "info threads" integration tests.
|
||||||
|
test-info-threads
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ proc show_setting {show_cmd expected_re} {
|
|||||||
# var_Xinteger tests. VARIANT determines which command/variant to
|
# var_Xinteger tests. VARIANT determines which command/variant to
|
||||||
# exercise.
|
# exercise.
|
||||||
proc test-integer {variant} {
|
proc test-integer {variant} {
|
||||||
set set_cmd "maint test-settings set $variant"
|
set set_cmd "maint set test-settings $variant"
|
||||||
set show_cmd "maint test-settings show $variant"
|
set show_cmd "maint show test-settings $variant"
|
||||||
|
|
||||||
# A bogus value.
|
# A bogus value.
|
||||||
gdb_test "$set_cmd bogus" \
|
gdb_test "$set_cmd bogus" \
|
||||||
@@ -122,7 +122,7 @@ proc test-integer {variant} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if {$variant == "zuinteger"} {
|
if {$variant == "zuinteger"} {
|
||||||
test_gdb_complete_multiple "maint test-settings set " "zuinteger" "" {
|
test_gdb_complete_multiple "maint set test-settings " "zuinteger" "" {
|
||||||
"zuinteger"
|
"zuinteger"
|
||||||
"zuinteger-unlimited"
|
"zuinteger-unlimited"
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,7 @@ proc test-integer {variant} {
|
|||||||
|
|
||||||
# Check show command completion.
|
# Check show command completion.
|
||||||
if {$variant == "zuinteger"} {
|
if {$variant == "zuinteger"} {
|
||||||
test_gdb_complete_multiple "maintenance test-settings show " "zuinteger" "" {
|
test_gdb_complete_multiple "maintenance show test-settings " "zuinteger" "" {
|
||||||
"zuinteger"
|
"zuinteger"
|
||||||
"zuinteger-unlimited"
|
"zuinteger-unlimited"
|
||||||
}
|
}
|
||||||
@@ -182,8 +182,8 @@ proc test-integer {variant} {
|
|||||||
proc_with_prefix test-boolean {} {
|
proc_with_prefix test-boolean {} {
|
||||||
# Use these variables to make sure we don't call the wrong command
|
# Use these variables to make sure we don't call the wrong command
|
||||||
# by mistake.
|
# by mistake.
|
||||||
set set_cmd "maint test-settings set boolean"
|
set set_cmd "maint set test-settings boolean"
|
||||||
set show_cmd "maint test-settings show boolean"
|
set show_cmd "maint show test-settings boolean"
|
||||||
|
|
||||||
# A bogus value.
|
# A bogus value.
|
||||||
gdb_test "$set_cmd bogus" \
|
gdb_test "$set_cmd bogus" \
|
||||||
@@ -277,8 +277,8 @@ proc_with_prefix test-boolean {} {
|
|||||||
proc_with_prefix test-auto-boolean {} {
|
proc_with_prefix test-auto-boolean {} {
|
||||||
# Use these variables to make sure we don't call the wrong command
|
# Use these variables to make sure we don't call the wrong command
|
||||||
# by mistake.
|
# by mistake.
|
||||||
set set_cmd "maint test-settings set auto-boolean"
|
set set_cmd "maint set test-settings auto-boolean"
|
||||||
set show_cmd "maint test-settings show auto-boolean"
|
set show_cmd "maint show test-settings auto-boolean"
|
||||||
|
|
||||||
# A bogus value.
|
# A bogus value.
|
||||||
gdb_test "$set_cmd bogus" \
|
gdb_test "$set_cmd bogus" \
|
||||||
@@ -381,8 +381,8 @@ proc_with_prefix test-auto-boolean {} {
|
|||||||
proc_with_prefix test-enum {} {
|
proc_with_prefix test-enum {} {
|
||||||
# Use these variables to make sure we don't call the wrong command
|
# Use these variables to make sure we don't call the wrong command
|
||||||
# by mistake.
|
# by mistake.
|
||||||
set set_cmd "maint test-settings set enum"
|
set set_cmd "maint set test-settings enum"
|
||||||
set show_cmd "maint test-settings show enum"
|
set show_cmd "maint show test-settings enum"
|
||||||
|
|
||||||
# Missing value.
|
# Missing value.
|
||||||
gdb_test "$set_cmd" \
|
gdb_test "$set_cmd" \
|
||||||
@@ -444,12 +444,15 @@ proc test-string {variant} {
|
|||||||
|
|
||||||
# Use these variables to make sure we don't call the wrong command
|
# Use these variables to make sure we don't call the wrong command
|
||||||
# by mistake.
|
# by mistake.
|
||||||
set set_cmd "maint test-settings set $variant"
|
set set_cmd "maint set test-settings $variant"
|
||||||
set show_cmd "maint test-settings show $variant"
|
set show_cmd "maint show test-settings $variant"
|
||||||
|
|
||||||
# Empty string. Also checks that gdb doesn't crash if we haven't
|
# Checks that gdb doesn't crash if we haven't set the string yet.
|
||||||
# set the string yet.
|
if {$variant != "filename"} {
|
||||||
gdb_test "$show_cmd" "^$show_cmd\r\n" "$show_cmd: empty first time"
|
gdb_test "$show_cmd" "^$show_cmd\r\n" "$show_cmd: show default"
|
||||||
|
} else {
|
||||||
|
gdb_test "$show_cmd" "/foo/bar" "$show_cmd: show default"
|
||||||
|
}
|
||||||
|
|
||||||
# A string value.
|
# A string value.
|
||||||
gdb_test_no_output "$set_cmd hello world"
|
gdb_test_no_output "$set_cmd hello world"
|
||||||
@@ -516,7 +519,7 @@ proc test-string {variant} {
|
|||||||
|
|
||||||
# Check show command completion.
|
# Check show command completion.
|
||||||
if {$variant == "string"} {
|
if {$variant == "string"} {
|
||||||
test_gdb_complete_multiple "maint test-settings show " "string" "" {
|
test_gdb_complete_multiple "maint show test-settings " "string" "" {
|
||||||
"string"
|
"string"
|
||||||
"string-noescape"
|
"string-noescape"
|
||||||
}
|
}
|
||||||
|
|||||||
41
gdb/testsuite/gdb.base/with.c
Normal file
41
gdb/testsuite/gdb.base/with.c
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/* This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2019 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
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
int xxx1 = 123;
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
int c;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S g_s = {1, 2, 3};
|
||||||
|
|
||||||
|
static void
|
||||||
|
inc ()
|
||||||
|
{
|
||||||
|
g_s.a++;;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
inc ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
289
gdb/testsuite/gdb.base/with.exp
Normal file
289
gdb/testsuite/gdb.base/with.exp
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
# This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
# Copyright 2019 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
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Test the "with" command.
|
||||||
|
|
||||||
|
load_lib completion-support.exp
|
||||||
|
|
||||||
|
standard_testfile .c
|
||||||
|
|
||||||
|
if {[build_executable "failed to prepare" $testfile $srcfile debug]} {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
clean_restart $binfile
|
||||||
|
|
||||||
|
# Test "maint with". VALUES is a list of values. A nested "with" is
|
||||||
|
# performed with each combination of pair of values from this list.
|
||||||
|
# This exercises setting a value, and restoring it too. This is
|
||||||
|
# particularly important for the "special" values like "unlimited",
|
||||||
|
# which for example for var_uinteger maps to 0 at the user-visible
|
||||||
|
# level, but maps to -1 internally.
|
||||||
|
|
||||||
|
proc test_with {setting values} {
|
||||||
|
foreach val1 $values {
|
||||||
|
foreach val2 $values {
|
||||||
|
gdb_test \
|
||||||
|
"maint with test-settings $setting $val1 -- maint with test-settings $setting $val2 -- p 1" \
|
||||||
|
" = 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test "maint with" in the error case. SETTING is the "maint set
|
||||||
|
# test-setting" setting to exercise. TMP_VAL is the value to set the
|
||||||
|
# setting to. EXPECTED_RE is the expected GDB output, which should be
|
||||||
|
# an error of some kind. Also checks that the setting's original
|
||||||
|
# value is preserved across the error.
|
||||||
|
|
||||||
|
proc test_with_error {setting tmp_val expected_re} {
|
||||||
|
global gdb_prompt
|
||||||
|
|
||||||
|
with_test_prefix "$setting, $tmp_val" {
|
||||||
|
set test "save org value"
|
||||||
|
set org_val ""
|
||||||
|
gdb_test_multiple "maint show test-settings $setting" $test {
|
||||||
|
-re "(.*)\r\n$gdb_prompt $" {
|
||||||
|
set org_val $expect_out(1,string)
|
||||||
|
pass $test
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_test \
|
||||||
|
"maint with test-settings $setting $tmp_val -- p 1" \
|
||||||
|
$expected_re
|
||||||
|
|
||||||
|
gdb_test "maint show test-settings $setting" "^$org_val" \
|
||||||
|
"value hasn't changed across error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test "with" framework basics, using the internal "maint with
|
||||||
|
# test-settings" subcommands.
|
||||||
|
with_test_prefix "maint" {
|
||||||
|
test_with "auto-boolean" {"on" "off" "auto"}
|
||||||
|
test_with "boolean" {"" "on" "off" "0" "1" "enable" "disable"}
|
||||||
|
test_with "integer" {"0" "1" "-1" "unlimited"}
|
||||||
|
test_with "uinteger" {"0" "1" "unlimited"}
|
||||||
|
test_with "zinteger" {"0" "1" "-1"}
|
||||||
|
test_with "zuinteger" {"0" "1"}
|
||||||
|
test_with "zuinteger-unlimited" {"-1" "unlimited" "0" "1"}
|
||||||
|
test_with "string" {"" "foo" "\"hello world\""}
|
||||||
|
test_with "string-noescape" {"" "foo" "\"hello world\""}
|
||||||
|
test_with "filename" {"/foo" "bar/x/y"}
|
||||||
|
test_with "optional-filename" {"" "/foo" "bar/x/y"}
|
||||||
|
test_with "enum" {"xxx" "yyy"}
|
||||||
|
|
||||||
|
# Check the most important error conditions. E.g., empty,
|
||||||
|
# negative or "unlimited" values for settings that don't accept
|
||||||
|
# those. Exhaustive error coverage of the set/with value parsing
|
||||||
|
# is left to "set" testing, in gdb.base/settings.exp.
|
||||||
|
test_with_error "auto-boolean" "" \
|
||||||
|
"\"on\", \"off\" or \"auto\" expected\\."
|
||||||
|
test_with_error "auto-boolean" "xxx" \
|
||||||
|
"\"on\", \"off\" or \"auto\" expected\\."
|
||||||
|
test_with_error "boolean" "2" "\"on\" or \"off\" expected\\."
|
||||||
|
test_with_error "uinteger" "-1" "integer -1 out of range"
|
||||||
|
test_with_error "uinteger" "" \
|
||||||
|
"Argument required \\(integer to set it to, or \"unlimited\"\\.\\)\\."
|
||||||
|
test_with_error "zuinteger" "-1" "integer -1 out of range"
|
||||||
|
test_with_error "zuinteger" "" \
|
||||||
|
"Argument required \\(integer to set it to\\.\\)\\."
|
||||||
|
test_with_error "zuinteger-unlimited" "-2" \
|
||||||
|
"only -1 is allowed to set as unlimited"
|
||||||
|
test_with_error "zuinteger-unlimited" "" \
|
||||||
|
"Argument required \\(integer to set it to, or \"unlimited\"\\.\\)\\."
|
||||||
|
test_with_error "filename" "" \
|
||||||
|
"Argument required \\(filename to set it to\\.\\)\\."
|
||||||
|
test_with_error "enum" "" \
|
||||||
|
"Requires an argument\\. Valid arguments are xxx, yyy, zzz\\."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Basic/core tests using user-visible commands.
|
||||||
|
with_test_prefix "basics" {
|
||||||
|
gdb_test "print g_s" " = {a = 1, b = 2, c = 3}"
|
||||||
|
gdb_test "with print pretty -- print g_s" \
|
||||||
|
[multi_line \
|
||||||
|
" = {" \
|
||||||
|
" a = 1," \
|
||||||
|
" b = 2," \
|
||||||
|
" c = 3" \
|
||||||
|
"}"]
|
||||||
|
|
||||||
|
# A boolean setting.
|
||||||
|
gdb_test "with non-stop on -- show non-stop" \
|
||||||
|
"Controlling the inferior in non-stop mode is on\\."
|
||||||
|
gdb_test "show non-stop" \
|
||||||
|
"Controlling the inferior in non-stop mode is off\\."
|
||||||
|
|
||||||
|
# Language.
|
||||||
|
gdb_test "with language pascal -- show language" \
|
||||||
|
"The current source language is \"pascal\"\\."
|
||||||
|
|
||||||
|
gdb_test "show language" \
|
||||||
|
"The current source language is \"auto; currently c\"\\."
|
||||||
|
|
||||||
|
gdb_test "with language ada -- print g_s" \
|
||||||
|
" = \\(a => 1, b => 2, c => 3\\)"
|
||||||
|
|
||||||
|
# Nested "with"s.
|
||||||
|
gdb_test "with language ada -- with language c -- print g_s" \
|
||||||
|
" = {a = 1, b = 2, c = 3}"
|
||||||
|
|
||||||
|
# "w" alias.
|
||||||
|
gdb_test "w language pascal -- show language" \
|
||||||
|
"The current source language is \"pascal\"\\." \
|
||||||
|
"w alias works"
|
||||||
|
|
||||||
|
# An early prototype of the "with" command got this wrong.
|
||||||
|
gdb_test \
|
||||||
|
"w print repeats unlimited -- w print repeats 1 -- p \"1223334444\"" \
|
||||||
|
" = \"1\", '2' <repeats 2 times>, '3' <repeats 3 times>, '4' <repeats 4 times>"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check a user-defined command.
|
||||||
|
with_test_prefix "user-defined" {
|
||||||
|
# A user defined command.
|
||||||
|
set test "define usercmd"
|
||||||
|
gdb_test_multiple "define usercmd" $test {
|
||||||
|
-re "End with" {
|
||||||
|
gdb_test \
|
||||||
|
[multi_line_input \
|
||||||
|
{print g_s} \
|
||||||
|
{end}] \
|
||||||
|
"" \
|
||||||
|
$test
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gdb_test "with language ada -- usercmd" \
|
||||||
|
" = \\(a => 1, b => 2, c => 3\\)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check repeating.
|
||||||
|
with_test_prefix "repeat" {
|
||||||
|
clean_restart $binfile
|
||||||
|
|
||||||
|
# "with" with no command reinvokes the previous command.
|
||||||
|
gdb_test "with language ada" \
|
||||||
|
"No previous command to relaunch" \
|
||||||
|
"reinvoke with no previous command to relaunch"
|
||||||
|
|
||||||
|
gdb_test "print g_s" " = {a = 1, b = 2, c = 3}"
|
||||||
|
|
||||||
|
gdb_test "with language ada" \
|
||||||
|
" = \\(a => 1, b => 2, c => 3\\)" \
|
||||||
|
"reinvoke with language"
|
||||||
|
|
||||||
|
# Same, but with "--".
|
||||||
|
gdb_test "with language fortran --" \
|
||||||
|
" = \\( a = 1, b = 2, c = 3 \\)" \
|
||||||
|
"reinvoke with language and --"
|
||||||
|
|
||||||
|
# Repeating repeats the original "print g_s", not the last "with"
|
||||||
|
# command.
|
||||||
|
set test "repeat command line"
|
||||||
|
send_gdb "\n"
|
||||||
|
gdb_test_multiple "" $test {
|
||||||
|
-re " = {a = 1, b = 2, c = 3}\r\n$gdb_prompt $" {
|
||||||
|
pass $test
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Basic run control.
|
||||||
|
with_test_prefix "run control" {
|
||||||
|
clean_restart $binfile
|
||||||
|
|
||||||
|
if ![runto_main] {
|
||||||
|
fail "cannot run to main"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check "with" with a synchronous execution command.
|
||||||
|
gdb_test "with disassemble-next-line on -- next" \
|
||||||
|
"return 0;.*=>.*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check errors.
|
||||||
|
with_test_prefix "errors" {
|
||||||
|
# Try both an unknown root setting and an unknown prefixed
|
||||||
|
# setting. The errors come from different locations in the
|
||||||
|
# sources.
|
||||||
|
gdb_test "with xxxx yyyy" \
|
||||||
|
"Undefined set command: \"xxxx\". Try \"help set\"\\."
|
||||||
|
gdb_test "with print xxxx yyyy" \
|
||||||
|
"Undefined set print command: \"xxxx yyyy\". Try \"help set print\"\\."
|
||||||
|
# Try one error case for "maint with", to make sure the right
|
||||||
|
# "maintenance with" prefix is shown.
|
||||||
|
gdb_test "maint with xxxx yyyy" \
|
||||||
|
"Undefined maintenance set command: \"xxxx\". Try \"help maintenance set\"\\."
|
||||||
|
|
||||||
|
# Try ambiguous settings.
|
||||||
|
gdb_test "with w" \
|
||||||
|
"Ambiguous set command \"w\": watchdog, width, write\\."
|
||||||
|
gdb_test "with print m" \
|
||||||
|
"Ambiguous set print command \"m\": max-depth, max-symbolic-offset\\."
|
||||||
|
|
||||||
|
gdb_test "with variable xxx=1" \
|
||||||
|
"Cannot use this setting with the \"with\" command"
|
||||||
|
|
||||||
|
gdb_test "with print elements -- p 1" \
|
||||||
|
"Argument required \\(integer to set it to, or \"unlimited\"\\.\\)\\."
|
||||||
|
|
||||||
|
gdb_test "with -- p 1" \
|
||||||
|
"Missing setting before '--' delimiter"
|
||||||
|
|
||||||
|
# Check that the setting is restored even if the command throws.
|
||||||
|
gdb_test "with print elements 1 -- unknowncommand" \
|
||||||
|
"Undefined command: \"unknowncommand\"\\. Try \"help\"\\."
|
||||||
|
gdb_test "show print elements" \
|
||||||
|
"Limit on string chars or array elements to print is 200\\."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check completion.
|
||||||
|
with_test_prefix "completion" {
|
||||||
|
test_gdb_complete_unique \
|
||||||
|
"with pri" \
|
||||||
|
"with print"
|
||||||
|
|
||||||
|
test_gdb_complete_unique \
|
||||||
|
"with print ele" \
|
||||||
|
"with print elements"
|
||||||
|
|
||||||
|
test_gdb_complete_unique \
|
||||||
|
"with print elements u" \
|
||||||
|
"with print elements unlimited"
|
||||||
|
|
||||||
|
test_gdb_complete_none \
|
||||||
|
"with print elements unlimited "
|
||||||
|
|
||||||
|
test_gdb_completion_offers_commands "with print elements unlimited -- "
|
||||||
|
|
||||||
|
# Check that the completer nests into the nested command line's
|
||||||
|
# completer.
|
||||||
|
test_gdb_complete_unique \
|
||||||
|
"with print elements unlimited -- with print ele" \
|
||||||
|
"with print elements unlimited -- with print elements"
|
||||||
|
|
||||||
|
# Check completion of "maint with". "maint with" and "with"'s
|
||||||
|
# completers share 99% of the code. All we need to care about
|
||||||
|
# here is that the completion word point is computed correctly, so
|
||||||
|
# any simple completion is sufficient.
|
||||||
|
test_gdb_complete_unique \
|
||||||
|
"maint with test-set" \
|
||||||
|
"maint with test-settings"
|
||||||
|
}
|
||||||
82
gdb/thread.c
82
gdb/thread.c
@@ -1199,6 +1199,33 @@ print_thread_info (struct ui_out *uiout, const char *requested_threads,
|
|||||||
print_thread_info_1 (uiout, requested_threads, 1, pid, 0);
|
print_thread_info_1 (uiout, requested_threads, 1, pid, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The options for the "info threads" command. */
|
||||||
|
|
||||||
|
struct info_threads_opts
|
||||||
|
{
|
||||||
|
/* For "-gid". */
|
||||||
|
int show_global_ids = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const gdb::option::option_def info_threads_option_defs[] = {
|
||||||
|
|
||||||
|
gdb::option::flag_option_def<info_threads_opts> {
|
||||||
|
"gid",
|
||||||
|
[] (info_threads_opts *opts) { return &opts->show_global_ids; },
|
||||||
|
N_("Show global thread IDs."),
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Create an option_def_group for the "info threads" options, with
|
||||||
|
IT_OPTS as context. */
|
||||||
|
|
||||||
|
static inline gdb::option::option_def_group
|
||||||
|
make_info_threads_options_def_group (info_threads_opts *it_opts)
|
||||||
|
{
|
||||||
|
return {{info_threads_option_defs}, it_opts};
|
||||||
|
}
|
||||||
|
|
||||||
/* Implementation of the "info threads" command.
|
/* Implementation of the "info threads" command.
|
||||||
|
|
||||||
Note: this has the drawback that it _really_ switches
|
Note: this has the drawback that it _really_ switches
|
||||||
@@ -1208,16 +1235,36 @@ print_thread_info (struct ui_out *uiout, const char *requested_threads,
|
|||||||
static void
|
static void
|
||||||
info_threads_command (const char *arg, int from_tty)
|
info_threads_command (const char *arg, int from_tty)
|
||||||
{
|
{
|
||||||
int show_global_ids = 0;
|
info_threads_opts it_opts;
|
||||||
|
|
||||||
if (arg != NULL
|
auto grp = make_info_threads_options_def_group (&it_opts);
|
||||||
&& check_for_argument (&arg, "-gid", sizeof ("-gid") - 1))
|
gdb::option::process_options
|
||||||
|
(&arg, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp);
|
||||||
|
|
||||||
|
print_thread_info_1 (current_uiout, arg, 0, -1, it_opts.show_global_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Completer for the "info threads" command. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
info_threads_command_completer (struct cmd_list_element *ignore,
|
||||||
|
completion_tracker &tracker,
|
||||||
|
const char *text, const char *word_ignored)
|
||||||
|
{
|
||||||
|
const auto grp = make_info_threads_options_def_group (nullptr);
|
||||||
|
|
||||||
|
if (gdb::option::complete_options
|
||||||
|
(tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Convenience to let the user know what the option can accept. */
|
||||||
|
if (*text == '\0')
|
||||||
{
|
{
|
||||||
arg = skip_spaces (arg);
|
gdb::option::complete_on_all_options (tracker, grp);
|
||||||
show_global_ids = 1;
|
/* Keep this "ID" in sync with what "help info threads"
|
||||||
|
says. */
|
||||||
|
tracker.add_completion (make_unique_xstrdup ("ID"));
|
||||||
}
|
}
|
||||||
|
|
||||||
print_thread_info_1 (current_uiout, arg, 0, -1, show_global_ids);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See gdbthread.h. */
|
/* See gdbthread.h. */
|
||||||
@@ -2068,12 +2115,23 @@ _initialize_thread (void)
|
|||||||
static struct cmd_list_element *thread_apply_list = NULL;
|
static struct cmd_list_element *thread_apply_list = NULL;
|
||||||
cmd_list_element *c;
|
cmd_list_element *c;
|
||||||
|
|
||||||
add_info ("threads", info_threads_command,
|
const auto info_threads_opts = make_info_threads_options_def_group (nullptr);
|
||||||
_("Display currently known threads.\n\
|
|
||||||
Usage: info threads [-gid] [ID]...\n\
|
/* Note: keep this "ID" in sync with what "info threads [TAB]"
|
||||||
-gid: Show global thread IDs.\n\
|
suggests. */
|
||||||
|
static std::string info_threads_help
|
||||||
|
= gdb::option::build_help (_("\
|
||||||
|
Display currently known threads.\n\
|
||||||
|
Usage: info threads [OPTION]... [ID]...\n\
|
||||||
|
\n\
|
||||||
|
Options:\n\
|
||||||
|
%OPTIONS%\
|
||||||
If ID is given, it is a space-separated list of IDs of threads to display.\n\
|
If ID is given, it is a space-separated list of IDs of threads to display.\n\
|
||||||
Otherwise, all threads are displayed."));
|
Otherwise, all threads are displayed."),
|
||||||
|
info_threads_opts);
|
||||||
|
|
||||||
|
c = add_info ("threads", info_threads_command, info_threads_help.c_str ());
|
||||||
|
set_cmd_completer_handle_brkchars (c, info_threads_command_completer);
|
||||||
|
|
||||||
add_prefix_cmd ("thread", class_run, thread_command, _("\
|
add_prefix_cmd ("thread", class_run, thread_command, _("\
|
||||||
Use this command to switch between threads.\n\
|
Use this command to switch between threads.\n\
|
||||||
|
|||||||
@@ -735,7 +735,7 @@ dont_repeat (void)
|
|||||||
|
|
||||||
/* See command.h */
|
/* See command.h */
|
||||||
|
|
||||||
void
|
const char *
|
||||||
repeat_previous ()
|
repeat_previous ()
|
||||||
{
|
{
|
||||||
/* Do not repeat this command, as this command is a repeating command. */
|
/* Do not repeat this command, as this command is a repeating command. */
|
||||||
@@ -745,6 +745,11 @@ repeat_previous ()
|
|||||||
so swap it with previous_saved_command_line. */
|
so swap it with previous_saved_command_line. */
|
||||||
std::swap (previous_saved_command_line, saved_command_line);
|
std::swap (previous_saved_command_line, saved_command_line);
|
||||||
std::swap (previous_repeat_arguments, repeat_arguments);
|
std::swap (previous_repeat_arguments, repeat_arguments);
|
||||||
|
|
||||||
|
const char *prev = skip_spaces (get_saved_command_line ());
|
||||||
|
if (*prev == '\0')
|
||||||
|
error (_("No previous command to relaunch"));
|
||||||
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See command.h. */
|
/* See command.h. */
|
||||||
|
|||||||
Reference in New Issue
Block a user