return hv_fetch_flags (hv, key, klen, lval, flags);
}
-SV**
+STATIC SV**
S_hv_fetch_flags(pTHX_ HV *hv, const char *key, I32 klen, I32 lval, int flags)
{
register XPVHV* xhv;
}
#ifdef ENV_IS_CASELESS
else if (mg_find((SV*)hv, PERL_MAGIC_env)) {
- U32 i;
+ I32 i;
for (i = 0; i < klen; ++i)
if (isLOWER(key[i])) {
char *nkey = strupr(SvPVX(sv_2mortal(newSVpvn(key,klen))));
for (; entry; entry = HeNEXT(entry)) {
if (HeHASH(entry) != hash) /* strings can't be equal */
continue;
- if (HeKLEN(entry) != klen)
+ if (HeKLEN(entry) != (I32)klen)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
flags |= HVhek_WASUTF8 | HVhek_FREEKEY;
}
- if (!hash)
- PERL_HASH(hash, key, klen);
+ if (!hash) {
+ if SvIsCOW_shared_hash(keysv) {
+ hash = SvUVX(keysv);
+ } else {
+ PERL_HASH(hash, key, klen);
+ }
+ }
/* entry = (HvARRAY(hv))[hash & (I32) HvMAX(hv)]; */
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;
- if (HeKLEN(entry) != klen)
+ if (HeKLEN(entry) != (I32)klen)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) {
if (HeHASH(entry) != hash) /* strings can't be equal */
continue;
- if (HeKLEN(entry) != klen)
+ if (HeKLEN(entry) != (I32)klen)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
xhv->xhv_keys++; /* HvKEYS(hv)++ */
if (i) { /* initial entry? */
xhv->xhv_fill++; /* HvFILL(hv)++ */
- if (xhv->xhv_keys > xhv->xhv_max /* HvKEYS(hv) > HvMAX(hv) */)
+ if (xhv->xhv_keys > (IV)xhv->xhv_max /* HvKEYS(hv) > HvMAX(hv) */)
hsplit(hv);
}
HvHASKFLAGS_on((SV*)hv);
}
- if (!hash)
- PERL_HASH(hash, key, klen);
+ if (!hash) {
+ if SvIsCOW_shared_hash(keysv) {
+ hash = SvUVX(keysv);
+ } else {
+ PERL_HASH(hash, key, klen);
+ }
+ }
if (!xhv->xhv_array /* !HvARRAY(hv) */)
Newz(505, xhv->xhv_array /* HvARRAY(hv) */,
for (; entry; i=0, entry = HeNEXT(entry)) {
if (HeHASH(entry) != hash) /* strings can't be equal */
continue;
- if (HeKLEN(entry) != klen)
+ if (HeKLEN(entry) != (I32)klen)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
xhv->xhv_keys++; /* HvKEYS(hv)++ */
if (i) { /* initial entry? */
xhv->xhv_fill++; /* HvFILL(hv)++ */
- if (xhv->xhv_keys > xhv->xhv_max /* HvKEYS(hv) > HvMAX(hv) */)
+ if (xhv->xhv_keys > (IV)xhv->xhv_max /* HvKEYS(hv) > HvMAX(hv) */)
hsplit(hv);
}
for (; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) {
if (HeHASH(entry) != hash) /* strings can't be equal */
continue;
- if (HeKLEN(entry) != klen)
+ if (HeKLEN(entry) != (I32)klen)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
for (; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) {
if (HeHASH(entry) != hash) /* strings can't be equal */
continue;
- if (HeKLEN(entry) != klen)
+ if (HeKLEN(entry) != (I32)klen)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
sv = sv_newmortal();
mg_copy((SV*)hv, sv, key, klen);
magic_existspack(sv, mg_find(sv, PERL_MAGIC_tiedelem));
- return SvTRUE(sv);
+ return (bool)SvTRUE(sv);
}
#ifdef ENV_IS_CASELESS
else if (mg_find((SV*)hv, PERL_MAGIC_env)) {
keysv = sv_2mortal(newSVsv(keysv));
mg_copy((SV*)hv, sv, (char*)keysv, HEf_SVKEY);
magic_existspack(svret, mg_find(sv, PERL_MAGIC_tiedelem));
- return SvTRUE(svret);
+ return (bool)SvTRUE(svret);
}
#ifdef ENV_IS_CASELESS
else if (mg_find((SV*)hv, PERL_MAGIC_env)) {
for (; entry; entry = HeNEXT(entry)) {
if (HeHASH(entry) != hash) /* strings can't be equal */
continue;
- if (HeKLEN(entry) != klen)
+ if (HeKLEN(entry) != (I32)klen)
continue;
if (HeKEY(entry) != key && memNE(HeKEY(entry),key,klen)) /* is this it? */
continue;
continue;
bep = aep+oldsize;
for (oentry = aep, entry = *aep; entry; entry = *oentry) {
- if ((HeHASH(entry) & newsize) != i) {
+ if ((HeHASH(entry) & newsize) != (U32)i) {
*oentry = HeNEXT(entry);
HeNEXT(entry) = *bep;
if (!*bep)
if (!SvMAGICAL((SV *)ohv)) {
/* It's an ordinary hash, so copy it fast. AMS 20010804 */
- int i, shared = !!HvSHAREKEYS(ohv);
+ STRLEN i;
+ bool shared = !!HvSHAREKEYS(ohv);
HE **ents, **oents = (HE **)HvARRAY(ohv);
char *a;
New(0, a, PERL_HV_ARRAY_ALLOC_BYTES(hv_max+1), char);
Returns entries from a hash iterator. See C<hv_iterinit>.
+You may call C<hv_delete> or C<hv_delete_ent> on the hash entry that the
+iterator currently points to, without losing your place or invalidating your
+iterator. Note that in this case the current entry is deleted from the hash
+with your iterator holding the last reference to it. Your iterator is flagged
+to free the entry on the next call to C<hv_iternext>, so you must not discard
+your iterator immediately else the entry will leak - call C<hv_iternext> to
+trigger the resource deallocation.
+
=cut
*/
}
/*
-XXX=for apidoc hv_iternext
+=for apidoc hv_iternext_flags
+
+Returns entries from a hash iterator. See C<hv_iterinit> and C<hv_iternext>.
+The C<flags> value will normally be zero; if HV_ITERNEXT_WANTPLACEHOLDERS is
+set the placeholders keys (for restricted hashes) will be returned in addition
+to normal keys. By default placeholders are automatically skipped over.
+Currently a placeholder is implemented with a value that is literally
+<&Perl_sv_undef> (a regular C<undef> value is a normal read-write SV for which
+C<!SvOK> is false). Note that the implementation of placeholders and
+restricted hashes may change, and the implementation currently is
+insufficiently abstracted for any change to be tidy.
-Returns entries from a hash iterator. See C<hv_iterinit>.
-
-XXX=cut
+=cut
*/
HE *
}
while (!entry) {
xhv->xhv_riter++; /* HvRITER(hv)++ */
- if (xhv->xhv_riter > xhv->xhv_max /* HvRITER(hv) > HvMAX(hv) */) {
+ if (xhv->xhv_riter > (I32)xhv->xhv_max /* HvRITER(hv) > HvMAX(hv) */) {
xhv->xhv_riter = -1; /* HvRITER(hv) = -1 */
break;
}
sv = newSVpvn ((char*)as_utf8, utf8_len);
SvUTF8_on (sv);
+ Safefree (as_utf8); /* bytes_to_utf8() allocates a new string */
} else {
sv = newSVpvn_share(HEK_KEY(hek),
(HEK_UTF8(hek) ? -HEK_LEN(hek) : HEK_LEN(hek)),
hek if non-NULL takes priority over the other 3, else str, len and hash
are used. If so, len and hash must both be valid for str.
*/
-void
+STATIC void
S_unshare_hek_or_pvn(pTHX_ HEK *hek, const char *str, I32 len, U32 hash)
{
register XPVHV* xhv;
return share_hek_flags (str, len, hash, flags);
}
-HEK *
+STATIC HEK *
S_share_hek_flags(pTHX_ const char *str, I32 len, register U32 hash, int flags)
{
register XPVHV* xhv;
xhv->xhv_keys++; /* HvKEYS(hv)++ */
if (i) { /* initial entry? */
xhv->xhv_fill++; /* HvFILL(hv)++ */
- if (xhv->xhv_keys > xhv->xhv_max /* HvKEYS(hv) > HvMAX(hv) */)
+ if (xhv->xhv_keys > (IV)xhv->xhv_max /* HvKEYS(hv) > HvMAX(hv) */)
hsplit(PL_strtab);
}
}