aboutsummaryrefslogtreecommitdiff
path: root/gdb/python
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/python')
-rw-r--r--gdb/python/py-cmd.c119
1 files changed, 52 insertions, 67 deletions
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index 1d89912..017d0b6 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -210,85 +210,70 @@ cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
/* Helper function for the Python command completers (both "pure"
completer and brkchar handler). This function takes COMMAND, TEXT
and WORD and tries to call the Python method for completion with
- these arguments. It also takes HANDLE_BRKCHARS_P, an argument to
- identify whether it is being called from the brkchar handler or
- from the "pure" completer. In the first case, it effectively calls
- the Python method for completion, and records the PyObject in a
- static variable (used as a "cache"). In the second case, it just
- returns that variable, without actually calling the Python method
- again. This saves us one Python method call.
-
- The reason for this two step dance is that we need to know the set
- of "brkchars" to use early on, before we actually try to perform
- the completion. But if a Python command supplies a "complete"
- method then we have to call that method first: it may return as its
- result the kind of completion to perform and that will in turn
- specify which brkchars to use. IOW, we need the result of the
- "complete" method before we actually perform the completion.
-
- It is important to mention that this function is built on the
- assumption that the calls to cmdpy_completer_handle_brkchars and
- cmdpy_completer will be subsequent with nothing intervening. This
- is true for our completer mechanism.
+ these arguments.
+
+ This function is usually called twice: once when we are figuring out
+ the break characters to be used, and another to perform the real
+ completion itself. The reason for this two step dance is that we
+ need to know the set of "brkchars" to use early on, before we
+ actually try to perform the completion. But if a Python command
+ supplies a "complete" method then we have to call that method
+ first: it may return as its result the kind of completion to
+ perform and that will in turn specify which brkchars to use. IOW,
+ we need the result of the "complete" method before we actually
+ perform the completion. The only situation when this function is
+ not called twice is when the user uses the "complete" command: in
+ this scenario, there is no call to determine the "brkchars".
+
+ Ideally, it would be nice to cache the result of the first call (to
+ determine the "brkchars") and return this value directly in the
+ second call (to perform the actual completion). However, due to
+ the peculiarity of the "complete" command mentioned above, it is
+ possible to put GDB in a bad state if you perform a TAB-completion
+ and then a "complete"-completion sequentially. Therefore, we just
+ recalculate everything twice for TAB-completions.
This function returns the PyObject representing the Python method
call. */
static PyObject *
cmdpy_completer_helper (struct cmd_list_element *command,
- const char *text, const char *word,
- int handle_brkchars_p)
+ const char *text, const char *word)
{
cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
PyObject *textobj, *wordobj;
- /* This static variable will server as a "cache" for us, in order to
- store the PyObject that results from calling the Python
- function. */
- static PyObject *resultobj = NULL;
+ PyObject *resultobj;
- if (handle_brkchars_p)
+ if (obj == NULL)
+ error (_("Invalid invocation of Python command object."));
+ if (!PyObject_HasAttr ((PyObject *) obj, complete_cst))
{
- /* If we were called to handle brkchars, it means this is the
- first function call of two that will happen in a row.
- Therefore, we need to call the completer ourselves, and cache
- the return value in the static variable RESULTOBJ. Then, in
- the second call, we can just use the value of RESULTOBJ to do
- our job. */
- if (resultobj != NULL)
- Py_DECREF (resultobj);
-
- resultobj = NULL;
- if (obj == NULL)
- error (_("Invalid invocation of Python command object."));
- if (!PyObject_HasAttr ((PyObject *) obj, complete_cst))
- {
- /* If there is no complete method, don't error. */
- return NULL;
- }
-
- textobj = PyUnicode_Decode (text, strlen (text), host_charset (), NULL);
- if (textobj == NULL)
- error (_("Could not convert argument to Python string."));
- wordobj = PyUnicode_Decode (word, sizeof (word), host_charset (), NULL);
- if (wordobj == NULL)
- {
- Py_DECREF (textobj);
- error (_("Could not convert argument to Python string."));
- }
+ /* If there is no complete method, don't error. */
+ return NULL;
+ }
- resultobj = PyObject_CallMethodObjArgs ((PyObject *) obj, complete_cst,
- textobj, wordobj, NULL);
+ textobj = PyUnicode_Decode (text, strlen (text), host_charset (), NULL);
+ if (textobj == NULL)
+ error (_("Could not convert argument to Python string."));
+ wordobj = PyUnicode_Decode (word, strlen (word), host_charset (), NULL);
+ if (wordobj == NULL)
+ {
Py_DECREF (textobj);
- Py_DECREF (wordobj);
- if (!resultobj)
- {
- /* Just swallow errors here. */
- PyErr_Clear ();
- }
+ error (_("Could not convert argument to Python string."));
+ }
- Py_XINCREF (resultobj);
+ resultobj = PyObject_CallMethodObjArgs ((PyObject *) obj, complete_cst,
+ textobj, wordobj, NULL);
+ Py_DECREF (textobj);
+ Py_DECREF (wordobj);
+ if (!resultobj)
+ {
+ /* Just swallow errors here. */
+ PyErr_Clear ();
}
+ Py_XINCREF (resultobj);
+
return resultobj;
}
@@ -308,7 +293,7 @@ cmdpy_completer_handle_brkchars (struct cmd_list_element *command,
/* Calling our helper to obtain the PyObject of the Python
function. */
- resultobj = cmdpy_completer_helper (command, text, word, 1);
+ resultobj = cmdpy_completer_helper (command, text, word);
/* Check if there was an error. */
if (resultobj == NULL)
@@ -338,8 +323,7 @@ cmdpy_completer_handle_brkchars (struct cmd_list_element *command,
done:
- /* We do not call Py_XDECREF here because RESULTOBJ will be used in
- the subsequent call to cmdpy_completer function. */
+ Py_XDECREF (resultobj);
do_cleanups (cleanup);
}
@@ -357,7 +341,7 @@ cmdpy_completer (struct cmd_list_element *command,
/* Calling our helper to obtain the PyObject of the Python
function. */
- resultobj = cmdpy_completer_helper (command, text, word, 0);
+ resultobj = cmdpy_completer_helper (command, text, word);
/* If the result object of calling the Python function is NULL, it
means that there was an error. In this case, just give up and
@@ -419,6 +403,7 @@ cmdpy_completer (struct cmd_list_element *command,
done:
+ Py_XDECREF (resultobj);
do_cleanups (cleanup);
return result;