int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope) { List *patchlist, *cpatchlist, *typelist; String *templateargs; String *tname; String *iname; String *tbase; patchlist = NewList(); cpatchlist = NewList(); typelist = NewList(); { String *tmp = NewStringEmpty(); if (tparms) { SwigType_add_template(tmp, tparms); } templateargs = Copy(tmp); Delete(tmp); } tname = Copy(Getattr(n, "name")); tbase = Swig_scopename_last(tname); /* Look for partial specialization matching */ if (Getattr(n, "partialargs")) { Parm *p, *tp; ParmList *ptargs = SwigType_function_parms(Getattr(n, "partialargs")); p = ptargs; tp = tparms; while (p && tp) { SwigType *ptype; SwigType *tptype; SwigType *partial_type; ptype = Getattr(p, "type"); tptype = Getattr(tp, "type"); if (ptype && tptype) { partial_type = partial_arg(tptype, ptype); /* Printf(stdout,"partial '%s' '%s' ---> '%s'\n", tptype, ptype, partial_type); */ Setattr(tp, "type", partial_type); Delete(partial_type); } p = nextSibling(p); tp = nextSibling(tp); } assert(ParmList_len(ptargs) == ParmList_len(tparms)); Delete(ptargs); } /* Parm *p = tparms; while (p) { Printf(stdout, "tparm: '%s' '%s' '%s'\n", Getattr(p, "name"), Getattr(p, "type"), Getattr(p, "value")); p = nextSibling(p); } */ /* Printf(stdout,"targs = '%s'\n", templateargs); Printf(stdout,"rname = '%s'\n", rname); Printf(stdout,"tname = '%s'\n", tname); */ cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist); /* Set the name */ { String *name = Getattr(n, "name"); if (name) { Append(name, templateargs); } iname = name; } /* Patch all of the types */ { Parm *tp = Getattr(n, "templateparms"); Parm *p = tparms; /* Printf(stdout,"%s\n", ParmList_str_defaultargs(tp)); */ if (tp) { Symtab *tsdecl = Getattr(n, "sym:symtab"); while (p && tp) { String *name, *value, *valuestr, *tydef, *tmp, *tmpr; int sz, i; String *dvalue = 0; String *qvalue = 0; name = Getattr(tp, "name"); value = Getattr(p, "value"); tydef = Getattr(p, "typedef"); if (name) { if (!value) value = Getattr(p, "type"); qvalue = Swig_symbol_typedef_reduce(value, tsdecl); dvalue = Swig_symbol_type_qualify(qvalue, tsdecl); if (SwigType_istemplate(dvalue)) { String *ty = Swig_symbol_template_deftype(dvalue, tscope); Delete(dvalue); dvalue = ty; } assert(dvalue); valuestr = SwigType_str(dvalue, 0); /* Need to patch default arguments */ { Parm *rp = nextSibling(p); while (rp) { String *rvalue = Getattr(rp, "value"); if (rvalue) { Replace(rvalue, name, dvalue, DOH_REPLACE_ID); } rp = nextSibling(rp); } } sz = Len(patchlist); for (i = 0; i < sz; i++) { String *s = Getitem(patchlist, i); Replace(s, name, dvalue, DOH_REPLACE_ID); } sz = Len(typelist); for (i = 0; i < sz; i++) { String *s = Getitem(typelist, i); /* Replace(s,name,value, DOH_REPLACE_ID); */ /* Printf(stdout,"name = '%s', value = '%s', tbase = '%s', iname='%s' s = '%s' --> ", name, dvalue, tbase, iname, s); */ SwigType_typename_replace(s, name, dvalue); SwigType_typename_replace(s, tbase, iname); /* Printf(stdout,"'%s'\n", s); */ } if (!tydef) { tydef = dvalue; } tmp = NewStringf("#%s", name); tmpr = NewStringf("\"%s\"", valuestr); sz = Len(cpatchlist); for (i = 0; i < sz; i++) { String *s = Getitem(cpatchlist, i); Replace(s, tmp, tmpr, DOH_REPLACE_ID); /* Replace(s,name,tydef, DOH_REPLACE_ID); */ Replace(s, name, valuestr, DOH_REPLACE_ID); } Delete(tmp); Delete(tmpr); Delete(valuestr); Delete(dvalue); Delete(qvalue); } p = nextSibling(p); tp = nextSibling(tp); if (!p) p = tp; } } else { /* No template parameters at all. This could be a specialization */ int i, sz; sz = Len(typelist); for (i = 0; i < sz; i++) { String *s = Getitem(typelist, i); SwigType_typename_replace(s, tbase, iname); } } } /* Patch bases */ { List *bases = Getattr(n, "baselist"); if (bases) { Iterator b; for (b = First(bases); b.item; b = Next(b)) { String *qn = Swig_symbol_type_qualify(b.item, tscope); Clear(b.item); Append(b.item, qn); Delete(qn); } } } Delete(patchlist); Delete(cpatchlist); Delete(typelist); Delete(tbase); Delete(tname); Delete(templateargs); /* set_nodeType(n,"template"); */ return 0; }
static int cparse_template_expand(Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) { static int expanded = 0; int ret; String *nodeType; if (!n) return 0; nodeType = nodeType(n); if (Getattr(n, "error")) return 0; if (Equal(nodeType, "template")) { /* Change the node type back to normal */ if (!expanded) { expanded = 1; set_nodeType(n, Getattr(n, "templatetype")); ret = cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist); expanded = 0; return ret; } else { /* Called when template appears inside another template */ /* Member templates */ set_nodeType(n, Getattr(n, "templatetype")); ret = cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist); set_nodeType(n, "template"); return ret; } } else if (Equal(nodeType, "cdecl")) { /* A simple C declaration */ SwigType *t, *v, *d; String *code; t = Getattr(n, "type"); v = Getattr(n, "value"); d = Getattr(n, "decl"); code = Getattr(n, "code"); Append(typelist, t); Append(typelist, d); Append(patchlist, v); Append(cpatchlist, code); if (Getattr(n, "conversion_operator")) { Append(cpatchlist, Getattr(n, "name")); if (Getattr(n, "sym:name")) { Append(cpatchlist, Getattr(n, "sym:name")); } } add_parms(Getattr(n, "parms"), cpatchlist, typelist); add_parms(Getattr(n, "throws"), cpatchlist, typelist); } else if (Equal(nodeType, "class")) { /* Patch base classes */ { int b = 0; for (b = 0; b < 3; ++b) { List *bases = Getattr(n, baselists[b]); if (bases) { int i; int ilen = Len(bases); for (i = 0; i < ilen; i++) { String *name = Copy(Getitem(bases, i)); Setitem(bases, i, name); Append(typelist, name); } } } } /* Patch children */ { Node *cn = firstChild(n); while (cn) { cparse_template_expand(cn, tname, rname, templateargs, patchlist, typelist, cpatchlist); cn = nextSibling(cn); } } } else if (Equal(nodeType, "constructor")) { String *name = Getattr(n, "name"); if (!(Getattr(n, "templatetype"))) { String *symname; String *stripped_name = SwigType_templateprefix(name); if (Strstr(tname, stripped_name)) { Replaceid(name, stripped_name, tname); } Delete(stripped_name); symname = Getattr(n, "sym:name"); if (symname) { stripped_name = SwigType_templateprefix(symname); if (Strstr(tname, stripped_name)) { Replaceid(symname, stripped_name, tname); } Delete(stripped_name); } if (strchr(Char(name), '<')) { Append(patchlist, Getattr(n, "name")); } else { Append(name, templateargs); } name = Getattr(n, "sym:name"); if (name) { if (strchr(Char(name), '<')) { Clear(name); Append(name, rname); } else { String *tmp = Copy(name); Replace(tmp, tname, rname, DOH_REPLACE_ANY); Clear(name); Append(name, tmp); Delete(tmp); } } /* Setattr(n,"sym:name",name); */ } Append(cpatchlist, Getattr(n, "code")); Append(typelist, Getattr(n, "decl")); add_parms(Getattr(n, "parms"), cpatchlist, typelist); add_parms(Getattr(n, "throws"), cpatchlist, typelist); } else if (Equal(nodeType, "destructor")) { String *name = Getattr(n, "name"); if (name) { if (strchr(Char(name), '<')) Append(patchlist, Getattr(n, "name")); else Append(name, templateargs); } name = Getattr(n, "sym:name"); if (name) { if (strchr(Char(name), '<')) { String *sn = Copy(tname); Setattr(n, "sym:name", sn); Delete(sn); } else { Replace(name, tname, rname, DOH_REPLACE_ANY); } } /* Setattr(n,"sym:name",name); */ Append(cpatchlist, Getattr(n, "code")); } else if (Equal(nodeType, "using")) { String *uname = Getattr(n, "uname"); if (uname && strchr(Char(uname), '<')) { Append(patchlist, uname); } if (Getattr(n, "namespace")) { /* Namespace link. This is nasty. Is other namespace defined? */ } } else { /* Look for obvious parameters */ Node *cn; Append(cpatchlist, Getattr(n, "code")); Append(typelist, Getattr(n, "type")); Append(typelist, Getattr(n, "decl")); add_parms(Getattr(n, "parms"), cpatchlist, typelist); add_parms(Getattr(n, "kwargs"), cpatchlist, typelist); add_parms(Getattr(n, "pattern"), cpatchlist, typelist); add_parms(Getattr(n, "throws"), cpatchlist, typelist); cn = firstChild(n); while (cn) { cparse_template_expand(cn, tname, rname, templateargs, patchlist, typelist, cpatchlist); cn = nextSibling(cn); } } return 0; }
static void cparse_template_expand(Node *templnode, Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) { static int expanded = 0; String *nodeType; if (!n) return; nodeType = nodeType(n); if (Getattr(n, "error")) return; if (Equal(nodeType, "template")) { /* Change the node type back to normal */ if (!expanded) { expanded = 1; set_nodeType(n, Getattr(n, "templatetype")); cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist); expanded = 0; return; } else { /* Called when template appears inside another template */ /* Member templates */ set_nodeType(n, Getattr(n, "templatetype")); cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist); set_nodeType(n, "template"); return; } } else if (Equal(nodeType, "cdecl")) { /* A simple C declaration */ SwigType *t, *v, *d; String *code; t = Getattr(n, "type"); v = Getattr(n, "value"); d = Getattr(n, "decl"); code = Getattr(n, "code"); Append(typelist, t); Append(typelist, d); Append(patchlist, v); Append(cpatchlist, code); if (Getattr(n, "conversion_operator")) { Append(cpatchlist, Getattr(n, "name")); if (Getattr(n, "sym:name")) { Append(cpatchlist, Getattr(n, "sym:name")); } } if (checkAttribute(n, "storage", "friend")) { String *symname = Getattr(n, "sym:name"); if (symname) { String *stripped_name = SwigType_templateprefix(symname); Setattr(n, "sym:name", stripped_name); Delete(stripped_name); } Append(typelist, Getattr(n, "name")); } add_parms(Getattr(n, "parms"), cpatchlist, typelist); add_parms(Getattr(n, "throws"), cpatchlist, typelist); } else if (Equal(nodeType, "class")) { /* Patch base classes */ { int b = 0; for (b = 0; b < 3; ++b) { List *bases = Getattr(n, baselists[b]); if (bases) { int i; int ilen = Len(bases); for (i = 0; i < ilen; i++) { String *name = Copy(Getitem(bases, i)); Setitem(bases, i, name); Append(typelist, name); } } } } /* Patch children */ { Node *cn = firstChild(n); while (cn) { cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist); cn = nextSibling(cn); } } } else if (Equal(nodeType, "constructor")) { String *name = Getattr(n, "name"); if (!(Getattr(n, "templatetype"))) { String *symname; String *stripped_name = SwigType_templateprefix(name); if (Strstr(tname, stripped_name)) { Replaceid(name, stripped_name, tname); } Delete(stripped_name); symname = Getattr(n, "sym:name"); if (symname) { stripped_name = SwigType_templateprefix(symname); if (Strstr(tname, stripped_name)) { Replaceid(symname, stripped_name, tname); } Delete(stripped_name); } if (strchr(Char(name), '<')) { Append(patchlist, Getattr(n, "name")); } else { Append(name, templateargs); } name = Getattr(n, "sym:name"); if (name) { if (strchr(Char(name), '<')) { Clear(name); Append(name, rname); } else { String *tmp = Copy(name); Replace(tmp, tname, rname, DOH_REPLACE_ANY); Clear(name); Append(name, tmp); Delete(tmp); } } /* Setattr(n,"sym:name",name); */ } Append(cpatchlist, Getattr(n, "code")); Append(typelist, Getattr(n, "decl")); add_parms(Getattr(n, "parms"), cpatchlist, typelist); add_parms(Getattr(n, "throws"), cpatchlist, typelist); } else if (Equal(nodeType, "destructor")) { /* We only need to patch the dtor of the template itself, not the destructors of any nested classes, so check that the parent of this node is the root * template node, with the special exception for %extend which adds its methods under an intermediate node. */ Node* parent = parentNode(n); if (parent == templnode || (parentNode(parent) == templnode && Equal(nodeType(parent), "extend"))) { String *name = Getattr(n, "name"); if (name) { if (strchr(Char(name), '<')) Append(patchlist, Getattr(n, "name")); else Append(name, templateargs); } name = Getattr(n, "sym:name"); if (name) { if (strchr(Char(name), '<')) { String *sn = Copy(tname); Setattr(n, "sym:name", sn); Delete(sn); } else { Replace(name, tname, rname, DOH_REPLACE_ANY); } } /* Setattr(n,"sym:name",name); */ Append(cpatchlist, Getattr(n, "code")); } } else if (Equal(nodeType, "using")) { String *uname = Getattr(n, "uname"); if (uname && strchr(Char(uname), '<')) { Append(patchlist, uname); } if (Getattr(n, "namespace")) { /* Namespace link. This is nasty. Is other namespace defined? */ } } else { /* Look for obvious parameters */ Node *cn; Append(cpatchlist, Getattr(n, "code")); Append(typelist, Getattr(n, "type")); Append(typelist, Getattr(n, "decl")); add_parms(Getattr(n, "parms"), cpatchlist, typelist); add_parms(Getattr(n, "kwargs"), cpatchlist, typelist); add_parms(Getattr(n, "pattern"), cpatchlist, typelist); add_parms(Getattr(n, "throws"), cpatchlist, typelist); cn = firstChild(n); while (cn) { cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist); cn = nextSibling(cn); } } }