Typemap matching rules enhancement for non-default typemaps. Previously all qualifiers were stripped in one step, now they are stripped one at a time starting with the left most qualifier.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12007 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2010-05-02 21:35:02 +00:00
commit efd200ffe2
10 changed files with 398 additions and 38 deletions

View file

@ -357,8 +357,8 @@ SwigType *SwigType_default_create(SwigType *ty) {
* SwigType_default_deduce()
*
* This function implements type deduction used in the typemap matching rules
* and is very close to the type deduction used in partial template specialization
* matching in that the most specialized type is always chosen.
* and is very close to the type deduction used in partial template class
* specialization matching in that the most specialized type is always chosen.
* SWIGTYPE is used as the generic type. The basic idea is to repeatedly call
* this function to find a deduced type unless until nothing matches.
*

View file

@ -159,6 +159,7 @@ extern "C" {
extern int SwigType_isenum(SwigType *t);
extern int SwigType_check_decl(SwigType *t, const_String_or_char_ptr decl);
extern SwigType *SwigType_strip_qualifiers(SwigType *t);
extern SwigType *SwigType_strip_single_qualifier(SwigType *t);
extern SwigType *SwigType_functionpointer_decompose(SwigType *t);
extern String *SwigType_base(const SwigType *t);
extern String *SwigType_namestr(const SwigType *t);

View file

@ -698,11 +698,11 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
Hash *backup = 0;
SwigType *primitive = 0;
SwigType *ctype = 0;
SwigType *ctype_unstripped = 0;
int ts;
int isarray;
const String *cname = 0;
const String *cqualifiedname = 0;
SwigType *unstripped = 0;
String *tm_method = typemap_method_name(tmap_method);
int debug_display = (in_typemap_search_multi == 0) && typemap_search_debug;
@ -718,7 +718,8 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
Delete(typestr);
}
while (ts >= 0) {
ctype = type;
ctype = Copy(type);
ctype_unstripped = Copy(ctype);
while (ctype) {
/* Try to get an exact type-match */
tm = get_typemap(ts, ctype);
@ -751,29 +752,25 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
goto ret_result;
}
/* No match so far. If the type is unstripped, we'll strip its
qualifiers and check. Otherwise, we'll try to resolve a typedef */
if (!unstripped) {
unstripped = ctype;
ctype = SwigType_strip_qualifiers(ctype);
if (!Equal(ctype, unstripped))
continue; /* Types are different */
Delete(ctype);
ctype = unstripped;
unstripped = 0;
}
/* No match so far - try with a qualifier stripped (strip one qualifier at a time until none remain)
* The order of stripping in SwigType_strip_single_qualifier is used to provide some sort of consistency
* with the default (SWIGTYPE) typemap matching rules for the first qualifier to be stripped. */
{
String *octype;
if (unstripped) {
Delete(ctype);
ctype = unstripped;
unstripped = 0;
SwigType *oldctype = ctype;
ctype = SwigType_strip_single_qualifier(oldctype);
if (!Equal(ctype, oldctype)) {
Delete(oldctype);
continue;
}
octype = ctype;
ctype = SwigType_typedef_resolve(ctype);
if (octype != type)
Delete(octype);
Delete(oldctype);
}
/* Once all qualifiers are stripped try resolve a typedef */
{
SwigType *oldctype = ctype;
ctype = SwigType_typedef_resolve(ctype_unstripped);
Delete(oldctype);
ctype_unstripped = Copy(ctype);
}
}
@ -802,12 +799,10 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
ret_result:
Delete(primitive);
if ((unstripped) && (unstripped != type))
Delete(unstripped);
if (matchtype)
*matchtype = Copy(ctype);
if (type != ctype)
Delete(ctype);
Delete(ctype);
Delete(ctype_unstripped);
return result;
}

View file

@ -1125,3 +1125,62 @@ SwigType *SwigType_strip_qualifiers(SwigType *t) {
}
return r;
}
/* -----------------------------------------------------------------------------
* SwigType_strip_single_qualifier()
*
* If the type contains a qualifier, strip one qualifier and return a new type.
* The left most qualifier is stripped first (when viewed as C source code) but
* this is the equivalent to the right most qualifier using SwigType notation.
* Example:
* r.q(const).p.q(const).int => r.q(const).p.int
* r.q(const).p.int => r.p.int
* r.p.int => r.p.int
* ----------------------------------------------------------------------------- */
SwigType *SwigType_strip_single_qualifier(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;
}