diff --git a/Doc/Manual/Varargs.html b/Doc/Manual/Varargs.html index a580c83bd..9564fe00b 100644 --- a/Doc/Manual/Varargs.html +++ b/Doc/Manual/Varargs.html @@ -509,10 +509,10 @@ like this:
-%typemap(in) (...)(char *args[10]) {
+%typemap(in) (...)(char *vargs[10]) {
   int i;
   int argc;
-  for (i = 0; i < 10; i++) args[i] = 0;
+  for (i = 0; i < 10; i++) vargs[i] = 0;
   argc = PyTuple_Size(varargs);
   if (argc > 10) {
     PyErr_SetString(PyExc_ValueError, "Too many arguments");
@@ -528,7 +528,7 @@ like this:
        return NULL;
     }
     pystr = PyUnicode_AsUTF8String(pyobj);
-    str = PyBytes_AsString(pystr);
+    str = strdup(PyBytes_AsString(pystr));
     Py_XDECREF(pystr);
 %#else  
     if (!PyString_Check(pyobj)) {
@@ -537,22 +537,34 @@ like this:
     }
     str = PyString_AsString(pyobj);
 %#endif
-    args[i] = str;
+    vargs[i] = str;
   }
-  $1 = (void *) args;
+  $1 = (void *)vargs;
+}
+
+%typemap(freearg) (...) {
+%#if PY_VERSION_HEX>=0x03000000
+  int i;
+  for (i = 0; i < 10; i++) {
+    free(vargs$argnum[i]);
+  }
+%#endif
 }
 

-In this typemap, the special variable varargs is a tuple +In the 'in' typemap, the special variable varargs is a tuple holding all of the extra arguments passed (this is specific to the Python module). The typemap then pulls this apart and sticks the values into the array of strings args. Then, the array is assigned to $1 (recall that this is the void * variable corresponding to (...)). However, this assignment is only half of the picture----clearly this alone is not enough to -make the function work. To patch everything up, you have to rewrite the +make the function work. The 'freearg' typemap cleans up memory +allocated in the 'in' typemap; this code is generated to be called +after the execlp function is called. To patch everything +up, you have to rewrite the underlying action code using the %feature directive like this:

@@ -560,9 +572,9 @@ this:
 %feature("action") execlp {
-   char *args = (char **) arg3;
-   result = execlp(arg1, arg2, args[0], args[1], args[2], args[3], args[4],
-                   args[5],args[6],args[7],args[8],args[9], NULL);
+  char **vargs = (char **) arg3;
+  result = execlp(arg1, arg2, vargs[0], vargs[1], vargs[2], vargs[3], vargs[4],
+                  vargs[5], vargs[6], vargs[7], vargs[8], vargs[9], NULL);
 }
 
 int execlp(const char *path, const char *arg, ...);
diff --git a/Examples/test-suite/python/python_varargs_typemap_runme.py b/Examples/test-suite/python/python_varargs_typemap_runme.py
index 79479e449..65be757c8 100644
--- a/Examples/test-suite/python/python_varargs_typemap_runme.py
+++ b/Examples/test-suite/python/python_varargs_typemap_runme.py
@@ -4,4 +4,4 @@ if (python_varargs_typemap.testfunc(1, 2.0, "three") != "three") :
     raise RuntimeError("testfunc failed!")
 
 if (python_varargs_typemap.testfunc(1, 2.0, "three", "four", "five") != "threefourfive") :
-    raise RuntimeError("testfunc failed!")
+    raise RuntimeError("testfunc failed! {}")
diff --git a/Examples/test-suite/python_varargs_typemap.i b/Examples/test-suite/python_varargs_typemap.i
index 09189f654..09deea3b7 100644
--- a/Examples/test-suite/python_varargs_typemap.i
+++ b/Examples/test-suite/python_varargs_typemap.i
@@ -4,13 +4,10 @@
   * chapter of the SWIG manual.
   */
 
-%{
-%}
-
-%typemap(in) (...)(char *args[10]) {
+%typemap(in) (...)(char *vargs[10]) {
   int i;
   int argc;
-  for (i = 0; i < 10; i++) args[i] = 0;
+  for (i = 0; i < 10; i++) vargs[i] = 0;
   argc = PyTuple_Size(varargs);
   if (argc > 10) {
     PyErr_SetString(PyExc_ValueError, "Too many arguments");
@@ -26,7 +23,7 @@
        return NULL;
     }
     pystr = PyUnicode_AsUTF8String(pyobj);
-    str = PyBytes_AsString(pystr);
+    str = strdup(PyBytes_AsString(pystr));
     Py_XDECREF(pystr);
 %#else  
     if (!PyString_Check(pyobj)) {
@@ -35,15 +32,24 @@
     }
     str = PyString_AsString(pyobj);
 %#endif
-    args[i] = str;
+    vargs[i] = str;
   }
-  $1 = (void *) args;
+  $1 = (void *)vargs;
 }
 
 %feature("action") testfunc {
-  char **args = (char **) arg3;
-  result = testfunc(arg1, arg2, args[0], args[1], args[2], args[3], args[4],
-                    args[5],args[6],args[7],args[8],args[9], NULL);
+  char **vargs = (char **) arg3;
+  result = testfunc(arg1, arg2, vargs[0], vargs[1], vargs[2], vargs[3], vargs[4],
+                    vargs[5], vargs[6], vargs[7], vargs[8], vargs[9], NULL);
+}
+
+%typemap(freearg) (...) {
+%#if PY_VERSION_HEX>=0x03000000
+  int i;
+  for (i = 0; i < 10; i++) {
+    free(vargs$argnum[i]);
+  }
+%#endif
 }
 
 %inline {