This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 11/28] use iterator protocol and avoid refcount bugs


The checker pointed out some refcounting bugs in cmdpy_completer.
And, while looking at it, I noticed that it was not using the iterator
protocol.  I couldn't think of a reason why not; and using an iterator
cleaned up the code, so this patch does that.

	* python/py-cmd.c (cmdpy_completer): Use iterator protocol.
	Correctly decref.
---
 gdb/python/py-cmd.c | 49 ++++++++++++++++++++++++++++---------------------
 1 file changed, 28 insertions(+), 21 deletions(-)

diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index 6516e1f..26823c7 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -247,26 +247,40 @@ cmdpy_completer (struct cmd_list_element *command,
   make_cleanup_py_decref (resultobj);
 
   result = NULL;
-  if (PySequence_Check (resultobj))
+  if (PyInt_Check (resultobj))
     {
-      Py_ssize_t i, len = PySequence_Size (resultobj);
-      Py_ssize_t out;
+      /* User code may also return one of the completion constants,
+	 thus requesting that sort of completion.  */
+      long value;
+
+      if (! gdb_py_int_as_long (resultobj, &value))
+	{
+	  /* Ignore.  */
+	  PyErr_Clear ();
+	}
+      else if (value >= 0 && value < (long) N_COMPLETERS)
+	result = completers[value].completer (command, text, word);
+    }
+  else
+    {
+      PyObject *iter = PyObject_GetIter (resultobj);
+      PyObject *elt;
 
-      if (len < 0)
+      if (iter == NULL)
 	goto done;
 
-      for (i = out = 0; i < len; ++i)
+      while ((elt = PyIter_Next (iter)) != NULL)
 	{
-	  PyObject *elt = PySequence_GetItem (resultobj, i);
 	  char *item;
 
-	  if (elt == NULL || ! gdbpy_is_string (elt))
+	  if (! gdbpy_is_string (elt))
 	    {
 	      /* Skip problem elements.  */
-	      PyErr_Clear ();
+	      Py_DECREF (elt);
 	      continue;
 	    }
 	  item = python_string_to_host_string (elt);
+	  Py_DECREF (elt);
 	  if (item == NULL)
 	    {
 	      /* Skip problem elements.  */
@@ -275,20 +289,13 @@ cmdpy_completer (struct cmd_list_element *command,
 	    }
 	  VEC_safe_push (char_ptr, result, item);
 	}
-    }
-  else if (PyInt_Check (resultobj))
-    {
-      /* User code may also return one of the completion constants,
-	 thus requesting that sort of completion.  */
-      long value;
 
-      if (! gdb_py_int_as_long (resultobj, &value))
-	{
-	  /* Ignore.  */
-	  PyErr_Clear ();
-	}
-      else if (value >= 0 && value < (long) N_COMPLETERS)
-	result = completers[value].completer (command, text, word);
+      Py_DECREF (iter);
+
+      /* If we got some results, ignore problems.  Otherwise, report
+	 the problem.  */
+      if (result != NULL && PyErr_Occurred ())
+	PyErr_Clear ();
     }
 
  done:
-- 
1.8.1.4



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]