}
/* Void wrapper to pass to visit() */
+/* XXX
static void
do_curse(pTHX_ SV * const sv) {
if ((PL_stderrgv && GvGP(PL_stderrgv) && (SV*)GvIO(PL_stderrgv) == sv)
return;
(void)curse(sv, 0);
}
+*/
/*
=for apidoc sv_clean_objs
case SVt_PVCV:
case SVt_PVFM:
case SVt_PVIO:
+ /* diag_listed_as: Can't coerce %s to %s in %s */
Perl_croak(aTHX_ "Can't coerce %s to integer in %s", sv_reftype(sv,0),
OP_DESC(PL_op));
default: NOOP;
case SVt_PVCV:
case SVt_PVFM:
case SVt_PVIO:
+ /* diag_listed_as: Can't coerce %s to %s in %s */
Perl_croak(aTHX_ "Can't coerce %s to number in %s", sv_reftype(sv,0),
OP_DESC(PL_op));
default: NOOP;
return len;
}
} else {
- (void) SvPV_force(sv,len);
+ (void) SvPV_force_flags(sv,len,flags & SV_GMAGIC);
}
}
}
}
}
+
+ if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
+ /* Update pos. We do it at the end rather than during
+ * the upgrade, to avoid slowing down the common case
+ * (upgrade without pos) */
+ MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global);
+ if (mg) {
+ I32 pos = mg->mg_len;
+ if (pos > 0 && (U32)pos > invariant_head) {
+ U8 *d = (U8*) SvPVX(sv) + invariant_head;
+ STRLEN n = (U32)pos - invariant_head;
+ while (n > 0) {
+ if (UTF8_IS_START(*d))
+ d++;
+ d++;
+ n--;
+ }
+ mg->mg_len = d - (U8*)SvPVX(sv);
+ }
+ }
+ if ((mg = mg_find(sv, PERL_MAGIC_utf8)))
+ magic_setutf8(sv,mg); /* clear UTF8 cache */
+ }
}
}
if (SvCUR(sv)) {
U8 *s;
STRLEN len;
+ int mg_flags = SV_GMAGIC;
if (SvIsCOW(sv)) {
sv_force_normal_flags(sv, 0);
}
- s = (U8 *) SvPV(sv, len);
+ if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
+ /* update pos */
+ MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global);
+ if (mg) {
+ I32 pos = mg->mg_len;
+ if (pos > 0) {
+ sv_pos_b2u(sv, &pos);
+ mg_flags = 0; /* sv_pos_b2u does get magic */
+ mg->mg_len = pos;
+ }
+ }
+ if ((mg = mg_find(sv, PERL_MAGIC_utf8)))
+ magic_setutf8(sv,mg); /* clear UTF8 cache */
+
+ }
+ s = (U8 *) SvPV_flags(sv, len, mg_flags);
+
if (!utf8_to_bytes(s, &len)) {
if (fail_ok)
return FALSE;
PERL_ARGS_ASSERT_SV_UTF8_DECODE;
if (SvPOKp(sv)) {
- const U8 *c;
+ const U8 *start, *c;
const U8 *e;
/* The octets may have got themselves encoded - get them back as
/* it is actually just a matter of turning the utf8 flag on, but
* we want to make sure everything inside is valid utf8 first.
*/
- c = (const U8 *) SvPVX_const(sv);
+ c = start = (const U8 *) SvPVX_const(sv);
if (!is_utf8_string(c, SvCUR(sv)+1))
return FALSE;
e = (const U8 *) SvEND(sv);
break;
}
}
+ if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
+ /* adjust pos to the start of a UTF8 char sequence */
+ MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global);
+ if (mg) {
+ I32 pos = mg->mg_len;
+ if (pos > 0) {
+ for (c = start + pos; c > start; c--) {
+ if (UTF8_IS_START(*c))
+ break;
+ }
+ mg->mg_len = c - start;
+ }
+ }
+ if ((mg = mg_find(sv, PERL_MAGIC_utf8)))
+ magic_setutf8(sv,mg); /* clear UTF8 cache */
+ }
}
return TRUE;
}
then a copy-on-write scalar drops its PV buffer (if any) and becomes
SvPOK_off rather than making a copy. (Used where this scalar is about to be
set to some other value.) In addition, the C<flags> parameter gets passed to
-C<sv_unref_flags()> when unrefing. C<sv_force_normal> calls this function
+C<sv_unref_flags()> when unreffing. C<sv_force_normal> calls this function
with flags set to 0.
=cut
if (!curse(sv, 1)) goto get_next_sv;
}
if (type >= SVt_PVMG) {
+ /* Free back-references before magic, in case the magic calls
+ * Perl code that has weak references to sv. */
+ if (type == SVt_PVHV)
+ Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv));
if (type == SVt_PVMG && SvPAD_OUR(sv)) {
SvREFCNT_dec(SvOURSTASH(sv));
- } else if (SvMAGIC(sv))
+ } else if (SvMAGIC(sv)) {
+ /* Free back-references before other types of magic. */
+ sv_unmagic(sv, PERL_MAGIC_backref);
mg_free(sv);
+ }
if (type == SVt_PVMG && SvPAD_TYPED(sv))
SvREFCNT_dec(SvSTASH(sv));
}
if (PL_last_swash_hv == (const HV *)sv) {
PL_last_swash_hv = NULL;
}
- Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv));
Perl_hv_undef_flags(aTHX_ MUTABLE_HV(sv), HV_NAME_SETALL);
break;
case SVt_PVAV:
}
if ((SvTYPE(sv) > SVt_PVLV && SvTYPE(sv) != SVt_PVFM)
|| isGV_with_GP(sv))
+ /* diag_listed_as: Can't coerce %s to %s in %s */
Perl_croak(aTHX_ "Can't coerce %s to string in %s", sv_reftype(sv,0),
OP_DESC(PL_op));
s = sv_2pv_flags(sv, &len, flags);
width = expect_number(&q);
}
- if (vectorize) {
- if (vectorarg) {
- if (args)
- vecsv = va_arg(*args, SV*);
- else if (evix) {
- vecsv = (evix > 0 && evix <= svmax)
- ? svargs[evix-1] : S_vcatpvfn_missing_argument(aTHX);
- } else {
- vecsv = svix < svmax
- ? svargs[svix++] : S_vcatpvfn_missing_argument(aTHX);
- }
- dotstr = SvPV_const(vecsv, dotstrlen);
- /* Keep the DO_UTF8 test *after* the SvPV call, else things go
- bad with tied or overloaded values that return UTF8. */
- if (DO_UTF8(vecsv))
- is_utf8 = TRUE;
- else if (has_utf8) {
- vecsv = sv_mortalcopy(vecsv);
- sv_utf8_upgrade(vecsv);
- dotstr = SvPV_const(vecsv, dotstrlen);
- is_utf8 = TRUE;
- }
- }
- if (args) {
- VECTORIZE_ARGS
- }
- else if (efix ? (efix > 0 && efix <= svmax) : svix < svmax) {
- vecsv = svargs[efix ? efix-1 : svix++];
- vecstr = (U8*)SvPV_const(vecsv,veclen);
- vec_utf8 = DO_UTF8(vecsv);
-
- /* if this is a version object, we need to convert
- * back into v-string notation and then let the
- * vectorize happen normally
- */
- if (sv_derived_from(vecsv, "version")) {
- char *version = savesvpv(vecsv);
- if ( hv_exists(MUTABLE_HV(SvRV(vecsv)), "alpha", 5 ) ) {
- Perl_warner(aTHX_ packWARN(WARN_INTERNAL),
- "vector argument not supported with alpha versions");
- goto unknown;
- }
- vecsv = sv_newmortal();
- scan_vstring(version, version + veclen, vecsv);
- vecstr = (U8*)SvPV_const(vecsv, veclen);
- vec_utf8 = DO_UTF8(vecsv);
- Safefree(version);
- }
- }
- else {
- vecstr = (U8*)"";
- veclen = 0;
+ if (vectorize && vectorarg) {
+ /* vectorizing, but not with the default "." */
+ if (args)
+ vecsv = va_arg(*args, SV*);
+ else if (evix) {
+ vecsv = (evix > 0 && evix <= svmax)
+ ? svargs[evix-1] : S_vcatpvfn_missing_argument(aTHX);
+ } else {
+ vecsv = svix < svmax
+ ? svargs[svix++] : S_vcatpvfn_missing_argument(aTHX);
}
+ dotstr = SvPV_const(vecsv, dotstrlen);
+ /* Keep the DO_UTF8 test *after* the SvPV call, else things go
+ bad with tied or overloaded values that return UTF8. */
+ if (DO_UTF8(vecsv))
+ is_utf8 = TRUE;
+ else if (has_utf8) {
+ vecsv = sv_mortalcopy(vecsv);
+ sv_utf8_upgrade(vecsv);
+ dotstr = SvPV_const(vecsv, dotstrlen);
+ is_utf8 = TRUE;
+ }
}
if (asterisk) {
}
}
+ if (vectorize) {
+ if (args) {
+ VECTORIZE_ARGS
+ }
+ else if (efix ? (efix > 0 && efix <= svmax) : svix < svmax) {
+ vecsv = svargs[efix ? efix-1 : svix++];
+ vecstr = (U8*)SvPV_const(vecsv,veclen);
+ vec_utf8 = DO_UTF8(vecsv);
+
+ /* if this is a version object, we need to convert
+ * back into v-string notation and then let the
+ * vectorize happen normally
+ */
+ if (sv_derived_from(vecsv, "version")) {
+ char *version = savesvpv(vecsv);
+ if ( hv_exists(MUTABLE_HV(SvRV(vecsv)), "alpha", 5 ) ) {
+ Perl_warner(aTHX_ packWARN(WARN_INTERNAL),
+ "vector argument not supported with alpha versions");
+ goto unknown;
+ }
+ vecsv = sv_newmortal();
+ scan_vstring(version, version + veclen, vecsv);
+ vecstr = (U8*)SvPV_const(vecsv, veclen);
+ vec_utf8 = DO_UTF8(vecsv);
+ Safefree(version);
+ }
+ }
+ else {
+ vecstr = (U8*)"";
+ veclen = 0;
+ }
+ }
+
/* SIZE */
switch (*q) {
PL_utf8_tolower = sv_dup_inc(proto_perl->Iutf8_tolower, param);
PL_utf8_tofold = sv_dup_inc(proto_perl->Iutf8_tofold, param);
PL_utf8_idstart = sv_dup_inc(proto_perl->Iutf8_idstart, param);
+ PL_utf8_xidstart = sv_dup_inc(proto_perl->Iutf8_xidstart, param);
PL_utf8_idcont = sv_dup_inc(proto_perl->Iutf8_idcont, param);
- PL_utf8_foldable = sv_dup_inc(proto_perl->Iutf8_foldable, param);
+ PL_utf8_xidcont = sv_dup_inc(proto_perl->Iutf8_xidcont, param);
+ PL_utf8_foldable = hv_dup_inc(proto_perl->Iutf8_foldable, param);
/* Did the locale setup indicate UTF-8? */
PL_utf8locale = proto_perl->Iutf8locale;
}
FREETMPS;
LEAVE;
+ if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
+ /* clear pos and any utf8 cache */
+ MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global);
+ if (mg)
+ mg->mg_len = -1;
+ if ((mg = mg_find(sv, PERL_MAGIC_utf8)))
+ magic_setutf8(sv,mg); /* clear UTF8 cache */
+ }
SvUTF8_on(sv);
return SvPVX(sv);
}