From ba327838bac4a3a536fabaae0d151ff24f359495 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 20 May 2013 20:21:55 +0000 Subject: [PATCH] * python/py-cmd.c (cmdpy_completer): Use iterator protocol. Correctly decref. --- gdb/ChangeLog | 5 ++++ gdb/python/py-cmd.c | 67 +++++++++++++++++++++++++-------------------- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 64bac86714..84ca5962e0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2013-05-20 Tom Tromey + + * python/py-cmd.c (cmdpy_completer): Use iterator protocol. + Correctly decref. + 2013-05-20 Tom Tromey * python/py-cmd.c (cmdpy_init): Decref 'ds_obj'. diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c index 6516e1ff76..26823c7fff 100644 --- a/gdb/python/py-cmd.c +++ b/gdb/python/py-cmd.c @@ -247,36 +247,7 @@ cmdpy_completer (struct cmd_list_element *command, make_cleanup_py_decref (resultobj); result = NULL; - if (PySequence_Check (resultobj)) - { - Py_ssize_t i, len = PySequence_Size (resultobj); - Py_ssize_t out; - - if (len < 0) - goto done; - - for (i = out = 0; i < len; ++i) - { - PyObject *elt = PySequence_GetItem (resultobj, i); - char *item; - - if (elt == NULL || ! gdbpy_is_string (elt)) - { - /* Skip problem elements. */ - PyErr_Clear (); - continue; - } - item = python_string_to_host_string (elt); - if (item == NULL) - { - /* Skip problem elements. */ - PyErr_Clear (); - continue; - } - VEC_safe_push (char_ptr, result, item); - } - } - else if (PyInt_Check (resultobj)) + if (PyInt_Check (resultobj)) { /* User code may also return one of the completion constants, thus requesting that sort of completion. */ @@ -290,6 +261,42 @@ cmdpy_completer (struct cmd_list_element *command, else if (value >= 0 && value < (long) N_COMPLETERS) result = completers[value].completer (command, text, word); } + else + { + PyObject *iter = PyObject_GetIter (resultobj); + PyObject *elt; + + if (iter == NULL) + goto done; + + while ((elt = PyIter_Next (iter)) != NULL) + { + char *item; + + if (! gdbpy_is_string (elt)) + { + /* Skip problem elements. */ + Py_DECREF (elt); + continue; + } + item = python_string_to_host_string (elt); + Py_DECREF (elt); + if (item == NULL) + { + /* Skip problem elements. */ + PyErr_Clear (); + continue; + } + VEC_safe_push (char_ptr, result, item); + } + + Py_DECREF (iter); + + /* If we got some results, ignore problems. Otherwise, report + the problem. */ + if (result != NULL && PyErr_Occurred ()) + PyErr_Clear (); + } done: