diff --git a/SWIG/Examples/test-suite/imports_b.h b/SWIG/Examples/test-suite/imports_b.h index f8d91ad1c..f50cee576 100644 --- a/SWIG/Examples/test-suite/imports_b.h +++ b/SWIG/Examples/test-suite/imports_b.h @@ -13,3 +13,19 @@ class B : public A A::MemberEnum global_test(A::MemberEnum e) { return e; } +struct C : A +{ + typedef A a_type; + + A* get_a(A* a) + { + return a; + } + + a_type* get_a_type(a_type* a) + { + return a; + } + +}; + diff --git a/SWIG/Examples/test-suite/python/imports_runme.py b/SWIG/Examples/test-suite/python/imports_runme.py index bd96e3b56..a4ce85eb4 100644 --- a/SWIG/Examples/test-suite/python/imports_runme.py +++ b/SWIG/Examples/test-suite/python/imports_runme.py @@ -7,3 +7,11 @@ import sys x = imports_b.B() imports_a.A.hello(x) +a = imports_a.A() + +c = imports_b.C() +a1 = c.get_a(c) +a2 = c.get_a_type(c) + +if a1.hello() != a2.hello(): + raise RuntimeError diff --git a/SWIG/Lib/common.swg b/SWIG/Lib/common.swg index 00fd49ec6..cb666f3eb 100644 --- a/SWIG/Lib/common.swg +++ b/SWIG/Lib/common.swg @@ -66,6 +66,43 @@ typedef struct swig_type_info { static swig_type_info *swig_type_list = 0; static swig_type_info **swig_type_list_handle = &swig_type_list; +/* + Compare two type names skipping the space characters, therefore + "char*" == "char *" and "Class" == "Class", etc. + + Return 0 when the two name types are equivalent, as in + strncmp, but skipping ' '. +*/ +static int +SWIG_TypeNameComp(const char *f1, const char *l1, + const char *f2, const char *l2) { + for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { + while ((*f1 == ' ') && (f1 != l1)) ++f1; + while ((*f2 == ' ') && (f2 != l2)) ++f2; + if (*f1 != *f2) return *f1 - *f2; + } + return (l1 - f1) - (l2 - f2); +} + +/* + Check type equivalence in a name list like ||... +*/ +static int +SWIG_TypeEquiv(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = SWIG_TypeNameComp(nb, ne, tb, te) == 0; + if (*ne) ++ne; + } + return equiv; +} + + /* Register a type mapping with the type-checking */ static swig_type_info * SWIG_TypeRegister(swig_type_info *ti) { @@ -73,7 +110,16 @@ SWIG_TypeRegister(swig_type_info *ti) { /* Check to see if this type has already been registered */ tc = *swig_type_list_handle; while (tc) { - if (strcmp(tc->name, ti->name) == 0) { + /* check simple type equivalence */ + int typeequiv = (strcmp(tc->name, ti->name) == 0); + /* check full type equivalence, resolving typedefs */ + if (!typeequiv) { + /* only if tc is not a typedef (no '|' on it) */ + if (tc->str && ti->str && !strstr(tc->str,"|")) { + typeequiv = SWIG_TypeEquiv(ti->str,tc->str); + } + } + if (typeequiv) { /* Already exists in the table. Just add additional types to the list */ if (ti->clientdata) tc->clientdata = ti->clientdata; head = tc; @@ -177,43 +223,6 @@ SWIG_TypePrettyName(const swig_type_info *type) { return type->name; } -/* - Compare two type names skipping the space characters, therefore - "char*" == "char *" and "Class" == "Class", etc. - - Return 0 when the two name types are equivalent, as in - strncmp, but skipping ' '. -*/ -static int -SWIG_TypeNameComp(const char *f1, const char *l1, - const char *f2, const char *l2) { - for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { - while ((*f1 == ' ') && (f1 != l1)) ++f1; - while ((*f2 == ' ') && (f2 != l2)) ++f2; - if (*f1 != *f2) return *f1 - *f2; - } - return (l1 - f1) - (l2 - f2); -} - -/* - Check type equivalence in a name list like ||... -*/ -static int -SWIG_TypeEquiv(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = SWIG_TypeNameComp(nb, ne, tb, te) == 0; - if (*ne) ++ne; - } - return equiv; -} - - /* Search for a swig_type_info structure */ static swig_type_info * SWIG_TypeQuery(const char *name) { @@ -230,7 +239,8 @@ SWIG_TypeQuery(const char *name) { static void SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { swig_type_info *tc, *equiv; - if (ti->clientdata == clientdata) return; + if (ti->clientdata) return; + /* if (ti->clientdata == clientdata) return; */ ti->clientdata = clientdata; equiv = ti->next; while (equiv) {