[15/18] Implement completion limiting for scmcmd_add_completion.

Message ID 20150413192338.29172.13475.stgit@valrhona.uglyboxes.com
State Superseded
Headers

Commit Message

Keith Seitz April 13, 2015, 7:23 p.m. UTC
  This patch converts scmcmd_add_completion to use maybe_add_completion and
adds some tests for this new behavior.

gdb/ChangeLog

	* guile/scm-cmd.c (cmdscm_add_completion): Add completer_data
	argument.  All callers updated.
	Use maybe_add_completion.

gdb/testsuite/ChangeLog

	* gdb.guile/scm-cmd.exp: Add completion limiting tests.
---
 gdb/guile/scm-cmd.c                 |   21 +++++++++++++++++----
 gdb/testsuite/gdb.guile/scm-cmd.exp |   24 ++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 4 deletions(-)
  

Patch

diff --git a/gdb/guile/scm-cmd.c b/gdb/guile/scm-cmd.c
index 2c57d17..1680c27 100644
--- a/gdb/guile/scm-cmd.c
+++ b/gdb/guile/scm-cmd.c
@@ -348,10 +348,12 @@  cmdscm_bad_completion_result (const char *msg, SCM completion)
    The result is a boolean indicating success.  */
 
 static int
-cmdscm_add_completion (SCM completion, VEC (char_ptr) **result)
+cmdscm_add_completion (SCM completion, struct completer_data *cdata,
+		       VEC (char_ptr) **result)
 {
   char *item;
   SCM except_scm;
+  enum maybe_add_completion_enum add_status;
 
   if (!scm_is_string (completion))
     {
@@ -370,7 +372,18 @@  cmdscm_add_completion (SCM completion, VEC (char_ptr) **result)
       return 0;
     }
 
-  VEC_safe_push (char_ptr, *result, item);
+  add_status = maybe_add_completion (cdata, item);
+  switch (add_status)
+    {
+    case MAYBE_ADD_COMPLETION_OK:
+    case MAYBE_ADD_COMPLETION_OK_MAX_REACHED:
+      VEC_safe_push (char_ptr, *result, item);
+      break;
+    case MAYBE_ADD_COMPLETION_MAX_REACHED:
+    case MAYBE_ADD_COMPLETION_DUPLICATE:
+      xfree (item);
+      break;
+    }
 
   return 1;
 }
@@ -418,7 +431,7 @@  cmdscm_completer (struct completer_data *cdata,
 	{
 	  SCM next = scm_car (list);
 
-	  if (!cmdscm_add_completion (next, &result))
+	  if (!cmdscm_add_completion (next, cdata, &result))
 	    {
 	      VEC_free (char_ptr, result);
 	      goto done;
@@ -442,7 +455,7 @@  cmdscm_completer (struct completer_data *cdata,
 	      goto done;
 	    }
 
-	  if (!cmdscm_add_completion (next, &result))
+	  if (!cmdscm_add_completion (next, cdata, &result))
 	    {
 	      VEC_free (char_ptr, result);
 	      goto done;
diff --git a/gdb/testsuite/gdb.guile/scm-cmd.exp b/gdb/testsuite/gdb.guile/scm-cmd.exp
index 53c0fdf..ac721c3 100644
--- a/gdb/testsuite/gdb.guile/scm-cmd.exp
+++ b/gdb/testsuite/gdb.guile/scm-cmd.exp
@@ -196,6 +196,30 @@  gdb_test "test-scheme-error-cmd ugh" \
     "Error occurred in Scheme-implemented GDB command." \
     "call scheme-error command"
 
+# Test completion limiting.
+set max_completions 2
+gdb_test_no_output "set max-completions $max_completions"
+set end "\\\*\\\*\\\* List may be truncated, "
+append end "max-completions reached\\\. \\\*\\\*\\\*"
+set test "limit complete completer-as-function 42\."
+gdb_test_multiple "complete completer-as-function 42\." $test {
+    "complete completer-as-function 42\\\." { exp_continue }
+    -re "completer-as-function 42\\\.\[1-3\]\r\n" {
+	incr seen
+	exp_continue
+    }
+    -re ".*$end\r\n$gdb_prompt $" {
+	if {$seen == $max_completions} {
+	    pass $test
+	} else {
+	    fail "$test ($seen/$max_completions)"
+	}
+    }
+    -re ".*$gdb_prompt $" {
+	fail "$test (unlimited)"
+    }
+}
+
 # If there is a problem with object management, this can often trigger it.
 # It is useful to do this last, after we've created a bunch of command objects.