diff options
author | William S Fulton <wsf@fultondesigns.co.uk> | 2008-01-31 22:45:59 +0000 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2008-01-31 22:45:59 +0000 |
commit | 629aae375ce9b52ac139294a9d7a360da3836dee (patch) | |
tree | bf3aeec7e76e39399f759a97da23e80dde8cef15 | |
parent | 560b18eb3f829dac7cfdfddf59dbd00f919d3fc7 (diff) | |
download | swig-629aae375ce9b52ac139294a9d7a360da3836dee.tar.gz |
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
-rw-r--r-- | CHANGES.current | 33 | ||||
-rw-r--r-- | Source/CParse/parser.y | 17 | ||||
-rw-r--r-- | Source/Modules/lang.cxx | 3 | ||||
-rw-r--r-- | Source/Modules/typepass.cxx | 4 | ||||
-rw-r--r-- | Source/Swig/typesys.c | 32 |
5 files changed, 76 insertions, 13 deletions
diff --git a/CHANGES.current b/CHANGES.current index 2585b2a38..b8aba8226 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,37 @@ 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 Small update to documentation in Typemaps.html, to warn about use of local variables in typemaps for multiple types. @@ -26,7 +57,7 @@ Version 1.3.34 (in progress) containers should be faster. 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 be generated into the C# director delegate methods. diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index bc700501e..9163d0b63 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1804,10 +1804,6 @@ except_directive : EXCEPT LPAREN ID RPAREN LBRACE { } ; -/* ------------------------------------------------------------ - %fragment(name,location) { ... } - ------------------------------------------------------------ */ - /* fragment keyword arguments */ stringtype : string LBRACE parm RBRACE { $$ = 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 { Hash *p = $5; $$ = new_node("fragment"); @@ -2502,11 +2506,14 @@ typemap_parm : type typemap_parameter_declarator { /* ------------------------------------------------------------ %types(parmlist); + %types(parmlist) %{ ... %} ------------------------------------------------------------ */ -types_directive : TYPES LPAREN parms RPAREN SEMI { +types_directive : TYPES LPAREN parms RPAREN stringbracesemi { $$ = new_node("types"); Setattr($$,"parms",$3); + if ($5) + Setattr($$,"convcode",NewString($5)); } ; diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 279e25a80..2f3e98672 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -776,6 +776,7 @@ int Language::typemapcopyDirective(Node *n) { int Language::typesDirective(Node *n) { Parm *parms = Getattr(n, "parms"); + String *convcode = Getattr(n, "convcode"); /* optional user supplied conversion code for custom casting */ while (parms) { SwigType *t = Getattr(parms, "type"); String *v = Getattr(parms, "value"); @@ -783,7 +784,7 @@ int Language::typesDirective(Node *n) { SwigType_remember(t); } else { if (SwigType_issimple(t)) { - SwigType_inherit(t, v, 0); + SwigType_inherit(t, v, 0, convcode); } } parms = nextSibling(parms); diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index b7e21ad26..d663aed6e 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -205,7 +205,7 @@ class TypePass:private Dispatcher { 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"); Node *bclass = n; /* Getattr(n,"class"); */ Hash *scopes = Getattr(bclass, "typescope"); - SwigType_inherit(clsname, bname, cast); + SwigType_inherit(clsname, bname, cast, 0); if (!importmode) { String *btype = Copy(bname); SwigType_add_pointer(btype); diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c index bb31fff23..2d7815741 100644 --- a/Source/Swig/typesys.c +++ b/Source/Swig/typesys.c @@ -1649,12 +1649,18 @@ String *SwigType_clientdata_collect(String *ms) { * 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 *conversions = 0; -void SwigType_inherit(String *derived, String *base, String *cast) { +void SwigType_inherit(String *derived, String *base, String *cast, String *conversioncode) { Hash *h; String *dd = 0; String *bb = 0; @@ -1685,7 +1691,13 @@ void SwigType_inherit(String *derived, String *base, String *cast) { Delete(h); } 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); @@ -1781,8 +1793,20 @@ void SwigType_inherit_equiv(File *out) { String *convname = NewStringf("%sTo%s", mprefix, mkey); String *lkey = SwigType_lstr(rk.key, 0); String *lprefix = SwigType_lstr(prefix, 0); - Printf(out, "static void *%s(void *x) {\n", convname); - Printf(out, " return (void *)((%s) %s ((%s) x));\n", lkey, Getattr(sub, bk.key), lprefix); + Hash *subhash = Getattr(sub, bk.key); + 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"); Setattr(conversions, ckey, convname); Delete(ckey); |