From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32239 invoked by alias); 16 Jan 2019 09:21:58 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 32228 invoked by uid 89); 16 Jan 2019 09:21:57 -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=emacs, Emacs, H*r:may, H*r:forged 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; Wed, 16 Jan 2019 09:21:52 +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 x0G9LjV4027097 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Wed, 16 Jan 2019 10:21:47 +0100 (CET) (envelope-from jan.vrany@fit.cvut.cz) Received: from sao (027906ee.bb.sky.com [2.121.6.238] (may be forged)) (authenticated bits=0 as user vranyj1) by imap.fit.cvut.cz (8.15.2/8.15.2) with ESMTPSA id x0G9LghX091925 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Wed, 16 Jan 2019 10:21:45 +0100 (CET) (envelope-from jan.vrany@fit.cvut.cz) Message-ID: Subject: Re: [PATCH] MI: Add new command -complete From: Jan Vrany To: gdb-patches@sourceware.org Date: Wed, 16 Jan 2019 09:21:00 -0000 In-Reply-To: <20190103222930.4365-1-jan.vrany@fit.cvut.cz> References: <20190103222930.4365-1-jan.vrany@fit.cvut.cz> Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.30.4-1 Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-SW-Source: 2019-01/txt/msg00368.txt.bz2 Polite ping. Jan On Thu, 2019-01-03 at 22:29 +0000, Jan Vrany wrote: > 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)"