[RFA,2/2] Add completion for COMMAND in 'frame apply all|level|COUNT... COMMAND'

Message ID 20190421134440.21100-3-philippe.waroquiers@skynet.be
State New, archived
Headers

Commit Message

Philippe Waroquiers April 21, 2019, 1:44 p.m. UTC
  This patch adds logic to complete the COMMAND part of the
'frame apply all|level|COUNT...' command.

gdb/ChangeLog
2019-04-21  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* stack.c (frame_apply_level_command_completer,
	frame_apply_all_command_completer, frame_apply_command_completer):
	 New functions.
	(frame_apply_level_command): Add comment
	referring to the corresponding completer function.
	(_initialize_stack): Setup completers for frame apply all,
	frame apply COUNT, frame apply level, faas.

gdb/testsuite/ChangeLog
2019-04-21  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* gdb.base/frameapply.exp: Test COMMAND completion.
---
 gdb/stack.c                           | 103 ++++++++++++++++++++++++--
 gdb/testsuite/gdb.base/frameapply.exp |  21 ++++++
 2 files changed, 119 insertions(+), 5 deletions(-)
  

Comments

Tom Tromey April 25, 2019, 1:33 p.m. UTC | #1
>>>>> "Philippe" == Philippe Waroquiers <philippe.waroquiers@skynet.be> writes:

Philippe> This patch adds logic to complete the COMMAND part of the
Philippe> 'frame apply all|level|COUNT...' command.

Thank you for doing this.

Philippe> +  while (text != NULL)
Philippe> +    {
Philippe> +      qcs_flags dummy;
Philippe> +
Philippe> +      if (parse_flags_qcs ("frame apply level COMMAND completer",
Philippe> +			   &text, &dummy))
Philippe> +	continue;

I think this has the same behavior as the earlier patch when completion
occurs just after a "-" or "-q".

Tom
  

Patch

diff --git a/gdb/stack.c b/gdb/stack.c
index f7fd9433b5..1a66de16a5 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -2733,6 +2733,9 @@  frame_apply_level_command (const char *cmd, int from_tty)
   const char *levels_str = cmd;
   number_or_range_parser levels (levels_str);
 
+  /* Changing this parsing logic probably implies to similarly update
+     frame_apply_level_command below.  */
+
   /* Skip the LEVEL list to find the flags and command args.  */
   while (!levels.finished ())
     {
@@ -2769,6 +2772,46 @@  frame_apply_level_command (const char *cmd, int from_tty)
     }
 }
 
+/* Skips the known arguments of frame apply level
+   and then invokes the usual command_completer.  */
+
+static void
+frame_apply_level_command_completer (struct cmd_list_element *cmd,
+				     completion_tracker &tracker,
+				     const char *text, const char *word)
+{
+  number_or_range_parser levels (text);
+  bool level_found = false;
+
+  while (!levels.finished ())
+    {
+      /* Call for effect.  */
+      levels.get_number ();
+
+      level_found = true;
+      if (levels.in_range ())
+	levels.skip_range ();
+    }
+
+  if (!level_found)
+    return;
+
+  text = levels.cur_tok ();
+
+  while (text != NULL)
+    {
+      qcs_flags dummy;
+
+      if (parse_flags_qcs ("frame apply level COMMAND completer",
+			   &text, &dummy))
+	continue;
+
+      break;
+    }
+
+  command_completer (cmd, tracker, text, word);
+}
+
 /* Implementation of the "frame apply all" command.  */
 
 static void
@@ -2781,6 +2824,28 @@  frame_apply_all_command (const char *cmd, int from_tty)
 			     get_current_frame (), INT_MAX);
 }
 
+/* Skips the known arguments of frame apply all
+   and then invokes the usual command_completer.  */
+
+static void
+frame_apply_all_command_completer (struct cmd_list_element *cmd,
+				   completion_tracker &tracker,
+				   const char *text, const char *word)
+{
+  while (text != NULL)
+    {
+      qcs_flags dummy;
+
+      if (parse_flags_qcs ("frame apply all COMMAND completer",
+			   &text, &dummy))
+	continue;
+
+      break;
+    }
+
+  command_completer (cmd, tracker, text, word);
+}
+
 /* Implementation of the "frame apply" command.  */
 
 static void
@@ -2810,6 +2875,31 @@  frame_apply_command (const char* cmd, int from_tty)
 			     trailing, count);
 }
 
+/* Skips the known arguments of frame apply COUNT
+   and then invokes the usual command_completer.  */
+
+static void
+frame_apply_command_completer (struct cmd_list_element *cmd,
+			       completion_tracker &tracker,
+			       const char *text, const char *word)
+{
+  if (get_number_trailer (&text, 0) == 0)
+    return;
+
+  while (text != NULL)
+    {
+      qcs_flags dummy;
+
+      if (parse_flags_qcs ("frame apply COUNT COMMAND completer",
+			   &text, &dummy))
+	continue;
+
+      break;
+    }
+
+  command_completer (cmd, tracker, text, word);
+}
+
 /* Implementation of the "faas" command.  */
 
 static void
@@ -2916,22 +3006,24 @@  Flag -c indicates to print the error and continue.\n\
 Flag -s indicates to silently ignore a COMMAND that raises an error\n\
 or produces no output."
 
-  add_prefix_cmd ("apply", class_stack, frame_apply_command,
+  cmd = add_prefix_cmd ("apply", class_stack, frame_apply_command,
 		  _("Apply a command to a number of frames.\n\
 Usage: frame apply COUNT [FLAG]... COMMAND\n\
 With a negative COUNT argument, applies the command on outermost -COUNT frames.\n"
 FRAME_APPLY_FLAGS_HELP),
 		  &frame_apply_cmd_list, "frame apply ", 1, &frame_cmd_list);
+  set_cmd_completer (cmd, frame_apply_command_completer);
 
-  add_cmd ("all", class_stack, frame_apply_all_command,
+  cmd = add_cmd ("all", class_stack, frame_apply_all_command,
 	   _("\
 Apply a command to all frames.\n\
 \n\
 Usage: frame apply all [FLAG]... COMMAND\n"
 FRAME_APPLY_FLAGS_HELP),
 	   &frame_apply_cmd_list);
+  set_cmd_completer (cmd, frame_apply_all_command_completer);
 
-  add_cmd ("level", class_stack, frame_apply_level_command,
+  cmd = add_cmd ("level", class_stack, frame_apply_level_command,
 	   _("\
 Apply a command to a list of frames.\n\
 \n\
@@ -2939,12 +3031,13 @@  Usage: frame apply level LEVEL... [FLAG]... COMMAND\n\
 ID is a space-separated list of LEVELs of frames to apply COMMAND on.\n"
 FRAME_APPLY_FLAGS_HELP),
 	   &frame_apply_cmd_list);
+  set_cmd_completer (cmd, frame_apply_level_command_completer);
 
-  add_com ("faas", class_stack, faas_command, _("\
+  cmd = add_com ("faas", class_stack, faas_command, _("\
 Apply a command to all frames (ignoring errors and empty output).\n\
 Usage: faas COMMAND\n\
 shortcut for 'frame apply all -s COMMAND'"));
-
+  set_cmd_completer (cmd, command_completer);
 
   add_prefix_cmd ("frame", class_stack,
 		  &frame_cmd.base_command, _("\
diff --git a/gdb/testsuite/gdb.base/frameapply.exp b/gdb/testsuite/gdb.base/frameapply.exp
index ccf30f2079..6b23d42143 100644
--- a/gdb/testsuite/gdb.base/frameapply.exp
+++ b/gdb/testsuite/gdb.base/frameapply.exp
@@ -18,6 +18,8 @@ 
 
 # Test 'frame apply [all | COUNT | -COUNT | level LEVEL...] [FLAG]... COMMAND'.
 
+load_lib completion-support.exp
+
 standard_testfile
 
 if { [prepare_for_testing "failed to prepare" ${testfile}] } {
@@ -36,6 +38,25 @@  set any "\[^\r\n\]*"
 set ws "\[ \t\]\+"
 set number "\[0-9]\+"
 
+# Check completion.
+test_gdb_complete_cmd_unique "frame apply al" "frame apply all"
+test_gdb_complete_cmd_unique "frame apply all info local" \
+    "frame apply all info locals"
+test_gdb_complete_cmd_unique "frame apply all -q info local" \
+    "frame apply all -q info locals"
+
+test_gdb_complete_cmd_unique "frame apply 3 info local" \
+    "frame apply 3 info locals"
+test_gdb_complete_cmd_unique "frame apply 3 -q info local" \
+    "frame apply 3 -q info locals"
+
+test_gdb_complete_cmd_unique "frame apply level 3 info local" \
+    "frame apply level 3 info locals"
+test_gdb_complete_cmd_unique "frame apply level 3 -q info local" \
+    "frame apply level 3 -q info locals"
+
+test_gdb_complete_cmd_unique "faas info local" "faas info locals"
+
 
 # Check all | COUNT | -COUNT | level LEVEL... with a simple command.
 with_test_prefix "simple command" {