static void mangle_namestr(String *mangled, SwigType *t) { int length = Len(t); if (SwigType_isqualifier(t)) { Append(mangled, "q_"); mangle_stringcopy(mangled, Char(t)+2, length-4); Append(mangled, "__"); } else if (SwigType_ismemberpointer(t)) { Append(mangled, "m_"); mangle_stringcopy(mangled, Char(t)+2, length-4); Append(mangled, "__"); } else if (SwigType_isarray(t)) { Append(mangled, "a_"); mangle_stringcopy(mangled, Char(t)+2, length-4); Append(mangled, "__"); } else if (SwigType_isfunction(t)) { List *p = SwigType_parmlist(t); int sz = Len(p); int i; Append(mangled, "f_"); for (i = 0; i < sz; i++) { mangle_subtype(mangled, Getitem(p, i)); Putc('_', mangled); } Append(mangled, (sz > 0) ? "_" : "__"); } else if (SwigType_isvarargs(t)) { Append(mangled, "___"); } else { char *d = Char(t); char *c = strstr(d, "<("); if (!c || !strstr(c + 2, ")>")) { /* not a template type */ mangle_stringcopy(mangled, Char(t), Len(t)); } else { /* a template type */ String *suffix; List *p; int i, sz; mangle_stringcopy(mangled, d, c-d); Putc('T', mangled); Putc('_', mangled); p = SwigType_parmlist(c + 1); sz = Len(p); for (i = 0; i < sz; i++) { mangle_subtype(mangled, Getitem(p, i)); Putc('_', mangled); } Putc('t', mangled); suffix = SwigType_templatesuffix(t); if (Len(suffix) > 0) { mangle_namestr(mangled, suffix); } else { Append(mangled, suffix); } Delete(suffix); Delete(p); } } }
FILE * Swig_open(const String_or_char *name) { FILE *f; String *filename; List *spath = 0; char *cname; int i; if (!directories) directories = NewList(); assert(directories); cname = Char(name); filename = NewString(cname); assert(filename); f = fopen(Char(filename),"r"); if (!f) { spath = Swig_search_path(); for (i = 0; i < Len(spath); i++) { Clear(filename); Printf(filename,"%s%s", Getitem(spath,i), cname); f = fopen(Char(filename),"r"); if (f) break; } Delete(spath); } if (f) { Delete(lastpath); lastpath = Copy(filename); } Delete(filename); return f; }
List * Swig_search_path() { String *filename; String *dirname; List *slist; int i; slist = NewList(); assert(slist); filename = NewString(""); assert(filename); #ifdef MACSWIG Printf(filename,"%s",SWIG_FILE_DELIMETER); #else Printf(filename,".%s", SWIG_FILE_DELIMETER); #endif Append(slist,filename); for (i = 0; i < Len(directories); i++) { dirname = Getitem(directories,i); filename = NewString(""); assert(filename); Printf(filename, "%s%s", dirname, SWIG_FILE_DELIMETER); Append(slist,filename); } return slist; }
static FILE *Swig_open_file(const_String_or_char_ptr name, int sysfile, int use_include_path) { FILE *f; String *filename; List *spath = 0; char *cname; int i, ilen; if (!directories) directories = NewList(); assert(directories); cname = Char(name); filename = NewString(cname); assert(filename); f = fopen(Char(filename), "r"); if (!f && use_include_path) { spath = Swig_search_path_any(sysfile); ilen = Len(spath); for (i = 0; i < ilen; i++) { Clear(filename); Printf(filename, "%s%s", Getitem(spath, i), cname); f = fopen(Char(filename), "r"); if (f) break; } Delete(spath); } if (f) { Delete(lastpath); lastpath = filename; } return f; }
int Swig_name_match_nameobj(Hash *rn, Node *n) { int match = 1; List *matchlist = Getattr(rn, "matchlist"); #ifdef SWIG_DEBUG Printf(stdout, "Swig_name_match_nameobj: %s\n", Getattr(n, "name")); #endif if (matchlist) { int ilen = Len(matchlist); int i; for (i = 0; match && (i < ilen); ++i) { Node *mi = Getitem(matchlist, i); List *lattr = Getattr(mi, "attrlist"); String *nval = Swig_get_lattr(n, lattr); int notmatch = GetFlag(mi, "notmatch"); int regexmatch = GetFlag(mi, "regexmatch"); match = 0; if (nval) { String *kwval = Getattr(mi, "value"); match = regexmatch ? Swig_name_regexmatch_value(n, kwval, nval) : Swig_name_match_value(kwval, nval); #ifdef SWIG_DEBUG Printf(stdout, "val %s %s %d %d \n", nval, kwval, match, ilen); #endif } if (notmatch) match = !match; } } #ifdef SWIG_DEBUG Printf(stdout, "Swig_name_match_nameobj: %d\n", match); #endif return match; }
/* ----------------------------------------------------------------------------- * brackets_count() * * Returns the number of brackets at the current depth. * A syntax error with unbalanced ) brackets will result in a NULL pointer return. * ----------------------------------------------------------------------------- */ static int *brackets_count(Scanner *s) { int *count; if (Len(s->brackets) > 0) count = (int *)Data(Getitem(s->brackets, 0)); else count = 0; return count; }
static List *Swig_search_path_any(int syspath) { String *filename; List *slist; int i, ilen; slist = NewList(); assert(slist); filename = NewStringEmpty(); assert(filename); #ifdef MACSWIG Printf(filename, "%s", SWIG_FILE_DELIMITER); #else Printf(filename, ".%s", SWIG_FILE_DELIMITER); #endif Append(slist, filename); Delete(filename); /* If there are any pushed directories. Add them first */ if (pdirectories) { ilen = Len(pdirectories); for (i = 0; i < ilen; i++) { filename = NewString(Getitem(pdirectories,i)); Append(filename,SWIG_FILE_DELIMITER); Append(slist,filename); Delete(filename); } } /* Add system directories next */ ilen = Len(directories); for (i = 0; i < ilen; i++) { filename = NewString(Getitem(directories,i)); Append(filename,SWIG_FILE_DELIMITER); if (syspath) { /* If doing a system include, put the system directories first */ Insert(slist,i,filename); } else { /* Otherwise, just put the system directories after the pushed directories (if any) */ Append(slist,filename); } Delete(filename); } return slist; }
SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual) { List *qlist; String *allq, *newq; int i, sz; const char *cqprev = 0; const char *c = Char(t); const char *cqual = Char(qual); /* if 't' has no qualifiers and 'qual' is a single qualifier, simply add it */ if ((strncmp(c, "q(", 2) != 0) && (strstr(cqual, " ") == 0)) { String *temp = NewStringf("q(%s).", cqual); Insert(t, 0, temp); Delete(temp); return t; } /* create string of all qualifiers */ if (strncmp(c, "q(", 2) == 0) { allq = SwigType_parm(t); Append(allq, " "); SwigType_del_element(t); /* delete old qualifier list from 't' */ } else { allq = NewStringEmpty(); } Append(allq, qual); /* create list of all qualifiers from string */ qlist = Split(allq, ' ', INT_MAX); Delete(allq); /* sort in alphabetical order */ SortList(qlist, Strcmp); /* create new qualifier string from unique elements of list */ sz = Len(qlist); newq = NewString("q("); for (i = 0; i < sz; ++i) { String *q = Getitem(qlist, i); const char *cq = Char(q); if (cqprev == 0 || strcmp(cqprev, cq) != 0) { if (i > 0) { Append(newq, " "); } Append(newq, q); cqprev = cq; } } Append(newq, ")."); Delete(qlist); /* replace qualifier string with new one */ Insert(t, 0, newq); Delete(newq); return t; }
Hash *Swig_name_nameobj_lget(List *namelist, Node *n, String *prefix, String *name, String *decl) { Hash *res = 0; if (namelist) { int len = Len(namelist); int i; int match = 0; for (i = 0; !match && (i < len); i++) { Hash *rn = Getitem(namelist, i); String *rdecl = Getattr(rn, "decl"); if (rdecl && (!decl || !Equal(rdecl, decl))) { continue; } else if (Swig_name_match_nameobj(rn, n)) { String *tname = Getattr(rn, "targetname"); if (tname) { String *sfmt = Getattr(rn, "sourcefmt"); String *sname = 0; int fullname = GetFlag(rn, "fullname"); int regextarget = GetFlag(rn, "regextarget"); if (sfmt) { if (fullname && prefix) { String *pname = NewStringf("%s::%s", prefix, name); sname = NewStringf(sfmt, pname); Delete(pname); } else { sname = NewStringf(sfmt, name); } } else { if (fullname && prefix) { sname = NewStringf("%s::%s", prefix, name); } else { sname = name; DohIncref(name); } } match = regextarget ? Swig_name_regexmatch_value(n, tname, sname) : Swig_name_match_value(tname, sname); Delete(sname); } else { /* Applying the renaming rule may fail if it contains a %(regex)s expression that doesn't match the given name. */ String *sname = NewStringf(Getattr(rn, "name"), name); if (sname) { if (Len(sname)) match = 1; Delete(sname); } } } if (match) { res = rn; break; } } } return res; }
static void mangle_subtype(String *mangled, SwigType *s) { List *elements; int nelements, i; assert(s); elements = SwigType_split(s); nelements = Len(elements); for (i = 0; i < nelements; i++) { SwigType *element = Getitem(elements, i); mangle_namestr(mangled, element); } Delete(elements); }
SwigType *SwigType_strip_single_qualifier(const SwigType *t) { static Hash *memoize_stripped = 0; SwigType *r = 0; List *l; int numitems; if (!memoize_stripped) memoize_stripped = NewHash(); r = Getattr(memoize_stripped, t); if (r) return Copy(r); l = SwigType_split(t); numitems = Len(l); if (numitems >= 2) { int item; /* iterate backwards from last but one item */ for (item = numitems - 2; item >= 0; --item) { String *subtype = Getitem(l, item); if (SwigType_isqualifier(subtype)) { Iterator it; Delitem(l, item); r = NewStringEmpty(); for (it = First(l); it.item; it = Next(it)) { Append(r, it.item); } break; } } } if (!r) r = Copy(t); Delete(l); { String *key, *value; key = Copy(t); value = Copy(r); Setattr(memoize_stripped, key, value); Delete(key); Delete(value); } return r; }
static DOH *Swig_get_lattr(Node *n, List *lattr) { DOH *res = 0; int ilen = Len(lattr); int i; for (i = 0; n && (i < ilen); ++i) { String *nattr = Getitem(lattr, i); res = Getattr(n, nattr); #ifdef SWIG_DEBUG if (!res) { Printf(stdout, "missing %s %s %s\n", nattr, Getattr(n, "name"), Getattr(n, "member")); } else { Printf(stdout, "lattr %d %s %s\n", i, nattr, DohIsString(res) ? res : Getattr(res, "name")); } #endif n = res; } return res; }
SwigType *SwigType_default_create(const SwigType *ty) { SwigType *r = 0; List *l; Iterator it; int numitems; if (!SwigType_isvarargs(ty)) { SwigType *t = SwigType_typedef_resolve_all(ty); r = NewStringEmpty(); l = SwigType_split(t); numitems = Len(l); if (numitems >= 1) { String *last_subtype = Getitem(l, numitems-1); if (SwigType_isenum(last_subtype)) Setitem(l, numitems-1, NewString("enum SWIGTYPE")); else Setitem(l, numitems-1, NewString("SWIGTYPE")); } for (it = First(l); it.item; it = Next(it)) { String *subtype = it.item; if (SwigType_isarray(subtype)) { if (Equal(subtype, "a().")) Append(r, NewString("a().")); else Append(r, NewString("a(ANY).")); } else if (SwigType_isfunction(subtype)) { Append(r, NewString("f(ANY).SWIGTYPE")); break; } else if (SwigType_ismemberpointer(subtype)) { Append(r, NewString("m(CLASS).SWIGTYPE")); break; } else { Append(r, subtype); } } Delete(l); Delete(t); } return r; }
/* ----------------------------------------------------------------------------- * nextchar() * * Returns the next character from the scanner or 0 if end of the string. * ----------------------------------------------------------------------------- */ static char nextchar(Scanner *s) { int nc; if (!s->str) return 0; while ((nc = Getc(s->str)) == EOF) { Delete(s->str); s->str = 0; Delitem(s->scanobjs, 0); if (Len(s->scanobjs) == 0) return 0; s->str = Getitem(s->scanobjs, 0); s->line = Getline(s->str); DohIncref(s->str); } if ((nc == '\n') && (!s->freeze_line)) s->line++; Putc(nc,s->text); return (char)nc; }
String *SwigType_namestr(const SwigType *t) { String *r; String *suffix; List *p; int i, sz; char *d = Char(t); char *c = strstr(d, "<("); if (!c || !strstr(c + 2, ")>")) return NewString(t); r = NewStringWithSize(d, c - d); if (*(c - 1) == '<') Putc(' ', r); Putc('<', r); p = SwigType_parmlist(c + 1); sz = Len(p); for (i = 0; i < sz; i++) { String *str = SwigType_str(Getitem(p, i), 0); /* Avoid creating a <: token, which is the same as [ in C++ - put a space after '<'. */ if (i == 0 && Len(str)) Putc(' ', r); Append(r, str); if ((i + 1) < sz) Putc(',', r); Delete(str); } Putc(' ', r); Putc('>', r); suffix = SwigType_templatesuffix(t); if (Len(suffix) > 0) { String *suffix_namestr = SwigType_namestr(suffix); Append(r, suffix_namestr); Delete(suffix_namestr); } else { Append(r, suffix); } Delete(suffix); Delete(p); return r; }
/* ----------------------------------------------------------------------------- * nextchar() * * Returns the next character from the scanner or 0 if end of the string. * ----------------------------------------------------------------------------- */ static char nextchar(SwigScanner *s) { char c[2] = {0,0}; int nc; if (!s->str) return 0; while ((nc = Getc(s->str)) == EOF) { Delete(s->str); s->str = 0; Delitem(s->scanobjs,0); if (Len(s->scanobjs) == 0) return 0; s->str = Getitem(s->scanobjs,0); if (s->str) { s->line = Getline(s->str); DohIncref(s->str); } } if (nc == '\n') s->line++; c[0] = (char) nc; c[1] = 0; Append(s->text,c); return c[0]; }
SwigType *SwigType_default_deduce(const SwigType *t) { SwigType *r = NewStringEmpty(); List *l; Iterator it; int numitems; l = SwigType_split(t); numitems = Len(l); if (numitems >= 1) { String *last_subtype = Getitem(l, numitems-1); int is_enum = SwigType_isenum(last_subtype); if (numitems >=2 ) { String *subtype = Getitem(l, numitems-2); /* last but one */ if (SwigType_isarray(subtype)) { if (is_enum) { /* enum deduction, enum SWIGTYPE => SWIGTYPE */ Setitem(l, numitems-1, NewString("SWIGTYPE")); } else { /* array deduction, a(ANY). => a(). => p. */ String *deduced_subtype = 0; if (Strcmp(subtype, "a().") == 0) { deduced_subtype = NewString("p."); } else if (Strcmp(subtype, "a(ANY).") == 0) { deduced_subtype = NewString("a()."); } else { assert(0); } Setitem(l, numitems-2, deduced_subtype); } } else if (SwigType_ismemberpointer(subtype)) { /* member pointer deduction, m(CLASS). => p. */ Setitem(l, numitems-2, NewString("p.")); } else if (is_enum && !SwigType_isqualifier(subtype)) { /* enum deduction, enum SWIGTYPE => SWIGTYPE */ Setitem(l, numitems-1, NewString("SWIGTYPE")); } else { /* simple type deduction, eg, r.p.p. => r.p. */ /* also function pointers eg, p.f(ANY). => p. */ Delitem(l, numitems-2); } } else { if (is_enum) { /* enum deduction, enum SWIGTYPE => SWIGTYPE */ Setitem(l, numitems-1, NewString("SWIGTYPE")); } else { /* delete the only item, we are done with deduction */ Delitem(l, 0); } } } else { assert(0); } for (it = First(l); it.item; it = Next(it)) { Append(r, it.item); } if (Len(r) == 0) { Delete(r); r = 0; } Delete(l); return r; }
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 Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { Node *n; String *tname, *rname = 0; Node *templ; List *mpartials = 0; Parm *p; Parm *parms; Parm *targs; ParmList *expandedparms; tname = Copy(name); parms = CopyParmList(tparms); /* Search for generic template */ templ = Swig_symbol_clookup(name, 0); /* Add default values from generic template */ if (templ) { Symtab *tsdecl = Getattr(templ, "sym:symtab"); targs = Getattr(templ, "templateparms"); expandedparms = Swig_symbol_template_defargs(parms, targs, tscope, tsdecl); } else { expandedparms = parms; } /* reduce the typedef */ p = expandedparms; while (p) { SwigType *ty = Getattr(p, "type"); if (ty) { SwigType *nt = Swig_symbol_type_qualify(ty, tscope); Setattr(p, "type", nt); Delete(nt); } p = nextSibling(p); } SwigType_add_template(tname, expandedparms); if (template_debug) { Printf(stdout, "\n%s:%d: template_debug: Searching for %s\n", cparse_file, cparse_line, tname); } /* Search for an exact specialization. Example: template<> class name<int> { ... } */ { if (template_debug) { Printf(stdout, " searching: '%s' (exact specialization)\n", tname); } n = Swig_symbol_clookup_local(tname, 0); if (!n) { SwigType *rname = Swig_symbol_typedef_reduce(tname, tscope); if (!Equal(rname, tname)) { if (template_debug) { Printf(stdout, " searching: '%s' (exact specialization)\n", rname); } n = Swig_symbol_clookup_local(rname, 0); } Delete(rname); } if (n) { Node *tn; String *nodeType = nodeType(n); if (Equal(nodeType, "template")) goto success; tn = Getattr(n, "template"); if (tn) { n = tn; goto success; /* Previously wrapped by a template return that */ } Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n)); Delete(tname); Delete(parms); return 0; /* Found a match, but it's not a template of any kind. */ } } /* Search for partial specialization. Example: template<typename T> class name<T *> { ... } */ /* Generate reduced template name (stripped of extraneous pointers, etc.) */ rname = NewStringf("%s<(", name); p = parms; while (p) { String *t; t = Getattr(p, "type"); if (!t) t = Getattr(p, "value"); if (t) { String *ty = Swig_symbol_typedef_reduce(t, tscope); String *tb = SwigType_base(ty); String *td = SwigType_default(ty); Replaceid(td, "enum SWIGTYPE", tb); Replaceid(td, "SWIGTYPE", tb); Append(rname, td); Delete(tb); Delete(ty); Delete(td); } p = nextSibling(p); if (p) { Append(rname, ","); } } Append(rname, ")>"); mpartials = NewList(); if (templ) { /* First, we search using an exact type prototype */ Parm *p; char tmp[32]; int i; List *partials; String *ss; Iterator pi; partials = Getattr(templ, "partials"); if (partials) { for (pi = First(partials); pi.item; pi = Next(pi)) { ss = Copy(pi.item); p = parms; i = 1; while (p) { String *t, *tn; sprintf(tmp, "$%d", i); t = Getattr(p, "type"); if (!t) t = Getattr(p, "value"); if (t) { String *ty = Swig_symbol_typedef_reduce(t, tscope); tn = SwigType_base(ty); Replaceid(ss, tmp, tn); Delete(tn); Delete(ty); } i++; p = nextSibling(p); } if (template_debug) { Printf(stdout, " searching: '%s' (partial specialization - %s)\n", ss, pi.item); } if ((Equal(ss, tname)) || (Equal(ss, rname))) { Append(mpartials, pi.item); } Delete(ss); } } } if (template_debug) { Printf(stdout, " Matched partials: %s\n", mpartials); } if (Len(mpartials)) { String *s = Getitem(mpartials, 0); n = Swig_symbol_clookup_local(s, 0); if (Len(mpartials) > 1) { if (n) { Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, cparse_file, cparse_line, "Instantiation of template '%s' is ambiguous,\n", SwigType_namestr(tname)); Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(n), Getline(n), " instantiation '%s' is used.\n", SwigType_namestr(Getattr(n, "name"))); } } } if (!n) { n = templ; } if (!n) { Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name); } else if (n) { String *nodeType = nodeType(n); if (!Equal(nodeType, "template")) { Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType); n = 0; } } success: Delete(tname); Delete(rname); Delete(mpartials); if ((template_debug) && (n)) { Printf(stdout, "Node: %p\n", n); Swig_print_node(n); } Delete(parms); return n; }
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 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); } } }
String *SwigType_str(SwigType *s, const String_or_char *id) { String *result; String *element = 0, *nextelement; List *elements; int nelements, i; if (id) { result = NewString(id); } else { result = NewStringEmpty(); } elements = SwigType_split(s); nelements = Len(elements); if (nelements > 0) { element = Getitem(elements, 0); } /* Now, walk the type list and start emitting */ for (i = 0; i < nelements; i++) { if (i < (nelements - 1)) { nextelement = Getitem(elements, i + 1); } else { nextelement = 0; } if (SwigType_isqualifier(element)) { DOH *q = 0; q = SwigType_parm(element); Insert(result, 0, " "); Insert(result, 0, q); Delete(q); } else if (SwigType_ispointer(element)) { Insert(result, 0, "*"); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result, 0, "("); Append(result, ")"); } } else if (SwigType_ismemberpointer(element)) { String *q; q = SwigType_parm(element); Insert(result, 0, "::*"); Insert(result, 0, q); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result, 0, "("); Append(result, ")"); } Delete(q); } else if (SwigType_isreference(element)) { Insert(result, 0, "&"); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result, 0, "("); Append(result, ")"); } } else if (SwigType_isarray(element)) { DOH *size; Append(result, "["); size = SwigType_parm(element); Append(result, size); Append(result, "]"); Delete(size); } else if (SwigType_isfunction(element)) { DOH *parms, *p; int j, plen; Append(result, "("); parms = SwigType_parmlist(element); plen = Len(parms); for (j = 0; j < plen; j++) { p = SwigType_str(Getitem(parms, j), 0); Append(result, p); if (j < (plen - 1)) Append(result, ","); } Append(result, ")"); Delete(parms); } else { if (strcmp(Char(element), "v(...)") == 0) { Insert(result, 0, "..."); } else { String *bs = SwigType_namestr(element); Insert(result, 0, " "); Insert(result, 0, bs); Delete(bs); } } element = nextelement; } Delete(elements); Chop(result); return result; }
static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { Node *n = 0; String *tname = 0; Node *templ; Symtab *primary_scope = 0; List *possiblepartials = 0; Parm *p; Parm *parms = 0; Parm *targs; ParmList *expandedparms; int *priorities_matrix = 0; int max_possible_partials = 0; int posslen = 0; /* Search for primary (unspecialized) template */ templ = Swig_symbol_clookup(name, 0); if (template_debug) { tname = Copy(name); SwigType_add_template(tname, tparms); Printf(stdout, "\n"); Swig_diagnostic(cparse_file, cparse_line, "template_debug: Searching for match to: '%s'\n", tname); Delete(tname); tname = 0; } if (templ) { tname = Copy(name); parms = CopyParmList(tparms); /* All template specializations must be in the primary template's scope, store the symbol table for this scope for specialization lookups */ primary_scope = Getattr(templ, "sym:symtab"); /* Add default values from primary template */ targs = Getattr(templ, "templateparms"); expandedparms = Swig_symbol_template_defargs(parms, targs, tscope, primary_scope); /* reduce the typedef */ p = expandedparms; while (p) { SwigType *ty = Getattr(p, "type"); if (ty) { SwigType *nt = Swig_symbol_type_qualify(ty, tscope); Setattr(p, "type", nt); Delete(nt); } p = nextSibling(p); } SwigType_add_template(tname, expandedparms); /* Search for an explicit (exact) specialization. Example: template<> class name<int> { ... } */ { if (template_debug) { Printf(stdout, " searching for : '%s' (explicit specialization)\n", tname); } n = Swig_symbol_clookup_local(tname, primary_scope); if (!n) { SwigType *rname = Swig_symbol_typedef_reduce(tname, tscope); if (!Equal(rname, tname)) { if (template_debug) { Printf(stdout, " searching for : '%s' (explicit specialization with typedef reduction)\n", rname); } n = Swig_symbol_clookup_local(rname, primary_scope); } Delete(rname); } if (n) { Node *tn; String *nodeType = nodeType(n); if (Equal(nodeType, "template")) { if (template_debug) { Printf(stdout, " explicit specialization found: '%s'\n", Getattr(n, "name")); } goto success; } tn = Getattr(n, "template"); if (tn) { if (template_debug) { Printf(stdout, " previous instantiation found: '%s'\n", Getattr(n, "name")); } n = tn; goto success; /* Previously wrapped by a template instantiation */ } Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n)); Delete(tname); Delete(parms); return 0; /* Found a match, but it's not a template of any kind. */ } } /* Search for partial specializations. * Example: template<typename T> class name<T *> { ... } * There are 3 types of template arguments: * (1) Template type arguments * (2) Template non type arguments * (3) Template template arguments * only (1) is really supported for partial specializations */ /* Rank each template parameter against the desired template parameters then build a matrix of best matches */ possiblepartials = NewList(); { char tmp[32]; List *partials; partials = Getattr(templ, "partials"); /* note that these partial specializations do not include explicit specializations */ if (partials) { Iterator pi; int parms_len = ParmList_len(parms); int *priorities_row; max_possible_partials = Len(partials); priorities_matrix = (int *)malloc(sizeof(int) * max_possible_partials * parms_len); /* slightly wasteful allocation for max possible matches */ priorities_row = priorities_matrix; for (pi = First(partials); pi.item; pi = Next(pi)) { Parm *p = parms; int all_parameters_match = 1; int i = 1; Parm *partialparms = Getattr(pi.item, "partialparms"); Parm *pp = partialparms; String *templcsymname = Getattr(pi.item, "templcsymname"); if (template_debug) { Printf(stdout, " checking match: '%s' (partial specialization)\n", templcsymname); } if (ParmList_len(partialparms) == parms_len) { while (p && pp) { SwigType *t; sprintf(tmp, "$%d", i); t = Getattr(p, "type"); if (!t) t = Getattr(p, "value"); if (t) { EMatch match = does_parm_match(t, Getattr(pp, "type"), tmp, tscope, priorities_row + i - 1); if (match < (int)PartiallySpecializedMatch) { all_parameters_match = 0; break; } } i++; p = nextSibling(p); pp = nextSibling(pp); } if (all_parameters_match) { Append(possiblepartials, pi.item); priorities_row += parms_len; } } } } } posslen = Len(possiblepartials); if (template_debug) { int i; if (posslen == 0) Printf(stdout, " matched partials: NONE\n"); else if (posslen == 1) Printf(stdout, " chosen partial: '%s'\n", Getattr(Getitem(possiblepartials, 0), "templcsymname")); else { Printf(stdout, " possibly matched partials:\n"); for (i = 0; i < posslen; i++) { Printf(stdout, " '%s'\n", Getattr(Getitem(possiblepartials, i), "templcsymname")); } } } if (posslen > 1) { /* Now go through all the possibly matched partial specialization templates and look for a non-ambiguous match. * Exact matches rank the highest and deduced parameters are ranked by how specialized they are, eg looking for * a match to const int *, the following rank (highest to lowest): * const int * (exact match) * const T * * T * * T * * An ambiguous example when attempting to match as either specialization could match: %template() X<int *, double *>; * template<typename T1, typename T2> X class {}; // primary template * template<typename T1> X<T1, double *> class {}; // specialization (1) * template<typename T2> X<int *, T2> class {}; // specialization (2) */ if (template_debug) { int row, col; int parms_len = ParmList_len(parms); Printf(stdout, " parameter priorities matrix (%d parms):\n", parms_len); for (row = 0; row < posslen; row++) { int *priorities_row = priorities_matrix + row*parms_len; Printf(stdout, " "); for (col = 0; col < parms_len; col++) { Printf(stdout, "%5d ", priorities_row[col]); } Printf(stdout, "\n"); } } { int row, col; int parms_len = ParmList_len(parms); /* Printf(stdout, " parameter priorities inverse matrix (%d parms):\n", parms_len); */ for (col = 0; col < parms_len; col++) { int *priorities_col = priorities_matrix + col; int maxpriority = -1; /* Printf(stdout, "max_possible_partials: %d col:%d\n", max_possible_partials, col); Printf(stdout, " "); */ /* determine the highest rank for this nth parameter */ for (row = 0; row < posslen; row++) { int *element_ptr = priorities_col + row*parms_len; int priority = *element_ptr; if (priority > maxpriority) maxpriority = priority; /* Printf(stdout, "%5d ", priority); */ } /* Printf(stdout, "\n"); */ /* flag all the parameters which equal the highest rank */ for (row = 0; row < posslen; row++) { int *element_ptr = priorities_col + row*parms_len; int priority = *element_ptr; *element_ptr = (priority >= maxpriority) ? 1 : 0; } } } { int row, col; int parms_len = ParmList_len(parms); Iterator pi = First(possiblepartials); Node *chosenpartials = NewList(); if (template_debug) Printf(stdout, " priority flags matrix:\n"); for (row = 0; row < posslen; row++) { int *priorities_row = priorities_matrix + row*parms_len; int highest_count = 0; /* count of highest priority parameters */ for (col = 0; col < parms_len; col++) { highest_count += priorities_row[col]; } if (template_debug) { Printf(stdout, " "); for (col = 0; col < parms_len; col++) { Printf(stdout, "%5d ", priorities_row[col]); } Printf(stdout, "\n"); } if (highest_count == parms_len) { Append(chosenpartials, pi.item); } pi = Next(pi); } if (Len(chosenpartials) > 0) { /* one or more best match found */ Delete(possiblepartials); possiblepartials = chosenpartials; posslen = Len(possiblepartials); } else { /* no best match found */ Delete(chosenpartials); } } } if (posslen > 0) { String *s = Getattr(Getitem(possiblepartials, 0), "templcsymname"); n = Swig_symbol_clookup_local(s, primary_scope); if (posslen > 1) { int i; if (n) { Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, cparse_file, cparse_line, "Instantiation of template '%s' is ambiguous,\n", SwigType_namestr(tname)); Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(n), Getline(n), " instantiation '%s' used,\n", SwigType_namestr(Getattr(n, "name"))); } for (i = 1; i < posslen; i++) { String *templcsymname = Getattr(Getitem(possiblepartials, i), "templcsymname"); Node *ignored_node = Swig_symbol_clookup_local(templcsymname, primary_scope); assert(ignored_node); Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(ignored_node), Getline(ignored_node), " instantiation '%s' ignored.\n", SwigType_namestr(Getattr(ignored_node, "name"))); } } } if (!n) { if (template_debug) { Printf(stdout, " chosen primary template: '%s'\n", Getattr(templ, "name")); } n = templ; } } else { if (template_debug) { Printf(stdout, " primary template not found\n"); } /* Give up if primary (unspecialized) template not found as specializations will only exist if there is a primary template */ n = 0; } if (!n) { Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name); } else if (n) { String *nodeType = nodeType(n); if (!Equal(nodeType, "template")) { Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType); n = 0; } } success: Delete(tname); Delete(possiblepartials); if ((template_debug) && (n)) { /* Printf(stdout, "Node: %p\n", n); Swig_print_node(n); */ Printf(stdout, " chosen template:'%s'\n", Getattr(n, "name")); } Delete(parms); free(priorities_matrix); return n; }
String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) { String *result, *cast; String *element = 0; String *nextelement; String *forwardelement; SwigType *td, *tc = 0; const SwigType *rs; List *elements; int nelements, i; int clear = 1; int firstarray = 1; int isreference = 0; int isfunction = 0; result = NewStringEmpty(); if (SwigType_isconst(s)) { tc = Copy(s); Delete(SwigType_pop(tc)); rs = tc; } else { rs = s; } if ((SwigType_isconst(rs) || SwigType_isarray(rs) || SwigType_isreference(rs))) { td = 0; } else { td = SwigType_typedef_resolve(rs); } if (td) { if ((SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) { elements = SwigType_split(td); } else { elements = SwigType_split(rs); } Delete(td); } else { elements = SwigType_split(rs); } nelements = Len(elements); if (nelements > 0) { element = Getitem(elements, 0); } /* Now, walk the type list and start emitting */ for (i = 0; i < nelements; i++) { if (i < (nelements - 1)) { nextelement = Getitem(elements, i + 1); forwardelement = nextelement; if (SwigType_isqualifier(nextelement)) { if (i < (nelements - 2)) forwardelement = Getitem(elements, i + 2); } } else { nextelement = 0; forwardelement = 0; } if (SwigType_isqualifier(element)) { DOH *q = 0; q = SwigType_parm(element); Insert(result, 0, " "); Insert(result, 0, q); Delete(q); clear = 0; } else if (SwigType_ispointer(element)) { Insert(result, 0, "*"); if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } firstarray = 0; } else if (SwigType_ismemberpointer(element)) { String *q; Insert(result, 0, "::*"); q = SwigType_parm(element); Insert(result, 0, q); Delete(q); if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } firstarray = 0; } else if (SwigType_isreference(element)) { Insert(result, 0, "&"); if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } if (!isfunction) isreference = 1; } else if (SwigType_isarray(element)) { DOH *size; if (firstarray && !isreference) { Append(result, "(*)"); firstarray = 0; } else { Append(result, "["); size = SwigType_parm(element); Append(result, size); Append(result, "]"); Delete(size); clear = 0; } } else if (SwigType_isfunction(element)) { DOH *parms, *p; int j, plen; Append(result, "("); parms = SwigType_parmlist(element); plen = Len(parms); for (j = 0; j < plen; j++) { p = SwigType_str(Getitem(parms, j), 0); Append(result, p); Delete(p); if (j < (plen - 1)) Append(result, ","); } Append(result, ")"); Delete(parms); isfunction = 1; } else { String *bs = SwigType_namestr(element); Insert(result, 0, " "); Insert(result, 0, bs); Delete(bs); } element = nextelement; } Delete(elements); if (clear) { cast = NewStringEmpty(); } else { cast = NewStringf("(%s)", result); } if (name) { if (isreference) { Append(cast, "*"); } Append(cast, name); } Delete(result); Delete(tc); return cast; }
SwigType *SwigType_ltype(const SwigType *s) { String *result; String *element; SwigType *td, *tc = 0; List *elements; int nelements, i; int firstarray = 1; int notypeconv = 0; result = NewStringEmpty(); tc = Copy(s); /* Nuke all leading qualifiers */ while (SwigType_isqualifier(tc)) { Delete(SwigType_pop(tc)); } if (SwigType_issimple(tc)) { /* Resolve any typedef definitions */ SwigType *tt = Copy(tc); td = 0; while ((td = SwigType_typedef_resolve(tt))) { if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) { /* We need to use the typedef type */ Delete(tt); tt = td; break; } else if (td) { Delete(tt); tt = td; } } if (td) { Delete(tc); tc = td; } } elements = SwigType_split(tc); nelements = Len(elements); /* Now, walk the type list and start emitting */ for (i = 0; i < nelements; i++) { element = Getitem(elements, i); /* when we see a function, we need to preserve the following types */ if (SwigType_isfunction(element)) { notypeconv = 1; } if (SwigType_isqualifier(element)) { /* Do nothing. Ignore */ } else if (SwigType_ispointer(element)) { Append(result, element); firstarray = 0; } else if (SwigType_ismemberpointer(element)) { Append(result, element); firstarray = 0; } else if (SwigType_isreference(element)) { if (notypeconv) { Append(result, element); } else { Append(result, "p."); } firstarray = 0; } else if (SwigType_isarray(element) && firstarray) { if (notypeconv) { Append(result, element); } else { Append(result, "p."); } firstarray = 0; } else if (SwigType_isenum(element)) { int anonymous_enum = (Cmp(element, "enum ") == 0); if (notypeconv || !anonymous_enum) { Append(result, element); } else { Append(result, "int"); } } else { Append(result, element); } } Delete(elements); Delete(tc); return result; }
String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) { String *result; String *element = 0; String *nextelement; String *forwardelement; List *elements; int nelements, i; if (id) { /* stringify the id expanding templates, for example when the id is a fully qualified templated class name */ String *id_str = NewString(id); /* unfortunate copy due to current const limitations */ result = SwigType_str(id_str, 0); Delete(id_str); } else { result = NewStringEmpty(); } elements = SwigType_split(s); nelements = Len(elements); if (nelements > 0) { element = Getitem(elements, 0); } /* Now, walk the type list and start emitting */ for (i = 0; i < nelements; i++) { if (i < (nelements - 1)) { nextelement = Getitem(elements, i + 1); forwardelement = nextelement; if (SwigType_isqualifier(nextelement)) { if (i < (nelements - 2)) forwardelement = Getitem(elements, i + 2); } } else { nextelement = 0; forwardelement = 0; } if (SwigType_isqualifier(element)) { DOH *q = 0; q = SwigType_parm(element); Insert(result, 0, " "); Insert(result, 0, q); Delete(q); } else if (SwigType_ispointer(element)) { Insert(result, 0, "*"); if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } } else if (SwigType_ismemberpointer(element)) { String *q; q = SwigType_parm(element); Insert(result, 0, "::*"); Insert(result, 0, q); if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } Delete(q); } else if (SwigType_isreference(element)) { Insert(result, 0, "&"); if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } } else if (SwigType_isarray(element)) { DOH *size; Append(result, "["); size = SwigType_parm(element); Append(result, size); Append(result, "]"); Delete(size); } else if (SwigType_isfunction(element)) { DOH *parms, *p; int j, plen; Append(result, "("); parms = SwigType_parmlist(element); plen = Len(parms); for (j = 0; j < plen; j++) { p = SwigType_str(Getitem(parms, j), 0); Append(result, p); if (j < (plen - 1)) Append(result, ","); } Append(result, ")"); Delete(parms); } else { if (strcmp(Char(element), "v(...)") == 0) { Insert(result, 0, "..."); } else { String *bs = SwigType_namestr(element); Insert(result, 0, " "); Insert(result, 0, bs); Delete(bs); } } element = nextelement; } Delete(elements); Chop(result); return result; }
void SwigType_typename_replace(SwigType *t, String *pat, String *rep) { String *nt; int i, ilen; List *elem; if (!Strstr(t, pat)) return; if (Equal(t, pat)) { Replace(t, pat, rep, DOH_REPLACE_ANY); return; } nt = NewStringEmpty(); elem = SwigType_split(t); ilen = Len(elem); for (i = 0; i < ilen; i++) { String *e = Getitem(elem, i); if (SwigType_issimple(e)) { if (Equal(e, pat)) { /* Replaces a type of the form 'pat' with 'rep<args>' */ Replace(e, pat, rep, DOH_REPLACE_ANY); } else if (SwigType_istemplate(e)) { /* Replaces a type of the form 'pat<args>' with 'rep' */ if (Equal(e, pat)) { String *repbase = SwigType_templateprefix(rep); Replace(e, pat, repbase, DOH_REPLACE_ID | DOH_REPLACE_FIRST); Delete(repbase); } { String *tsuffix; List *tparms = SwigType_parmlist(e); int j, jlen; String *nt = SwigType_templateprefix(e); Append(nt, "<("); jlen = Len(tparms); for (j = 0; j < jlen; j++) { SwigType_typename_replace(Getitem(tparms, j), pat, rep); Append(nt, Getitem(tparms, j)); if (j < (jlen - 1)) Putc(',', nt); } tsuffix = SwigType_templatesuffix(e); Printf(nt, ")>%s", tsuffix); Delete(tsuffix); Clear(e); Append(e, nt); Delete(nt); Delete(tparms); } } else if (Swig_scopename_check(e)) { String *first, *rest; first = Swig_scopename_first(e); rest = Swig_scopename_suffix(e); SwigType_typename_replace(rest, pat, rep); SwigType_typename_replace(first, pat, rep); Clear(e); Printv(e, first, "::", rest, NIL); Delete(first); Delete(rest); } } else if (SwigType_isfunction(e)) { int j, jlen; List *fparms = SwigType_parmlist(e); Clear(e); Append(e, "f("); jlen = Len(fparms); for (j = 0; j < jlen; j++) { SwigType_typename_replace(Getitem(fparms, j), pat, rep); Append(e, Getitem(fparms, j)); if (j < (jlen - 1)) Putc(',', e); } Append(e, ")."); Delete(fparms); } else if (SwigType_isarray(e)) { Replace(e, pat, rep, DOH_REPLACE_ID); } Append(nt, e); } Clear(t); Append(t, nt); Delete(nt); Delete(elem); }