From e0adc5af012fbf034e3e8c049ac4a1f6602bfe81 Mon Sep 17 00:00:00 2001 From: Marcelo Matus Date: Wed, 17 Mar 2004 08:36:06 +0000 Subject: [PATCH] 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 struct A { %fragment("incode"{A},"header") { /* 'incode' especialized fragment */ } %typemap(in,fragment="incode"{A}) { /* here we use the 'type especialized' fragment "incode"{A } */ } }; git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5753 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Swig/fragment.c | 131 ++++++++++++++++++++++++++++++----------- Source/Swig/typemap.c | 42 ++++++------- 2 files changed, 119 insertions(+), 54 deletions(-) diff --git a/Source/Swig/fragment.c b/Source/Swig/fragment.c index b83d43869..429878a78 100644 --- a/Source/Swig/fragment.c +++ b/Source/Swig/fragment.c @@ -19,6 +19,8 @@ char cvsroot_fragment_c[] = "$Header$"; #include "swig.h" static Hash *fragments = 0; +static int debug = 0; + /* ----------------------------------------------------------------------------- * Swig_fragment_register() @@ -29,16 +31,31 @@ static Hash *fragments = 0; void Swig_fragment_register(Node* fragment) { - String *name = Getattr(fragment,"name"); - String *section = Getattr(fragment,"section"); - String *ccode = Copy(Getattr(fragment,"code")); - Hash *kwargs = Getattr(fragment,"kwargs"); - if (!fragments) { - fragments = NewHash(); + if (Getattr(fragment,"emitonly")) { + Swig_fragment_emit(fragment); + return; + } else { + String *name = Copy(Getattr(fragment,"value")); + 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 * ----------------------------------------------------------------------------- */ -void -Swig_fragment_emit(String *name) { - String *code; - if (!fragments) return; - - 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); - } +static +char* char_index(char* str, char c) +{ + while (*str && (c != *str)) ++str; + return (c == *str) ? str : 0; } + +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); +} + diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 38a9fbf5e..ed6e61230 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -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 * ----------------------------------------------------------------------------- */ +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) { SwigType *type; @@ -1187,8 +1190,15 @@ String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const Stri /* Attach kwargs */ kw = Getattr(tm,"kwargs"); 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"))); - Setattr(node,tmop_name(temp), Copy(Getattr(kw,"value"))); + Setattr(node,tmop_name(temp), value); 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)); f = Getattr(node,tmop_name(temp)); if (f) { - char *c, *tok; - String *t = Copy(f); - c = Char(t); - tok = strtok(c,","); - while (tok) { - Swig_fragment_emit(tok); - tok = strtok(NULL,","); - } - Delete(t); + Swig_fragment_emit(f); } } @@ -1248,9 +1250,17 @@ Swig_typemap_attach_kwargs(Hash *tm, const String_or_char *op, Parm *p) { String *temp = NewString(""); Parm *kw = Getattr(tm,"kwargs"); 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); 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); } 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 *f = Getattr(p,tmop_name(temp)); if (f) { - char *c, *tok; - String *t = Copy(f); - c = Char(t); - tok = strtok(c,","); - while (tok) { - Swig_fragment_emit(tok); - tok = strtok(NULL,","); - } - Delete(t); + Swig_fragment_emit(f); } Delete(temp); }