Fix bug which could result in %rename not taking effect for derived classes.

We used to modify the hash table that we iterated on in
Swig_name_object_inherit() and this could, and sometimes did, change the
iteration order in such way that not all entries we were looking for could be
found. In practice this means that sometimes the methods renamed or ignored in
the base class could be mysteriously not renamed or ignored in a derived
class.

Fix this by avoiding modifying the hash table in place and using another
temporary hash table instead.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12865 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Vadim Zeitlin 2011-12-08 22:34:08 +00:00
commit 084425335f
2 changed files with 25 additions and 2 deletions

View file

@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.5 (in progress)
===========================
2011-12-08: vadz
Bug fix: Handle methods renamed or ignored in the base class correctly in the derived classes
(they could be sometimes mysteriously not renamed or ignored there before).
2011-12-03: klickvebrot
[D] Fix exception glue code for newer DMD 2 versions.
[D] Do not default to 32 bit glue code for DMD anymore.

View file

@ -565,6 +565,7 @@ DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType
void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) {
Iterator ki;
Hash *derh;
String *bprefix;
String *dprefix;
char *cbprefix;
@ -573,6 +574,9 @@ void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) {
if (!namehash)
return;
/* Temporary hash holding all the entries we add while we iterate over
namehash itself as we can't modify the latter while iterating over it. */
derh = NULL;
bprefix = NewStringf("%s::", base);
dprefix = NewStringf("%s::", derived);
cbprefix = Char(bprefix);
@ -580,13 +584,19 @@ void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) {
for (ki = First(namehash); ki.key; ki = Next(ki)) {
char *k = Char(ki.key);
if (strncmp(k, cbprefix, plen) == 0) {
/* Copy, adjusting name, this element to the derived hash. */
Iterator oi;
String *nkey = NewStringf("%s%s", dprefix, k + plen);
Hash *n = ki.item;
Hash *newh = Getattr(namehash, nkey);
Hash *newh;
if (!derh)
derh = NewHash();
newh = Getattr(derh, nkey);
if (!newh) {
newh = NewHash();
Setattr(namehash, nkey, newh);
Setattr(derh, nkey, newh);
Delete(newh);
}
for (oi = First(n); oi.key; oi = Next(oi)) {
@ -599,8 +609,17 @@ void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) {
Delete(nkey);
}
}
/* Merge the contents of derived hash into the main hash. */
if (derh) {
for (ki = First(derh); ki.key; ki = Next(ki)) {
Setattr(namehash, ki.key, ki.item);
}
}
Delete(bprefix);
Delete(dprefix);
Delete(derh);
}
/* -----------------------------------------------------------------------------