From patchwork Thu Jan 3 22:29:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Vrany X-Patchwork-Id: 30958 Received: (qmail 82244 invoked by alias); 3 Jan 2019 22:30:32 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 81426 invoked by uid 89); 3 Jan 2019 22:30:07 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, SPF_PASS autolearn=ham version=3.3.2 spammy=channel, channels, mai, Display X-HELO: relay.fit.cvut.cz Received: from relay.fit.cvut.cz (HELO relay.fit.cvut.cz) (147.32.232.237) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 03 Jan 2019 22:30:00 +0000 Received: from imap.fit.cvut.cz (imap.fit.cvut.cz [147.32.232.238]) by relay.fit.cvut.cz (8.15.2/8.15.2) with ESMTPS id x03MTsfJ038864 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 3 Jan 2019 23:29:56 +0100 (CET) (envelope-from jan.vrany@fit.cvut.cz) Received: from localhost (02788930.bb.sky.com [2.120.137.48] (may be forged)) (authenticated bits=0 as user vranyj1) by imap.fit.cvut.cz (8.15.2/8.15.2) with ESMTPSA id x03MTpB4059903 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Thu, 3 Jan 2019 23:29:54 +0100 (CET) (envelope-from jan.vrany@fit.cvut.cz) From: Jan Vrany To: gdb-patches@sourceware.org Cc: Jan Vrany Subject: [PATCH] MI: Add new command -complete Date: Thu, 3 Jan 2019 22:29:30 +0000 Message-Id: <20190103222930.4365-1-jan.vrany@fit.cvut.cz> MIME-Version: 1.0 There is a CLI command 'complete' intended to use with emacs. Such a command would also be useful for MI frontends, when separate CLI and MI channels cannot be used. For example, on Windows (because of lack of PTYs) or when GDB is used through SSH session. This commit adds a new '-complete' MI command which is implemented using CLI's 'complete'. gdb/Changelog: 2019-01-03 Jan Vrany * cli/cli-cmds.h: Export complete_command. * cli/cli-cmds.c (complete_command): Update to print completions on MI channel if requested. * mi/mi-cmds.c: Define new -complete command implemented using it CLI command 'complete'. * NEWS: Mention new -complete command. gdb/doc/ChangeLog: 2019-01-03 Jan Vrany * gdb.texinfo (Miscellaneous GDB/MI Commands): Document new MI command -complete. gdb/testsuite/ChangeLog: 2019-01-03 Jan Vrany * gdb.mi/mi-complete.exp: New file. --- gdb/ChangeLog | 9 +++ gdb/NEWS | 7 ++ gdb/cli/cli-cmds.c | 95 +++++++++++++++++++--------- gdb/cli/cli-cmds.h | 4 ++ gdb/doc/ChangeLog | 5 ++ gdb/doc/gdb.texinfo | 32 ++++++++++ gdb/mi/mi-cmds.c | 3 + gdb/testsuite/ChangeLog | 4 ++ gdb/testsuite/gdb.mi/mi-complete.exp | 71 +++++++++++++++++++++ 9 files changed, 199 insertions(+), 31 deletions(-) create mode 100644 gdb/testsuite/gdb.mi/mi-complete.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 08c7c6c1f4..322b539417 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2019-01-03 Jan Vrany + + * cli/cli-cmds.h: Export complete_command. + * cli/cli-cmds.c (complete_command): Update to print completions + on MI channel if requested. + * mi/mi-cmds.c: Define new -complete command implemented using + it CLI command 'complete'. + * NEWS: Mention new -complete command. + 2018-12-17 Andrew Burgess * dwarf2read.c (struct dwarf2_cu): Convert the fields 'mark', diff --git a/gdb/NEWS b/gdb/NEWS index 913f3ae3b6..6b561af71f 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -96,6 +96,13 @@ maint show dwarf unwinders info proc files Display a list of open files for a process. +* New MI commands + +-complete + This lists all the possible completions for the rest of the line, if it + were to be given as a command itself. This is intended for use by MI frontends + in cases when separate CLI and MI channels cannot be used. + * Changed commands target remote FILENAME diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index 135f550b80..468f66dac6 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -223,16 +223,22 @@ help_command (const char *command, int from_tty) /* Note: The "complete" command is used by Emacs to implement completion. [Is that why this function writes output with *_unfiltered?] */ -static void +void complete_command (const char *arg, int from_tty) { + struct ui_out *uiout = current_uiout; + bool is_mi_like = uiout->is_mi_like_p (); + dont_repeat (); if (max_completions == 0) { - /* Only print this for non-mi frontends. An MI frontend may not - be able to handle this. */ - if (!current_uiout->is_mi_like_p ()) + if (is_mi_like) + { + error (_("max-completions is zero," + " completion is disabled.\n")); + } + else { printf_unfiltered (_("max-completions is zero," " completion is disabled.\n")); @@ -278,34 +284,61 @@ complete_command (const char *arg, int from_tty) completion_result result = tracker->build_completion_result (word, word - arg, strlen (arg)); - if (result.number_matches != 0) - { - if (result.number_matches == 1) - printf_unfiltered ("%s%s\n", arg_prefix.c_str (), result.match_list[0]); - else - { - result.sort_match_list (); - - for (size_t i = 0; i < result.number_matches; i++) - { - printf_unfiltered ("%s%s", - arg_prefix.c_str (), - result.match_list[i + 1]); - if (quote_char) - printf_unfiltered ("%c", quote_char); - printf_unfiltered ("\n"); - } - } - - if (result.number_matches == max_completions) - { - /* ARG_PREFIX and WORD are included in the output so that emacs - will include the message in the output. */ - printf_unfiltered (_("%s%s %s\n"), - arg_prefix.c_str (), word, - get_max_completions_reached_message ()); - } + { + ui_out_emit_list completions_emitter (uiout, "completions"); + if (result.number_matches != 0) + { + if (result.number_matches == 1) + { + if (is_mi_like) + uiout->field_fmt(NULL, "%s%s", arg_prefix.c_str (), + result.match_list[0]); + else + printf_unfiltered ("%s%s\n", arg_prefix.c_str (), + result.match_list[0]); + } + else + { + result.sort_match_list (); + + for (size_t i = 0; i < result.number_matches; i++) + { + if (is_mi_like) + { + uiout->field_fmt(NULL, "%s%s", arg_prefix.c_str (), + result.match_list[i + 1]); + } + else + { + printf_unfiltered ("%s%s", arg_prefix.c_str (), + result.match_list[i + 1]); + if (quote_char) + printf_unfiltered ("%c", quote_char); + printf_unfiltered ("\n"); + } + } + } + } } + + if (result.number_matches == max_completions) + { + if (is_mi_like) + uiout->field_string("max_completions_reached", "1"); + else + { + /* ARG_PREFIX and WORD are included in the output so that emacs + will include the message in the output. */ + printf_unfiltered (_("%s%s %s\n"), + arg_prefix.c_str (), word, + get_max_completions_reached_message ()); + } + } + else + { + if (is_mi_like) + uiout->field_string("max_completions_reached", "0"); + } } int diff --git a/gdb/cli/cli-cmds.h b/gdb/cli/cli-cmds.h index 3fa188dba6..bcd12c0c0b 100644 --- a/gdb/cli/cli-cmds.h +++ b/gdb/cli/cli-cmds.h @@ -106,6 +106,10 @@ void init_cmd_lists (void); void init_cli_cmds (void); +/* Exported to gdb/mi/mi-cmds.c */ + +void complete_command (const char *, int); + int is_complete_command (struct cmd_list_element *cmd); /* Exported to gdb/main.c */ diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 68d3068c72..da81f6a6c1 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2019-01-03 Jan Vrany + + * gdb.texinfo (Miscellaneous GDB/MI Commands): Document new + MI command -complete. + 2018-12-13 John Baldwin * gdb.texinfo (Set Catchpoints): Add an anchor for 'catch syscall'. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index d766e44e63..7f88273145 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -34236,6 +34236,38 @@ fullname="/home/nickrob/myprog.c",line="73",arch="i386:x86_64"@} (gdb) @end smallexample +@subheading The @code{-complete} Command +@findex -complete + +@subheading Synopsis + +@smallexample +-complete @var{command} +@end smallexample + +Show a list of completions for partially typed CLI @var{command}. The +@var{command} should be given in verbatim without any quoting / escaping. + +This command is intended for @sc{gdb/mi} frontends that cannot use two separate +CLI and MI channels - for example: because of lack of PTYs like on Windows or +because @sc{gdb} is used remotely via a SSH connection. + +@subheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{complete}. + +@subheading Example + +@smallexample +(gdb) +-complete br +^done,completions=["break","break-range"],max_completions_reached="0" +(gdb) +-complete b madv +^done,completions=["b madvise"],max_completions_reached="0" +(gdb) +@end smallexample + @node Annotations @chapter @value{GDBN} Annotations diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c index 51014eded2..7b510f71d4 100644 --- a/gdb/mi/mi-cmds.c +++ b/gdb/mi/mi-cmds.c @@ -20,9 +20,11 @@ #include "defs.h" #include "top.h" +#include "cli/cli-cmds.h" #include "mi-cmds.h" #include "mi-main.h" + struct mi_cmd; static struct mi_cmd **lookup_table (const char *command); static void build_table (struct mi_cmd *commands); @@ -75,6 +77,7 @@ static struct mi_cmd mi_cmds[] = &mi_suppress_notification.breakpoint), DEF_MI_CMD_MI_1 ("catch-unload", mi_cmd_catch_unload, &mi_suppress_notification.breakpoint), + DEF_MI_CMD_CLI ("complete", "complete", 1), DEF_MI_CMD_MI ("data-disassemble", mi_cmd_disassemble), DEF_MI_CMD_MI ("data-evaluate-expression", mi_cmd_data_evaluate_expression), DEF_MI_CMD_MI ("data-list-changed-registers", diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index ab3a74fffd..40da71b2c5 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-01-03 Jan Vrany + + * gdb.mi/mi-complete.exp: New file. + 2018-12-12 Andrew Burgess * gdb.base/annota1.exp: Update a test regexp. diff --git a/gdb/testsuite/gdb.mi/mi-complete.exp b/gdb/testsuite/gdb.mi/mi-complete.exp new file mode 100644 index 0000000000..14c763a966 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-complete.exp @@ -0,0 +1,71 @@ +# Copyright 2018 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 . + +# Verify -data-evaluate-expression. There are really minimal tests. + +# The goal is not to test gdb functionality, which is done by other tests, +# but to verify the correct output response to MI operations. +# + +load_lib mi-support.exp +set MIFLAGS "-i=mi" + +gdb_exit +if [mi_gdb_start] { + continue +} + +standard_testfile basics.c + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "failed to compile" + return -1 +} + +mi_run_to_main + +mi_gdb_test "1-complete br" \ + "1\\^done,completions=\\\[.*\"break\",.*\"break-range\".*\\\],max_completions_reached=\"0\"" \ + "-complete br" + +# Check empty completion list +mi_gdb_test "5-complete bogus" \ + "5\\^done,completions=\\\[\\\],max_completions_reached=\"0\"" \ + "-complete bogus" + + +# Check completions for commands with space +mi_gdb_test "4-complete b mai" \ + "4\\^done,completions=\\\[.*\"b main\".*\\\],max_completions_reached=\"0\"" \ + "-complete b mai" + +mi_gdb_test "-info-gdb-mi-command complete" \ + "\\^done,command=\{exists=\"true\"\}" \ + "-info-gdb-mi-command complete" + +# Limit max completions and check that max_completions_reached=\"0\" is set +# to 1. +send_gdb "set max-completions 1\n" + +mi_gdb_test "2-complete br" \ + ".*2\\^done,completions=\\\[\"br\[A-Za-z0-9-\]+\"\\\],max_completions_reached=\"1\"" \ + "-complete br (max-completions 1)" + +# Disable completions and check an error is returned +send_gdb "set max-completions 0\n" + +mi_gdb_test "3-complete br" \ + ".*3\\^error,msg=\".*" \ + "-complete br (max-completions 1)"