%varargs - better documentation and remove additional argument generation which didn't work properly as a sentinel
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12666 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
6e87b73c40
commit
74aa3f218f
4 changed files with 57 additions and 16 deletions
|
|
@ -4,6 +4,14 @@ See the RELEASENOTES file for a summary of changes in each release.
|
||||||
|
|
||||||
Version 2.0.4 (in progress)
|
Version 2.0.4 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
2011-05-14: wsfulton
|
||||||
|
%varargs when used with a numeric argument used to create an additional argument
|
||||||
|
which was intended to provide a guaranteed sentinel value. This never worked and now
|
||||||
|
the additional argument is not generated.
|
||||||
|
|
||||||
|
2011-05-13: wsfulton
|
||||||
|
[python] Additional fixes for python3.2 support.
|
||||||
|
|
||||||
2011-05-07: szager
|
2011-05-07: szager
|
||||||
[python] Fixed PyGetSetDescr for python3.2.
|
[python] Fixed PyGetSetDescr for python3.2.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -331,33 +331,62 @@ int open(const char *path, int oflags, int mode = 0);
|
||||||
<p>
|
<p>
|
||||||
In this case, <tt>%varargs</tt> is simply providing more specific information about the
|
In this case, <tt>%varargs</tt> is simply providing more specific information about the
|
||||||
extra arguments that might be passed to a function.
|
extra arguments that might be passed to a function.
|
||||||
If the parameters to a varargs function are of uniform type, <tt>%varargs</tt> can also
|
If the arguments to a varargs function are of uniform type, <tt>%varargs</tt> can also
|
||||||
accept a numerical argument count as follows:
|
accept a numerical argument count as follows:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%varargs(10,char *arg = NULL) execlp;
|
%varargs(3, char *str = NULL) execlp;
|
||||||
...
|
...
|
||||||
int execlp(const char *path, const char *arg1, ...);
|
int execlp(const char *path, const char *arg, ...);
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
This would wrap <tt>execlp()</tt> as a function that accepted up to 10 optional arguments.
|
and is effectively seen as:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
int execlp(const char *path, const char *arg,
|
||||||
|
char *str1 = NULL,
|
||||||
|
char *str2 = NULL,
|
||||||
|
char *str3 = NULL);
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This would wrap <tt>execlp()</tt> as a function that accepted up to 3 optional arguments.
|
||||||
Depending on the application, this may be more than enough for practical purposes.
|
Depending on the application, this may be more than enough for practical purposes.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Argument replacement is most appropriate in cases where the types of
|
The handling of <a href="SWIGPlus.html#SWIGPlus_default_args">default arguments</a> can be changed via the
|
||||||
the extra arguments is uniform and the maximum number of arguments is
|
<tt>compactdefaultargs</tt> feature. If this feature is used, for example
|
||||||
known. When replicated argument replacement is used, at least one extra
|
</p>
|
||||||
argument is added to the end of the arguments when making the function call.
|
|
||||||
This argument serves as a sentinel to make sure the list is properly terminated.
|
<div class="code">
|
||||||
It has the same value as that supplied to the <tt>%varargs</tt> directive.
|
<pre>
|
||||||
|
%feature("compactdefaultargs") execlp;
|
||||||
|
%varargs(3, char *str = NULL) execlp;
|
||||||
|
...
|
||||||
|
int execlp(const char *path, const char *arg, ...);
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
a call from the target language which does not provide the maximum number of arguments, such as,
|
||||||
|
<tt>execlp("a", "b", "c")</tt>
|
||||||
|
will generate C code which includes the missing default values, that is, <tt>execlp("a", "b", "c", NULL, NULL)</tt>.
|
||||||
|
If <tt>compactdefaultargs</tt> is not used, then the generated code will be
|
||||||
|
<tt>execlp("a", "b", "c")</tt>. The former is useful for helping providing a sentinel to terminate the argument list.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
Argument replacement is most appropriate in cases where the types of
|
||||||
|
the extra arguments are uniform and the maximum number of arguments are
|
||||||
|
known.
|
||||||
Argument replacement is not as useful when working with functions that accept
|
Argument replacement is not as useful when working with functions that accept
|
||||||
mixed argument types such as <tt>printf()</tt>. Providing general purpose
|
mixed argument types such as <tt>printf()</tt>. Providing general purpose
|
||||||
wrappers to such functions presents special problems (covered shortly).
|
wrappers to such functions presents special problems (covered shortly).
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,10 @@ if varargs.test_plenty("Hello", 1) != "Hello":
|
||||||
if varargs.test_plenty("Hello", 1, 2) != "Hello":
|
if varargs.test_plenty("Hello", 1, 2) != "Hello":
|
||||||
raise RuntimeError, "Failed"
|
raise RuntimeError, "Failed"
|
||||||
|
|
||||||
if varargs.test_plenty("Hello", 1, 2, 3) != "Hello":
|
|
||||||
raise RuntimeError, "Failed"
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
varargs.test_plenty("Hello", 1, 2, 3, 4)
|
varargs.test_plenty("Hello", 1, 2, 3)
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
pass
|
pass
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
|
|
||||||
|
|
@ -2627,10 +2627,15 @@ varargs_parms : parms { $$ = $1; }
|
||||||
Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n");
|
Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n");
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
} else {
|
} else {
|
||||||
|
String *name = Getattr($3, "name");
|
||||||
$$ = Copy($3);
|
$$ = Copy($3);
|
||||||
Setattr($$,"name","VARARGS_SENTINEL");
|
if (name)
|
||||||
for (i = 0; i < n; i++) {
|
Setattr($$, "name", NewStringf("%s%d", name, n));
|
||||||
|
for (i = 1; i < n; i++) {
|
||||||
p = Copy($3);
|
p = Copy($3);
|
||||||
|
name = Getattr(p, "name");
|
||||||
|
if (name)
|
||||||
|
Setattr(p, "name", NewStringf("%s%d", name, n-i));
|
||||||
set_nextSibling(p,$$);
|
set_nextSibling(p,$$);
|
||||||
Delete($$);
|
Delete($$);
|
||||||
$$ = p;
|
$$ = p;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue