| /* ------------------------------------------------------------- | |
| * SWIG library containing argc and argv multi-argument typemaps | |
| * ------------------------------------------------------------- */ | |
| %fragment("SWIG_AsArgcArgv", "header", fragment="SWIG_AsCharPtrAndSize") { | |
| SWIGINTERN int | |
| SWIG_AsArgcArgv(PyObject *input, swig_type_info *ppchar_info, size_t *argc, char ***argv, int *owner) { | |
| void *vptr; | |
| int res = SWIG_ConvertPtr(input, &vptr, ppchar_info, 0); | |
| if (SWIG_IsOK(res)) { | |
| /* seems dangerous, but the user asked for it... */ | |
| size_t i = 0; | |
| if (argv && *argv) { while ((*argv)[i] != 0) ++i; } | |
| if (argc) *argc = i; | |
| if (owner) *owner = 0; | |
| return SWIG_OK; | |
| } | |
| PyErr_Clear(); | |
| int is_list = PyList_Check(input); | |
| if (!is_list && !PyTuple_Check(input)) return SWIG_TypeError; | |
| size_t i; | |
| res = SWIG_OK; | |
| size_t size = is_list ? PyList_Size(input) : PyTuple_Size(input); | |
| if (argv != NULL) { | |
| char **p = %new_array(size + 1, char*); | |
| if (p == NULL) { | |
| SWIG_Error(SWIG_MemoryError, "Failed to allocate memory for 'int ARGC, char **ARGV'"); | |
| return SWIG_ERROR; | |
| } | |
| *argv = p; | |
| } | |
| for (i = 0; i < size; ++i) { | |
| /* Thread safety: a list could be modified by another thread while this function | |
| is running, causing its elements to get dereferenced between PyList_GetItem and | |
| SWIG_AsCharPtrAndSize, resulting in a segfault. | |
| tuples are immutable, so this is not an issue for them. */ | |
| PyObject *obj = is_list ? SWIG_PyList_GetItemRef(input, i) : PyTuple_GetItem(input, i); | |
| if (!obj) { | |
| /* List was shrunk by another thread. Return early with SWIG_OK. */ | |
| PyErr_Clear(); | |
| break; | |
| } | |
| if (argv) { | |
| char *cptr = 0; size_t sz = 0; int alloc = 0; | |
| res = SWIG_AsCharPtrAndSize(obj, &cptr, &sz, &alloc); | |
| if (SWIG_IsOK(res)) { | |
| if (cptr && sz) { | |
| if (alloc == SWIG_NEWOBJ) { | |
| (*argv)[i] = cptr; | |
| } else { | |
| char *p = %new_array(sz, char); | |
| if (p == NULL) { | |
| SWIG_Error(SWIG_MemoryError, "Failed to allocate string for 'int ARGC, char **ARGV'"); | |
| (*argv)[i] = 0; | |
| res = SWIG_MemoryError; | |
| } else { | |
| memcpy(p, cptr, sz); | |
| (*argv)[i] = p; | |
| } | |
| } | |
| } else { | |
| (*argv)[i] = 0; | |
| } | |
| } | |
| } else { | |
| res = SWIG_AsCharPtrAndSize(obj, 0, 0, 0); | |
| } | |
| if (is_list) Py_DECREF(obj); | |
| if (!SWIG_IsOK(res)) break; | |
| } | |
| if (argc) *argc = i; // Covers early exits from for loop | |
| if (argv) (*argv)[i] = 0; | |
| if (owner) *owner = 1; | |
| return res; | |
| } | |
| } | |
| /* | |
| This typemap works with either a char **, a python list or a python | |
| tuple | |
| */ | |
| %typemap(in,noblock=0,fragment="SWIG_AsArgcArgv") (int ARGC, char **ARGV) (int res,char **argv = 0, size_t argc = 0, int owner= 0) { | |
| res = SWIG_AsArgcArgv($input, $descriptor(char**), &argc, &argv, &owner); | |
| if (!SWIG_IsOK(res)) { | |
| $1 = 0; $2 = 0; | |
| %argument_fail(SWIG_TypeError, "int ARGC, char **ARGV", $symname, $argnum); | |
| } else { | |
| $1 = %static_cast(argc,$1_ltype); | |
| $2 = %static_cast(argv, $2_ltype); | |
| } | |
| } | |
| %typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) { | |
| int res = SWIG_AsArgcArgv($input, $descriptor(char**), 0, 0, 0); | |
| $1 = SWIG_IsOK(res); | |
| } | |
| %typemap(freearg,noblock=1) (int ARGC, char **ARGV) { | |
| if (owner$argnum) { | |
| size_t i = argc$argnum; | |
| while (i) %delete_array(argv$argnum[--i]); | |
| %delete_array(argv$argnum); | |
| } | |
| } |