Fixes for SWIG_TypeQuery and templates/typedefs,

before the swig_type_info fields 'str' and 'name'
where not consistent, one was fully resolved (name),
the other not, therefore

  typedef int Int;
  template <class C> struct Class {};

  SWIG_TypeQuery($descriptor(Class<int>*))

wasn't necessary the same that

  typedef int Int;
  template <class C> struct Class {};

  SWIG_TypeQuery("Class<int> *")

the problem was visible only when the latter form was used,
like in a static auxiliar function outside a typemap.

also, relax type name comparison with blanks, ie

  SWIG_TypeQuery("Class<int> *") := SWIG_TypeQuery("Class<int > *")


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5703 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2004-02-10 03:42:38 +00:00
commit d3caa4eefc
2 changed files with 100 additions and 55 deletions

View file

@ -167,12 +167,33 @@ SWIG_TypeName(const swig_type_info *ty) {
return ty->name; return ty->name;
} }
/*
Compare two type names skipping the space characters, therefore
"char*" == "char *" and "Class<int>" == "Class<int >", etc.
Return 0 when the two name types are equivalent, as in
strncmp, but skipping ' '.
*/
static int
SWIG_TypeNameComp(const char *name1, const char *name2) {
register size_t s1 = strlen(name1);
register size_t s2 = strlen(name2);
register size_t i1 = 0;
register size_t i2 = 0;
for( ; (i1 < s1) && (i2 < s2); ++i1, ++i2) {
while ((name1[i1] == ' ') && (i1 < s1)) ++i1;
while ((name2[i2] == ' ') && (i2 < s2)) ++i2;
if (name1[i1] != name2[i2]) return name1[i1] - name2[i2];
}
return (s1 - i1) - (s2 - i2);
}
/* Search for a swig_type_info structure */ /* Search for a swig_type_info structure */
SWIGRUNTIME(swig_type_info *) SWIGRUNTIME(swig_type_info *)
SWIG_TypeQuery(const char *name) { SWIG_TypeQuery(const char *name) {
swig_type_info *ty = swig_type_list; swig_type_info *ty = swig_type_list;
while (ty) { while (ty) {
if (ty->str && (strcmp(name,ty->str) == 0)) return ty; if (ty->str && (SWIG_TypeNameComp(name,ty->str) == 0)) return ty;
if (ty->name && (strcmp(name,ty->name) == 0)) return ty; if (ty->name && (strcmp(name,ty->name) == 0)) return ty;
ty = ty->prev; ty = ty->prev;
} }

View file

@ -104,10 +104,23 @@ static Typetab *global_scope = 0; /* The global scope
static Hash *scopes = 0; /* Hash table containing fully qualified scopes */ static Hash *scopes = 0; /* Hash table containing fully qualified scopes */
/* Performance optimization */ /* Performance optimization */
#define SWIG_TYPEDEF_RESOLVE_CACHE
static Hash *typedef_resolve_cache = 0; static Hash *typedef_resolve_cache = 0;
static Hash *typedef_all_cache = 0; static Hash *typedef_all_cache = 0;
static Hash *typedef_qualified_cache = 0; static Hash *typedef_qualified_cache = 0;
/* common attribute keys, to avoid calling find_key all the times */
static String *k_name = 0;
static String *k_qname = 0;
static String *k_symtab = 0;
static String *k_using = 0;
static String *k_scope = 0;
static String *k_typetab = 0;
static String *k_inherit = 0;
static String *k_parent = 0;
static String *k_value = 0;
static void flush_cache() { static void flush_cache() {
typedef_resolve_cache = 0; typedef_resolve_cache = 0;
typedef_all_cache = 0; typedef_all_cache = 0;
@ -117,21 +130,32 @@ static void flush_cache() {
/* Initialize the scoping system */ /* Initialize the scoping system */
void SwigType_typesystem_init() { void SwigType_typesystem_init() {
k_name = NewString("name");
k_qname = NewString("qname");
k_symtab = NewString("symtab");
k_using = NewString("using");
k_scope = NewString("scope");
k_typetab = NewString("typetab");
k_inherit = NewString("inherit");
k_parent = NewString("parent");
k_value = NewString("value");
if (global_scope) Delete(global_scope); if (global_scope) Delete(global_scope);
if (scopes) Delete(scopes); if (scopes) Delete(scopes);
current_scope = NewHash(); current_scope = NewHash();
global_scope = current_scope; global_scope = current_scope;
Setattr(current_scope,"name",""); /* No name for global scope */ Setattr(current_scope,k_name,""); /* No name for global scope */
current_typetab = NewHash(); current_typetab = NewHash();
Setattr(current_scope,"typetab", current_typetab); Setattr(current_scope,k_typetab, current_typetab);
current_symtab = 0; current_symtab = 0;
scopes = NewHash(); scopes = NewHash();
Setattr(scopes,"",current_scope); Setattr(scopes,"",current_scope);
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* SwigType_typedef() * SwigType_typedef()
* *
@ -189,15 +213,15 @@ int SwigType_typedef_class(String_or_char *name) {
String * String *
SwigType_scope_name(Typetab *ttab) { SwigType_scope_name(Typetab *ttab) {
String *qname = NewString(Getattr(ttab,"name")); String *qname = NewString(Getattr(ttab,k_name));
ttab = Getattr(ttab,"parent"); ttab = Getattr(ttab,k_parent);
while (ttab) { while (ttab) {
String *pname = Getattr(ttab,"name"); String *pname = Getattr(ttab,k_name);
if (Len(pname)) { if (Len(pname)) {
Insert(qname,0,"::"); Insert(qname,0,"::");
Insert(qname,0,pname); Insert(qname,0,pname);
} }
ttab = Getattr(ttab,"parent"); ttab = Getattr(ttab,k_parent);
} }
return qname; return qname;
} }
@ -216,15 +240,15 @@ void SwigType_new_scope(const String_or_char *name) {
name = "<unnamed>"; name = "<unnamed>";
} }
s = NewHash(); s = NewHash();
Setattr(s,"name", name); Setattr(s,k_name, name);
Setattr(s,"parent", current_scope); Setattr(s,k_parent, current_scope);
ttab = NewHash(); ttab = NewHash();
Setattr(s,"typetab", ttab); Setattr(s,k_typetab, ttab);
/* Build fully qualified name and */ /* Build fully qualified name and */
qname = SwigType_scope_name(s); qname = SwigType_scope_name(s);
Setattr(scopes,qname,s); Setattr(scopes,qname,s);
Setattr(s,"qname",qname); Setattr(s,k_qname,qname);
Delete(qname); Delete(qname);
current_scope = s; current_scope = s;
@ -244,10 +268,10 @@ void
SwigType_inherit_scope(Typetab *scope) { SwigType_inherit_scope(Typetab *scope) {
List *inherits; List *inherits;
int i, len; int i, len;
inherits = Getattr(current_scope,"inherit"); inherits = Getattr(current_scope,k_inherit);
if (!inherits) { if (!inherits) {
inherits = NewList(); inherits = NewList();
Setattr(current_scope,"inherit", inherits); Setattr(current_scope,k_inherit, inherits);
} }
assert(scope != current_scope); assert(scope != current_scope);
@ -290,10 +314,10 @@ SwigType_using_scope(Typetab *scope) {
{ {
List *ulist; List *ulist;
int i, len; int i, len;
ulist = Getattr(current_scope,"using"); ulist = Getattr(current_scope,k_using);
if (!ulist) { if (!ulist) {
ulist = NewList(); ulist = NewList();
Setattr(current_scope,"using", ulist); Setattr(current_scope,k_using, ulist);
} }
assert(scope != current_scope); assert(scope != current_scope);
len = Len(ulist); len = Len(ulist);
@ -315,7 +339,7 @@ SwigType_using_scope(Typetab *scope) {
Typetab *SwigType_pop_scope() { Typetab *SwigType_pop_scope() {
Typetab *s, *s1; Typetab *s, *s1;
s = Getattr(current_scope,"parent"); s = Getattr(current_scope,k_parent);
if (!s) { if (!s) {
current_scope = 0; current_scope = 0;
current_typetab = 0; current_typetab = 0;
@ -324,8 +348,8 @@ Typetab *SwigType_pop_scope() {
} }
s1 = current_scope; s1 = current_scope;
current_scope = s; current_scope = s;
current_typetab = Getattr(s,"typetab"); current_typetab = Getattr(s,k_typetab);
current_symtab = Getattr(s,"symtab"); current_symtab = Getattr(s,k_symtab);
flush_cache(); flush_cache();
return s1; return s1;
} }
@ -341,8 +365,8 @@ SwigType_set_scope(Typetab *t) {
Typetab *old = current_scope; Typetab *old = current_scope;
if (!t) t = global_scope; if (!t) t = global_scope;
current_scope = t; current_scope = t;
current_typetab = Getattr(t,"typetab"); current_typetab = Getattr(t,k_typetab);
current_symtab = Getattr(t,"symtab"); current_symtab = Getattr(t,k_symtab);
flush_cache(); flush_cache();
return old; return old;
} }
@ -355,7 +379,7 @@ SwigType_set_scope(Typetab *t) {
void void
SwigType_attach_symtab(Symtab *sym) { SwigType_attach_symtab(Symtab *sym) {
Setattr(current_scope,"symtab",sym); Setattr(current_scope,k_symtab,sym);
current_symtab = sym; current_symtab = sym;
} }
@ -371,15 +395,15 @@ void SwigType_print_scope(Typetab *t) {
for (i = First(scopes); i.key; i = Next(i)) { for (i = First(scopes); i.key; i = Next(i)) {
t = i.item; t = i.item;
ttab = Getattr(i.item,"typetab"); ttab = Getattr(i.item,k_typetab);
Printf(stdout,"Type scope '%s' (%x)\n", i.key, i.item); Printf(stdout,"Type scope '%s' (%x)\n", i.key, i.item);
{ {
List *inherit = Getattr(i.item,"inherit"); List *inherit = Getattr(i.item,k_inherit);
if (inherit) { if (inherit) {
Iterator j; Iterator j;
for (j = First(inherit); j.item; j = Next(j)) { for (j = First(inherit); j.item; j = Next(j)) {
Printf(stdout," Inherits from '%s' (%x)\n", Getattr(j.item,"qname"), j.item); Printf(stdout," Inherits from '%s' (%x)\n", Getattr(j.item,k_qname), j.item);
} }
} }
} }
@ -406,7 +430,7 @@ SwigType_find_scope(Typetab *s, String *nameprefix) {
ss = s; ss = s;
while (ss) { while (ss) {
String *full; String *full;
String *qname = Getattr(ss,"qname"); String *qname = Getattr(ss,k_qname);
if (qname) { if (qname) {
full = NewStringf("%s::%s", qname, nameprefix); full = NewStringf("%s::%s", qname, nameprefix);
} else { } else {
@ -425,7 +449,7 @@ SwigType_find_scope(Typetab *s, String *nameprefix) {
if (!s) { if (!s) {
/* Check inheritance */ /* Check inheritance */
List *inherit; List *inherit;
inherit = Getattr(ss,"using"); inherit = Getattr(ss,k_using);
if (inherit) { if (inherit) {
Typetab *ttab; Typetab *ttab;
int i, len; int i, len;
@ -444,7 +468,7 @@ SwigType_find_scope(Typetab *s, String *nameprefix) {
} }
} }
if (!check_parent) break; if (!check_parent) break;
ss = Getattr(ss,"parent"); ss = Getattr(ss,k_parent);
} }
if (nnameprefix) Delete(nnameprefix); if (nnameprefix) Delete(nnameprefix);
return 0; return 0;
@ -460,19 +484,21 @@ SwigType_find_scope(Typetab *s, String *nameprefix) {
static Typetab *resolved_scope = 0; static Typetab *resolved_scope = 0;
/* Internal function */ /* Internal function */
static SwigType * static SwigType *
typedef_resolve(Typetab *s, String *base) { typedef_resolve(Typetab *s, String *base) {
Hash *ttab; Hash *ttab;
SwigType *type; SwigType *type;
List *inherit; List *inherit;
Typetab *parent;
if (!s) return 0; /* if (!s) return 0; *//* now is checked bellow */
/* Printf(stdout,"Typetab %s : %s\n", Getattr(s,"name"), base); */ /* Printf(stdout,"Typetab %s : %s\n", Getattr(s,"name"), base); */
if (Getmark(s)) return 0; if (Getmark(s)) return 0;
Setmark(s,1); Setmark(s,1);
ttab = Getattr(s,"typetab"); ttab = Getattr(s,k_typetab);
type = Getattr(ttab,base); type = Getattr(ttab,base);
if (type) { if (type) {
resolved_scope = s; resolved_scope = s;
@ -480,7 +506,7 @@ typedef_resolve(Typetab *s, String *base) {
return type; return type;
} }
/* Hmmm. Not found in my scope. It could be in an inherited scope */ /* Hmmm. Not found in my scope. It could be in an inherited scope */
inherit = Getattr(s,"inherit"); inherit = Getattr(s,k_inherit);
if (inherit) { if (inherit) {
int i,len; int i,len;
len = Len(inherit); len = Len(inherit);
@ -492,7 +518,8 @@ typedef_resolve(Typetab *s, String *base) {
} }
} }
} }
type = typedef_resolve(Getattr(s,"parent"), base); parent = Getattr(s,k_parent);
type = parent ? typedef_resolve(parent, base) : 0;
Setmark(s,0); Setmark(s,0);
return type; return type;
} }
@ -515,20 +542,16 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
resolved_scope = 0; resolved_scope = 0;
/* #ifdef SWIG_TYPEDEF_RESOLVE_CACHE
if (!typedef_resolve_cache) { if (!typedef_resolve_cache) {
typedef_resolve_cache = NewHash(); typedef_resolve_cache = NewHash();
} }
r = Getattr(typedef_resolve_cache,t); r = Getattr(typedef_resolve_cache,t);
if (r) { if (r) {
if (r != noscope) { resolved_scope = Getmeta(r,k_scope);
resolved_scope = Getmeta(r,"scope"); return Copy(r);
return Copy(r);
} else {
return 0;
}
} }
*/ #endif
base = SwigType_base(t); base = SwigType_base(t);
@ -539,7 +562,7 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
ttab = current_typetab; ttab = current_typetab;
if (Strncmp(base,"::",2) == 0) { if (Strncmp(base,"::",2) == 0) {
s = global_scope; s = global_scope;
ttab = Getattr(s,"typetab"); ttab = Getattr(s,k_typetab);
Delitem(base,0); Delitem(base,0);
Delitem(base,0); Delitem(base,0);
} }
@ -572,7 +595,7 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
/* Printf(stdout,"%s type = '%s'\n", Getattr(s,"name"), type); */ /* Printf(stdout,"%s type = '%s'\n", Getattr(s,"name"), type); */
if ((type) && (!Swig_scopename_check(type))) { if ((type) && (!Swig_scopename_check(type))) {
Typetab *rtab = resolved_scope; Typetab *rtab = resolved_scope;
String *qname = Getattr(resolved_scope,"qname"); String *qname = Getattr(resolved_scope,k_qname);
/* If qualified *and* the typename is defined from the resolved scope, we qualify */ /* If qualified *and* the typename is defined from the resolved scope, we qualify */
if ((qname) && typedef_resolve(resolved_scope,type)) { if ((qname) && typedef_resolve(resolved_scope,type)) {
type = Copy(type); type = Copy(type);
@ -717,22 +740,20 @@ SwigType *SwigType_typedef_resolve(SwigType *t) {
} }
return_result: return_result:
/* #ifdef SWIG_TYPEDEF_RESOLVE_CACHE
{ {
String *key = NewString(t); String *key = NewString(t);
if (!r) { if (r) {
Setattr(typedef_resolve_cache,key,noscope);
} else {
SwigType *r1; SwigType *r1;
Setattr(typedef_resolve_cache,key,r); Setattr(typedef_resolve_cache,key,r);
Setmeta(r,"scope",resolved_scope); Setmeta(r,k_scope,resolved_scope);
r1 = Copy(r); r1 = Copy(r);
Delete(r); Delete(r);
r = r1; r = r1;
} }
Delete(key); Delete(key);
} }
*/ #endif
return r; return r;
} }
@ -805,7 +826,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
resolved_scope = 0; resolved_scope = 0;
if (typedef_resolve(current_scope,e)) { if (typedef_resolve(current_scope,e)) {
/* resolved_scope contains the scope that actually resolved the symbol */ /* resolved_scope contains the scope that actually resolved the symbol */
String *qname = Getattr(resolved_scope,"qname"); String *qname = Getattr(resolved_scope,k_qname);
if (qname) { if (qname) {
Insert(e,0,"::"); Insert(e,0,"::");
Insert(e,0,qname); Insert(e,0,qname);
@ -849,7 +870,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
break; break;
} }
Delete(qs); Delete(qs);
cs = Getattr(cs,"parent"); cs = Getattr(cs,k_parent);
} }
} }
} }
@ -886,7 +907,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
String *qn = Swig_symbol_qualified(n); String *qn = Swig_symbol_qualified(n);
if (Len(qn)) { if (Len(qn)) {
Append(qn,"::"); Append(qn,"::");
Append(qn,Getattr(n,"name")); Append(qn,Getattr(n,k_name));
Delete(value); Delete(value);
value = qn; value = qn;
continue; continue;
@ -894,9 +915,9 @@ SwigType *SwigType_typedef_qualified(SwigType *t)
Delete(qn); Delete(qn);
break; break;
} }
} else if ((Strcmp(nodeType(n),"cdecl") == 0) && (Getattr(n,"value"))) { } else if ((Strcmp(nodeType(n),"cdecl") == 0) && (Getattr(n,k_value))) {
Delete(value); Delete(value);
value = Copy(Getattr(n,"value")); value = Copy(Getattr(n,k_value));
continue; continue;
} }
} }
@ -1028,7 +1049,7 @@ int SwigType_typedef_using(String_or_char *name) {
td = SwigType_typedef_resolve(name); td = SwigType_typedef_resolve(name);
/* Printf(stdout,"td = '%s' %x\n", td, resolved_scope); */ /* Printf(stdout,"td = '%s' %x\n", td, resolved_scope); */
if (resolved_scope) { if (resolved_scope) {
defined_name = Getattr(resolved_scope,"qname"); defined_name = Getattr(resolved_scope,k_qname);
if (defined_name) { if (defined_name) {
defined_name = Copy(defined_name); defined_name = Copy(defined_name);
Append(defined_name,"::"); Append(defined_name,"::");
@ -1045,7 +1066,7 @@ int SwigType_typedef_using(String_or_char *name) {
prefix = Swig_scopename_prefix(name); prefix = Swig_scopename_prefix(name);
s = SwigType_find_scope(current_scope,prefix); s = SwigType_find_scope(current_scope,prefix);
if (s) { if (s) {
Hash *ttab = Getattr(s,"typetab"); Hash *ttab = Getattr(s,k_typetab);
if (!Getattr(ttab,base) && defined_name) { if (!Getattr(ttab,base) && defined_name) {
Setattr(ttab,base, defined_name); Setattr(ttab,base, defined_name);
} }
@ -1653,6 +1674,7 @@ SwigType_emit_type_table(File *f_forward, File *f_table) {
while (ki.key) { while (ki.key) {
List *el; List *el;
Iterator ei; Iterator ei;
SwigType *ft;
const String *cd; const String *cd;
Printf(f_forward,"#define SWIGTYPE%s swig_types[%d] \n", ki.key, i); Printf(f_forward,"#define SWIGTYPE%s swig_types[%d] \n", ki.key, i);
@ -1660,7 +1682,8 @@ SwigType_emit_type_table(File *f_forward, File *f_table) {
cd = SwigType_clientdata_collect(ki.key,0); cd = SwigType_clientdata_collect(ki.key,0);
if (!cd) cd = "0"; if (!cd) cd = "0";
Printv(types,"{\"", ki.key, "\", 0, \"", SwigType_str(Getattr(r_ltype,ki.key),0),"\", ", cd, ", 0, 0, 0},", NIL); ft = SwigType_typedef_resolve_all(Getattr(r_ltype,ki.key));
Printv(types,"{\"", ki.key, "\", 0, \"",SwigType_str(ft,0),"\", ", cd, ", 0, 0, 0},", NIL);
el = SwigType_equivalent_mangle(ki.key,0,0); el = SwigType_equivalent_mangle(ki.key,0,0);
for (ei = First(el); ei.item; ei = Next(ei)) { for (ei = First(el); ei.item; ei = Next(ei)) {
String *ckey; String *ckey;
@ -1675,6 +1698,7 @@ SwigType_emit_type_table(File *f_forward, File *f_table) {
Delete(ckey); Delete(ckey);
} }
Delete(el); Delete(el);
Delete(ft);
Printf(types,"{0, 0, 0, 0, 0, 0, 0}};\n"); Printf(types,"{0, 0, 0, 0, 0, 0, 0}};\n");
Printv(table, "_swigt_", ki.key, ", \n", NIL); Printv(table, "_swigt_", ki.key, ", \n", NIL);
ki = Next(ki); ki = Next(ki);