Support special variable expansion in special variable macros in typemap attributes.

Add test cases for special variable expansions and special variable
macros (aka embedded typemaps) expansion.
This commit is contained in:
William S Fulton 2015-07-22 13:02:15 +01:00
commit 2f00f6c8cc
4 changed files with 234 additions and 16 deletions

View file

@ -374,6 +374,7 @@ CPP_TEST_CASES += \
smart_pointer_templatevariables \
smart_pointer_typedef \
special_variables \
special_variable_attributes \
special_variable_macros \
static_array_member \
static_const_member \

View file

@ -0,0 +1,32 @@
// This is the bool runtime testcase. It checks that the C++ bool type works.
using System;
using special_variable_attributesNamespace;
public class special_variable_attributes_runme {
public static void Main() {
if (special_variable_attributes.getNumber1() != 111)
throw new ApplicationException("getNumber1 failed");
if (special_variable_attributes.getNumber2() != 222)
throw new ApplicationException("getNumber2 failed");
if (special_variable_attributes.getNumber3() != 333)
throw new ApplicationException("getNumber3 failed");
if (special_variable_attributes.bounceNumber1(10) != 110)
throw new ApplicationException("bounceNumber1 failed");
if (special_variable_attributes.bounceNumber2(10) != 220)
throw new ApplicationException("bounceNumber2 failed");
if (special_variable_attributes.bounceNumber3(10) != 330)
throw new ApplicationException("bounceNumber3 failed");
if (special_variable_attributes.multi1(12.34) != 12+34)
throw new ApplicationException("multi1 failed");
if (special_variable_attributes.multi2(12.34) != 12+34+55)
throw new ApplicationException("multi2 failed");
if (special_variable_attributes.multi3(12.34) != 12+34+77)
throw new ApplicationException("multi3 failed");
}
}

View file

@ -0,0 +1,170 @@
%module special_variable_attributes
// Special variable expansion and special variable macros, aka embedded typemaps - expansion tests
// Tests these are expanded within typemap attributes.
// Also tests that these are expanded when used together, so that the special variables
// can be used as the type passed to the special variable macro.
// C# is used for testing as it is one of the few languages that uses a lot of typemap attributes.
// Attributes in both 'in' and 'out' typemaps are needed, that is,
// typemaps targeting both parameters and return values respectively).
#ifdef SWIGCSHARP
// Check special variable expansion in typemap attributes.
// This changes return by reference into return by value.
// Takes advantage of the fact that 'int' is a valid type in both C and C#.
// This is not a realistic use, just a way to test the variable expansion in the 'out' attribute.
%typemap(ctype, out="$*1_ltype") int& getNumber1 "_not_used_"
%typemap(imtype, out="$*1_ltype") int& getNumber1 "_not_used_"
%typemap(cstype, out="$*1_ltype") int& getNumber1 "_not_used_"
%typemap(out) int& getNumber1 "$result = *$1;"
%typemap(csout, excode=SWIGEXCODE) int & getNumber1 {
int ret = $imcall;$excode
return ret;
}
#endif
%inline %{
int& getNumber1() {
static int num = 111;
return num;
}
%}
#ifdef SWIGCSHARP
// Check special variable macro expansion in typemap attributes.
// This changes return by reference into return by value.
%typemap(ctype, out="$typemap(ctype, int)") int& getNumber2 "_not_used_"
%typemap(imtype, out="$typemap(imtype, int)") int& getNumber2 "_not_used_"
%typemap(cstype, out="$typemap(cstype, int)") int& getNumber2 "_not_used_"
%typemap(out) int& getNumber2 "$result = *$1;"
%typemap(csout, excode=SWIGEXCODE) int & getNumber2 {
int ret = $imcall;$excode
return ret;
}
#endif
%inline %{
int& getNumber2() {
static int num = 222;
return num;
}
%}
#ifdef SWIGCSHARP
// Check special variable macro expansion and special variable expansion in typemap attributes.
// This changes return by reference into return by value.
%typemap(ctype, out="$typemap(ctype, $*1_ltype)") int& getNumber3 "_not_used_"
%typemap(imtype, out="$typemap(imtype, $*1_ltype)") int& getNumber3 "_not_used_"
%typemap(cstype, out="$typemap(cstype, $*1_ltype)") int& getNumber3 "_not_used_"
%typemap(out) int& getNumber3 "$result = *$1;"
%typemap(csout, excode=SWIGEXCODE) int & getNumber3 {
int ret = $imcall;$excode
return ret;
}
#endif
%inline %{
int& getNumber3() {
static int num = 333;
return num;
}
%}
#ifdef SWIGCSHARP
// Check special variable macro expansion in typemap attributes.
%typemap(csin,
pre=" $typemap(cstype, int) $csinput_scaled = 11;"
) int num1
%{$csinput * $csinput_scaled %}
#endif
%inline %{
int bounceNumber1(int num1) {
return num1;
}
%}
#ifdef SWIGCSHARP
// Check special variable expansion in typemap attributes.
%typemap(csin,
pre=" $1_type $csinput_scaled = 22;"
) int num2
%{$csinput * $csinput_scaled %}
#endif
%inline %{
int bounceNumber2(int num2) {
return num2;
}
%}
#ifdef SWIGCSHARP
// Check special variable and special variable macro expansion in typemap attributes.
%typemap(csin,
pre=" $typemap(cstype, $1_type) $csinput_scaled = 33;"
) int num3
%{$csinput * $csinput_scaled %}
#endif
%inline %{
int bounceNumber3(int num3) {
return num3;
}
%}
/////////////////////////////////
//// Multi-argument typemaps ////
/////////////////////////////////
// Test expansion of special variables
#ifdef SWIGCSHARP
%typemap(ctype) (int intvar, char charvar) "double"
%typemap(imtype) (int intvar, char charvar) "double"
%typemap(cstype) (int intvar, char charvar) "double"
%typemap(in) (int intvar, char charvar)
%{
// split double value a.b into two numbers, a and b*100
$1 = (int)$input;
$2 = ($input - $1 + 0.005) * 100;
%}
%typemap(csin,
pre=" $1_type $csinput_$1_type = 50;\n" // $1_type should expand to int
" $2_type $csinput_$2_type = 'A';" // $2_type should expand to char
) (int intvar, char charvar)
%{$csinput + ($csinput_int - 50 + $csinput_char - 'A') + ($csinput_$1_type - 50 + $csinput_$2_type - 'A')%}
#endif
%inline %{
int multi1(int intvar, char charvar) {
return intvar + charvar;
}
%}
#ifdef SWIGCSHARP
%typemap(csin,
pre=" $typemap(cstype, int) $csinput_$typemap(cstype, int) = 50;\n" // also should expand to int
" $typemap(cstype, char) $csinput_$typemap(cstype, char) = 'A';" // also should expand to char
) (int intvar, char charvar)
%{55 + $csinput + ($csinput_int - 50 + $csinput_char - 'A') + ($csinput_$typemap(cstype, int) - 50 + $csinput_$typemap(cstype, char) - 'A')%}
#endif
%inline %{
int multi2(int intvar, char charvar) {
return intvar + charvar;
}
%}
#ifdef SWIGCSHARP
%typemap(csin,
pre=" $typemap(cstype, $1_type) $csinput_$typemap(cstype, $1_type) = 50;\n" // also should expand to int
" $typemap(cstype, $2_type) $csinput_$typemap(cstype, $2_type) = 'A';" // also should expand to char
) (int intvar, char charvar)
%{77 + $csinput + ($csinput_int - 50 + $csinput_char - 'A') + ($csinput_$typemap(cstype, $1_type) - 50 + $csinput_$typemap(cstype, $2_type) - 'A')%}
#endif
%inline %{
int multi3(int intvar, char charvar) {
return intvar + charvar;
}
%}

View file

@ -1398,14 +1398,16 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No
String *kwtype = Getattr(kw, "type");
char *ckwname = Char(Getattr(kw, "name"));
{
/* Expand variables and typemaps in kwargs. */
/* Expand special variables in typemap attributes. */
SwigType *ptype = Getattr(node, "type");
String *pname = Getattr(node, "name");
String *lname = Getattr(node, "lname");
SwigType *mtype = Getattr(node, "tmap:match");
SwigType *matchtype = mtype ? mtype : ptype;
ParmList *parm_sublist;
typemap_replace_vars(value, NULL, matchtype, ptype, pname, lname, 0);
typemap_replace_vars(value, NULL, matchtype, ptype, pname, lname, 1);
/* Expand special variable macros (embedded typemaps) in typemap attributes. */
parm_sublist = NewParmWithoutFileLineInfo(ptype, pname);
Setattr(parm_sublist, "lname", lname);
replace_embedded_typemap(value, parm_sublist, NULL, tm);
@ -1572,30 +1574,43 @@ String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *node, co
* If this hash (tm) contains a linked list of parameters under its "kwargs"
* attribute, add keys for each of those named keyword arguments to this
* parameter for later use.
* For example, attach the typemap attributes to p:
* For example, attach the typemap attributes to firstp (first parameter in parameter list):
* %typemap(in, foo="xyz") ...
* A new attribute called "tmap:in:foo" with value "xyz" is attached to p.
* A new attribute called "tmap:in:foo" with value "xyz" is attached to firstp.
* Also expands special variables and special variable macros in the typemap attributes.
* ----------------------------------------------------------------------------- */
static void typemap_attach_kwargs(Hash *tm, const_String_or_char_ptr tmap_method, Parm *p) {
static void typemap_attach_kwargs(Hash *tm, const_String_or_char_ptr tmap_method, Parm *firstp, int nmatch) {
String *temp = NewStringEmpty();
Parm *kw = Getattr(tm, "kwargs");
while (kw) {
String *value = Copy(Getattr(kw, "value"));
String *type = Getattr(kw, "type");
{
/* Expand variables and typemaps in kwargs. */
SwigType *ptype = Getattr(p, "type");
int i;
Parm *p = firstp;
/* Expand special variables */
for (i = 0; i < nmatch; i++) {
SwigType *type = Getattr(p, "type");
String *pname = Getattr(p, "name");
String *lname = Getattr(p, "lname");
SwigType *mtype = Getattr(p, "tmap:match");
SwigType *matchtype = mtype ? mtype : ptype;
ParmList *parm_sublist;
typemap_replace_vars(value, NULL, matchtype, ptype, pname, lname, 0);
parm_sublist = NewParmWithoutFileLineInfo(ptype, pname);
SwigType *matchtype = mtype ? mtype : type;
typemap_replace_vars(value, NULL, matchtype, type, pname, lname, i + 1);
p = nextSibling(p);
}
/* Expand special variable macros (embedded typemaps).
* Special variable are expanded first above as they might be used in the special variable macros.
* For example: $typemap(imtype, $2_type). */
p = firstp;
for (i = 0; i < nmatch; i++) {
SwigType *type = Getattr(p, "type");
String *pname = Getattr(p, "name");
String *lname = Getattr(p, "lname");
ParmList *parm_sublist = NewParmWithoutFileLineInfo(type, pname);
Setattr(parm_sublist, "lname", lname);
replace_embedded_typemap(value, parm_sublist, NULL, tm);
Delete(parm_sublist);
p = nextSibling(p);
}
if (type) {
Hash *v = NewHash();
@ -1606,13 +1621,13 @@ static void typemap_attach_kwargs(Hash *tm, const_String_or_char_ptr tmap_method
}
Clear(temp);
Printf(temp, "%s:%s", tmap_method, Getattr(kw, "name"));
Setattr(p, typemap_method_name(temp), value);
Setattr(firstp, typemap_method_name(temp), value);
Delete(value);
kw = nextSibling(kw);
}
Clear(temp);
Printf(temp, "%s:match_type", tmap_method);
Setattr(p, typemap_method_name(temp), Getattr(tm, "type"));
Setattr(firstp, typemap_method_name(temp), Getattr(tm, "type"));
Delete(temp);
}
@ -1807,7 +1822,7 @@ void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *p
Setattr(firstp, typemap_method_name(temp), p);
/* Attach kwargs */
typemap_attach_kwargs(tm, tmap_method, firstp);
typemap_attach_kwargs(tm, tmap_method, firstp, nmatch);
/* Replace the argument number */
sprintf(temp, "%d", argnum);