Additions to %types so that a user can specify the code to go into the casting / conversion function

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@10222 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2008-01-31 22:45:59 +00:00
commit 629aae375c
5 changed files with 76 additions and 13 deletions

View file

@ -1,6 +1,37 @@
Version 1.3.34 (in progress) Version 1.3.34 (in progress)
============================ ============================
01/31/2008: wsfulton
Additions to the %types directive. Now the conversion / casting code can be
overridden to some custom code in the %types directive, like so:
%types(fromtype = totype) %{
... code to convert fromtype to totype and return ...
%}
The special variable $from will be replaced by the name of the parameter of the
type being converted from. The code must return the totype cast to void *. Example:
class Time;
class Date;
Date &Time::dateFromTime();
%types(Time = Date) %{
Time *t = (Time *)$from;
Date &d = t->dateFromTime();
return (void *) &d;
%}
resulting in the conversion / casting code looking something like:
static void *_p_TimeTo_p_Date(void *x) {
Time *t = (Time *)x;
Date &d = t->dateFromTime();
return (void *) &d;
}
This is advanced usage, please use only if you understand the runtime type system.
01/30/2008: mgossage 01/30/2008: mgossage
Small update to documentation in Typemaps.html, to warn about use of local Small update to documentation in Typemaps.html, to warn about use of local
variables in typemaps for multiple types. variables in typemaps for multiple types.
@ -26,7 +57,7 @@ Version 1.3.34 (in progress)
containers should be faster. containers should be faster.
01/18/2008: wsfulton 01/18/2008: wsfulton
Add 'directorinattributes' and 'directoroutattributes' typemap attributes [C#] Add 'directorinattributes' and 'directoroutattributes' typemap attributes
for the imtype typemap. These should contain C# attributes which will for the imtype typemap. These should contain C# attributes which will
be generated into the C# director delegate methods. be generated into the C# director delegate methods.

View file

@ -1804,10 +1804,6 @@ except_directive : EXCEPT LPAREN ID RPAREN LBRACE {
} }
; ;
/* ------------------------------------------------------------
%fragment(name,location) { ... }
------------------------------------------------------------ */
/* fragment keyword arguments */ /* fragment keyword arguments */
stringtype : string LBRACE parm RBRACE { stringtype : string LBRACE parm RBRACE {
$$ = NewHash(); $$ = NewHash();
@ -1825,6 +1821,14 @@ fname : string {
} }
; ;
/* ------------------------------------------------------------
%fragment(name, section) %{ ... %}
%fragment("name" {type}, "section") %{ ... %}
%fragment("name", "section", fragment="fragment1", fragment="fragment2") %{ ... %}
Also as above but using { ... }
%fragment("name");
------------------------------------------------------------ */
fragment_directive: FRAGMENT LPAREN fname COMMA kwargs RPAREN HBLOCK { fragment_directive: FRAGMENT LPAREN fname COMMA kwargs RPAREN HBLOCK {
Hash *p = $5; Hash *p = $5;
$$ = new_node("fragment"); $$ = new_node("fragment");
@ -2502,11 +2506,14 @@ typemap_parm : type typemap_parameter_declarator {
/* ------------------------------------------------------------ /* ------------------------------------------------------------
%types(parmlist); %types(parmlist);
%types(parmlist) %{ ... %}
------------------------------------------------------------ */ ------------------------------------------------------------ */
types_directive : TYPES LPAREN parms RPAREN SEMI { types_directive : TYPES LPAREN parms RPAREN stringbracesemi {
$$ = new_node("types"); $$ = new_node("types");
Setattr($$,"parms",$3); Setattr($$,"parms",$3);
if ($5)
Setattr($$,"convcode",NewString($5));
} }
; ;

View file

@ -776,6 +776,7 @@ int Language::typemapcopyDirective(Node *n) {
int Language::typesDirective(Node *n) { int Language::typesDirective(Node *n) {
Parm *parms = Getattr(n, "parms"); Parm *parms = Getattr(n, "parms");
String *convcode = Getattr(n, "convcode"); /* optional user supplied conversion code for custom casting */
while (parms) { while (parms) {
SwigType *t = Getattr(parms, "type"); SwigType *t = Getattr(parms, "type");
String *v = Getattr(parms, "value"); String *v = Getattr(parms, "value");
@ -783,7 +784,7 @@ int Language::typesDirective(Node *n) {
SwigType_remember(t); SwigType_remember(t);
} else { } else {
if (SwigType_issimple(t)) { if (SwigType_issimple(t)) {
SwigType_inherit(t, v, 0); SwigType_inherit(t, v, 0, convcode);
} }
} }
parms = nextSibling(parms); parms = nextSibling(parms);

View file

@ -205,7 +205,7 @@ class TypePass:private Dispatcher {
Setmeta(bname, "already_warned", "1"); Setmeta(bname, "already_warned", "1");
} }
} }
SwigType_inherit(clsname, bname, cast); SwigType_inherit(clsname, bname, cast, 0);
} }
} }
} }
@ -225,7 +225,7 @@ class TypePass:private Dispatcher {
String *bname = Getattr(n, "name"); String *bname = Getattr(n, "name");
Node *bclass = n; /* Getattr(n,"class"); */ Node *bclass = n; /* Getattr(n,"class"); */
Hash *scopes = Getattr(bclass, "typescope"); Hash *scopes = Getattr(bclass, "typescope");
SwigType_inherit(clsname, bname, cast); SwigType_inherit(clsname, bname, cast, 0);
if (!importmode) { if (!importmode) {
String *btype = Copy(bname); String *btype = Copy(bname);
SwigType_add_pointer(btype); SwigType_add_pointer(btype);

View file

@ -1649,12 +1649,18 @@ String *SwigType_clientdata_collect(String *ms) {
* from them. * from them.
* *
* subclass is a hash that maps base-classes to all of the classes derived from them. * subclass is a hash that maps base-classes to all of the classes derived from them.
*
* derived - name of derived class
* base - name of base class
* cast - additional casting code when casting from derived to base
* conversioncode - if set, overrides the default code in the function when casting
* from derived to base
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
static Hash *subclass = 0; static Hash *subclass = 0;
static Hash *conversions = 0; static Hash *conversions = 0;
void SwigType_inherit(String *derived, String *base, String *cast) { void SwigType_inherit(String *derived, String *base, String *cast, String *conversioncode) {
Hash *h; Hash *h;
String *dd = 0; String *dd = 0;
String *bb = 0; String *bb = 0;
@ -1685,7 +1691,13 @@ void SwigType_inherit(String *derived, String *base, String *cast) {
Delete(h); Delete(h);
} }
if (!Getattr(h, derived)) { if (!Getattr(h, derived)) {
Setattr(h, derived, cast ? cast : (void *) ""); Hash *c = NewHash();
if (cast)
Setattr(c, "cast", cast);
if (conversioncode)
Setattr(c, "convcode", conversioncode);
Setattr(h, derived, c);
Delete(c);
} }
Delete(dd); Delete(dd);
@ -1781,8 +1793,20 @@ void SwigType_inherit_equiv(File *out) {
String *convname = NewStringf("%sTo%s", mprefix, mkey); String *convname = NewStringf("%sTo%s", mprefix, mkey);
String *lkey = SwigType_lstr(rk.key, 0); String *lkey = SwigType_lstr(rk.key, 0);
String *lprefix = SwigType_lstr(prefix, 0); String *lprefix = SwigType_lstr(prefix, 0);
Printf(out, "static void *%s(void *x) {\n", convname); Hash *subhash = Getattr(sub, bk.key);
Printf(out, " return (void *)((%s) %s ((%s) x));\n", lkey, Getattr(sub, bk.key), lprefix); String *convcode = Getattr(subhash, "convcode");
Printf(out, "static void *%s(void *x) {", convname);
if (convcode) {
String *fn = Copy(convcode);
Replaceall(fn, "$from", "x");
Printf(out, "%s", fn);
} else {
String *cast = Getattr(subhash, "cast");
Printf(out, "\n return (void *)((%s) ", lkey);
if (cast)
Printf(out, "%s", cast);
Printf(out, " ((%s) x));\n", lprefix);
}
Printf(out, "}\n"); Printf(out, "}\n");
Setattr(conversions, ckey, convname); Setattr(conversions, ckey, convname);
Delete(ckey); Delete(ckey);