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)
============================
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.

View file

@ -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));
}
;

View file

@ -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);

View file

@ -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);

View file

@ -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);