Fix vararg documentation for Python 3
Memory handling is different to Python 2.
This commit is contained in:
parent
074c0039db
commit
f15eb3f5ec
3 changed files with 40 additions and 22 deletions
|
|
@ -509,10 +509,10 @@ like this:
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(in) (...)(char *args[10]) {
|
%typemap(in) (...)(char *vargs[10]) {
|
||||||
int i;
|
int i;
|
||||||
int argc;
|
int argc;
|
||||||
for (i = 0; i < 10; i++) args[i] = 0;
|
for (i = 0; i < 10; i++) vargs[i] = 0;
|
||||||
argc = PyTuple_Size(varargs);
|
argc = PyTuple_Size(varargs);
|
||||||
if (argc > 10) {
|
if (argc > 10) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Too many arguments");
|
PyErr_SetString(PyExc_ValueError, "Too many arguments");
|
||||||
|
|
@ -528,7 +528,7 @@ like this:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
pystr = PyUnicode_AsUTF8String(pyobj);
|
pystr = PyUnicode_AsUTF8String(pyobj);
|
||||||
str = PyBytes_AsString(pystr);
|
str = strdup(PyBytes_AsString(pystr));
|
||||||
Py_XDECREF(pystr);
|
Py_XDECREF(pystr);
|
||||||
%#else
|
%#else
|
||||||
if (!PyString_Check(pyobj)) {
|
if (!PyString_Check(pyobj)) {
|
||||||
|
|
@ -537,22 +537,34 @@ like this:
|
||||||
}
|
}
|
||||||
str = PyString_AsString(pyobj);
|
str = PyString_AsString(pyobj);
|
||||||
%#endif
|
%#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
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
In this typemap, the special variable <tt>varargs</tt> is a tuple
|
In the 'in' typemap, the special variable <tt>varargs</tt> is a tuple
|
||||||
holding all of the extra arguments passed (this is specific to the
|
holding all of the extra arguments passed (this is specific to the
|
||||||
Python module). The typemap then pulls this apart and sticks the
|
Python module). The typemap then pulls this apart and sticks the
|
||||||
values into the array of strings <tt>args</tt>. Then, the array is
|
values into the array of strings <tt>args</tt>. Then, the array is
|
||||||
assigned to <tt>$1</tt> (recall that this is the <tt>void *</tt>
|
assigned to <tt>$1</tt> (recall that this is the <tt>void *</tt>
|
||||||
variable corresponding to <tt>(...)</tt>). However, this assignment
|
variable corresponding to <tt>(...)</tt>). However, this assignment
|
||||||
is only half of the picture----clearly this alone is not enough to
|
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 <tt>execlp</tt> function is called. To patch everything
|
||||||
|
up, you have to rewrite the
|
||||||
underlying action code using the <tt>%feature</tt> directive like
|
underlying action code using the <tt>%feature</tt> directive like
|
||||||
this:
|
this:
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -560,9 +572,9 @@ this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%feature("action") execlp {
|
%feature("action") execlp {
|
||||||
char *args = (char **) arg3;
|
char **vargs = (char **) arg3;
|
||||||
result = execlp(arg1, arg2, args[0], args[1], args[2], args[3], args[4],
|
result = execlp(arg1, arg2, vargs[0], vargs[1], vargs[2], vargs[3], vargs[4],
|
||||||
args[5],args[6],args[7],args[8],args[9], NULL);
|
vargs[5], vargs[6], vargs[7], vargs[8], vargs[9], NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int execlp(const char *path, const char *arg, ...);
|
int execlp(const char *path, const char *arg, ...);
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,4 @@ if (python_varargs_typemap.testfunc(1, 2.0, "three") != "three") :
|
||||||
raise RuntimeError("testfunc failed!")
|
raise RuntimeError("testfunc failed!")
|
||||||
|
|
||||||
if (python_varargs_typemap.testfunc(1, 2.0, "three", "four", "five") != "threefourfive") :
|
if (python_varargs_typemap.testfunc(1, 2.0, "three", "four", "five") != "threefourfive") :
|
||||||
raise RuntimeError("testfunc failed!")
|
raise RuntimeError("testfunc failed! {}")
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,10 @@
|
||||||
* chapter of the SWIG manual.
|
* chapter of the SWIG manual.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
%{
|
%typemap(in) (...)(char *vargs[10]) {
|
||||||
%}
|
|
||||||
|
|
||||||
%typemap(in) (...)(char *args[10]) {
|
|
||||||
int i;
|
int i;
|
||||||
int argc;
|
int argc;
|
||||||
for (i = 0; i < 10; i++) args[i] = 0;
|
for (i = 0; i < 10; i++) vargs[i] = 0;
|
||||||
argc = PyTuple_Size(varargs);
|
argc = PyTuple_Size(varargs);
|
||||||
if (argc > 10) {
|
if (argc > 10) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Too many arguments");
|
PyErr_SetString(PyExc_ValueError, "Too many arguments");
|
||||||
|
|
@ -26,7 +23,7 @@
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
pystr = PyUnicode_AsUTF8String(pyobj);
|
pystr = PyUnicode_AsUTF8String(pyobj);
|
||||||
str = PyBytes_AsString(pystr);
|
str = strdup(PyBytes_AsString(pystr));
|
||||||
Py_XDECREF(pystr);
|
Py_XDECREF(pystr);
|
||||||
%#else
|
%#else
|
||||||
if (!PyString_Check(pyobj)) {
|
if (!PyString_Check(pyobj)) {
|
||||||
|
|
@ -35,15 +32,24 @@
|
||||||
}
|
}
|
||||||
str = PyString_AsString(pyobj);
|
str = PyString_AsString(pyobj);
|
||||||
%#endif
|
%#endif
|
||||||
args[i] = str;
|
vargs[i] = str;
|
||||||
}
|
}
|
||||||
$1 = (void *) args;
|
$1 = (void *)vargs;
|
||||||
}
|
}
|
||||||
|
|
||||||
%feature("action") testfunc {
|
%feature("action") testfunc {
|
||||||
char **args = (char **) arg3;
|
char **vargs = (char **) arg3;
|
||||||
result = testfunc(arg1, arg2, args[0], args[1], args[2], args[3], args[4],
|
result = testfunc(arg1, arg2, vargs[0], vargs[1], vargs[2], vargs[3], vargs[4],
|
||||||
args[5],args[6],args[7],args[8],args[9], NULL);
|
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 {
|
%inline {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue