register XPVHV* xhv;
register U32 hash;
register HE *entry;
- char *origkey = key;
SV *sv;
if (!hv)
}
#ifdef ENV_IS_CASELESS
else if (mg_find((SV*)hv,'E')) {
- sv = sv_2mortal(newSVpv(key,klen));
- key = strupr(SvPVX(sv));
+ U32 i;
+ for (i = 0; i < klen; ++i)
+ if (isLOWER(key[i])) {
+ char *nkey = strupr(SvPVX(sv_2mortal(newSVpv(key,klen))));
+ SV **ret = hv_fetch(hv, nkey, klen, 0);
+ if (!ret && lval)
+ ret = hv_store(hv, key, klen, NEWSV(61,0), 0);
+ return ret;
+ }
}
#endif
}
if ((gotenv = ENV_getenv(key)) != Nullch) {
sv = newSVpv(gotenv,strlen(gotenv));
SvTAINTED_on(sv);
- return hv_store(hv,origkey,klen,sv,hash);
+ return hv_store(hv,key,klen,sv,hash);
}
}
#endif
if (lval) { /* gonna assign to this, so it better be there */
sv = NEWSV(61,0);
- return hv_store(hv,origkey,klen,sv,hash);
+ return hv_store(hv,key,klen,sv,hash);
}
return 0;
}
register char *key;
STRLEN klen;
register HE *entry;
- SV *origkeysv = keysv;
SV *sv;
if (!hv)
}
#ifdef ENV_IS_CASELESS
else if (mg_find((SV*)hv,'E')) {
+ U32 i;
key = SvPV(keysv, klen);
- keysv = sv_2mortal(newSVpv(key,klen));
- (void)strupr(SvPVX(keysv));
- hash = 0;
+ for (i = 0; i < klen; ++i)
+ if (isLOWER(key[i])) {
+ SV *nkeysv = sv_2mortal(newSVpv(key,klen));
+ (void)strupr(SvPVX(nkeysv));
+ entry = hv_fetch_ent(hv, nkeysv, 0, 0);
+ if (!entry && lval)
+ entry = hv_store_ent(hv, keysv, NEWSV(61,0), hash);
+ return entry;
+ }
}
#endif
}
if ((gotenv = ENV_getenv(key)) != Nullch) {
sv = newSVpv(gotenv,strlen(gotenv));
SvTAINTED_on(sv);
- return hv_store_ent(hv,origkeysv,sv,hash);
+ return hv_store_ent(hv,keysv,sv,hash);
}
}
#endif
if (lval) { /* gonna assign to this, so it better be there */
sv = NEWSV(61,0);
- return hv_store_ent(hv,origkeysv,sv,hash);
+ return hv_store_ent(hv,keysv,sv,hash);
}
return 0;
}
*needs_copy = TRUE;
switch (mg->mg_type) {
case 'P':
- case 'I':
case 'S':
*needs_store = FALSE;
}
if (!hv)
return Nullsv;
if (SvRMAGICAL(hv)) {
- sv = *hv_fetch(hv, key, klen, TRUE);
- mg_clear(sv);
- if (mg_find(sv, 's')) {
- return Nullsv; /* %SIG elements cannot be deleted */
- }
- else if (mg_find(sv, 'p')) {
- sv_unmagic(sv, 'p'); /* No longer an element */
- return sv;
- }
+ bool needs_copy;
+ bool needs_store;
+ hv_magic_check (hv, &needs_copy, &needs_store);
+
+ if (needs_copy) {
+ sv = *hv_fetch(hv, key, klen, TRUE);
+ mg_clear(sv);
+ if (!needs_store) {
+ if (mg_find(sv, 'p')) {
+ sv_unmagic(sv, 'p'); /* No longer an element */
+ return sv;
+ }
+ return Nullsv; /* element cannot be deleted */
+ }
#ifdef ENV_IS_CASELESS
- else if (mg_find((SV*)hv,'E')) {
- sv = sv_2mortal(newSVpv(key,klen));
- key = strupr(SvPVX(sv));
- }
+ else if (mg_find((SV*)hv,'E')) {
+ sv = sv_2mortal(newSVpv(key,klen));
+ key = strupr(SvPVX(sv));
+ }
#endif
+ }
}
xhv = (XPVHV*)SvANY(hv);
if (!xhv->xhv_array)
if (!hv)
return Nullsv;
if (SvRMAGICAL(hv)) {
- entry = hv_fetch_ent(hv, keysv, TRUE, hash);
- sv = HeVAL(entry);
- mg_clear(sv);
- if (mg_find(sv, 'p')) {
- sv_unmagic(sv, 'p'); /* No longer an element */
- return sv;
- }
+ bool needs_copy;
+ bool needs_store;
+ hv_magic_check (hv, &needs_copy, &needs_store);
+
+ if (needs_copy) {
+ entry = hv_fetch_ent(hv, keysv, TRUE, hash);
+ sv = HeVAL(entry);
+ mg_clear(sv);
+ if (!needs_store) {
+ if (mg_find(sv, 'p')) {
+ sv_unmagic(sv, 'p'); /* No longer an element */
+ return sv;
+ }
+ return Nullsv; /* element cannot be deleted */
+ }
#ifdef ENV_IS_CASELESS
- else if (mg_find((SV*)hv,'E')) {
- key = SvPV(keysv, klen);
- keysv = sv_2mortal(newSVpv(key,klen));
- (void)strupr(SvPVX(keysv));
- hash = 0;
- }
+ else if (mg_find((SV*)hv,'E')) {
+ key = SvPV(keysv, klen);
+ keysv = sv_2mortal(newSVpv(key,klen));
+ (void)strupr(SvPVX(keysv));
+ hash = 0;
+ }
#endif
+ }
}
xhv = (XPVHV*)SvANY(hv);
if (!xhv->xhv_array)