*
**** 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.
#define RF_warned 2 /* warned about big count? */
#define RF_evaled 4 /* Did an EVAL with setting? */
#define RF_utf8 8 /* String contains multibyte chars? */
+#define RF_false 16 /* odd number of nested negatives */
#define UTF ((PL_reg_flags & RF_utf8) != 0)
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]);
goto fail_finish;
/* we may be pointing at the wrong string */
if (s && RX_MATCH_COPIED(prog))
- s = prog->subbeg + (s - SvPVX(sv));
+ 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) {
I32 doevery = (prog->reganch & ROPT_SKIP) == 0;
char *m;
STRLEN ln;
+ STRLEN lnc;
unsigned int c1;
unsigned int c2;
char *e;
}
break;
case EXACTF:
- m = STRING(c);
- ln = STR_LEN(c);
+ m = STRING(c);
+ ln = STR_LEN(c); /* length to match in octets/bytes */
+ lnc = (I32) ln; /* length to match in characters */
if (UTF) {
STRLEN ulen1, ulen2;
+ U8 *sm = (U8 *) m;
U8 tmpbuf1[UTF8_MAXLEN_UCLC+1];
U8 tmpbuf2[UTF8_MAXLEN_UCLC+1];
0, ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
c2 = utf8n_to_uvchr(tmpbuf2, UTF8_MAXLEN_UCLC,
0, ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
+ lnc = 0;
+ while (sm < ((U8 *) m + ln)) {
+ lnc++;
+ sm += UTF8SKIP(sm);
+ }
}
else {
c1 = *(U8*)m;
}
goto do_exactf;
case EXACTFL:
- m = STRING(c);
- ln = STR_LEN(c);
+ m = STRING(c);
+ ln = STR_LEN(c);
+ lnc = (I32) ln;
c1 = *(U8*)m;
c2 = PL_fold_locale[c1];
do_exactf:
- e = HOP3c(strend, -(I32)ln, s);
+ e = HOP3c(strend, -((I32)lnc), s);
if (norun && e < s)
e = s; /* Due to minlen logic of intuit() */
STRLEN len, foldlen;
if (c1 == c2) {
+ /* Upper and lower of 1st char are equal -
+ * probably not a "letter". */
while (s <= e) {
c = utf8n_to_uvchr((U8*)s, UTF8_MAXLEN, &len,
ckWARN(WARN_UTF8) ?
PL_multiline ? FBMrf_MULTILINE : 0))) ) {
/* we may be pointing at the wrong string */
if ((flags & REXEC_SCREAM) && RX_MATCH_COPIED(prog))
- s = prog->subbeg + (s - SvPVX(sv));
+ s = strbeg + (s - SvPVX(sv));
DEBUG_r( did_match = 1 );
if (HOPc(s, -back_max) > last1) {
last1 = HOPc(s, -back_min);
last = scream_olds; /* Only one occurrence. */
/* we may be pointing at the wrong string */
else if (RX_MATCH_COPIED(prog))
- s = prog->subbeg + (s - SvPVX(sv));
+ 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;
if (PL_reg_sv) {
/* Make $_ available to executed code. */
if (PL_reg_sv != DEFSV) {
- /* SAVE_DEFSV does *not* suffice here for USE_5005THREADS */
- SAVESPTR(DEFSV);
+ SAVE_DEFSV;
DEFSV = PL_reg_sv;
}
$` 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:
"%*s already tried at this position...\n",
REPORT_CODE_OFF+PL_regindent*2, "")
);
- sayNO_SILENT;
+ if (PL_reg_flags & RF_false)
+ sayYES;
+ else
+ sayNO_SILENT;
}
PL_reg_poscache[o] |= (1<<b);
}
if (! HAS_TEXT(text_node)) c1 = c2 = -1000;
else {
if (PL_regkind[(U8)OP(text_node)] == REF) {
- I32 n, ln;
- n = ARG(text_node); /* which paren pair */
- ln = PL_regstartp[n];
- /* assume yes if we haven't seen CLOSEn */
- if (
- (I32)*PL_reglastparen < n ||
- ln == -1 ||
- ln == PL_regendp[n]
- ) {
- c1 = c2 = -1000;
- goto assume_ok_MM;
- }
- c1 = *(PL_bostr + ln);
+ c1 = c2 = -1000;
+ goto assume_ok_MM;
}
else { c1 = (U8)*STRING(text_node); }
if (OP(text_node) == EXACTF || OP(text_node) == REFF)
if (! HAS_TEXT(text_node)) c1 = c2 = -1000;
else {
if (PL_regkind[(U8)OP(text_node)] == REF) {
- I32 n, ln;
- n = ARG(text_node); /* which paren pair */
- ln = PL_regstartp[n];
- /* assume yes if we haven't seen CLOSEn */
- if (
- (I32)*PL_reglastparen < n ||
- ln == -1 ||
- ln == PL_regendp[n]
- ) {
- c1 = c2 = -1000;
- goto assume_ok_REG;
- }
- c1 = *(PL_bostr + ln);
+ c1 = c2 = -1000;
+ goto assume_ok_REG;
}
else { c1 = (U8)*STRING(text_node); }
if (! HAS_TEXT(text_node)) c1 = c2 = -1000;
else {
if (PL_regkind[(U8)OP(text_node)] == REF) {
- I32 n, ln;
- n = ARG(text_node); /* which paren pair */
- ln = PL_regstartp[n];
- /* assume yes if we haven't seen CLOSEn */
- if (
- (I32)*PL_reglastparen < n ||
- ln == -1 ||
- ln == PL_regendp[n]
- ) {
- c1 = c2 = -1000;
- goto assume_ok_easy;
- }
- s = (U8*)PL_bostr + ln;
+ c1 = c2 = -1000;
+ goto assume_ok_easy;
}
else { s = (U8*)STRING(text_node); }
}
else
PL_reginput = locinput;
+ PL_reg_flags ^= RF_false;
goto do_ifmatch;
case IFMATCH:
n = 1;
do_ifmatch:
inner = NEXTOPER(NEXTOPER(scan));
if (regmatch(inner) != n) {
+ if (n == 0)
+ PL_reg_flags ^= RF_false;
say_no:
if (logical) {
logical = 0;
else
sayNO;
}
+ if (n == 0)
+ PL_reg_flags ^= RF_false;
say_yes:
if (logical) {
logical = 0;
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;