/* pp_ctl.c
*
- * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- * 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by Larry Wall and others
+ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ * 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
/* multiple args; concatentate them */
dMARK; dORIGMARK;
tmpstr = PAD_SV(ARGTARG);
- sv_setpvn(tmpstr, "", 0);
+ sv_setpvs(tmpstr, "");
while (++MARK <= SP) {
if (PL_amagic_generation) {
SV *sv;
SV * nsv = NULL;
OP * parseres = NULL;
const char *fmt;
- bool oneline;
if (!SvMAGICAL(tmpForm) || !SvCOMPILED(tmpForm)) {
if (SvREADONLY(tmpForm)) {
*t = '\0';
sv_catpvn_utf8_upgrade(PL_formtarget, f, arg, nsv);
t = SvEND(PL_formtarget);
+ f += arg;
break;
}
if (!targ_is_utf8 && DO_UTF8(tmpForm)) {
case FF_LINESNGL:
chopspace = 0;
- oneline = TRUE;
- goto ff_line;
case FF_LINEGLOB:
- oneline = FALSE;
- ff_line:
{
+ const bool oneline = fpc[-1] == FF_LINESNGL;
const char *s = item = SvPV_const(sv, len);
+ item_is_utf8 = DO_UTF8(sv);
itemsize = len;
- if ((item_is_utf8 = DO_UTF8(sv)))
- itemsize = sv_len_utf8(sv);
if (itemsize) {
- bool chopped = FALSE;
+ STRLEN to_copy = itemsize;
const char *const send = s + len;
+ const U8 *source = (const U8 *) s;
+ U8 *tmp = NULL;
+
gotsome = TRUE;
chophere = s + itemsize;
while (s < send) {
if (*s++ == '\n') {
if (oneline) {
- chopped = TRUE;
+ to_copy = s - SvPVX_const(sv) - 1;
chophere = s;
break;
} else {
if (s == send) {
itemsize--;
- chopped = TRUE;
+ to_copy--;
} else
lines++;
}
}
}
- SvCUR_set(PL_formtarget, t - SvPVX_const(PL_formtarget));
- if (targ_is_utf8)
- SvUTF8_on(PL_formtarget);
- if (oneline) {
- SvCUR_set(sv, chophere - item);
- sv_catsv(PL_formtarget, sv);
- SvCUR_set(sv, itemsize);
- } else
- sv_catsv(PL_formtarget, sv);
- if (chopped)
- SvCUR_set(PL_formtarget, SvCUR(PL_formtarget) - 1);
- SvGROW(PL_formtarget, SvCUR(PL_formtarget) + fudge + 1);
+ if (targ_is_utf8 && !item_is_utf8) {
+ source = tmp = bytes_to_utf8(source, &to_copy);
+ SvCUR_set(PL_formtarget,
+ t - SvPVX_const(PL_formtarget));
+ } else {
+ if (item_is_utf8 && !targ_is_utf8) {
+ /* Upgrade targ to UTF8, and then we reduce it to
+ a problem we have a simple solution for. */
+ SvCUR_set(PL_formtarget,
+ t - SvPVX_const(PL_formtarget));
+ targ_is_utf8 = TRUE;
+ /* Don't need get magic. */
+ sv_utf8_upgrade_flags(PL_formtarget, 0);
+ } else {
+ SvCUR_set(PL_formtarget,
+ t - SvPVX_const(PL_formtarget));
+ }
+
+ /* Easy. They agree. */
+ assert (item_is_utf8 == targ_is_utf8);
+ }
+ SvGROW(PL_formtarget,
+ SvCUR(PL_formtarget) + to_copy + fudge + 1);
t = SvPVX(PL_formtarget) + SvCUR(PL_formtarget);
- if (item_is_utf8)
- targ_is_utf8 = TRUE;
+
+ Copy(source, t, to_copy, char);
+ t += to_copy;
+ SvCUR_set(PL_formtarget, SvCUR(PL_formtarget) + to_copy);
+ if (item_is_utf8) {
+ if (SvGMAGICAL(sv)) {
+ /* Mustn't call sv_pos_b2u() as it does a second
+ mg_get(). Is this a bug? Do we need a _flags()
+ variant? */
+ itemsize = utf8_length(source, source + itemsize);
+ } else {
+ sv_pos_b2u(sv, &itemsize);
+ }
+ assert(!tmp);
+ } else if (tmp) {
+ Safefree(tmp);
+ }
}
break;
}
RETURNOP(((LOGOP*)cUNOP->op_first)->op_other);
}
}
- sv_setpvn(TARG, "", 0);
+ sv_setpvs(TARG, "");
SETs(targ);
RETURN;
}
SV * const err = ERRSV;
const char *e = NULL;
if (!SvPOK(err))
- sv_setpvn(err,"",0);
+ sv_setpvs(err,"");
else if (SvCUR(err) >= sizeof(prefix)+msglen-1) {
STRLEN len;
e = SvPV_const(err, len);
}
}
else /* SvTYPE(maybe_ary) == SVt_PVAV */ {
- cx->blk_loop.state_u.ary.ary = (AV*)maybe_ary;
+ cx->blk_loop.state_u.ary.ary = MUTABLE_AV(maybe_ary);
SvREFCNT_inc(maybe_ary);
cx->blk_loop.state_u.ary.ix =
(PL_op->op_private & OPpITER_REVERSED) ?
PL_curpm = newpm; /* ... and pop $1 et al */
LEAVESUB(sv);
- if (clear_errsv)
- sv_setpvn(ERRSV,"",0);
+ if (clear_errsv) {
+ CLEAR_ERRSV();
+ }
return retop;
}
if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVCV) {
I32 cxix;
register PERL_CONTEXT *cx;
- CV* cv = (CV*)SvRV(sv);
+ CV *cv = MUTABLE_CV(SvRV(sv));
SV** mark;
I32 items = 0;
I32 oldsave;
PAD_SET_CUR_NOSAVE(padlist, CvDEPTH(cv));
if (CxHASARGS(cx))
{
- AV* const av = (AV*)PAD_SVl(0);
+ AV *const av = MUTABLE_AV(PAD_SVl(0));
cx->blk_sub.savearray = GvAV(PL_defgv);
- GvAV(PL_defgv) = (AV*)SvREFCNT_inc_simple(av);
+ GvAV(PL_defgv) = MUTABLE_AV(SvREFCNT_inc_simple(av));
CX_CURPAD_SAVE(cx->blk_sub);
cx->blk_sub.argarray = av;
(*startop)->op_ppaddr = PL_ppaddr[OP_NULL];
lex_end();
/* XXX DAPM do this properly one year */
- *padp = (AV*)SvREFCNT_inc_simple(PL_comppad);
+ *padp = MUTABLE_AV(SvREFCNT_inc_simple(PL_comppad));
LEAVE;
if (IN_PERL_COMPILETIME)
CopHINTS_set(&PL_compiling, PL_hints);
PUSHMARK(SP);
SAVESPTR(PL_compcv);
- PL_compcv = (CV*)newSV_type(SVt_PVCV);
+ PL_compcv = MUTABLE_CV(newSV_type(SVt_PVCV));
CvEVAL_on(PL_compcv);
assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_EVAL);
cxstack[cxstack_ix].blk_eval.cv = PL_compcv;
CvOUTSIDE_SEQ(PL_compcv) = seq;
- CvOUTSIDE(PL_compcv) = (CV*)SvREFCNT_inc_simple(outside);
+ CvOUTSIDE(PL_compcv) = MUTABLE_CV(SvREFCNT_inc_simple(outside));
/* set up a scratch pad */
if (saveop && (saveop->op_type != OP_REQUIRE) && (saveop->op_flags & OPf_SPECIAL))
PL_in_eval |= EVAL_KEEPERR;
else
- sv_setpvn(ERRSV,"",0);
+ CLEAR_ERRSV();
if (yyparse() || PL_parser->error_count || !PL_eval_root) {
SV **newsp; /* Used by POPBLOCK. */
PERL_CONTEXT *cx = &cxstack[cxstack_ix];
I32 first = 0;
AV *lav;
SV * const req = SvRV(sv);
- SV * const pv = *hv_fetchs((HV*)req, "original", FALSE);
+ SV * const pv = *hv_fetchs(MUTABLE_HV(req), "original", FALSE);
/* get the left hand term */
- lav = (AV *)SvRV(*hv_fetchs((HV*)req, "version", FALSE));
+ lav = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(req), "version", FALSE)));
first = SvIV(*av_fetch(lav,0,0));
if ( first > (int)PERL_REVISION /* probably 'use 6.0' */
- || hv_exists((HV*)req, "qv", 2 ) /* qv style */
+ || hv_exists(MUTABLE_HV(req), "qv", 2 ) /* qv style */
|| av_len(lav) > 1 /* FP with > 3 digits */
|| strstr(SvPVX(pv),".0") /* FP with leading 0 */
) {
if (SvTYPE(SvRV(loader)) == SVt_PVAV
&& !sv_isobject(loader))
{
- loader = *av_fetch((AV *)SvRV(loader), 0, TRUE);
+ loader = *av_fetch(MUTABLE_AV(SvRV(loader)), 0, TRUE);
}
Perl_sv_setpvf(aTHX_ namesv, "/loader/0x%"UVxf"/%s",
}
}
- if (SvROK(arg) && SvTYPE(SvRV(arg)) == SVt_PVGV) {
+ if (SvROK(arg) && isGV_with_GP(SvRV(arg))) {
arg = SvRV(arg);
}
- if (SvTYPE(arg) == SVt_PVGV) {
+ if (isGV_with_GP(arg)) {
IO * const io = GvIO((GV *)arg);
++filter_has_file;
{
dVAR;
dSP;
- mXPUSHs((SV*)Perl_hv_copy_hints_hv(aTHX_ (HV*)cSVOP_sv));
+ mXPUSHs((SV*)Perl_hv_copy_hints_hv(aTHX_ MUTABLE_HV(cSVOP_sv)));
RETURN;
}
const int fakelen = 9 + 1;
if (PL_op->op_private & OPpEVAL_HAS_HH) {
- saved_hh = (HV*) SvREFCNT_inc(POPs);
+ saved_hh = MUTABLE_HV(SvREFCNT_inc(POPs));
}
sv = POPs;
}
else {
LEAVE;
- if (!(save_flags & OPf_SPECIAL))
- sv_setpvn(ERRSV,"",0);
+ if (!(save_flags & OPf_SPECIAL)) {
+ CLEAR_ERRSV();
+ }
}
RETURNOP(retop);
if (flags & G_KEEPERR)
PL_in_eval |= EVAL_KEEPERR;
else
- sv_setpvn(ERRSV,"",0);
+ CLEAR_ERRSV();
if (flags & G_FAKINGEVAL) {
PL_eval_root = PL_op; /* Only needed so that goto works right. */
}
PL_curpm = newpm; /* Don't pop $1 et al till now */
LEAVE;
- sv_setpvn(ERRSV,"",0);
+ CLEAR_ERRSV();
RETURN;
}
if (SM_OTHER_REF(PVHV)) {
/* Check that the key-sets are identical */
HE *he;
- HV *other_hv = (HV *) SvRV(Other);
+ HV *other_hv = MUTABLE_HV(SvRV(Other));
bool tied = FALSE;
bool other_tied = FALSE;
U32 this_key_count = 0,
}
else if (SvTIED_mg((SV *) other_hv, PERL_MAGIC_tied)) {
HV * const temp = other_hv;
- other_hv = (HV *) This;
+ other_hv = MUTABLE_HV(This);
This = (SV *) temp;
tied = TRUE;
}
if (SvTIED_mg((SV *) other_hv, PERL_MAGIC_tied))
other_tied = TRUE;
- if (!tied && HvUSEDKEYS((HV *) This) != HvUSEDKEYS(other_hv))
+ if (!tied && HvUSEDKEYS((const HV *) This) != HvUSEDKEYS(other_hv))
RETPUSHNO;
/* The hashes have the same number of keys, so it suffices
to check that one is a subset of the other. */
- (void) hv_iterinit((HV *) This);
- while ( (he = hv_iternext((HV *) This)) ) {
+ (void) hv_iterinit(MUTABLE_HV(This));
+ while ( (he = hv_iternext(MUTABLE_HV(This))) ) {
I32 key_len;
char * const key = hv_iterkey(he, &key_len);
++ this_key_count;
if(!hv_exists(other_hv, key, key_len)) {
- (void) hv_iterinit((HV *) This); /* reset iterator */
+ (void) hv_iterinit(MUTABLE_HV(This)); /* reset iterator */
RETPUSHNO;
}
}
RETPUSHYES;
}
else if (SM_OTHER_REF(PVAV)) {
- AV * const other_av = (AV *) SvRV(Other);
+ AV * const other_av = MUTABLE_AV(SvRV(Other));
const I32 other_len = av_len(other_av) + 1;
I32 i;
if (svp) { /* ??? When can this not happen? */
key = SvPV(*svp, key_len);
- if (hv_exists((HV *) This, key, key_len))
+ if (hv_exists(MUTABLE_HV(This), key, key_len))
RETPUSHYES;
}
}
PMOP * const matcher = make_matcher(other_regex);
HE *he;
- (void) hv_iterinit((HV *) This);
- while ( (he = hv_iternext((HV *) This)) ) {
+ (void) hv_iterinit(MUTABLE_HV(This));
+ while ( (he = hv_iternext(MUTABLE_HV(This))) ) {
if (matcher_matches_sv(matcher, hv_iterkeysv(he))) {
- (void) hv_iterinit((HV *) This);
+ (void) hv_iterinit(MUTABLE_HV(This));
destroy_matcher(matcher);
RETPUSHYES;
}
RETPUSHNO;
}
else {
- if (hv_exists_ent((HV *) This, Other, 0))
+ if (hv_exists_ent(MUTABLE_HV(This), Other, 0))
RETPUSHYES;
else
RETPUSHNO;
}
else if (SM_REF(PVAV)) {
if (SM_OTHER_REF(PVAV)) {
- AV *other_av = (AV *) SvRV(Other);
- if (av_len((AV *) This) != av_len(other_av))
+ AV *other_av = MUTABLE_AV(SvRV(Other));
+ if (av_len(MUTABLE_AV(This)) != av_len(other_av))
RETPUSHNO;
else {
I32 i;
(void) sv_2mortal((SV *) seen_other);
}
for(i = 0; i <= other_len; ++i) {
- SV * const * const this_elem = av_fetch((AV *)This, i, FALSE);
+ SV * const * const this_elem = av_fetch(MUTABLE_AV(This), i, FALSE);
SV * const * const other_elem = av_fetch(other_av, i, FALSE);
if (!this_elem || !other_elem) {
}
else if (SM_OTHER_REGEX) {
PMOP * const matcher = make_matcher(other_regex);
- const I32 this_len = av_len((AV *) This);
+ const I32 this_len = av_len(MUTABLE_AV(This));
I32 i;
for(i = 0; i <= this_len; ++i) {
- SV * const * const svp = av_fetch((AV *)This, i, FALSE);
+ SV * const * const svp = av_fetch(MUTABLE_AV(This), i, FALSE);
if (svp && matcher_matches_sv(matcher, *svp)) {
destroy_matcher(matcher);
RETPUSHYES;
else if (SvIOK(Other) || SvNOK(Other)) {
I32 i;
- for(i = 0; i <= AvFILL((AV *) This); ++i) {
- SV * const * const svp = av_fetch((AV *)This, i, FALSE);
+ for(i = 0; i <= AvFILL(MUTABLE_AV(This)); ++i) {
+ SV * const * const svp = av_fetch(MUTABLE_AV(This), i, FALSE);
if (!svp)
continue;
RETPUSHNO;
}
else if (SvPOK(Other)) {
- const I32 this_len = av_len((AV *) This);
+ const I32 this_len = av_len(MUTABLE_AV(This));
I32 i;
for(i = 0; i <= this_len; ++i) {
- SV * const * const svp = av_fetch((AV *)This, i, FALSE);
+ SV * const * const svp = av_fetch(MUTABLE_AV(This), i, FALSE);
if (!svp)
continue;