[v4,2/2] MI: Add new command -complete

Message ID 20190418115847.19854-3-jan.vrany@fit.cvut.cz
State New, archived
Headers

Commit Message

Jan Vrany April 18, 2019, 11:58 a.m. UTC
  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.

gdb/Changelog:
2019-01-28  Jan Vrany  <jan.vrany@fit.cvut.cz>

	* mi/mi-cmds.h (mi_cmd_complete): New function.
	* mi/mi-main.c (mi_cmd_complete): Likewise.
	* mi/mi-cmds.c: Define new MI command -complete.
	* NEWS: Mention new -complete command.

gdb/doc/ChangeLog:
2019-01-28  Jan Vrany  <jan.vrany@fit.cvut.cz>

	* gdb.texinfo (Miscellaneous GDB/MI Commands): Document new
	MI command -complete.

gdb/testsuite/ChangeLog:
2019-01-28  Jan Vrany  <jan.vrany@fit.cvut.cz>

	* gdb.mi/mi-complete.exp: New file.
	* gdb.mi/mi-complete.cc: Likewise.
---
 gdb/ChangeLog                        |  7 +++
 gdb/NEWS                             |  7 +++
 gdb/doc/ChangeLog                    |  5 ++
 gdb/doc/gdb.texinfo                  | 61 +++++++++++++++++++++++
 gdb/mi/mi-cmds.c                     |  1 +
 gdb/mi/mi-cmds.h                     |  1 +
 gdb/mi/mi-main.c                     | 45 +++++++++++++++++
 gdb/testsuite/ChangeLog              |  5 ++
 gdb/testsuite/gdb.mi/mi-complete.cc  | 40 ++++++++++++++++
 gdb/testsuite/gdb.mi/mi-complete.exp | 72 ++++++++++++++++++++++++++++
 10 files changed, 244 insertions(+)
 create mode 100644 gdb/testsuite/gdb.mi/mi-complete.cc
 create mode 100644 gdb/testsuite/gdb.mi/mi-complete.exp
  

Comments

Eli Zaretskii April 18, 2019, 12:50 p.m. UTC | #1
> From: Jan Vrany <jan.vrany@fit.cvut.cz>
> Cc: Jan Vrany <jan.vrany@fit.cvut.cz>
> Date: Thu, 18 Apr 2019 12:58:47 +0100
> 
> +The result consists of two one or two fields:
                          ^^^^^^^^^^^^^^
A typo.

> +@smallexample
> +(gdb)
> +-complete br
> +^done,completion="break",matches=["break","break-range"],max_completions_reached="0"
> +(gdb)
> +-complete "b ma"
> +^done,completion="b ma",matches=["b madvise","b main"],max_completions_reached="0"
> +(gdb)
> +-complete "b push_b"
> +^done,completion="b push_back(",
> +      matches=["b A::push_back(void*)",
> +               "b std::string::push_back(char)",
> +               "b std::vector<int, std::allocator<int> >::push_back(int&&)"],
> +      max_completions_reached="0"

The "done" lines are too long, please break them into lines shorter
than 70 characters.

Otherwise, the documentation parts are OK.

Thanks.
  
Pedro Alves April 18, 2019, 2:14 p.m. UTC | #2
This version is OK, with the tiny issue below addressed.

Can you push this yourself, or do you need someone to do it for you?

> +/* Implement the "-complete" command.  */
> +
> +void
> +mi_cmd_complete (const char *command, char **argv, int argc)
> +{
> +  if (argc != 1)
> +    error (_("Usage: -complete COMMAND"));
> +
> +  if (max_completions == 0)
> +    error (_("max-completions is zero, completion is disabled.\n"));

errors should not end in \n.

Thanks,
Pedro Alves
  
Jan Vrany April 18, 2019, 2:54 p.m. UTC | #3
On Thu, 2019-04-18 at 15:14 +0100, Pedro Alves wrote:
> This version is OK, with the tiny issue below addressed.
> 
> Can you push this yourself, or do you need someone to do it for you?

No, I can't. I'll send a v5 with two more fixes shortly - if all is OK, 
can you push it, please? 

Thanks! Jan

> 
> > +/* Implement the "-complete" command.  */
> > +
> > +void
> > +mi_cmd_complete (const char *command, char **argv, int argc)
> > +{
> > +  if (argc != 1)
> > +    error (_("Usage: -complete COMMAND"));
> > +
> > +  if (max_completions == 0)
> > +    error (_("max-completions is zero, completion is disabled.\n"));
> 
> errors should not end in \n.
> 
> Thanks,
> Pedro Alves
  
Pedro Alves April 18, 2019, 4:14 p.m. UTC | #4
On 4/18/19 3:54 PM, Jan Vrany wrote:
> On Thu, 2019-04-18 at 15:14 +0100, Pedro Alves wrote:
>> This version is OK, with the tiny issue below addressed.
>>
>> Can you push this yourself, or do you need someone to do it for you?
> 
> No, I can't. I'll send a v5 with two more fixes shortly - if all is OK, 
> can you push it, please? 

I see you've already posted some more patches.  Do you plan to continue
contributing to GDB?  If so, might as well give you write access to
the repo so you can push your own patches yourself.  Let me know what
you prefer.

Thanks,
Pedro Alves
  
Jan Vrany May 16, 2019, 11:27 a.m. UTC | #5
Polite ping. 

The v5 - hopefully good - is here: 

https://sourceware.org/ml/gdb-patches/2019-04/msg00323.html

Thanks! Jan

On Thu, 2019-04-18 at 15:54 +0100, Jan Vrany wrote:
> On Thu, 2019-04-18 at 15:14 +0100, Pedro Alves wrote:
> > This version is OK, with the tiny issue below addressed.
> > 
> > Can you push this yourself, or do you need someone to do it for you?
> 
> No, I can't. I'll send a v5 with two more fixes shortly - if all is OK, 
> can you push it, please? 
> 
> Thanks! Jan
> 
> > > +/* Implement the "-complete" command.  */
> > > +
> > > +void
> > > +mi_cmd_complete (const char *command, char **argv, int argc)
> > > +{
> > > +  if (argc != 1)
> > > +    error (_("Usage: -complete COMMAND"));
> > > +
> > > +  if (max_completions == 0)
> > > +    error (_("max-completions is zero, completion is disabled.\n"));
> > 
> > errors should not end in \n.
> > 
> > Thanks,
> > Pedro Alves
  
Tom Tromey May 16, 2019, 5:31 p.m. UTC | #6
>>>>> "Jan" == Jan Vrany <jan.vrany@fit.cvut.cz> writes:

Jan> Polite ping. 
Jan> The v5 - hopefully good - is here: 
Jan> https://sourceware.org/ml/gdb-patches/2019-04/msg00323.html

I read through these, and they looked good to me.
Please check them in.  Thanks for doing this.

Tom
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index f2b0c16ec5..87fa43dd06 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@ 
+2019-01-28  Jan Vrany  <jan.vrany@fit.cvut.cz>
+
+	* mi/mi-cmds.h (mi_cmd_complete): New function.
+	* mi/mi-main.c (mi_cmd_complete): Likewise.
+	* mi/mi-cmds.c: Define new MI command -complete.
+	* NEWS: Mention new -complete command.
+
 2019-01-24  Jan Vrany  <jan.vrany@fit.cvut.cz>
 
 	* completer.h (complete): New function.
diff --git a/gdb/NEWS b/gdb/NEWS
index 5309a8f923..7aa31ccb17 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -27,6 +27,13 @@ 
      'array_indexes', 'symbols', 'unions', 'deref_refs', 'actual_objects',
      'static_members', 'max_elements', 'repeat_threshold', and 'format'.
 
+* 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.
+
 *** Changes in GDB 8.3
 
 * GDB and GDBserver now support access to additional registers on
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 64073278fa..6f7a48787e 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@ 
+2019-01-28  Jan Vrany  <jan.vrany@fit.cvut.cz>
+
+	* gdb.texinfo (Miscellaneous GDB/MI Commands): Document new
+	MI command -complete.
+
 2019-04-17  Alan Hayward  <alan.hayward@arm.com>
 
 	* gdb.texinfo (Other Command-Line Arguments for gdbserver)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index a3a5f3e28c..52b203fd90 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -34438,6 +34438,67 @@  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}.
+
+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 @value{GDBN} is used remotely via a SSH connection.
+
+@subheading Result
+
+The result consists of two one or two fields:
+
+@table @samp
+@item completion
+This field contains the completed @var{command}.  If @var{command}
+has no known completions, this field is omitted.
+
+@item matches
+This field contains a (possibly empty) array of matches.  It is always present.
+
+@item max_completions_reached
+This field contains @code{1} if number of known completions is above
+@code{max-completions} limit (see @ref{Completion}), otherwise it contains
+@code{0}.  It is always present.
+
+@end table
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{complete}.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-complete br
+^done,completion="break",matches=["break","break-range"],max_completions_reached="0"
+(gdb)
+-complete "b ma"
+^done,completion="b ma",matches=["b madvise","b main"],max_completions_reached="0"
+(gdb)
+-complete "b push_b"
+^done,completion="b push_back(",
+      matches=["b A::push_back(void*)",
+               "b std::string::push_back(char)",
+               "b std::vector<int, std::allocator<int> >::push_back(int&&)"],
+      max_completions_reached="0"
+(gdb)
+-complete "nonexist"
+^done,matches=[],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 fe30ac2e82..bbc0e2bd93 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -75,6 +75,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_MI ("complete", mi_cmd_complete),
   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/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 7b22ce7813..58aa2d6f77 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -125,6 +125,7 @@  extern mi_cmd_argv_ftype mi_cmd_var_update;
 extern mi_cmd_argv_ftype mi_cmd_enable_pretty_printing;
 extern mi_cmd_argv_ftype mi_cmd_enable_frame_filters;
 extern mi_cmd_argv_ftype mi_cmd_var_set_update_range;
+extern mi_cmd_argv_ftype mi_cmd_complete;
 
 /* Description of a single command.  */
 
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 17ca807471..0d8a27e6cc 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2726,6 +2726,51 @@  mi_multi_location_breakpoint_output_fixed (ui_out *uiout)
   return mi_uiout->version () >= 3 || fix_multi_location_breakpoint_output;
 }
 
+/* Implement the "-complete" command.  */
+
+void
+mi_cmd_complete (const char *command, char **argv, int argc)
+{
+  if (argc != 1)
+    error (_("Usage: -complete COMMAND"));
+
+  if (max_completions == 0)
+    error (_("max-completions is zero, completion is disabled.\n"));
+
+  int quote_char = '\0';
+  const char *word;
+
+  completion_result result = complete (argv[0], &word, &quote_char);
+
+  std::string arg_prefix (argv[0], word - argv[0]);
+
+  struct ui_out *uiout = current_uiout;
+
+  if (result.number_matches > 0)
+    uiout->field_fmt ("completion", "%s%s",
+                      arg_prefix.c_str (),result.match_list[0]);
+
+  {
+    ui_out_emit_list completions_emitter (uiout, "matches");
+
+    if (result.number_matches == 1)
+      uiout->field_fmt (NULL, "%s%s",
+                        arg_prefix.c_str (), result.match_list[0]);
+    else
+      {
+        result.sort_match_list ();
+        for (size_t i = 0; i < result.number_matches; i++)
+          {
+            uiout->field_fmt (NULL, "%s%s",
+                              arg_prefix.c_str (), result.match_list[i + 1]);
+          }
+      }
+  }
+  uiout->field_string ("max_completions_reached",
+                       result.number_matches == max_completions ? "1" : "0");
+}
+
+
 void
 _initialize_mi_main (void)
 {
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index d46422635b..eed638c5b2 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@ 
+2019-01-28  Jan Vrany  <jan.vrany@fit.cvut.cz>
+
+	* gdb.mi/mi-complete.exp: New file.
+	* gdb.mi/mi-complete.cc: Likewise.
+
 2019-04-15  Leszek Swirski  <leszeks@google.com>
 
 	* gdb.arch/amd64-eval.cc: New file.
diff --git a/gdb/testsuite/gdb.mi/mi-complete.cc b/gdb/testsuite/gdb.mi/mi-complete.cc
new file mode 100644
index 0000000000..3742152864
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-complete.cc
@@ -0,0 +1,40 @@ 
+/* Copyright 2018-2019 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#include <vector>
+
+class A
+{
+public:
+  void push_back (void *value);
+};
+
+void
+A::push_back (void *value)
+{
+  /* nothing */
+}
+
+int
+main (int argc, char **argv)
+{
+  std::vector < int >v;
+  v.push_back (1);
+  A a;
+  a.push_back (&v);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.mi/mi-complete.exp b/gdb/testsuite/gdb.mi/mi-complete.exp
new file mode 100644
index 0000000000..692b004fd9
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-complete.exp
@@ -0,0 +1,72 @@ 
+# Copyright 2018-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/>.
+
+# Verify GDB/MI -complete in various scenarios. This test only tests
+# -complete command, not the correctness of completions.
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+standard_testfile .cc
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+     untested "failed to compile"
+     return -1
+}
+
+mi_run_to_main
+
+mi_gdb_test "1-complete br" \
+            "1\\^done,completion=\"break\",matches=\\\[.*\"break\",.*\"break-range\".*\\\],max_completions_reached=\"0\"" \
+            "-complete br"
+
+# Check empty completion list.
+mi_gdb_test "5-complete bogus" \
+            "5\\^done,matches=\\\[\\\],max_completions_reached=\"0\"" \
+            "-complete bogus"
+
+# Check completions for commands with space.
+mi_gdb_test "4-complete \"b mai\"" \
+            "4\\^done,completion=\"b main\",matches=\\\[.*\"b main\".*\\\],max_completions_reached=\"0\"" \
+            "-complete \"b mai\""
+
+# Check wildmatching.
+mi_gdb_test "5-complete \"b push_ba\"" \
+            "5\\^done,completion=\"b push_back\\(\",matches=\\\[.*\"b A::push_back\\(void\\*\\)\".*\\\],max_completions_reached=\"0\"" \
+            "-complete \"b push_ba\", wildmatching"
+
+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,completion=\"br\[A-Za-z0-9-\]+\",matches=\\\[\"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 0"