summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2003-11-22 10:37:24 +0000
committerNicholas Clark <nick@ccl4.org>2003-11-22 10:37:24 +0000
commit9b7c1c416b1df37975076158920b5c2b361392c1 (patch)
tree42f4bbd7b06e508335dd8bb25a0e9144cb9e9d7d /hv.c
parent8829b5e274708a88ac8ad69b61a45a9d67695db5 (diff)
downloadperl-9b7c1c416b1df37975076158920b5c2b361392c1.tar.gz
Shift negative klen/flags games from hv_exists_common out to hv_exists
p4raw-id: //depot/perl@21768
Diffstat (limited to 'hv.c')
-rw-r--r--hv.c50
1 files changed, 33 insertions, 17 deletions
diff --git a/hv.c b/hv.c
index 3fad5656b9..b2235fd001 100644
--- a/hv.c
+++ b/hv.c
@@ -959,9 +959,19 @@ C<klen> is the length of the key.
*/
bool
-Perl_hv_exists(pTHX_ HV *hv, const char *key, I32 klen)
+Perl_hv_exists(pTHX_ HV *hv, const char *key, I32 klen_i32)
{
- return hv_exists_common(hv, NULL, key, klen, 0);
+ STRLEN klen;
+ int flags;
+
+ if (klen_i32 < 0) {
+ klen = -klen_i32;
+ flags = HVhek_UTF8;
+ } else {
+ klen = klen_i32;
+ flags = 0;
+ }
+ return hv_exists_common(hv, NULL, key, klen, flags, 0);
}
/*
@@ -977,35 +987,29 @@ computed.
bool
Perl_hv_exists_ent(pTHX_ HV *hv, SV *keysv, U32 hash)
{
- return hv_exists_common(hv, keysv, NULL, 0, hash);
+ return hv_exists_common(hv, keysv, NULL, 0, 0, hash);
}
bool
-S_hv_exists_common(pTHX_ HV *hv, SV *keysv, const char *key, I32 klen_i32,
- U32 hash)
+S_hv_exists_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
+ int k_flags, U32 hash)
{
register XPVHV* xhv;
- STRLEN klen;
register HE *entry;
SV *sv;
bool is_utf8;
const char *keysave;
- int k_flags = 0;
+ int masked_flags;
if (!hv)
return 0;
if (keysv) {
key = SvPV(keysv, klen);
+ k_flags = 0;
is_utf8 = (SvUTF8(keysv) != 0);
} else {
- if (klen_i32 < 0) {
- klen = -klen_i32;
- is_utf8 = TRUE;
- } else {
- klen = klen_i32;
- is_utf8 = FALSE;
- }
+ is_utf8 = ((k_flags & HVhek_UTF8) ? TRUE : FALSE);
}
keysave = key;
@@ -1051,16 +1055,28 @@ S_hv_exists_common(pTHX_ HV *hv, SV *keysv, const char *key, I32 klen_i32,
if (is_utf8) {
key = (char*)bytes_from_utf8((U8*)key, &klen, &is_utf8);
+
+ if (k_flags & HVhek_FREEKEY) {
+ /* This shouldn't happen if our caller does what we expect,
+ but strictly the API allows it. */
+ Safefree(keysave);
+ }
+
if (is_utf8)
- k_flags = HVhek_UTF8;
+ k_flags |= HVhek_UTF8;
+ else
+ k_flags &= ~HVhek_UTF8;
if (key != keysave)
- k_flags |= HVhek_FREEKEY;
+ k_flags |= HVhek_WASUTF8 | HVhek_FREEKEY;
}
+
if (HvREHASH(hv)) {
PERL_HASH_INTERNAL(hash, key, klen);
} else if (!hash)
PERL_HASH(hash, key, klen);
+ masked_flags = (k_flags & HVhek_MASK);
+
#ifdef DYNAMIC_ENV_FETCH
if (!xhv->xhv_array /* !HvARRAY(hv) */) entry = Null(HE*);
else
@@ -1074,7 +1090,7 @@ S_hv_exists_common(pTHX_ HV *hv, SV *keysv, const char *key, I32 klen_i32,
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
- if ((HeKFLAGS(entry) ^ k_flags) & HVhek_UTF8)
+ if ((HeKFLAGS(entry) ^ masked_flags) & HVhek_UTF8)
continue;
if (k_flags & HVhek_FREEKEY)
Safefree(key);