From f15eb3f5ec3ee77d521d675f42654edde9c46509 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 24 May 2013 22:51:27 +0100 Subject: Fix vararg documentation for Python 3 Memory handling is different to Python 2. --- Doc/Manual/Varargs.html | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'Doc/Manual') 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, ...);
-- 
cgit v1.2.3