From 0e0331dd62afb53005a08f2f5e22a631204110e6 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Fri, 29 Oct 2010 15:25:07 -0200 Subject: Fix function PySequenceToArgcArgv to support unicode strings. Also fix some reference leaks. Reviewer: Luciano Wolf Lauro Moura --- libshiboken/helper.cpp | 45 +++++++++++++++++++++++++++++---------------- libshiboken/helper.h | 14 +++++++++++--- 2 files changed, 40 insertions(+), 19 deletions(-) (limited to 'libshiboken') diff --git a/libshiboken/helper.cpp b/libshiboken/helper.cpp index f61fc1447..c37c54328 100644 --- a/libshiboken/helper.cpp +++ b/libshiboken/helper.cpp @@ -27,33 +27,46 @@ namespace Shiboken bool PySequenceToArgcArgv(PyObject* argList, int* argc, char*** argv, const char* defaultAppName) +{ + return sequenceToArgcArgv(argList, argc, argv, defaultAppName); +} + +bool +sequenceToArgcArgv(PyObject* argList, int* argc, char*** argv, const char* defaultAppName) { if (!PySequence_Check(argList)) return false; + if (!defaultAppName) + defaultAppName = "PySideApplication"; + // Check all items - int numArgs = PySequence_Size(argList); - for (int i = 0; i < numArgs; ++i) - if (!PyString_Check(PySequence_GetItem(argList, i))) + Shiboken::AutoDecRef args(PySequence_Fast(argList, 0)); + int numArgs = PySequence_Fast_GET_SIZE(argList); + for (int i = 0; i < numArgs; ++i) { + PyObject* item = PySequence_Fast_GET_ITEM(args.object(), i); + if (!PyString_Check(item) && !PyUnicode_Check(item)) return false; + } - bool addAppName = !numArgs && defaultAppName; - *argc = addAppName ? 1 : numArgs; - + *argc = numArgs + 1; *argv = new char*[*argc]; for (int i = 0; i < numArgs; ++i) { - PyObject* item = PySequence_GetItem(argList, i); - char* string = PyString_AS_STRING(item); - int size = strlen(string); - (*argv)[i] = new char[size+1]; - (*argv)[i] = strcpy((*argv)[i], string); - Py_DECREF(item); + PyObject* item = PySequence_Fast_GET_ITEM(args.object(), i); + char* string; + if (PyUnicode_Check(item)) { + Shiboken::AutoDecRef utf8(PyUnicode_AsUTF8String(item)); + string = strdup(PyString_AS_STRING(utf8.object())); + } else { + string = strdup(PyString_AS_STRING(item)); + } + (*argv)[i+1] = string; } - if (addAppName) { - (*argv)[0] = new char[strlen(defaultAppName)+1]; - (*argv)[0] = strcpy((*argv)[0], defaultAppName); - } + // Try to get the script name + PyObject* globals = PyEval_GetGlobals(); + PyObject* appName = PyDict_GetItemString(globals, "__file__"); + (*argv)[0] = strdup(appName ? PyString_AS_STRING(appName) : defaultAppName); return true; } diff --git a/libshiboken/helper.h b/libshiboken/helper.h index 363409076..a06304123 100644 --- a/libshiboken/helper.h +++ b/libshiboken/helper.h @@ -67,12 +67,20 @@ inline PyObject* makeTuple(const A& a, const B& b, const C& c, const D& d, const /** * It transforms a python sequence into two C variables, argc and argv. -* If the sequence is empty and defaultAppName was provided, argc will be 1 and -* argv will have a copy of defaultAppName. +* This function tries to find the application (script) name and put it into argv[0], if +* the application name can't be guessed, defaultAppName will be used. * -* \note argc and argv *should* be deleted by the user. +* No memory is allocated is an error occur. +* +* \note argc must be a valid address. +* \note The argv array is allocated using new operator and each item is allocated using malloc. * \returns True on sucess, false otherwise. */ +LIBSHIBOKEN_API bool sequenceToArgcArgv(PyObject* argList, int* argc, char*** argv, const char* defaultAppName = 0); + +/** + * \deprecated Use sequenceToArgcArgv instead. + */ LIBSHIBOKEN_API bool PySequenceToArgcArgv(PyObject* argList, int* argc, char*** argv, const char* defaultAppName = 0); /** -- cgit v1.2.3