*
**** Alterations to Henry's code are...
****
- **** Copyright (c) 1991-2002, Larry Wall
+ **** Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ **** 2000, 2001, 2002, 2003, 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.
Perl_croak(aTHX_ "panic: paren_elems_to_push < 0");
#define REGCP_OTHER_ELEMS 6
- SSCHECK(paren_elems_to_push + REGCP_OTHER_ELEMS);
+ SSGROW(paren_elems_to_push + REGCP_OTHER_ELEMS);
for (p = PL_regsize; p > parenfloor; p--) {
/* REGCP_PARENS_ELEMS are pushed per pairs of parentheses. */
SSPUSHINT(PL_regendp[p]);
char *i_strpos = strpos;
SV *dsv = PERL_DEBUG_PAD_ZERO(0);
#endif
+ RX_MATCH_UTF8_set(prog,do_utf8);
if (prog->reganch & ROPT_UTF8) {
DEBUG_r(PerlIO_printf(Perl_debug_log,
start_shift + (s - strbeg), end_shift, pp, 0);
else
goto fail_finish;
+ /* we may be pointing at the wrong string */
+ if (s && RX_MATCH_COPIED(prog))
+ s = strbeg + (s - SvPVX(sv));
if (data)
*data->scream_olds = s;
}
char *startpos = strbeg;
t = s;
- if (prog->reganch & ROPT_UTF8) {
- PL_regdata = prog->data;
- PL_bostr = startpos;
- }
+ cache_re(prog);
s = find_byclass(prog, prog->regstclass, s, endpos, startpos, 1);
if (!s) {
#ifdef DEBUGGING
SV *dsv0 = PERL_DEBUG_PAD_ZERO(0);
SV *dsv1 = PERL_DEBUG_PAD_ZERO(1);
#endif
+ RX_MATCH_UTF8_set(prog,do_utf8);
PL_regcc = 0;
: (s = fbm_instr((unsigned char*)HOP3(s, back_min, strend),
(unsigned char*)strend, must,
PL_multiline ? FBMrf_MULTILINE : 0))) ) {
+ /* we may be pointing at the wrong string */
+ if ((flags & REXEC_SCREAM) && RX_MATCH_COPIED(prog))
+ s = strbeg + (s - SvPVX(sv));
DEBUG_r( did_match = 1 );
if (HOPc(s, -back_max) > last1) {
last1 = HOPc(s, -back_min);
end_shift, &scream_pos, 1); /* last one */
if (!last)
last = scream_olds; /* Only one occurrence. */
+ /* we may be pointing at the wrong string */
+ else if (RX_MATCH_COPIED(prog))
+ s = strbeg + (s - SvPVX(sv));
}
else {
STRLEN len;
/* make sure $`, $&, $', and $digit will work later */
if ( !(flags & REXEC_NOT_FIRST) ) {
- if (RX_MATCH_COPIED(prog)) {
- Safefree(prog->subbeg);
- RX_MATCH_COPIED_off(prog);
- }
+ RX_MATCH_COPY_FREE(prog);
if (flags & REXEC_COPY_STR) {
I32 i = PL_regeol - startpos + (stringarg - strbeg);
-
- s = savepvn(strbeg, i);
- prog->subbeg = s;
+#ifdef PERL_COPY_ON_WRITE
+ if ((SvIsCOW(sv)
+ || (SvFLAGS(sv) & CAN_COW_MASK) == CAN_COW_FLAGS)) {
+ if (DEBUG_C_TEST) {
+ PerlIO_printf(Perl_debug_log,
+ "Copy on write: regexp capture, type %d\n",
+ (int) SvTYPE(sv));
+ }
+ prog->saved_copy = sv_setsv_cow(prog->saved_copy, sv);
+ prog->subbeg = SvPVX(prog->saved_copy);
+ assert (SvPOKp(prog->saved_copy));
+ } else
+#endif
+ {
+ RX_MATCH_COPIED_on(prog);
+ s = savepvn(strbeg, i);
+ prog->subbeg = s;
+ }
prog->sublen = i;
- RX_MATCH_COPIED_on(prog);
}
else {
prog->subbeg = strbeg;
$` inside (?{}) could fail... */
PL_reg_oldsaved = prog->subbeg;
PL_reg_oldsavedlen = prog->sublen;
+#ifdef PERL_COPY_ON_WRITE
+ PL_nrs = prog->saved_copy;
+#endif
RX_MATCH_COPIED_off(prog);
}
else
COP *ocurcop = PL_curcop;
PAD *old_comppad;
SV *ret;
+ struct regexp *oreg = PL_reg_re;
n = ARG(scan);
PL_op = (OP_4tree*)PL_regdata->data[n];
re_cc_state state;
CHECKPOINT cp, lastcp;
int toggleutf;
+ register SV *sv;
- if(SvROK(ret) || SvRMAGICAL(ret)) {
- SV *sv = SvROK(ret) ? SvRV(ret) : ret;
-
- if(SvMAGICAL(sv))
- mg = mg_find(sv, PERL_MAGIC_qr);
+ if(SvROK(ret) && SvSMAGICAL(sv = SvRV(ret)))
+ mg = mg_find(sv, PERL_MAGIC_qr);
+ else if (SvSMAGICAL(ret)) {
+ if (SvGMAGICAL(ret))
+ sv_unmagic(ret, PERL_MAGIC_qr);
+ else
+ mg = mg_find(ret, PERL_MAGIC_qr);
}
+
if (mg) {
re = (regexp *)mg->mg_obj;
(void)ReREFCNT_inc(re);
if (DO_UTF8(ret)) pm.op_pmdynflags |= PMdf_DYN_UTF8;
re = CALLREGCOMP(aTHX_ t, t + len, &pm);
if (!(SvFLAGS(ret)
- & (SVs_TEMP | SVs_PADTMP | SVf_READONLY)))
+ & (SVs_TEMP | SVs_PADTMP | SVf_READONLY
+ | SVs_GMG)))
sv_magic(ret,(SV*)ReREFCNT_inc(re),
PERL_MAGIC_qr,0,0);
PL_regprecomp = oprecomp;
sw = SvTRUE(ret);
logical = 0;
}
- else
+ else {
sv_setsv(save_scalar(PL_replgv), ret);
+ cache_re(oreg);
+ }
break;
}
case OPEN:
case ANYOF:
if (do_utf8) {
loceol = PL_regeol;
- while (hardcount < max && scan < loceol) {
- bool cont = FALSE;
- if (ANYOF_FLAGS(p) & ANYOF_UNICODE) {
- if (reginclass(p, (U8*)scan, 0, do_utf8))
- cont = TRUE;
- }
- else {
- U8 c = (U8)scan[0];
-
- if (UTF8_IS_INVARIANT(c)) {
- if (ANYOF_BITMAP_TEST(p, c))
- cont = TRUE;
- }
- else {
- if (reginclass(p, (U8*)scan, 0, do_utf8))
- cont = TRUE;
- }
- }
- if (!cont)
- break;
+ while (hardcount < max && scan < loceol &&
+ reginclass(p, (U8*)scan, 0, do_utf8)) {
scan += UTF8SKIP(scan);
hardcount++;
}
if (PL_reg_oldsaved) {
PL_reg_re->subbeg = PL_reg_oldsaved;
PL_reg_re->sublen = PL_reg_oldsavedlen;
+#ifdef PERL_COPY_ON_WRITE
+ PL_reg_re->saved_copy = PL_nrs;
+#endif
RX_MATCH_COPIED_on(PL_reg_re);
}
PL_reg_magic->mg_len = PL_reg_oldpos;