This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
add const qualifier to most char* prototypes, handle ripple effect
[perl5.git] / hv.h
diff --git a/hv.h b/hv.h
index a9de8ca..1763a88 100644 (file)
--- a/hv.h
+++ b/hv.h
@@ -1,6 +1,6 @@
 /*    hv.h
  *
- *    Copyright (c) 1991-1994, Larry Wall
+ *    Copyright (c) 1991-1997, Larry Wall
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -8,20 +8,26 @@
  */
 
 typedef struct he HE;
+typedef struct hek HEK;
 
 struct he {
     HE         *hent_next;
-    char       *hent_key;
+    HEK                *hent_hek;
     SV         *hent_val;
-    U32                hent_hash;
-    I32                hent_klen;
 };
 
+struct hek {
+    U32                hek_hash;
+    I32                hek_len;
+    char       hek_key[1];
+};
+
+/* This structure must match the beginning of struct xpvmg in sv.h. */
 struct xpvhv {
     char *     xhv_array;      /* pointer to malloced string */
     STRLEN     xhv_fill;       /* how full xhv_array currently is */
     STRLEN     xhv_max;        /* subscript of last element of xhv_array */
-    I32                xhv_keys;       /* how many elements in the array */
+    IV         xhv_keys;       /* how many elements in the array */
     double     xnv_nv;         /* numeric value, if any */
     MAGIC*     xmg_magic;      /* magic for scalar array */
     HV*                xmg_stash;      /* class package */
@@ -34,19 +40,17 @@ struct xpvhv {
 
 #define PERL_HASH(hash,str,len) \
      STMT_START        { \
-       register char *s_PeRlHaSh = str; \
+       register const char *s_PeRlHaSh = str; \
        register I32 i_PeRlHaSh = len; \
        register U32 hash_PeRlHaSh = 0; \
        while (i_PeRlHaSh--) \
            hash_PeRlHaSh = hash_PeRlHaSh * 33 + *s_PeRlHaSh++; \
-       (hash) = hash_PeRlHaSh; \
+       (hash) = hash_PeRlHaSh + (hash_PeRlHaSh>>5); \
     } STMT_END
 
 
-/* these hash entry flags ride on hent_klen */
-
-#define HEf_LAZYDEL    -1      /* entry must be deleted during next iter step */
-#define HEf_SVKEY      -2      /* hent_key is a SV* (only for magic/tied HVs) */
+/* these hash entry flags ride on hent_klen (for use only in magic/tied HVs) */
+#define HEf_SVKEY      -2      /* hent_key is a SV* */
 
 
 #define Nullhv Null(HV*)
@@ -63,7 +67,9 @@ struct xpvhv {
 #define HvSHAREKEYS_on(hv)     (SvFLAGS(hv) |= SVphv_SHAREKEYS)
 #define HvSHAREKEYS_off(hv)    (SvFLAGS(hv) &= ~SVphv_SHAREKEYS)
 
-#ifdef OVERLOAD
+#define HvLAZYDEL(hv)          (SvFLAGS(hv) & SVphv_LAZYDEL)
+#define HvLAZYDEL_on(hv)       (SvFLAGS(hv) |= SVphv_LAZYDEL)
+#define HvLAZYDEL_off(hv)      (SvFLAGS(hv) &= ~SVphv_LAZYDEL)
 
 /* Maybe amagical: */
 /* #define HV_AMAGICmb(hv)      (SvFLAGS(hv) & (SVpgv_badAM | SVpgv_AM)) */
@@ -78,24 +84,33 @@ struct xpvhv {
 #define HV_badAMAGIC_off(hv) (SvFLAGS(hv) &= ~SVpgv_badAM)
 */
 
-#endif /* OVERLOAD */
-
 #define Nullhe Null(HE*)
 #define HeNEXT(he)             (he)->hent_next
-#define HeKEY(he)              (he)->hent_key
-#define HeKLEN(he)             (he)->hent_klen
+#define HeKEY_hek(he)          (he)->hent_hek
+#define HeKEY(he)              HEK_KEY(HeKEY_hek(he))
+#define HeKEY_sv(he)           (*(SV**)HeKEY(he))
+#define HeKLEN(he)             HEK_LEN(HeKEY_hek(he))
 #define HeVAL(he)              (he)->hent_val
-#define HeHASH(he)             (he)->hent_hash
-#define HePV(he)               ((he)->hent_klen == HEf_SVKEY) ?                \
-                               SvPV((SV*)((he)->hent_key),na) :                \
-                               (he)->hent_key))
-#define HeSVKEY(he)            (((he)->hent_key &&                             \
-                                 (he)->hent_klen == HEf_SVKEY) ?               \
-                                (SV*)((he)->hent_key) : Nullsv)
-
-#define HeSVKEY_force(he)      ((he)->hent_key ?                               \
-                                (((he)->hent_klen == HEf_SVKEY) ?              \
-                                 (SV*)((he)->hent_key) :                       \
-                                 sv_2mortal(newSVpv((he)->hent_key,            \
-                                                    (he)->hent_klen))) :       \
-                                &sv_undef)
+#define HeHASH(he)             HEK_HASH(HeKEY_hek(he))
+#define HePV(he,lp)            ((HeKLEN(he) == HEf_SVKEY) ?            \
+                                SvPV(HeKEY_sv(he),lp) :                \
+                                (((lp = HeKLEN(he)) >= 0) ?            \
+                                 HeKEY(he) : Nullch))
+
+#define HeSVKEY(he)            ((HeKEY(he) &&                          \
+                                 HeKLEN(he) == HEf_SVKEY) ?            \
+                                HeKEY_sv(he) : Nullsv)
+
+#define HeSVKEY_force(he)      (HeKEY(he) ?                            \
+                                ((HeKLEN(he) == HEf_SVKEY) ?           \
+                                 HeKEY_sv(he) :                        \
+                                 sv_2mortal(newSVpv(HeKEY(he),         \
+                                                    HeKLEN(he)))) :    \
+                                &PL_sv_undef)
+#define HeSVKEY_set(he,sv)     ((HeKLEN(he) = HEf_SVKEY), (HeKEY_sv(he) = sv))
+
+#define Nullhek Null(HEK*)
+#define HEK_BASESIZE           STRUCT_OFFSET(HEK, hek_key[0])
+#define HEK_HASH(hek)          (hek)->hek_hash
+#define HEK_LEN(hek)           (hek)->hek_len
+#define HEK_KEY(hek)           (hek)->hek_key