/* hv.c
*
- * Copyright (c) 1991-1997, Larry Wall
+ * Copyright (c) 1991-1999, Larry Wall
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
# define ARRAY_ALLOC_BYTES(size) ( (size)*sizeof(HE*) )
#else
# define MALLOC_OVERHEAD 16
-# define ARRAY_ALLOC_BYTES(size) ( (size)*sizeof(HE*)*2 - MALLOC_OVERHEAD )
+# define ARRAY_ALLOC_BYTES(size) ( ((size) < 64) \
+ ? (size)*sizeof(HE*) \
+ : (size)*sizeof(HE*)*2 - MALLOC_OVERHEAD )
#endif
STATIC HE*
U32 i;
for (i = 0; i < klen; ++i)
if (isLOWER(key[i])) {
- char *nkey = strupr(SvPVX(sv_2mortal(newSVpv(key,klen))));
+ char *nkey = strupr(SvPVX(sv_2mortal(newSVpvn(key,klen))));
SV **ret = hv_fetch(hv, nkey, klen, 0);
if (!ret && lval)
ret = hv_store(hv, key, klen, NEWSV(61,0), 0);
}
#ifdef DYNAMIC_ENV_FETCH /* %ENV lookup? If so, try to fetch the value now */
if (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME)) {
- char *gotenv;
-
- if ((gotenv = PerlEnv_getenv(key)) != Nullch) {
- sv = newSVpv(gotenv,strlen(gotenv));
- SvTAINTED_on(sv);
- return hv_store(hv,key,klen,sv,hash);
- }
+ unsigned long len;
+ char *env = PerlEnv_ENVgetenv_len(key,&len);
+ if (env) {
+ sv = newSVpvn(env,len);
+ SvTAINTED_on(sv);
+ return hv_store(hv,key,klen,sv,hash);
+ }
}
#endif
if (lval) { /* gonna assign to this, so it better be there */
key = SvPV(keysv, klen);
for (i = 0; i < klen; ++i)
if (isLOWER(key[i])) {
- SV *nkeysv = sv_2mortal(newSVpv(key,klen));
+ SV *nkeysv = sv_2mortal(newSVpvn(key,klen));
(void)strupr(SvPVX(nkeysv));
entry = hv_fetch_ent(hv, nkeysv, 0, 0);
if (!entry && lval)
}
#ifdef DYNAMIC_ENV_FETCH /* %ENV lookup? If so, try to fetch the value now */
if (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME)) {
- char *gotenv;
-
- if ((gotenv = PerlEnv_getenv(key)) != Nullch) {
- sv = newSVpv(gotenv,strlen(gotenv));
- SvTAINTED_on(sv);
- return hv_store_ent(hv,keysv,sv,hash);
- }
+ unsigned long len;
+ char *env = PerlEnv_ENVgetenv_len(key,&len);
+ if (env) {
+ sv = newSVpvn(env,len);
+ SvTAINTED_on(sv);
+ return hv_store_ent(hv,keysv,sv,hash);
+ }
}
#endif
if (lval) { /* gonna assign to this, so it better be there */
return 0;
#ifdef ENV_IS_CASELESS
else if (mg_find((SV*)hv,'E')) {
- SV *sv = sv_2mortal(newSVpv(key,klen));
+ SV *sv = sv_2mortal(newSVpvn(key,klen));
key = strupr(SvPVX(sv));
hash = 0;
}
#ifdef ENV_IS_CASELESS
else if (mg_find((SV*)hv,'E')) {
key = SvPV(keysv, klen);
- keysv = sv_2mortal(newSVpv(key,klen));
+ keysv = sv_2mortal(newSVpvn(key,klen));
(void)strupr(SvPVX(keysv));
hash = 0;
}
}
#ifdef ENV_IS_CASELESS
else if (mg_find((SV*)hv,'E')) {
- sv = sv_2mortal(newSVpv(key,klen));
+ sv = sv_2mortal(newSVpvn(key,klen));
key = strupr(SvPVX(sv));
}
#endif
#ifdef ENV_IS_CASELESS
else if (mg_find((SV*)hv,'E')) {
key = SvPV(keysv, klen);
- keysv = sv_2mortal(newSVpv(key,klen));
+ keysv = sv_2mortal(newSVpvn(key,klen));
(void)strupr(SvPVX(keysv));
hash = 0;
}
}
#ifdef ENV_IS_CASELESS
else if (mg_find((SV*)hv,'E')) {
- sv = sv_2mortal(newSVpv(key,klen));
+ sv = sv_2mortal(newSVpvn(key,klen));
key = strupr(SvPVX(sv));
}
#endif
}
xhv = (XPVHV*)SvANY(hv);
+#ifndef DYNAMIC_ENV_FETCH
if (!xhv->xhv_array)
return 0;
+#endif
PERL_HASH(hash, key, klen);
+#ifdef DYNAMIC_ENV_FETCH
+ if (!xhv->xhv_array) entry = Null(HE*);
+ else
+#endif
entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
for (; entry; entry = HeNEXT(entry)) {
if (HeHASH(entry) != hash) /* strings can't be equal */
continue;
return TRUE;
}
+#ifdef DYNAMIC_ENV_FETCH /* is it out there? */
+ if (HvNAME(hv) && strEQ(HvNAME(hv), ENV_HV_NAME)) {
+ unsigned long len;
+ char *env = PerlEnv_ENVgetenv_len(key,&len);
+ if (env) {
+ sv = newSVpvn(env,len);
+ SvTAINTED_on(sv);
+ (void)hv_store(hv,key,klen,sv,hash);
+ return TRUE;
+ }
+ }
+#endif
return FALSE;
}
#ifdef ENV_IS_CASELESS
else if (mg_find((SV*)hv,'E')) {
key = SvPV(keysv, klen);
- keysv = sv_2mortal(newSVpv(key,klen));
+ keysv = sv_2mortal(newSVpvn(key,klen));
(void)strupr(SvPVX(keysv));
hash = 0;
}
}
xhv = (XPVHV*)SvANY(hv);
+#ifndef DYNAMIC_ENV_FETCH
if (!xhv->xhv_array)
return 0;
+#endif
key = SvPV(keysv, klen);
if (!hash)
PERL_HASH(hash, key, klen);
+#ifdef DYNAMIC_ENV_FETCH
+ if (!xhv->xhv_array) entry = Null(HE*);
+ else
+#endif
entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
for (; entry; entry = HeNEXT(entry)) {
if (HeHASH(entry) != hash) /* strings can't be equal */
continue;
return TRUE;
}
+#ifdef DYNAMIC_ENV_FETCH /* is it out there? */
+ if (HvNAME(hv) && strEQ(HvNAME(hv), ENV_HV_NAME)) {
+ unsigned long len;
+ char *env = PerlEnv_ENVgetenv_len(key,&len);
+ if (env) {
+ sv = newSVpvn(env,len);
+ SvTAINTED_on(sv);
+ (void)hv_store_ent(hv,keysv,sv,hash);
+ return TRUE;
+ }
+ }
+#endif
return FALSE;
}
croak("Bad hash");
xhv = (XPVHV*)SvANY(hv);
entry = xhv->xhv_eiter;
-#ifdef DYNAMIC_ENV_FETCH /* set up %ENV for iteration */
- if (HvNAME(hv) && strEQ(HvNAME(hv), ENV_HV_NAME))
- prime_env_iter();
-#endif
if (entry && HvLAZYDEL(hv)) { /* was deleted earlier? */
HvLAZYDEL_off(hv);
hv_free_ent(hv, entry);
xhv->xhv_eiter = Null(HE*);
return Null(HE*);
}
+#ifdef DYNAMIC_ENV_FETCH /* set up %ENV for iteration */
+ if (!entry && HvNAME(hv) && strEQ(HvNAME(hv), ENV_HV_NAME))
+ prime_env_iter();
+#endif
if (!xhv->xhv_array)
Newz(506,xhv->xhv_array, ARRAY_ALLOC_BYTES(xhv->xhv_max + 1), char);
if (HeKLEN(entry) == HEf_SVKEY)
return sv_mortalcopy(HeKEY_sv(entry));
else
- return sv_2mortal(newSVpv((HeKLEN(entry) ? HeKEY(entry) : ""),
+ return sv_2mortal(newSVpvn((HeKLEN(entry) ? HeKEY(entry) : ""),
HeKLEN(entry)));
}