[v3,10/19] Implement completion limiting for cmdpy_completer.

Message ID 20150806191815.32159.84277.stgit@valrhona.uglyboxes.com
State New, archived
Headers

Commit Message

Keith Seitz Aug. 6, 2015, 7:18 p.m. UTC
  Differences in this revision:

1. Free string memory after passing to add_completion.

---

This patch converts cmdpy_completer, used by commands written in
python.  It also adds tests for some untested python functionality
related to completion.

gdb/ChangeLog

	* python/py-cmd.c (cmdpy_completer) Use add_completion.
	Free memory associated with `item'.

gdb/testsuite/ChangeLog

	* gdb.python/py-completion.exp: Test completion functions,
	with and without completion limiting.
---
 gdb/python/py-cmd.c                        |    9 +++++-
 gdb/testsuite/gdb.python/py-completion.exp |   45 ++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 1 deletion(-)
  

Comments

Doug Evans Aug. 23, 2015, 4:06 a.m. UTC | #1
Keith Seitz <keiths@redhat.com> writes:
> Differences in this revision:
>
> 1. Free string memory after passing to add_completion.
>
> ---
>
> This patch converts cmdpy_completer, used by commands written in
> python.  It also adds tests for some untested python functionality
> related to completion.
>
> gdb/ChangeLog
>
> 	* python/py-cmd.c (cmdpy_completer) Use add_completion.
> 	Free memory associated with `item'.
>
> gdb/testsuite/ChangeLog
>
> 	* gdb.python/py-completion.exp: Test completion functions,
> 	with and without completion limiting.

LGTM, but see comment below.

> ---
>  gdb/python/py-cmd.c                        |    9 +++++-
>  gdb/testsuite/gdb.python/py-completion.exp |   45 ++++++++++++++++++++++++++++
>  2 files changed, 53 insertions(+), 1 deletion(-)
>
> diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
> index 21d842e..36e352e 100644
> --- a/gdb/python/py-cmd.c
> +++ b/gdb/python/py-cmd.c
> @@ -392,7 +392,14 @@ cmdpy_completer (struct completer_data *cdata,
>  	      PyErr_Clear ();
>  	      continue;
>  	    }
> -	  VEC_safe_push (char_ptr, result, item);
> +
> +	  if (add_completion (cdata, &result, item, NULL, NULL)
> +	      == ADD_COMPLETION_MAX_REACHED)
> +	    {
> +	      xfree (item);
> +	      break;
> +	    }
> +	  xfree (item);
>  	}
>  
>        Py_DECREF (iter);
> diff --git a/gdb/testsuite/gdb.python/py-completion.exp b/gdb/testsuite/gdb.python/py-completion.exp
> index 5e45087..f7f23a3 100644
> --- a/gdb/testsuite/gdb.python/py-completion.exp
> +++ b/gdb/testsuite/gdb.python/py-completion.exp
> @@ -128,3 +128,48 @@ if {[readline_is_used]} {
>  	    "completelimit2 cl29"
>  	}
>  }
> +
> +# The terminal at the end of the complete command
> +set end "\\\*\\\*\\\* List may be truncated, "
> +append end "max-completions reached\\\. \\\*\\\*\\\*"

====
Another case where it'd be nice to just call a function
(test_completion_limit?) and have this regexp live there?
It may be that each case is sufficiently different that such
a function would be too complex to handle all its potential callers,
I didn't study each case too thoroughly.
Just wanted to bring the issue up.

> +
> +set max_completions 3
> +gdb_test_no_output "set max-completions $max_completions"
> +set seen 0
> +
> +set testname "limit completions of 'complete completel'"
> +gdb_test_multiple "complete completel" $testname {
> +    "complete completel" { exp_continue }
> +
> +    -re "completelimit\[1-9\]+\r\n" {
> +	incr seen
> +	exp_continue
> +    }
> +
> +    -re "completel $end\r\n$gdb_prompt $" {
> +	if {$seen == $max_completions} {
> +	    pass $testname
> +	} else {
> +	    fail "$testname ($seen/$max_completions)"
> +	}
> +    }
> +}
> +
> +set testname "limit completions of 'complete completelimit1 c'"
> +set seen 0
> +gdb_test_multiple "complete completelimit1 c" $testname {
> +    "complete completelimit1 c" { exp_continue }
> +
> +    -re "completelimit1 cl1\[1-9\]+\r\n" {
> +	incr seen
> +	exp_continue
> +    }
> +
> +    -re "completelimit1 c $end\r\n$gdb_prompt $" {
> +	if {$seen == $max_completions} {
> +	    pass $testname
> +	} else {
> +	    fail "$testname ($seen/$max_completions)"
> +	}
> +    }
> +}
  

Patch

diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index 21d842e..36e352e 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -392,7 +392,14 @@  cmdpy_completer (struct completer_data *cdata,
 	      PyErr_Clear ();
 	      continue;
 	    }
-	  VEC_safe_push (char_ptr, result, item);
+
+	  if (add_completion (cdata, &result, item, NULL, NULL)
+	      == ADD_COMPLETION_MAX_REACHED)
+	    {
+	      xfree (item);
+	      break;
+	    }
+	  xfree (item);
 	}
 
       Py_DECREF (iter);
diff --git a/gdb/testsuite/gdb.python/py-completion.exp b/gdb/testsuite/gdb.python/py-completion.exp
index 5e45087..f7f23a3 100644
--- a/gdb/testsuite/gdb.python/py-completion.exp
+++ b/gdb/testsuite/gdb.python/py-completion.exp
@@ -128,3 +128,48 @@  if {[readline_is_used]} {
 	    "completelimit2 cl29"
 	}
 }
+
+# The terminal at the end of the complete command
+set end "\\\*\\\*\\\* List may be truncated, "
+append end "max-completions reached\\\. \\\*\\\*\\\*"
+
+set max_completions 3
+gdb_test_no_output "set max-completions $max_completions"
+set seen 0
+
+set testname "limit completions of 'complete completel'"
+gdb_test_multiple "complete completel" $testname {
+    "complete completel" { exp_continue }
+
+    -re "completelimit\[1-9\]+\r\n" {
+	incr seen
+	exp_continue
+    }
+
+    -re "completel $end\r\n$gdb_prompt $" {
+	if {$seen == $max_completions} {
+	    pass $testname
+	} else {
+	    fail "$testname ($seen/$max_completions)"
+	}
+    }
+}
+
+set testname "limit completions of 'complete completelimit1 c'"
+set seen 0
+gdb_test_multiple "complete completelimit1 c" $testname {
+    "complete completelimit1 c" { exp_continue }
+
+    -re "completelimit1 cl1\[1-9\]+\r\n" {
+	incr seen
+	exp_continue
+    }
+
+    -re "completelimit1 c $end\r\n$gdb_prompt $" {
+	if {$seen == $max_completions} {
+	    pass $testname
+	} else {
+	    fail "$testname ($seen/$max_completions)"
+	}
+    }
+}