Support special variable expansion in %extend.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@13871 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2012-10-11 19:28:02 +00:00
commit b17a77c6ea
9 changed files with 117 additions and 40 deletions

View file

@ -4,16 +4,21 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.9 (in progress) Version 2.0.9 (in progress)
=========================== ===========================
2012-10-11: wsfulton
Most of the special variables available for use in %exception are now also available for expansion in
%extend blocks. These are: $name $symname $overname $decl $fulldecl $parentname $parentsymname, see docs
on "Class extension" in SWIGPlus.html. Patch based on submission from Kris Thielemans.
2012-10-10: wsfulton
Additional new special variables in %exception are expanded as follows:
$parentname - The parent class name (if any) for a method.
$parentsymname - The target language parent class name (if any) for a method.
2012-10-08: iant 2012-10-08: iant
[Go] Generating Go code now requires using the -intgosize option to [Go] Generating Go code now requires using the -intgosize option to
indicate the size of the 'int' type in Go. This is because the indicate the size of the 'int' type in Go. This is because the
size of the type is changing from Go 1.0 to Go 1.1 for x86_64. size of the type is changing from Go 1.0 to Go 1.1 for x86_64.
2012-09-14: wsfulton
Additional new special variables in %exception are expanded as follows:
$parentname - The parent class name (if any) for a method.
$parentsymname - The target language parent class name (if any) for a method.
2012-09-14: wsfulton 2012-09-14: wsfulton
Add new warning if the empty template instantiation is used as a base class, for example: Add new warning if the empty template instantiation is used as a base class, for example:

View file

@ -454,6 +454,11 @@ variables are replaced with.
<td>The actual operation to be performed (a function call, method invocation, variable access, etc.)</td> <td>The actual operation to be performed (a function call, method invocation, variable access, etc.)</td>
</tr> </tr>
<tr>
<td>$name</td>
<td>The C/C++ symbol name for the function.</td>
</tr>
<tr> <tr>
<td>$symname</td> <td>$symname</td>
<td>The symbol name used internally by SWIG</td> <td>The symbol name used internally by SWIG</td>

View file

@ -2838,6 +2838,12 @@ struct Derived : Base {
} }
</pre></div> </pre></div>
<p>
The following special variables are expanded if used within a %extend block:
$name, $symname, $overname, $decl, $fulldecl, $parentname and $parentsymname.
The <a href="Customization.html#Customization_exception_special_variables">Special variables</a> section provides more information each of these special variables.
</p>
<p> <p>
The<tt> %extend</tt> directive follows all of the same conventions The<tt> %extend</tt> directive follows all of the same conventions
as its use with C structures. Please refer to the <a href="SWIG.html#SWIG_adding_member_functions">Adding member functions to C structures</a> as its use with C structures. Please refer to the <a href="SWIG.html#SWIG_adding_member_functions">Adding member functions to C structures</a>

View file

@ -204,6 +204,7 @@ CPP_TEST_CASES += \
extend_constructor_destructor \ extend_constructor_destructor \
extend_default \ extend_default \
extend_placement \ extend_placement \
extend_special_variables \
extend_template \ extend_template \
extend_template_ns \ extend_template_ns \
extend_typedef_class \ extend_typedef_class \

View file

@ -0,0 +1,21 @@
%module extend_special_variables
%rename(ForExtensionNewName) ForExtension;
%rename(extended_renamed) ForExtension::extended;
%extend ForExtension {
ForExtension() {
return new ForExtension();
}
const char* extended() {
return "name:$name symname:$symname wrapname:$wrapname overname:$overname decl:$decl fulldecl:$fulldecl parentclasssymname:$parentclasssymname parentclassname:$parentclassname";
}
const char* extended(int) {
return "name:$name symname:$symname wrapname:$wrapname overname:$overname decl:$decl fulldecl:$fulldecl parentclasssymname:$parentclasssymname parentclassname:$parentclassname";
}
}
%inline %{
struct ForExtension {
};
%}

View file

@ -0,0 +1,25 @@
import extend_special_variables.*;
public class extend_special_variables_runme {
static {
try {
System.loadLibrary("extend_special_variables");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[])
{
ForExtensionNewName f = new ForExtensionNewName();
verify(f.extended_renamed(), "name:extended symname:extended_renamed wrapname: overname:__SWIG_0 decl:ForExtension::extended() fulldecl:char const * ForExtension::extended() parentclasssymname:ForExtensionNewName parentclassname:ForExtension");
verify(f.extended_renamed(10), "name:extended symname:extended_renamed wrapname: overname:__SWIG_1 decl:ForExtension::extended(int) fulldecl:char const * ForExtension::extended(int) parentclasssymname:ForExtensionNewName parentclassname:ForExtension");
}
static void verify(String received, String expected) {
if (!received.equals(expected))
throw new RuntimeException("Incorrect, received: " + received);
}
}

View file

@ -363,39 +363,9 @@ int emit_action_code(Node *n, String *wrappercode, String *eaction) {
tm = Copy(tm); tm = Copy(tm);
if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) { if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
if (Strstr(tm, "$")) { if (Strstr(tm, "$")) {
Replaceall(tm, "$name", Getattr(n, "name")); Swig_replace_special_variables(n, parentNode(n), tm);
Replaceall(tm, "$symname", Getattr(n, "sym:name"));
Replaceall(tm, "$function", eaction); // deprecated Replaceall(tm, "$function", eaction); // deprecated
Replaceall(tm, "$action", eaction); Replaceall(tm, "$action", eaction);
Replaceall(tm, "$wrapname", Getattr(n, "wrap:name"));
String *overloaded = Getattr(n, "sym:overloaded");
Replaceall(tm, "$overname", overloaded ? Char(Getattr(n, "sym:overname")) : "");
if (Strstr(tm, "$decl")) {
String *decl = Swig_name_decl(n);
Replaceall(tm, "$decl", decl);
Delete(decl);
}
if (Strstr(tm, "$fulldecl")) {
String *fulldecl = Swig_name_fulldecl(n);
Replaceall(tm, "$fulldecl", fulldecl);
Delete(fulldecl);
}
Node *parentnode = parentNode(n);
Node *parentclass = (parentnode && Equal(nodeType(parentnode), "class")) ? parentnode : 0;
if (Strstr(tm, "$parentclasssymname")) {
String *parentclasssymname = 0;
if (parentclass)
parentclasssymname = Getattr(parentclass, "sym:name");
Replaceall(tm, "$parentclasssymname", parentclasssymname ? parentclasssymname : "");
}
if (Strstr(tm, "$parentclassname")) {
String *parentclassname = 0;
if (parentclass)
parentclassname = Getattr(parentclass, "name");
Replaceall(tm, "$parentclassname", parentclassname ? parentclassname : "");
}
} }
Printv(wrappercode, tm, "\n", NIL); Printv(wrappercode, tm, "\n", NIL);
Delete(tm); Delete(tm);

View file

@ -759,6 +759,46 @@ String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String
return func; return func;
} }
/* -----------------------------------------------------------------------------
* Swig_replace_special_variables()
*
* Replaces special variables with a value from the supplied node
* ----------------------------------------------------------------------------- */
void Swig_replace_special_variables(Node *n, Node *parentnode, String *code) {
Node *parentclass = parentnode;
String *overloaded = Getattr(n, "sym:overloaded");
Replaceall(code, "$name", Getattr(n, "name"));
Replaceall(code, "$symname", Getattr(n, "sym:name"));
Replaceall(code, "$wrapname", Getattr(n, "wrap:name"));
Replaceall(code, "$overname", overloaded ? Char(Getattr(n, "sym:overname")) : "");
if (Strstr(code, "$decl")) {
String *decl = Swig_name_decl(n);
Replaceall(code, "$decl", decl);
Delete(decl);
}
if (Strstr(code, "$fulldecl")) {
String *fulldecl = Swig_name_fulldecl(n);
Replaceall(code, "$fulldecl", fulldecl);
Delete(fulldecl);
}
if (parentclass && !Equal(nodeType(parentclass), "class"))
parentclass = 0;
if (Strstr(code, "$parentclasssymname")) {
String *parentclasssymname = 0;
if (parentclass)
parentclasssymname = Getattr(parentclass, "sym:name");
Replaceall(code, "$parentclasssymname", parentclasssymname ? parentclasssymname : "");
}
if (Strstr(code, "$parentclassname")) {
String *parentclassname = 0;
if (parentclass)
parentclassname = Getattr(parentclass, "name");
Replaceall(code, "$parentclassname", parentclassname ? parentclassname : "");
}
}
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* extension_code() * extension_code()
* *
@ -767,14 +807,17 @@ String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String
* return_type function_name(parms) code * return_type function_name(parms) code
* *
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
static String *extension_code(const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) { static String *extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) {
String *parms_str = cplusplus ? ParmList_str_defaultargs(parms) : ParmList_str(parms); String *parms_str = cplusplus ? ParmList_str_defaultargs(parms) : ParmList_str(parms);
String *sig = NewStringf("%s(%s)", function_name, parms_str); String *sig = NewStringf("%s(%s)", function_name, parms_str);
String *rt_sig = SwigType_str(return_type, sig); String *rt_sig = SwigType_str(return_type, sig);
String *body = NewStringf("SWIGINTERN %s", rt_sig); String *body = NewStringf("SWIGINTERN %s", rt_sig);
Printv(body, code, "\n", NIL); Printv(body, code, "\n", NIL);
if (self) if (Strstr(body, "$")) {
Replaceall(body, "$self", self); Swig_replace_special_variables(n, parentNode(parentNode(n)), body);
if (self)
Replaceall(body, "$self", self);
}
Delete(parms_str); Delete(parms_str);
Delete(sig); Delete(sig);
Delete(rt_sig); Delete(rt_sig);
@ -791,7 +834,7 @@ static String *extension_code(const String *function_name, ParmList *parms, Swig
* *
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) { int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) {
String *body = extension_code(function_name, parms, return_type, code, cplusplus, self); String *body = extension_code(n, function_name, parms, return_type, code, cplusplus, self);
Setattr(n, "wrap:code", body); Setattr(n, "wrap:code", body);
Delete(body); Delete(body);
return SWIG_OK; return SWIG_OK;

View file

@ -354,6 +354,7 @@ extern int ParmList_is_compactdefargs(ParmList *p);
extern String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String *self, int varcref); extern String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String *self, int varcref);
extern int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self); extern int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self);
extern void Swig_replace_special_variables(Node *n, Node *parentnode, String *code);
/* --- Transformations --- */ /* --- Transformations --- */