MI: Add new command -complete
authorJan Vrany <jan.vrany@fit.cvut.cz>
Fri, 17 May 2019 09:58:23 +0000 (10:58 +0100)
committerJan Vrany <jan.vrany@fit.cvut.cz>
Fri, 17 May 2019 09:58:23 +0000 (10:58 +0100)
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
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/mi/mi-cmds.c
gdb/mi/mi-cmds.h
gdb/mi/mi-main.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.mi/mi-complete.cc [new file with mode: 0644]
gdb/testsuite/gdb.mi/mi-complete.exp [new file with mode: 0644]

index f05cbb9f7cb3308189d0c451dcbb15b68d35d72e..c7e3f32521464a9cc054bf70f12f352112214da0 100644 (file)
@@ -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.
index 288615b8cd3df7efc18eb2f35f410768deb0336a..1e92a2b52c219daa9254c09771827368e9231897 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -46,6 +46,13 @@ show print max-depth
   The default max-depth is 20, but this can be set to unlimited to get
   the old behavior back.
 
+* 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
index 4ea3250951e82222acc091f773e1cab8372e9c86..55dab15fca15950e984b559edf7f4e3dd1ea1818 100644 (file)
@@ -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-05-14  Tom de Vries  <tdevries@suse.de>
 
        * gdb.texinfo (Automatic symbol index cache): Add concept and command
index 328d510dd85bc583d24e003f78fdc0c8fe41540e..37e2f14ad0fa42a4888588f5894cdaea611f59fd 100644 (file)
@@ -34538,6 +34538,71 @@ 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 or three 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
 
index fe30ac2e8222e923aa834be2a3dee8f7e2ef2635..bbc0e2bd9302afb99949b73c288508af35d49a40 100644 (file)
@@ -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",
index 7b22ce7813470d3ab2f8b8e6d8f085f03d1752b6..58aa2d6f77981a7eefeaeee47965d31f3c3c07a8 100644 (file)
@@ -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.  */
 
index 01786c3c1e84602293f0ecb35621d7231babe6a1..4921c13528ec305e0dd950f5def69a1193ef42c7 100644 (file)
@@ -2708,6 +2708,51 @@ mi_cmd_fix_multi_location_breakpoint_output (const char *command, char **argv,
   fix_multi_location_breakpoint_output_globally = true;
 }
 
+/* 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."));
+
+  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)
 {
index 78289d61cf58eb74710e6804caba2361c063b9c8..bdabbc72985713937a5eccef247728d907e00d67 100644 (file)
@@ -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-05-15  Bernhard Heckel  <bernhard.heckel@intel.com>
 
        * gdb.fortran/vla-sizeof.exp: Add tests of sizeof applied to
diff --git a/gdb/testsuite/gdb.mi/mi-complete.cc b/gdb/testsuite/gdb.mi/mi-complete.cc
new file mode 100644 (file)
index 0000000..3742152
--- /dev/null
@@ -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 (file)
index 0000000..692b004
--- /dev/null
@@ -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"