(Retracted by #7978, too shaky yet.)
Simon Cozens [Sat, 2 Dec 2000 19:49:35 +0000 (19:49 +0000)]
Subject: Re: utf8 in hash keys, implementor missing
Message-ID: <20001202194935.A25673@pembro33.pmb.ox.ac.uk>

The first step at UTF-8 hash keys.

p4raw-id: //depot/perl@7977

doop.c
hv.c
pp.c
sv.h

diff --git a/doop.c b/doop.c
index 3c34425..762c679 100644 (file)
--- a/doop.c
+++ b/doop.c
@@ -1177,8 +1177,11 @@ Perl_do_kv(pTHX)
     PUTBACK;   /* hv_iternext and hv_iterval might clobber stack_sp */
     while ((entry = hv_iternext(keys))) {
        SPAGAIN;
-       if (dokeys)
+       if (dokeys) {
            XPUSHs(hv_iterkeysv(entry));        /* won't clobber stack_sp */
+           if (SvUTF8((SV*)keys))
+               SvUTF8_on(TOPs); /* Yuck */
+       } 
        if (dovalues) {
            PUTBACK;
            tmpstr = realhv ?
diff --git a/hv.c b/hv.c
index 8a43a19..51c8d0a 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -245,6 +245,9 @@ Perl_hv_fetch_ent(pTHX_ HV *hv, SV *keysv, I32 lval, register U32 hash)
     if (!hv)
        return 0;
 
+    if (SvUTF8((SV*)hv) && !SvUTF8(keysv))
+        sv_utf8_upgrade(keysv);
+
     if (SvRMAGICAL(hv)) {
        if (mg_find((SV*)hv,'P')) {
            dTHR;
@@ -463,6 +466,20 @@ Perl_hv_store_ent(pTHX_ HV *hv, SV *keysv, SV *val, register U32 hash)
        return 0;
 
     xhv = (XPVHV*)SvANY(hv);
+
+    if (SvUTF8((SV*)hv) && !SvUTF8(keysv))
+       sv_utf8_upgrade(keysv);
+    else if (SvUTF8(keysv) && !SvUTF8((SV*)hv)) { /* Upgrade hash */
+       SvUTF8_on((SV*)hv);
+       /* XXX Need to save iterator to prevent weird things during "each" */
+       (void)hv_iterinit(hv);
+       while (entry = hv_iternext(hv)) {
+           if (HeKLEN(entry) != HEf_SVKEY) /* Upgrade to SV key */
+               HeSVKEY_set(entry, newSVpvn(HeKEY(entry), HeKLEN(entry)));
+           sv_utf8_upgrade(HeKEY_sv(entry));
+       }
+    }
+
     if (SvMAGICAL(hv)) {
        dTHR;
        bool needs_copy;
diff --git a/pp.c b/pp.c
index 10e6c6a..b3e2030 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -2693,6 +2693,8 @@ PP(pp_each)
     EXTEND(SP, 2);
     if (entry) {
        PUSHs(hv_iterkeysv(entry));     /* won't clobber stack_sp */
+       if (SvUTF8((SV*)hash))
+           SvUTF8_on(TOPs);
        if (gimme == G_ARRAY) {
            SV *val;
            PUTBACK;
diff --git a/sv.h b/sv.h
index 425acc3..42a4e39 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -227,7 +227,7 @@ perform the upgrade if necessary.  See C<svtype>.
 
 #define SVrepl_EVAL    0x40000000      /* Replacement part of s///e */
 
-#define SVphv_SHAREKEYS 0x20000000     /* keys live on shared string table */
+#define SVphv_SHAREKEYS 0x80000000     /* keys live on shared string table */
 #define SVphv_LAZYDEL  0x40000000      /* entry in xhv_eiter must be deleted */
 
 #define SVprv_WEAKREF   0x80000000      /* Weak reference */