pipe command completer
This commit adds a completer for the "pipe" command. It can complete "pipe"'s options, and the specified GDB command. To make the completer aware of the "-d" option, this converts the option processing to use gdb::option. Tests included. gdb/ChangeLog: 2019-07-03 Pedro Alves <palves@redhat.com> PR cli/24732 * cli/cli-cmds.c (struct pipe_cmd_opts): New. (pipe_cmd_option_defs): New. (make_pipe_cmd_options_def_group): New. (pipe_command): Use gdb::option::process_options. (pipe_command_completer): New function. (_initialize_cli_cmds): Install completer for "pipe" command. gdb/testsuite/ChangeLog: 2019-07-03 Pedro Alves <palves@redhat.com> PR cli/24732 * gdb.base/shell.exp: Load completion-support.exp. Adjust expected error output. Add completion tests.
This commit is contained in:
parent
a994424fa1
commit
5f4ba3e701
4 changed files with 144 additions and 11 deletions
|
@ -1,3 +1,13 @@
|
|||
2019-07-03 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR cli/24732
|
||||
* cli/cli-cmds.c (struct pipe_cmd_opts): New.
|
||||
(pipe_cmd_option_defs): New.
|
||||
(make_pipe_cmd_options_def_group): New.
|
||||
(pipe_command): Use gdb::option::process_options.
|
||||
(pipe_command_completer): New function.
|
||||
(_initialize_cli_cmds): Install completer for "pipe" command.
|
||||
|
||||
2019-07-03 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* cli/cli-option.c (union option_value) <string>: New field.
|
||||
|
|
|
@ -960,32 +960,68 @@ edit_command (const char *arg, int from_tty)
|
|||
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. */
|
||||
|
||||
static void
|
||||
pipe_command (const char *arg, int from_tty)
|
||||
{
|
||||
std::string delim ("|");
|
||||
pipe_cmd_opts opts;
|
||||
|
||||
if (arg != nullptr && check_for_argument (&arg, "-d", 2))
|
||||
{
|
||||
delim = extract_arg (&arg);
|
||||
if (delim.empty ())
|
||||
error (_("Missing delimiter DELIM after -d"));
|
||||
}
|
||||
auto grp = make_pipe_cmd_options_def_group (&opts);
|
||||
gdb::option::process_options
|
||||
(&arg, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
|
||||
|
||||
const char *delim = "|";
|
||||
if (opts.delimiter != nullptr)
|
||||
delim = opts.delimiter;
|
||||
|
||||
const char *command = arg;
|
||||
if (command == nullptr)
|
||||
error (_("Missing COMMAND"));
|
||||
|
||||
arg = strstr (arg, delim.c_str ());
|
||||
arg = strstr (arg, delim);
|
||||
|
||||
if (arg == nullptr)
|
||||
error (_("Missing delimiter before SHELL_COMMAND"));
|
||||
|
||||
std::string gdb_cmd (command, arg - command);
|
||||
|
||||
arg += delim.length (); /* Skip the delimiter. */
|
||||
arg += strlen (delim); /* Skip the delimiter. */
|
||||
|
||||
if (gdb_cmd.empty ())
|
||||
gdb_cmd = repeat_previous ();
|
||||
|
@ -1019,6 +1055,43 @@ pipe_command (const char *arg, int from_tty)
|
|||
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
|
||||
list_command (const char *arg, int from_tty)
|
||||
{
|
||||
|
@ -2045,6 +2118,7 @@ case COMMAND contains a | character.\n\
|
|||
\n\
|
||||
With no COMMAND, repeat the last executed command\n\
|
||||
and send its output to SHELL_COMMAND."));
|
||||
set_cmd_completer_handle_brkchars (c, pipe_command_completer);
|
||||
add_com_alias ("|", "pipe", class_support, 0);
|
||||
|
||||
add_com ("list", class_files, list_command, _("\
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2019-07-03 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR cli/24732
|
||||
* gdb.base/shell.exp: Load completion-support.exp.
|
||||
Adjust expected error output. Add completion tests.
|
||||
|
||||
2019-07-03 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* lib/completion-support.exp (test_gdb_complete_cmd_multiple): Use
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
# Test that the "shell", "!", "|" and "pipe" commands work.
|
||||
|
||||
load_lib completion-support.exp
|
||||
|
||||
gdb_exit
|
||||
gdb_start
|
||||
|
||||
|
@ -92,8 +94,8 @@ gdb_test "p \$_shell_exitsignal" " = 2" "pipe interrupt exitsignal"
|
|||
|
||||
# Error handling verifications.
|
||||
gdb_test "|" "Missing COMMAND" "all missing"
|
||||
gdb_test "|-d" "Missing delimiter DELIM after -d" "-d value missing"
|
||||
gdb_test "|-d " "Missing delimiter DELIM after -d" "-d spaces value missing"
|
||||
gdb_test "|-d" "-d requires an argument" "-d value missing"
|
||||
gdb_test "|-d " "-d requires an argument" "-d spaces value missing"
|
||||
gdb_test "| echo coucou" \
|
||||
"Missing delimiter before SHELL_COMMAND" \
|
||||
"| delimiter missing"
|
||||
|
@ -110,3 +112,44 @@ gdb_test "|-d! echo coucou ! wc" \
|
|||
"Missing delimiter before SHELL_COMMAND" \
|
||||
"delimiter missing due to missing space"
|
||||
|
||||
# Completion tests.
|
||||
|
||||
test_gdb_complete_unique \
|
||||
"pipe" \
|
||||
"pipe"
|
||||
|
||||
# Note that unlike "pipe", "|" doesn't require a space. This checks
|
||||
# that completion behaves that way too.
|
||||
foreach cmd {"pipe " "| " "|"} {
|
||||
test_gdb_completion_offers_commands "$cmd"
|
||||
|
||||
# There's only one option.
|
||||
test_gdb_complete_unique \
|
||||
"${cmd}-" \
|
||||
"${cmd}-d"
|
||||
|
||||
# Cannot complete "-d"'s argument.
|
||||
test_gdb_complete_none "${cmd}-d "
|
||||
test_gdb_complete_none "${cmd}-d main"
|
||||
|
||||
# Check completing a GDB command, with and without -d.
|
||||
test_gdb_complete_unique \
|
||||
"${cmd}maint set test-se" \
|
||||
"${cmd}maint set test-settings"
|
||||
test_gdb_complete_unique \
|
||||
"${cmd}-d XXX maint set test-se" \
|
||||
"${cmd}-d XXX maint set test-settings"
|
||||
|
||||
# Check that GDB doesn't try to complete the shell command.
|
||||
test_gdb_complete_none \
|
||||
"${cmd}print 1 | "
|
||||
|
||||
# Same, while making sure that the completer understands "-d".
|
||||
test_gdb_complete_unique \
|
||||
"${cmd}-d XXX maint set" \
|
||||
"${cmd}-d XXX maint set"
|
||||
test_gdb_complete_none \
|
||||
"${cmd}-d set maint set"
|
||||
test_gdb_complete_none \
|
||||
"${cmd}-d set maint set "
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue