The two-for-loops is no more a valid way to walk through
Jarkko Hietaniemi [Fri, 27 Jun 2003 10:08:20 +0000 (10:08 +0000)]
a hash (this was the reason the Hash/Util.t intermittently
failed, the two-loop didn't find all the SVs of the HV).

p4raw-id: //depot/perl@19867

hv.c

diff --git a/hv.c b/hv.c
index ee08ce4..6f6eca1 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -1705,27 +1705,29 @@ Perl_hv_clear(pTHX_ HV *hv)
 
     xhv = (XPVHV*)SvANY(hv);
 
-    if(SvREADONLY(hv)) {
+    if (SvREADONLY(hv)) {
        /* restricted hash: convert all keys to placeholders */
-       I32 i;
-       HE* entry;
-       for (i=0; i< (I32) xhv->xhv_max; i++) {
-           entry = ((HE**)xhv->xhv_array)[i];
-           for (; entry; entry = HeNEXT(entry)) {
-               /* not already placeholder */
-               if (HeVAL(entry) != &PL_sv_undef) {
-                   if (HeVAL(entry) && SvREADONLY(HeVAL(entry))) {
-                       SV* keysv = hv_iterkeysv(entry);
-                       Perl_croak(aTHX_
-       "Attempt to delete readonly key '%"SVf"' from a restricted hash",
-                                  keysv);
-                   }
-                   SvREFCNT_dec(HeVAL(entry));
-                   HeVAL(entry) = &PL_sv_undef;
-                   xhv->xhv_placeholders++; /* HvPLACEHOLDERS(hv)++ */
-               }
+       HE* he;
+
+       hv_iterinit(hv);
+       while ((he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS))) {
+           SV *val;
+           
+           val = hv_iterval(hv, he);
+           if (val != &PL_sv_undef) { /* not already placeholder */
+                if (val && SvREADONLY(val)) {
+                     SV* keysv = hv_iterkeysv(he);
+
+                     Perl_croak(aTHX_
+                                "Attempt to delete readonly key '%"SVf"' from a restricted hash",
+                                keysv);
+                }
+                SvREFCNT_dec(val);
+                HeVAL(he) = &PL_sv_undef;
+                xhv->xhv_placeholders++; /* HvPLACEHOLDERS(hv)++ */
            }
        }
+       hv_iterinit(hv);
        return;
     }