summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorInaba Hiroto <inaba@st.rim.or.jp>2000-12-10 03:02:00 +0900
committerJarkko Hietaniemi <jhi@iki.fi>2000-12-09 21:51:16 +0000
commitc3654f1afb5dff5b62753314bd22e2270ff9f009 (patch)
treeee63ce0958fe7b4c7ab15fab34fa806e3714c2c7 /hv.c
parentcb3e09590bdc6f7bb084eeb2305484eacc1a5cff (diff)
downloadperl-c3654f1afb5dff5b62753314bd22e2270ff9f009.tar.gz
Additional patch for UTF8-keys (Re: perl@8016)
Message-ID: <3A31F508.34F4BB23@st.rim.or.jp> exists() didn't work for UTF-8 keys, and neither did shared hash keys. p4raw-id: //depot/perl@8056
Diffstat (limited to 'hv.c')
-rw-r--r--hv.c75
1 files changed, 42 insertions, 33 deletions
diff --git a/hv.c b/hv.c
index 334f7ad306..f5aa4a8d7f 100644
--- a/hv.c
+++ b/hv.c
@@ -94,7 +94,8 @@ S_save_hek(pTHX_ const char *str, I32 len, U32 hash)
void
Perl_unshare_hek(pTHX_ HEK *hek)
{
- unsharepvn(HEK_KEY(hek),HEK_LEN(hek),HEK_HASH(hek));
+ unsharepvn(HEK_KEY(hek),HEK_UTF8(hek)?-HEK_LEN(hek):HEK_LEN(hek),
+ HEK_HASH(hek));
}
#if defined(USE_ITHREADS)
@@ -118,9 +119,9 @@ Perl_he_dup(pTHX_ HE *e, bool shared)
if (HeKLEN(e) == HEf_SVKEY)
HeKEY_sv(ret) = SvREFCNT_inc(sv_dup(HeKEY_sv(e)));
else if (shared)
- HeKEY_hek(ret) = share_hek(HeKEY(e), HeKLEN_UTF8(e), HeHASH(e));
+ HeKEY_hek(ret) = share_hek(HeKEY(e), HeKLEN_UTF8(e), HeHASH(e));
else
- HeKEY_hek(ret) = save_hek(HeKEY(e), HeKLEN_UTF8(e), HeHASH(e));
+ HeKEY_hek(ret) = save_hek(HeKEY(e), HeKLEN_UTF8(e), HeHASH(e));
HeVAL(ret) = SvREFCNT_inc(sv_dup(HeVAL(e)));
return ret;
}
@@ -205,8 +206,8 @@ Perl_hv_fetch(pTHX_ HV *hv, const char *key, I32 klen, I32 lval)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
- if (HeKUTF8(entry) != (char)is_utf8)
- continue;
+ if (HeKUTF8(entry) != (char)is_utf8)
+ continue;
return &HeVAL(entry);
}
#ifdef DYNAMIC_ENV_FETCH /* %ENV lookup? If so, try to fetch the value now */
@@ -222,7 +223,7 @@ Perl_hv_fetch(pTHX_ HV *hv, const char *key, I32 klen, I32 lval)
#endif
if (lval) { /* gonna assign to this, so it better be there */
sv = NEWSV(61,0);
- return hv_store(hv,key,is_utf8?-klen:klen,sv,hash);
+ return hv_store(hv,key,is_utf8?-klen:klen,sv,hash);
}
return 0;
}
@@ -317,8 +318,8 @@ Perl_hv_fetch_ent(pTHX_ HV *hv, SV *keysv, I32 lval, register U32 hash)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
- if (HeKUTF8(entry) != (char)is_utf8)
- continue;
+ if (HeKUTF8(entry) != (char)is_utf8)
+ continue;
return entry;
}
#ifdef DYNAMIC_ENV_FETCH /* %ENV lookup? If so, try to fetch the value now */
@@ -428,8 +429,8 @@ Perl_hv_store(pTHX_ HV *hv, const char *key, I32 klen, SV *val, register U32 has
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
- if (HeKUTF8(entry) != (char)is_utf8)
- continue;
+ if (HeKUTF8(entry) != (char)is_utf8)
+ continue;
SvREFCNT_dec(HeVAL(entry));
HeVAL(entry) = val;
return &HeVAL(entry);
@@ -437,9 +438,9 @@ Perl_hv_store(pTHX_ HV *hv, const char *key, I32 klen, SV *val, register U32 has
entry = new_HE();
if (HvSHAREKEYS(hv))
- HeKEY_hek(entry) = share_hek(key, is_utf8?-klen:klen, hash);
+ HeKEY_hek(entry) = share_hek(key, is_utf8?-klen:klen, hash);
else /* gotta do the real thing */
- HeKEY_hek(entry) = save_hek(key, is_utf8?-klen:klen, hash);
+ HeKEY_hek(entry) = save_hek(key, is_utf8?-klen:klen, hash);
HeVAL(entry) = val;
HeNEXT(entry) = *oentry;
*oentry = entry;
@@ -532,8 +533,8 @@ Perl_hv_store_ent(pTHX_ HV *hv, SV *keysv, SV *val, register U32 hash)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
- if (HeKUTF8(entry) != (char)is_utf8)
- continue;
+ if (HeKUTF8(entry) != (char)is_utf8)
+ continue;
SvREFCNT_dec(HeVAL(entry));
HeVAL(entry) = val;
return entry;
@@ -541,9 +542,9 @@ Perl_hv_store_ent(pTHX_ HV *hv, SV *keysv, SV *val, register U32 hash)
entry = new_HE();
if (HvSHAREKEYS(hv))
- HeKEY_hek(entry) = share_hek(key, is_utf8?-klen:klen, hash);
+ HeKEY_hek(entry) = share_hek(key, is_utf8?-klen:klen, hash);
else /* gotta do the real thing */
- HeKEY_hek(entry) = save_hek(key, is_utf8?-klen:klen, hash);
+ HeKEY_hek(entry) = save_hek(key, is_utf8?-klen:klen, hash);
HeVAL(entry) = val;
HeNEXT(entry) = *oentry;
*oentry = entry;
@@ -626,8 +627,8 @@ Perl_hv_delete(pTHX_ HV *hv, const char *key, I32 klen, I32 flags)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
- if (HeKUTF8(entry) != (char)is_utf8)
- continue;
+ if (HeKUTF8(entry) != (char)is_utf8)
+ continue;
*oentry = HeNEXT(entry);
if (i && !*oentry)
xhv->xhv_fill--;
@@ -717,8 +718,8 @@ Perl_hv_delete_ent(pTHX_ HV *hv, SV *keysv, I32 flags, U32 hash)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
- if (HeKUTF8(entry) != (char)is_utf8)
- continue;
+ if (HeKUTF8(entry) != (char)is_utf8)
+ continue;
*oentry = HeNEXT(entry);
if (i && !*oentry)
xhv->xhv_fill--;
@@ -799,8 +800,8 @@ Perl_hv_exists(pTHX_ HV *hv, const char *key, I32 klen)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
- if (HeKUTF8(entry) != (char)is_utf8)
- continue;
+ if (HeKUTF8(entry) != (char)is_utf8)
+ continue;
return TRUE;
}
#ifdef DYNAMIC_ENV_FETCH /* is it out there? */
@@ -837,6 +838,7 @@ Perl_hv_exists_ent(pTHX_ HV *hv, SV *keysv, U32 hash)
STRLEN klen;
register HE *entry;
SV *sv;
+ bool is_utf8;
if (!hv)
return 0;
@@ -866,6 +868,7 @@ Perl_hv_exists_ent(pTHX_ HV *hv, SV *keysv, U32 hash)
#endif
key = SvPV(keysv, klen);
+ is_utf8 = (SvUTF8(keysv) != 0);
if (!hash)
PERL_HASH(hash, key, klen);
@@ -881,6 +884,8 @@ Perl_hv_exists_ent(pTHX_ HV *hv, SV *keysv, U32 hash)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
+ if (HeKUTF8(entry) != (char)is_utf8)
+ continue;
return TRUE;
}
#ifdef DYNAMIC_ENV_FETCH /* is it out there? */
@@ -1095,7 +1100,7 @@ Perl_newHVhv(pTHX_ HV *ohv)
/* Slow way */
hv_iterinit(ohv);
while ((entry = hv_iternext(ohv))) {
- hv_store(hv, HeKEY(entry), HeKLEN_UTF8(entry),
+ hv_store(hv, HeKEY(entry), HeKLEN_UTF8(entry),
SvREFCNT_inc(HeVAL(entry)), HeHASH(entry));
}
HvRITER(ohv) = hv_riter;
@@ -1386,13 +1391,9 @@ Perl_hv_iterkeysv(pTHX_ register HE *entry)
{
if (HeKLEN(entry) == HEf_SVKEY)
return sv_mortalcopy(HeKEY_sv(entry));
- else {
- SV *sv = newSVpvn_share((HeKLEN(entry) ? HeKEY(entry) : ""),
- HeKLEN(entry), HeHASH(entry));
- if (HeKUTF8(entry))
- SvUTF8_on(sv);
- return sv_2mortal(sv);
- }
+ else
+ return sv_2mortal(newSVpvn_share((HeKLEN(entry) ? HeKEY(entry) : ""),
+ HeKLEN_UTF8(entry), HeHASH(entry)));
}
/*
@@ -1469,6 +1470,12 @@ Perl_unsharepvn(pTHX_ const char *str, I32 len, U32 hash)
register HE **oentry;
register I32 i = 1;
I32 found = 0;
+ bool is_utf8 = FALSE;
+
+ if (len < 0) {
+ len = -len;
+ is_utf8 = TRUE;
+ }
/* what follows is the moral equivalent of:
if ((Svp = hv_fetch(PL_strtab, tmpsv, FALSE, hash))) {
@@ -1486,6 +1493,8 @@ Perl_unsharepvn(pTHX_ const char *str, I32 len, U32 hash)
continue;
if (HeKEY(entry) != str && memNE(HeKEY(entry),str,len)) /* is this it? */
continue;
+ if (HeKUTF8(entry) != (char)is_utf8)
+ continue;
found = 1;
if (--HeVAL(entry) == Nullsv) {
*oentry = HeNEXT(entry);
@@ -1538,14 +1547,14 @@ Perl_share_hek(pTHX_ const char *str, I32 len, register U32 hash)
continue;
if (HeKEY(entry) != str && memNE(HeKEY(entry),str,len)) /* is this it? */
continue;
- if (HeKUTF8(entry) != (char)is_utf8)
- continue;
+ if (HeKUTF8(entry) != (char)is_utf8)
+ continue;
found = 1;
break;
}
if (!found) {
entry = new_HE();
- HeKEY_hek(entry) = save_hek(str, is_utf8?-len:len, hash);
+ HeKEY_hek(entry) = save_hek(str, is_utf8?-len:len, hash);
HeVAL(entry) = Nullsv;
HeNEXT(entry) = *oentry;
*oentry = entry;