/* gdb commands implemented in Python
- Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2008-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "defs.h"
#include "arch-utils.h"
#include "value.h"
-#include "exceptions.h"
#include "python-internal.h"
#include "charset.h"
#include "gdbcmd.h"
#include "cli/cli-decode.h"
#include "completer.h"
#include "language.h"
+#include "py-ref.h"
/* Struct representing built-in completion types. */
struct cmdpy_completer
{
/* Python symbol name. */
- char *name;
+ const char *name;
/* Completion function. */
- char **(*completer) (struct cmd_list_element *, char *, char *);
+ completer_ftype *completer;
};
-static struct cmdpy_completer completers[] =
+static const struct cmdpy_completer completers[] =
{
{ "COMPLETE_NONE", noop_completer },
{ "COMPLETE_FILENAME", filename_completer },
{ "COMPLETE_LOCATION", location_completer },
{ "COMPLETE_COMMAND", command_completer },
- { "COMPLETE_SYMBOL", make_symbol_completion_list_fn },
+ { "COMPLETE_SYMBOL", symbol_completer },
+ { "COMPLETE_EXPRESSION", expression_completer },
};
#define N_COMPLETERS (sizeof (completers) / sizeof (completers[0]))
typedef struct cmdpy_object cmdpy_object;
-static PyTypeObject cmdpy_object_type;
-
+extern PyTypeObject cmdpy_object_type
+ CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("cmdpy_object");
/* Constants used by this module. */
static PyObject *invoke_cst;
static void
cmdpy_destroyer (struct cmd_list_element *self, void *context)
{
- cmdpy_object *cmd;
- struct cleanup *cleanup;
-
- cleanup = ensure_python_env (get_current_arch (), current_language);
+ gdbpy_enter enter_py (get_current_arch (), current_language);
/* Release our hold on the command object. */
- cmd = (cmdpy_object *) context;
+ gdbpy_ref<cmdpy_object> cmd ((cmdpy_object *) context);
cmd->command = NULL;
- Py_DECREF (cmd);
/* We allocated the name, doc string, and perhaps the prefix
name. */
- xfree (self->name);
- xfree (self->doc);
- xfree (self->prefixname);
-
- do_cleanups (cleanup);
+ xfree ((char *) self->name);
+ xfree ((char *) self->doc);
+ xfree ((char *) self->prefixname);
}
/* Called by gdb to invoke the command. */
static void
-cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
+cmdpy_function (struct cmd_list_element *command,
+ const char *args, int from_tty)
{
cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
- PyObject *argobj, *ttyobj, *result;
- struct cleanup *cleanup;
- cleanup = ensure_python_env (get_current_arch (), current_language);
+ gdbpy_enter enter_py (get_current_arch (), current_language);
if (! obj)
error (_("Invalid invocation of Python command object."));
if (obj->command->prefixname)
{
/* A prefix command does not need an invoke method. */
- do_cleanups (cleanup);
return;
}
error (_("Python command object missing 'invoke' method."));
if (! args)
args = "";
- argobj = PyUnicode_Decode (args, strlen (args), host_charset (), NULL);
- if (! argobj)
+ gdbpy_ref<> argobj (PyUnicode_Decode (args, strlen (args), host_charset (),
+ NULL));
+ if (argobj == NULL)
{
gdbpy_print_stack ();
error (_("Could not convert arguments to Python string."));
}
- ttyobj = from_tty ? Py_True : Py_False;
- Py_INCREF (ttyobj);
- result = PyObject_CallMethodObjArgs ((PyObject *) obj, invoke_cst, argobj,
- ttyobj, NULL);
- Py_DECREF (argobj);
- Py_DECREF (ttyobj);
+ gdbpy_ref<> ttyobj
+ = gdbpy_ref<>::new_reference (from_tty ? Py_True : Py_False);
+ gdbpy_ref<> result (PyObject_CallMethodObjArgs ((PyObject *) obj, invoke_cst,
+ argobj.get (), ttyobj.get (),
+ NULL));
- if (! result)
+ if (result == NULL)
+ gdbpy_handle_exception ();
+}
+
+/* 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.
+
+ 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 a reference to the PyObject representing the
+ Python method call. */
+
+static gdbpy_ref<>
+cmdpy_completer_helper (struct cmd_list_element *command,
+ const char *text, const char *word)
+{
+ cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
+
+ if (obj == NULL)
+ error (_("Invalid invocation of Python command object."));
+ if (!PyObject_HasAttr ((PyObject *) obj, complete_cst))
{
- PyObject *ptype, *pvalue, *ptraceback;
- char *msg;
+ /* If there is no complete method, don't error. */
+ return NULL;
+ }
- PyErr_Fetch (&ptype, &pvalue, &ptraceback);
+ gdbpy_ref<> textobj (PyUnicode_Decode (text, strlen (text), host_charset (),
+ NULL));
+ if (textobj == NULL)
+ error (_("Could not convert argument to Python string."));
- /* Try to fetch an error message contained within ptype, pvalue.
- When fetching the error message we need to make our own copy,
- we no longer own ptype, pvalue after the call to PyErr_Restore. */
+ gdbpy_ref<> wordobj;
+ if (word == NULL)
+ {
+ /* "brkchars" phase. */
+ wordobj = gdbpy_ref<>::new_reference (Py_None);
+ }
+ else
+ {
+ wordobj.reset (PyUnicode_Decode (word, strlen (word), host_charset (),
+ NULL));
+ if (wordobj == NULL)
+ error (_("Could not convert argument to Python string."));
+ }
- msg = gdbpy_exception_to_string (ptype, pvalue);
- make_cleanup (xfree, msg);
+ gdbpy_ref<> resultobj (PyObject_CallMethodObjArgs ((PyObject *) obj,
+ complete_cst,
+ textobj.get (),
+ wordobj.get (), NULL));
+ if (resultobj == NULL)
+ {
+ /* Just swallow errors here. */
+ PyErr_Clear ();
+ }
- if (msg == NULL)
- {
- /* An error occurred computing the string representation of the
- error message. This is rare, but we should inform the user. */
- printf_filtered (_("An error occurred in a Python command\n"
- "and then another occurred computing the error message.\n"));
- gdbpy_print_stack ();
- }
+ return resultobj;
+}
+
+/* Python function called to determine the break characters of a
+ certain completer. We are only interested in knowing if the
+ completer registered by the user will return one of the integer
+ codes (see COMPLETER_* symbols). */
- /* Don't print the stack for gdb.GdbError exceptions.
- It is generally used to flag user errors.
+static void
+cmdpy_completer_handle_brkchars (struct cmd_list_element *command,
+ completion_tracker &tracker,
+ const char *text, const char *word)
+{
+ gdbpy_enter enter_py (get_current_arch (), current_language);
- We also don't want to print "Error occurred in Python command"
- for user errors. However, a missing message for gdb.GdbError
- exceptions is arguably a bug, so we flag it as such. */
+ /* Calling our helper to obtain a reference to the PyObject of the Python
+ function. */
+ gdbpy_ref<> resultobj = cmdpy_completer_helper (command, text, word);
- if (! PyErr_GivenExceptionMatches (ptype, gdbpy_gdberror_exc)
- || msg == NULL || *msg == '\0')
+ /* Check if there was an error. */
+ if (resultobj == NULL)
+ return;
+
+ if (PyInt_Check (resultobj.get ()))
+ {
+ /* User code may also return one of the completion constants,
+ thus requesting that sort of completion. We are only
+ interested in this kind of return. */
+ long value;
+
+ if (!gdb_py_int_as_long (resultobj.get (), &value))
{
- PyErr_Restore (ptype, pvalue, ptraceback);
- gdbpy_print_stack ();
- if (msg != NULL && *msg != '\0')
- error (_("Error occurred in Python command: %s"), msg);
- else
- error (_("Error occurred in Python command."));
+ /* Ignore. */
+ PyErr_Clear ();
}
- else
+ else if (value >= 0 && value < (long) N_COMPLETERS)
{
- Py_XDECREF (ptype);
- Py_XDECREF (pvalue);
- Py_XDECREF (ptraceback);
- error ("%s", msg);
+ completer_handle_brkchars_ftype *brkchars_fn;
+
+ /* This is the core of this function. Depending on which
+ completer type the Python function returns, we have to
+ adjust the break characters accordingly. */
+ brkchars_fn = (completer_handle_brkchars_func_for_completer
+ (completers[value].completer));
+ brkchars_fn (command, tracker, text, word);
}
}
-
- Py_DECREF (result);
- do_cleanups (cleanup);
}
/* Called by gdb for command completion. */
-static char **
-cmdpy_completer (struct cmd_list_element *command, char *text, char *word)
-{
- cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
- PyObject *textobj, *wordobj, *resultobj = NULL;
- char **result = NULL;
- struct cleanup *cleanup;
- cleanup = ensure_python_env (get_current_arch (), current_language);
+static void
+cmdpy_completer (struct cmd_list_element *command,
+ completion_tracker &tracker,
+ const char *text, const char *word)
+{
+ gdbpy_enter enter_py (get_current_arch (), current_language);
- if (! obj)
- error (_("Invalid invocation of Python command object."));
- if (! PyObject_HasAttr ((PyObject *) obj, complete_cst))
- {
- /* If there is no complete method, don't error -- instead, just
- say that there are no completions. */
- goto done;
- }
+ /* Calling our helper to obtain a reference to the PyObject of the Python
+ function. */
+ gdbpy_ref<> resultobj = cmdpy_completer_helper (command, text, word);
- textobj = PyUnicode_Decode (text, strlen (text), host_charset (), NULL);
- if (! textobj)
- error (_("Could not convert argument to Python string."));
- wordobj = PyUnicode_Decode (word, strlen (word), host_charset (), NULL);
- if (! wordobj)
- error (_("Could not convert argument to Python string."));
+ /* If the result object of calling the Python function is NULL, it
+ means that there was an error. In this case, just give up. */
+ if (resultobj == NULL)
+ return;
- resultobj = PyObject_CallMethodObjArgs ((PyObject *) obj, complete_cst,
- textobj, wordobj, NULL);
- Py_DECREF (textobj);
- Py_DECREF (wordobj);
- if (! resultobj)
+ if (PyInt_Check (resultobj.get ()))
{
- /* Just swallow errors here. */
- PyErr_Clear ();
- goto done;
- }
- make_cleanup_py_decref (resultobj);
+ /* User code may also return one of the completion constants,
+ thus requesting that sort of completion. */
+ long value;
- result = NULL;
- if (PySequence_Check (resultobj))
+ if (! gdb_py_int_as_long (resultobj.get (), &value))
+ {
+ /* Ignore. */
+ PyErr_Clear ();
+ }
+ else if (value >= 0 && value < (long) N_COMPLETERS)
+ completers[value].completer (command, tracker, text, word);
+ }
+ else
{
- Py_ssize_t i, len = PySequence_Size (resultobj);
- Py_ssize_t out;
+ gdbpy_ref<> iter (PyObject_GetIter (resultobj.get ()));
- if (len < 0)
- goto done;
+ if (iter == NULL)
+ return;
- result = (char **) xmalloc ((len + 1) * sizeof (char *));
- for (i = out = 0; i < len; ++i)
+ bool got_matches = false;
+ while (true)
{
- PyObject *elt = PySequence_GetItem (resultobj, i);
+ gdbpy_ref<> elt (PyIter_Next (iter.get ()));
+ if (elt == NULL)
+ break;
- if (elt == NULL || ! gdbpy_is_string (elt))
+ if (! gdbpy_is_string (elt.get ()))
{
/* Skip problem elements. */
- PyErr_Clear ();
continue;
}
- result[out] = python_string_to_host_string (elt);
- if (result[out] == NULL)
+ gdb::unique_xmalloc_ptr<char>
+ item (python_string_to_host_string (elt.get ()));
+ if (item == NULL)
{
/* Skip problem elements. */
PyErr_Clear ();
continue;
}
- ++out;
+ tracker.add_completion (std::move (item));
+ got_matches = true;
}
- 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);
+ /* If we got some results, ignore problems. Otherwise, report
+ the problem. */
+ if (got_matches && PyErr_Occurred ())
+ PyErr_Clear ();
}
-
- done:
-
- 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);
+ result = (char *) xmalloc (lastchar - i + 2);
+ 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)
{
return result;
}
- prefix_text = xmalloc (i + 2);
- memcpy (prefix_text, text, i + 1);
- prefix_text[i + 1] = '\0';
+ std::string prefix_text (name, i + 1);
- text = prefix_text;
- elt = lookup_cmd_1 (&text, *start_list, NULL, 1);
- if (!elt || elt == (struct cmd_list_element *) -1)
+ prefix_text2 = prefix_text.c_str ();
+ elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, 1);
+ if (elt == NULL || elt == CMD_LIST_AMBIGUOUS)
{
PyErr_Format (PyExc_RuntimeError, _("Could not find command prefix %s."),
- prefix_text);
- xfree (prefix_text);
+ prefix_text.c_str ());
xfree (result);
return NULL;
}
if (elt->prefixlist)
{
- xfree (prefix_text);
*base_list = elt->prefixlist;
return result;
}
PyErr_Format (PyExc_RuntimeError, _("'%s' is not a prefix command."),
- prefix_text);
- xfree (prefix_text);
+ prefix_text.c_str ());
xfree (result);
return NULL;
}
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;
- volatile struct gdb_exception except;
struct cmd_list_element **cmd_list;
char *cmd_name, *pfx_name;
- static char *keywords[] = { "name", "command_class", "completer_class",
- "prefix", NULL };
+ static const char *keywords[] = { "name", "command_class", "completer_class",
+ "prefix", NULL };
PyObject *is_prefix = NULL;
int cmp;
return -1;
}
- if (! PyArg_ParseTupleAndKeywords (args, kw, "si|iO", keywords, &name, &cmdtype,
- &completetype, &is_prefix))
+ if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "si|iO",
+ keywords, &name, &cmdtype,
+ &completetype, &is_prefix))
return -1;
if (cmdtype != no_class && cmdtype != class_run
&& 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;
if (completetype < -1 || completetype >= (int) N_COMPLETERS)
{
- PyErr_Format (PyExc_RuntimeError, _("Invalid completion type argument."));
+ PyErr_Format (PyExc_RuntimeError,
+ _("Invalid completion type 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);
-
+ pfx_name = (char *) 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))
{
- PyObject *ds_obj = PyObject_GetAttr (self, gdbpy_doc_cst);
+ gdbpy_ref<> ds_obj (PyObject_GetAttr (self, gdbpy_doc_cst));
- if (ds_obj && gdbpy_is_string (ds_obj))
+ if (ds_obj != NULL && gdbpy_is_string (ds_obj.get ()))
{
- docstring = python_string_to_host_string (ds_obj);
+ docstring = python_string_to_host_string (ds_obj.get ()).release ();
if (docstring == NULL)
{
xfree (cmd_name);
if (! docstring)
docstring = xstrdup (_("This command is not documented."));
- Py_INCREF (self);
+ gdbpy_ref<> self_ref = gdbpy_ref<>::new_reference (self);
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
struct cmd_list_element *cmd;
pfx_name, allow_unknown, cmd_list);
}
else
- cmd = add_cmd (cmd_name, (enum command_class) cmdtype, NULL,
+ cmd = add_cmd (cmd_name, (enum command_class) cmdtype,
docstring, cmd_list);
/* There appears to be no API to set this. */
cmd->destroyer = cmdpy_destroyer;
obj->command = cmd;
- set_cmd_context (cmd, self);
+ set_cmd_context (cmd, self_ref.release ());
set_cmd_completer (cmd, ((completetype == -1) ? cmdpy_completer
: completers[completetype].completer));
+ if (completetype == -1)
+ set_cmd_completer_handle_brkchars (cmd,
+ cmdpy_completer_handle_brkchars);
}
- if (except.reason < 0)
+ CATCH (except, RETURN_MASK_ALL)
{
xfree (cmd_name);
xfree (docstring);
xfree (pfx_name);
- Py_DECREF (self);
- PyErr_Format (except.reason == RETURN_QUIT
- ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
- "%s", except.message);
+ gdbpy_convert_exception (except);
return -1;
}
+ END_CATCH
+
return 0;
}
\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. */
+ and there is no reason to expose tui, I think. */
if (PyModule_AddIntConstant (gdb_module, "COMMAND_NONE", no_class) < 0
|| PyModule_AddIntConstant (gdb_module, "COMMAND_RUNNING", class_run) < 0
|| PyModule_AddIntConstant (gdb_module, "COMMAND_DATA", class_vars) < 0
|| 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
{ 0 }
};
-static PyTypeObject cmdpy_object_type =
+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
PyObject *
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);
+ gdbpy_ref<> 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 (*input != '\0')
{
- char **c_argv = gdb_buildargv (input);
- int i;
+ gdb_argv c_argv (input);
- for (i = 0; c_argv[i] != NULL; ++i)
+ for (char *arg : c_argv)
{
- PyObject *argp = PyString_FromString (c_argv[i]);
+ gdbpy_ref<> argp (PyString_FromString (arg));
if (argp == NULL
- || PyList_Append (py_argv, argp) < 0)
- {
- if (argp != NULL)
- {
- Py_DECREF (argp);
- }
- Py_DECREF (py_argv);
- freeargv (c_argv);
- return NULL;
- }
+ || PyList_Append (py_argv.get (), argp.get ()) < 0)
+ return NULL;
}
-
- freeargv (c_argv);
}
- return py_argv;
+ return py_argv.release ();
}