From 084425335f0c637fa5d31fa880d193995effb324 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 8 Dec 2011 22:34:08 +0000 Subject: [PATCH] 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 --- CHANGES.current | 4 ++++ Source/Swig/naming.c | 23 +++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 8105a0fe6..3b283bd75 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -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. diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index 539442bac..a35a92ac7 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -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); } /* -----------------------------------------------------------------------------