Refactoring to Sv*_set() macros - patch #6
[p5sagit/p5-mst-13.2.git] / hv.c
diff --git a/hv.c b/hv.c
index cebf2f9..8c6ec39 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -1,7 +1,7 @@
 /*    hv.c
  *
  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- *    2000, 2001, 2002, 2003, by Larry Wall and others
+ *    2000, 2001, 2002, 2003, 2004, 2005, by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
 
 /* 
 =head1 Hash Manipulation Functions
+
+A HV structure represents a Perl hash. It consists mainly of an array
+of pointers, each of which points to a linked list of HE structures. The
+array is indexed by the hash function of the key, so each linked list
+represents all the hash entries with the same hash value. Each HE contains
+a pointer to the actual value, plus a pointer to a HEK structure which
+holds the key and hash value.
+
+=cut
+
 */
 
 #include "EXTERN.h"
@@ -80,7 +90,7 @@ S_more_he(pTHX)
 STATIC HEK *
 S_save_hek_flags(pTHX_ const char *str, I32 len, U32 hash, int flags)
 {
-    int flags_masked = flags & HVhek_MASK;
+    const int flags_masked = flags & HVhek_MASK;
     char *k;
     register HEK *hek;
 
@@ -218,7 +228,7 @@ Perl_hv_store(pTHX_ HV *hv, const char *key, I32 klen_i32, SV *val, U32 hash)
        flags = 0;
     }
     hek = hv_fetch_common (hv, NULL, key, klen, flags,
-                          (HV_FETCH_ISSTORE|HV_FETCH_JUST_SV), val, 0);
+                          (HV_FETCH_ISSTORE|HV_FETCH_JUST_SV), val, hash);
     return hek ? &HeVAL(hek) : NULL;
 }
 
@@ -445,7 +455,7 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
                    if (isLOWER(key[i])) {
                        /* Would be nice if we had a routine to do the
                           copy and upercase in a single pass through.  */
-                       char *nkey = strupr(savepvn(key,klen));
+                       const char *nkey = strupr(savepvn(key,klen));
                        /* Note that this fetch is for nkey (the uppercased
                           key) whereas the store is for key (the original)  */
                        entry = hv_fetch_common(hv, Nullsv, nkey, klen,
@@ -505,6 +515,7 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
                key = (const char*)strupr((char*)key);
                is_utf8 = 0;
                hash = 0;
+               keysv = 0;
 
                if (flags & HVhek_FREEKEY) {
                    Safefree(keysave);
@@ -547,6 +558,7 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
                    key = (const char*)strupr((char*)key);
                    is_utf8 = 0;
                    hash = 0;
+                   keysv = 0;
 
                    if (flags & HVhek_FREEKEY) {
                        Safefree(keysave);
@@ -977,19 +989,21 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
            continue;
        if ((HeKFLAGS(entry) ^ masked_flags) & HVhek_UTF8)
            continue;
-        if (k_flags & HVhek_FREEKEY)
-            Safefree(key);
 
        /* if placeholder is here, it's already been deleted.... */
        if (HeVAL(entry) == &PL_sv_placeholder)
        {
-           return Nullsv;
+         if (k_flags & HVhek_FREEKEY)
+            Safefree(key);
+         return Nullsv;
        }
        else if (SvREADONLY(hv) && HeVAL(entry) && SvREADONLY(HeVAL(entry))) {
            S_hv_notallowed(aTHX_ k_flags, key, klen,
                            "delete readonly key '%"SVf"' from"
                            );
        }
+        if (k_flags & HVhek_FREEKEY)
+            Safefree(key);
 
        if (d_flags & G_DISCARD)
            sv = Nullsv;
@@ -1482,7 +1496,7 @@ Clears any placeholders from a hash.  If a restricted hash has any of its keys
 marked as readonly and the key is subsequently deleted, the key is not actually
 deleted but is marked by assigning it a value of &PL_sv_placeholder.  This tags
 it so it will be ignored by future operations such as iterating over the hash,
-but will still allow the hash to have a value reaasigned to the key at some
+but will still allow the hash to have a value reassigned to the key at some
 future point.  This function clears any such placeholder keys from the hash.
 See Hash::Util::lock_keys() for an example of its use.
 
@@ -1519,7 +1533,7 @@ Perl_hv_clear_placeholders(pTHX_ HV *hv)
 
                if (--items == 0) {
                    /* Finished.  */
-                   HvTOTALKEYS(hv) -= HvPLACEHOLDERS(hv);
+                   HvTOTALKEYS(hv) -= (IV)HvPLACEHOLDERS(hv);
                    if (HvKEYS(hv) == 0)
                        HvHASKFLAGS_off(hv);
                    HvPLACEHOLDERS(hv) = 0;
@@ -1985,7 +1999,7 @@ S_unshare_hek_or_pvn(pTHX_ HEK *hek, const char *str, I32 len, U32 hash)
             break;
         }
     } else {
-        int flags_masked = k_flags & HVhek_MASK;
+        const int flags_masked = k_flags & HVhek_MASK;
         for (entry = *oentry; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) {
             if (HeHASH(entry) != hash)         /* strings can't be equal */
                 continue;
@@ -2014,9 +2028,10 @@ S_unshare_hek_or_pvn(pTHX_ HEK *hek, const char *str, I32 len, U32 hash)
     UNLOCK_STRTAB_MUTEX;
     if (!found && ckWARN_d(WARN_INTERNAL))
        Perl_warner(aTHX_ packWARN(WARN_INTERNAL),
-                    "Attempt to free non-existent shared string '%s'%s",
+                    "Attempt to free non-existent shared string '%s'%s"
+                    pTHX__FORMAT,
                     hek ? HEK_KEY(hek) : str,
-                    (k_flags & HVhek_UTF8) ? " (utf8)" : "");
+                    ((k_flags & HVhek_UTF8) ? " (utf8)" : "") pTHX__VALUE);
     if (k_flags & HVhek_FREEKEY)
        Safefree(str);
 }
@@ -2060,7 +2075,7 @@ S_share_hek_flags(pTHX_ const char *str, I32 len, register U32 hash, int flags)
     register HE **oentry;
     register I32 i = 1;
     I32 found = 0;
-    int flags_masked = flags & HVhek_MASK;
+    const int flags_masked = flags & HVhek_MASK;
 
     /* what follows is the moral equivalent of:
 
@@ -2179,3 +2194,13 @@ Perl_hv_assert(pTHX_ HV *hv)
   HvRITER(hv) = riter;         /* Restore hash iterator state */
   HvEITER(hv) = eiter;
 }
+
+/*
+ * Local variables:
+ * c-indentation-style: bsd
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vim: shiftwidth=4:
+*/