Fragments can now be "type especialized", as the typemaps. The
syntax is as follows
%fragment("name","header") { /* an old fragment */ }
%fragment("name" {Type}, "header") { /* the fragment is type dependent */}
Now fragments can also be used inside templates:
template <class T>
struct A {
%fragment("incode"{A<T>},"header") {
/* 'incode' especialized fragment */
}
%typemap(in,fragment="incode"{A<T>}) {
/*
here we use the 'type especialized' fragment
"incode"{A<T> }
*/
}
};
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@5753 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
238cc1455c
commit
6c150e4328
2 changed files with 119 additions and 54 deletions
|
|
@ -19,6 +19,8 @@ char cvsroot_fragment_c[] = "$Header$";
|
||||||
#include "swig.h"
|
#include "swig.h"
|
||||||
|
|
||||||
static Hash *fragments = 0;
|
static Hash *fragments = 0;
|
||||||
|
static int debug = 0;
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Swig_fragment_register()
|
* Swig_fragment_register()
|
||||||
|
|
@ -29,16 +31,31 @@ static Hash *fragments = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
Swig_fragment_register(Node* fragment) {
|
Swig_fragment_register(Node* fragment) {
|
||||||
String *name = Getattr(fragment,"name");
|
if (Getattr(fragment,"emitonly")) {
|
||||||
String *section = Getattr(fragment,"section");
|
Swig_fragment_emit(fragment);
|
||||||
String *ccode = Copy(Getattr(fragment,"code"));
|
return;
|
||||||
Hash *kwargs = Getattr(fragment,"kwargs");
|
} else {
|
||||||
if (!fragments) {
|
String *name = Copy(Getattr(fragment,"value"));
|
||||||
fragments = NewHash();
|
String *type = Getattr(fragment,"type");
|
||||||
|
if (type) {
|
||||||
|
String *mangle = Swig_string_mangle(type);
|
||||||
|
Printf(name,"%s",mangle);
|
||||||
|
Delete(mangle);
|
||||||
|
}
|
||||||
|
if (debug) Printf(stdout,"register fragment %s %s\n",name,type);
|
||||||
|
if (!fragments) {
|
||||||
|
fragments = NewHash();
|
||||||
|
}
|
||||||
|
if (!Getattr(fragments,name)) {
|
||||||
|
String *section = Getattr(fragment,"section");
|
||||||
|
String *ccode = Copy(Getattr(fragment,"code"));
|
||||||
|
Hash *kwargs = Getattr(fragment,"kwargs");
|
||||||
|
Setmeta(ccode,"section",Copy(section));
|
||||||
|
if (kwargs) Setmeta(ccode,"kwargs",Copy(kwargs));
|
||||||
|
Setattr(fragments,name,ccode);
|
||||||
|
if (debug) Printf(stdout,"registering fragment %s %s\n",name,section);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Setmeta(ccode,"section",Copy(section));
|
|
||||||
if (kwargs) Setmeta(ccode,"kwargs",Copy(kwargs));
|
|
||||||
Setattr(fragments,Copy(name),ccode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
|
|
@ -47,29 +64,75 @@ Swig_fragment_register(Node* fragment) {
|
||||||
* Emit a fragment
|
* Emit a fragment
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void
|
static
|
||||||
Swig_fragment_emit(String *name) {
|
char* char_index(char* str, char c)
|
||||||
String *code;
|
{
|
||||||
if (!fragments) return;
|
while (*str && (c != *str)) ++str;
|
||||||
|
return (c == *str) ? str : 0;
|
||||||
code = Getattr(fragments,name);
|
|
||||||
if (code) {
|
|
||||||
String *section = Getmeta(code,"section");
|
|
||||||
Hash *n = Getmeta(code,"kwargs");
|
|
||||||
while (n) {
|
|
||||||
if (Cmp(Getattr(n,"name"),"fragment") == 0) {
|
|
||||||
Swig_fragment_emit(Getattr(n,"value"));
|
|
||||||
}
|
|
||||||
n = nextSibling(n);
|
|
||||||
}
|
|
||||||
if (section) {
|
|
||||||
File *f = Swig_filebyname(section);
|
|
||||||
if (!f) {
|
|
||||||
Swig_error(Getfile(code),Getline(code),"Bad section '%s' for code fragment '%s'\n", section,name);
|
|
||||||
} else {
|
|
||||||
Printf(f,"%s\n",code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Delattr(fragments,name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Swig_fragment_emit(Node *n) {
|
||||||
|
String *code;
|
||||||
|
char *pc, *tok;
|
||||||
|
String *t;
|
||||||
|
String *mangle = 0;
|
||||||
|
String *name = 0;
|
||||||
|
String *type = 0;
|
||||||
|
|
||||||
|
if (!fragments) return;
|
||||||
|
|
||||||
|
name = Getattr(n,"value");
|
||||||
|
if (!name) {
|
||||||
|
name = n;
|
||||||
|
}
|
||||||
|
type = Getattr(n,"type");
|
||||||
|
if (type) {
|
||||||
|
SwigType *rtype = SwigType_typedef_resolve_all(type);
|
||||||
|
mangle = Swig_string_mangle(rtype);
|
||||||
|
Delete(rtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug) Printf(stdout,"looking fragment %s %s\n",name, type);
|
||||||
|
t = Copy(name);
|
||||||
|
tok = Char(t);
|
||||||
|
pc = char_index(tok,',');
|
||||||
|
if (pc) *pc = 0;
|
||||||
|
while (tok) {
|
||||||
|
String *name = NewStringf("%s", tok);
|
||||||
|
if (mangle) Printf(name,"%s",mangle);
|
||||||
|
code = Getattr(fragments,name);
|
||||||
|
if (debug) Printf(stdout,"looking subfragment %s\n", name);
|
||||||
|
if (code && (Strcmp(code,"ignore") != 0)) {
|
||||||
|
String *section = Getmeta(code,"section");
|
||||||
|
Hash *n = Getmeta(code,"kwargs");
|
||||||
|
while (n) {
|
||||||
|
if (Cmp(Getattr(n,"name"),"fragment") == 0) {
|
||||||
|
if (debug) Printf(stdout,"emitting fragment %s %s\n",n, type);
|
||||||
|
Swig_fragment_emit(n);
|
||||||
|
}
|
||||||
|
n = nextSibling(n);
|
||||||
|
}
|
||||||
|
if (section) {
|
||||||
|
File *f = Swig_filebyname(section);
|
||||||
|
if (!f) {
|
||||||
|
Swig_error(Getfile(code),Getline(code),
|
||||||
|
"Bad section '%s' for code fragment '%s'\n", section,name);
|
||||||
|
} else {
|
||||||
|
if (debug) Printf(stdout,"emitting subfragment %s %s\n",name, section);
|
||||||
|
if (debug) Printf(f,"/* begin fragment %s */\n",name);
|
||||||
|
Printf(f,"%s\n",code);
|
||||||
|
if (debug) Printf(f,"/* end fragment %s */\n\n",name);
|
||||||
|
Setattr(fragments,name,"ignore");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tok = pc ? pc + 1 : 0;
|
||||||
|
if (tok) {
|
||||||
|
pc = char_index(tok,',');
|
||||||
|
if (pc) *pc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Delete(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1100,6 +1100,9 @@ String *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_
|
||||||
* Attach one or more typemaps to a node
|
* Attach one or more typemaps to a node
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
Node *
|
||||||
|
Swig_cparse_template_locate(String *name, Parm *tparms);
|
||||||
|
|
||||||
String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const String_or_char *lname, Wrapper *f)
|
String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const String_or_char *lname, Wrapper *f)
|
||||||
{
|
{
|
||||||
SwigType *type;
|
SwigType *type;
|
||||||
|
|
@ -1187,8 +1190,15 @@ String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const Stri
|
||||||
/* Attach kwargs */
|
/* Attach kwargs */
|
||||||
kw = Getattr(tm,"kwargs");
|
kw = Getattr(tm,"kwargs");
|
||||||
while (kw) {
|
while (kw) {
|
||||||
|
String *value = Copy(Getattr(kw,"value"));
|
||||||
|
String *type = Getattr(kw,"type");
|
||||||
|
if (type) {
|
||||||
|
String *mangle = Swig_string_mangle(type);
|
||||||
|
Printf(value,"%s",mangle);
|
||||||
|
Delete(mangle);
|
||||||
|
}
|
||||||
sprintf(temp,"%s:%s",Char(op),Char(Getattr(kw,"name")));
|
sprintf(temp,"%s:%s",Char(op),Char(Getattr(kw,"name")));
|
||||||
Setattr(node,tmop_name(temp), Copy(Getattr(kw,"value")));
|
Setattr(node,tmop_name(temp), value);
|
||||||
kw = nextSibling(kw);
|
kw = nextSibling(kw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1208,15 +1218,7 @@ String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const Stri
|
||||||
sprintf(temp,"%s:fragment", Char(op));
|
sprintf(temp,"%s:fragment", Char(op));
|
||||||
f = Getattr(node,tmop_name(temp));
|
f = Getattr(node,tmop_name(temp));
|
||||||
if (f) {
|
if (f) {
|
||||||
char *c, *tok;
|
Swig_fragment_emit(f);
|
||||||
String *t = Copy(f);
|
|
||||||
c = Char(t);
|
|
||||||
tok = strtok(c,",");
|
|
||||||
while (tok) {
|
|
||||||
Swig_fragment_emit(tok);
|
|
||||||
tok = strtok(NULL,",");
|
|
||||||
}
|
|
||||||
Delete(t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1248,9 +1250,17 @@ Swig_typemap_attach_kwargs(Hash *tm, const String_or_char *op, Parm *p) {
|
||||||
String *temp = NewString("");
|
String *temp = NewString("");
|
||||||
Parm *kw = Getattr(tm,"kwargs");
|
Parm *kw = Getattr(tm,"kwargs");
|
||||||
while (kw) {
|
while (kw) {
|
||||||
|
String *value = Copy(Getattr(kw,"value"));
|
||||||
|
String *type = Getattr(kw,"type");
|
||||||
|
if (type) {
|
||||||
|
Hash *v = NewHash();
|
||||||
|
Setattr(v,"value",value);
|
||||||
|
Setattr(v,"type",type);
|
||||||
|
value = v;
|
||||||
|
}
|
||||||
Clear(temp);
|
Clear(temp);
|
||||||
Printf(temp,"%s:%s",op,Getattr(kw,"name"));
|
Printf(temp,"%s:%s",op,Getattr(kw,"name"));
|
||||||
Setattr(p,tmop_name(temp),Copy(Getattr(kw,"value")));
|
Setattr(p,tmop_name(temp),value);
|
||||||
kw = nextSibling(kw);
|
kw = nextSibling(kw);
|
||||||
}
|
}
|
||||||
Delete(temp);
|
Delete(temp);
|
||||||
|
|
@ -1278,15 +1288,7 @@ Swig_typemap_emit_code_fragments(const String_or_char *op, Parm *p) {
|
||||||
String *temp = NewStringf("%s:fragment",op);
|
String *temp = NewStringf("%s:fragment",op);
|
||||||
String *f = Getattr(p,tmop_name(temp));
|
String *f = Getattr(p,tmop_name(temp));
|
||||||
if (f) {
|
if (f) {
|
||||||
char *c, *tok;
|
Swig_fragment_emit(f);
|
||||||
String *t = Copy(f);
|
|
||||||
c = Char(t);
|
|
||||||
tok = strtok(c,",");
|
|
||||||
while (tok) {
|
|
||||||
Swig_fragment_emit(tok);
|
|
||||||
tok = strtok(NULL,",");
|
|
||||||
}
|
|
||||||
Delete(t);
|
|
||||||
}
|
}
|
||||||
Delete(temp);
|
Delete(temp);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue