diff options
author | Pedro Alves <palves@redhat.com> | 2019-07-03 16:57:51 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2019-07-03 17:18:54 +0100 |
commit | 5f4ba3e701d74f280d4bd8820d9c39a854e0d2cf (patch) | |
tree | e3b67db8010eb2372226f3fbd5a33c2e5edbb8b3 /gdb/cli | |
parent | a994424fa1e80d982644038f1ce6538e247aeed1 (diff) | |
download | gdb-5f4ba3e701d74f280d4bd8820d9c39a854e0d2cf.zip gdb-5f4ba3e701d74f280d4bd8820d9c39a854e0d2cf.tar.gz gdb-5f4ba3e701d74f280d4bd8820d9c39a854e0d2cf.tar.bz2 |
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.
Diffstat (limited to 'gdb/cli')
-rw-r--r-- | gdb/cli/cli-cmds.c | 92 |
1 files changed, 83 insertions, 9 deletions
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index d1ecd62..368ddf5 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -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, _("\ |