/* gdb commands implemented in Python
- Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2008-2013 Free Software Foundation, Inc.
This file is part of GDB.
/* Python symbol name. */
char *name;
/* Completion function. */
- char **(*completer) (struct cmd_list_element *, char *, char *);
+ completer_ftype *completer;
};
static struct cmdpy_completer completers[] =
{ "COMPLETE_LOCATION", location_completer },
{ "COMPLETE_COMMAND", command_completer },
{ "COMPLETE_SYMBOL", make_symbol_completion_list_fn },
+ { "COMPLETE_EXPRESSION", expression_completer },
};
#define N_COMPLETERS (sizeof (completers) / sizeof (completers[0]))
typedef struct cmdpy_object cmdpy_object;
-static PyTypeObject cmdpy_object_type;
-
+static PyTypeObject cmdpy_object_type
+ CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("cmdpy_object");
/* Constants used by this module. */
static PyObject *invoke_cst;
/* We allocated the name, doc string, and perhaps the prefix
name. */
- xfree (self->name);
+ xfree ((char *) self->name);
xfree (self->doc);
xfree (self->prefixname);
}
/* Called by gdb for command completion. */
-static char **
-cmdpy_completer (struct cmd_list_element *command, char *text, char *word)
+
+static VEC (char_ptr) *
+cmdpy_completer (struct cmd_list_element *command,
+ const char *text, const char *word)
{
cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
PyObject *textobj, *wordobj, *resultobj = NULL;
- char **result = NULL;
+ VEC (char_ptr) *result = NULL;
struct cleanup *cleanup;
cleanup = ensure_python_env (get_current_arch (), current_language);
PyErr_Clear ();
goto done;
}
- 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 (len < 0)
+ 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 (iter == NULL)
goto done;
- result = (char **) xmalloc ((len + 1) * sizeof (char *));
- 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;
}
- result[out] = python_string_to_host_string (elt);
- if (result[out] == NULL)
+ item = python_string_to_host_string (elt);
+ Py_DECREF (elt);
+ if (item == NULL)
{
/* Skip problem elements. */
PyErr_Clear ();
continue;
}
- ++out;
+ VEC_safe_push (char_ptr, result, item);
}
- result[out] = NULL;
- }
- else if (PyInt_Check (resultobj))
- {
- /* User code may also return one of the completion constants,
- thus requesting that sort of completion. */
- long value = PyInt_AsLong (resultobj);
- 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:
+ Py_XDECREF (resultobj);
do_cleanups (cleanup);
return result;
/* Helper for cmdpy_init which locates the command list to use and
pulls out the command name.
-
- TEXT is the command name list. The final word in the list is the
+
+ NAME is the command name list. The final word in the list is the
name of the new command. All earlier words must be existing prefix
commands.
*BASE_LIST is set to the final prefix command's list of
*sub-commands.
-
+
START_LIST is the list in which the search starts.
This function returns the xmalloc()d name of the new command. On
error sets the Python error and returns NULL. */
+
char *
-gdbpy_parse_command_name (char *text,
+gdbpy_parse_command_name (const char *name,
struct cmd_list_element ***base_list,
struct cmd_list_element **start_list)
{
struct cmd_list_element *elt;
- int len = strlen (text);
+ int len = strlen (name);
int i, lastchar;
char *prefix_text;
+ const char *prefix_text2;
char *result;
/* Skip trailing whitespace. */
- for (i = len - 1; i >= 0 && (text[i] == ' ' || text[i] == '\t'); --i)
+ for (i = len - 1; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i)
;
if (i < 0)
{
lastchar = i;
/* Find first character of the final word. */
- for (; i > 0 && (isalnum (text[i - 1])
- || text[i - 1] == '-'
- || text[i - 1] == '_');
+ for (; i > 0 && (isalnum (name[i - 1])
+ || name[i - 1] == '-'
+ || name[i - 1] == '_');
--i)
;
result = xmalloc (lastchar - i + 2);
- memcpy (result, &text[i], lastchar - i + 1);
+ memcpy (result, &name[i], lastchar - i + 1);
result[lastchar - i + 1] = '\0';
/* Skip whitespace again. */
- for (--i; i >= 0 && (text[i] == ' ' || text[i] == '\t'); --i)
+ for (--i; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i)
;
if (i < 0)
{
}
prefix_text = xmalloc (i + 2);
- memcpy (prefix_text, text, i + 1);
+ memcpy (prefix_text, name, i + 1);
prefix_text[i + 1] = '\0';
- text = prefix_text;
- elt = lookup_cmd_1 (&text, *start_list, NULL, 1);
+ prefix_text2 = prefix_text;
+ elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, 1);
if (!elt || elt == (struct cmd_list_element *) -1)
{
PyErr_Format (PyExc_RuntimeError, _("Could not find command prefix %s."),
If PREFIX is True, then this command is a prefix command.
The documentation for the command is taken from the doc string for
- the python class.
-
-*/
+ the python class. */
+
static int
cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
{
cmdpy_object *obj = (cmdpy_object *) self;
- char *name;
+ const char *name;
int cmdtype;
int completetype = -1;
char *docstring = NULL;
&& cmdtype != class_files && cmdtype != class_support
&& cmdtype != class_info && cmdtype != class_breakpoint
&& cmdtype != class_trace && cmdtype != class_obscure
- && cmdtype != class_maintenance)
+ && cmdtype != class_maintenance && cmdtype != class_user)
{
PyErr_Format (PyExc_RuntimeError, _("Invalid command class argument."));
return -1;
return -1;
pfx_name = NULL;
- if (is_prefix != NULL)
+ if (is_prefix != NULL)
{
cmp = PyObject_IsTrue (is_prefix);
if (cmp == 1)
{
int i, out;
-
+
/* Make a normalized form of the command name. */
pfx_name = xmalloc (strlen (name) + 2);
-
+
i = 0;
out = 0;
while (name[i])
pfx_name[out] = '\0';
}
else if (cmp < 0)
+ {
+ xfree (cmd_name);
return -1;
+ }
}
if (PyObject_HasAttr (self, gdbpy_doc_cst))
{
{
xfree (cmd_name);
xfree (pfx_name);
+ Py_DECREF (ds_obj);
return -1;
}
}
+
+ Py_XDECREF (ds_obj);
}
if (! docstring)
docstring = xstrdup (_("This command is not documented."));
\f
/* Initialize the 'commands' code. */
-void
+
+int
gdbpy_initialize_commands (void)
{
int i;
+ cmdpy_object_type.tp_new = PyType_GenericNew;
if (PyType_Ready (&cmdpy_object_type) < 0)
- return;
+ return -1;
/* Note: alias and user are special; pseudo appears to be unused,
and there is no reason to expose tui or xdb, I think. */
|| PyModule_AddIntConstant (gdb_module, "COMMAND_OBSCURE",
class_obscure) < 0
|| PyModule_AddIntConstant (gdb_module, "COMMAND_MAINTENANCE",
- class_maintenance) < 0)
- return;
+ class_maintenance) < 0
+ || PyModule_AddIntConstant (gdb_module, "COMMAND_USER", class_user) < 0)
+ return -1;
for (i = 0; i < N_COMPLETERS; ++i)
{
if (PyModule_AddIntConstant (gdb_module, completers[i].name, i) < 0)
- return;
+ return -1;
}
- Py_INCREF (&cmdpy_object_type);
- PyModule_AddObject (gdb_module, "Command",
- (PyObject *) &cmdpy_object_type);
+ if (gdb_pymodule_addobject (gdb_module, "Command",
+ (PyObject *) &cmdpy_object_type) < 0)
+ return -1;
invoke_cst = PyString_FromString ("invoke");
+ if (invoke_cst == NULL)
+ return -1;
complete_cst = PyString_FromString ("complete");
+ if (complete_cst == NULL)
+ return -1;
+
+ return 0;
}
\f
static PyTypeObject cmdpy_object_type =
{
- PyObject_HEAD_INIT (NULL)
- 0, /*ob_size*/
+ PyVarObject_HEAD_INIT (NULL, 0)
"gdb.Command", /*tp_name*/
sizeof (cmdpy_object), /*tp_basicsize*/
0, /*tp_itemsize*/
0, /* tp_dictoffset */
cmdpy_init, /* tp_init */
0, /* tp_alloc */
- PyType_GenericNew /* tp_new */
};
\f
gdbpy_string_to_argv (PyObject *self, PyObject *args)
{
PyObject *py_argv;
- char *input;
+ const char *input;
if (!PyArg_ParseTuple (args, "s", &input))
return NULL;
py_argv = PyList_New (0);
+ if (py_argv == NULL)
+ return NULL;
/* buildargv uses NULL to represent an empty argument list, but we can't use
that in Python. Instead, if ARGS is "" then return an empty list.
if (argp == NULL
|| PyList_Append (py_argv, argp) < 0)
{
- if (argp != NULL)
- {
- Py_DECREF (argp);
- }
+ Py_XDECREF (argp);
Py_DECREF (py_argv);
freeargv (c_argv);
return NULL;
}
+ Py_DECREF (argp);
}
freeargv (c_argv);