summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2003-12-14 17:06:13 +0000
committerNicholas Clark <nick@ccl4.org>2003-12-14 17:06:13 +0000
commit086cb327289a4871101f072239f753777e628728 (patch)
tree007f618cb3061a5b133f3bebb657fe37a3da3b42 /hv.c
parente593d2fe2376152f45b2d89d0e59a1b9b2af5bb5 (diff)
downloadperl-086cb327289a4871101f072239f753777e628728.tar.gz
Some fool missed a letter n.
(and then "optimised" code based on its absense. D'oh) Restore the correct behaviour - fetch with uppercase key, then if still not found store with mixed/lowercase key. p4raw-id: //depot/perl@21906
Diffstat (limited to 'hv.c')
-rw-r--r--hv.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/hv.c b/hv.c
index 601f52fc51..78d028065d 100644
--- a/hv.c
+++ b/hv.c
@@ -439,25 +439,28 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
U32 i;
for (i = 0; i < klen; ++i)
if (isLOWER(key[i])) {
- const char *keysave = key;
- /* Will need to free this, so set FREEKEY flag
- on call to hv_fetch_common. */
- key = savepvn(key,klen);
- key = (const char*)strupr((char*)key);
-
- if (flags & HVhek_FREEKEY)
- Safefree(keysave);
-
- /* This isn't strictly the same as the old hv_fetch
- magic, which made a call to hv_fetch, followed
- by a call to hv_store if that failed and lvalue
- was true.
- Which I believe could have been done by simply
- passing the lvalue through to the first hv_fetch.
- So I will do that here. */
- return hv_fetch_common(hv, Nullsv, key, klen,
- HVhek_FREEKEY,
- action, Nullsv, 0);
+ /* 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));
+ /* 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,
+ HVhek_FREEKEY, /* free nkey */
+ 0 /* non-LVAL fetch */,
+ Nullsv /* no value */,
+ 0 /* compute hash */);
+ if (!entry && (action & HV_FETCH_LVALUE)) {
+ /* This call will free key if necessary.
+ Do it this way to encourage compiler to tail
+ call optimise. */
+ entry = hv_fetch_common(hv, keysv, key, klen,
+ flags, HV_FETCH_ISSTORE,
+ NEWSV(61,0), hash);
+ } else {
+ if (flags & HVhek_FREEKEY)
+ Safefree(key);
+ }
+ return entry;
}
}
#endif