%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:
William S Fulton 2011-05-14 00:13:43 +00:00
commit 74aa3f218f
4 changed files with 57 additions and 16 deletions

View file

@ -4,6 +4,14 @@ See the RELEASENOTES file for a summary of changes in each release.
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
[python] Fixed PyGetSetDescr for python3.2.

View file

@ -331,33 +331,62 @@ int open(const char *path, int oflags, int mode = 0);
<p>
In this case, <tt>%varargs</tt> is simply providing more specific information about the
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:
</p>
<div class="code">
<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>
</div>
<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.
</p>
<p>
Argument replacement is most appropriate in cases where the types of
the extra arguments is uniform and the maximum number of arguments is
known. When replicated argument replacement is used, at least one extra
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.
It has the same value as that supplied to the <tt>%varargs</tt> directive.
The handling of <a href="SWIGPlus.html#SWIGPlus_default_args">default arguments</a> can be changed via the
<tt>compactdefaultargs</tt> feature. If this feature is used, for example
</p>
<div class="code">
<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>
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
mixed argument types such as <tt>printf()</tt>. Providing general purpose
wrappers to such functions presents special problems (covered shortly).

View file

@ -27,11 +27,10 @@ if varargs.test_plenty("Hello", 1) != "Hello":
if varargs.test_plenty("Hello", 1, 2) != "Hello":
raise RuntimeError, "Failed"
if varargs.test_plenty("Hello", 1, 2, 3) != "Hello":
raise RuntimeError, "Failed"
try:
varargs.test_plenty("Hello", 1, 2, 3, 4)
varargs.test_plenty("Hello", 1, 2, 3)
raise RuntimeError
except NotImplementedError:
pass
except TypeError:
pass

View file

@ -2627,10 +2627,15 @@ varargs_parms : parms { $$ = $1; }
Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n");
$$ = 0;
} else {
String *name = Getattr($3, "name");
$$ = Copy($3);
Setattr($$,"name","VARARGS_SENTINEL");
for (i = 0; i < n; i++) {
if (name)
Setattr($$, "name", NewStringf("%s%d", name, n));
for (i = 1; i < n; i++) {
p = Copy($3);
name = Getattr(p, "name");
if (name)
Setattr(p, "name", NewStringf("%s%d", name, n-i));
set_nextSibling(p,$$);
Delete($$);
$$ = p;