/* for use after a quantifier and before an EXACT-like node -- japhy */
#define JUMPABLE(rn) ( \
OP(rn) == OPEN || OP(rn) == CLOSE || OP(rn) == EVAL || \
- OP(rn) == SUSPEND || OP(rn) == IFMATCH \
+ OP(rn) == SUSPEND || OP(rn) == IFMATCH || \
+ OP(rn) == PLUS || OP(rn) == MINMOD || \
+ (PL_regkind[(U8)OP(rn)] == CURLY && ARG1(rn) > 0) \
)
-#define NEAR_EXACT(rn) (PL_regkind[(U8)OP(rn)] == EXACT || JUMPABLE(rn))
+#define HAS_TEXT(rn) ( \
+ PL_regkind[(U8)OP(rn)] == EXACT || PL_regkind[(U8)OP(rn)] == REF \
+)
-#define NEXT_IMPT(rn) STMT_START { \
+#define FIND_NEXT_IMPT(rn) STMT_START { \
while (JUMPABLE(rn)) \
- if (OP(rn) == SUSPEND || OP(rn) == IFMATCH) \
+ if (OP(rn) == SUSPEND || OP(rn) == IFMATCH || \
+ PL_regkind[(U8)OP(rn)] == CURLY) \
rn = NEXTOPER(NEXTOPER(rn)); \
+ else if (OP(rn) == PLUS) \
+ rn = NEXTOPER(rn); \
else rn += NEXT_OFF(rn); \
} STMT_END
char *check_at = Nullch; /* check substr found at this pos */
#ifdef DEBUGGING
char *i_strpos = strpos;
- SV *dsv = sv_2mortal(newSVpvn("", 0));
+ SV *dsv = PERL_DEBUG_PAD_ZERO(0);
#endif
DEBUG_r({
- char *s = UTF ? sv_uni_display(dsv, sv, 60, 0) : strpos;
- STRLEN len = UTF ? strlen(s) : strend - strpos;
+ char*s = UTF ? sv_uni_display(dsv, sv, 60, 0) : strpos;
+ int len = UTF ? strlen(s) : strend - strpos;
if (!PL_colorset)
reginitcolors();
PerlIO_printf(Perl_debug_log,
PL_reg_flags |= RF_utf8;
if (prog->minlen > CHR_DIST((U8*)strend, (U8*)strpos)) {
- DEBUG_r(PerlIO_printf(Perl_debug_log, "String too short...\n"));
+ DEBUG_r(PerlIO_printf(Perl_debug_log,
+ "String too short... [re_intuit_start]\n"));
goto fail;
}
strbeg = (sv && SvPOK(sv)) ? strend - SvCUR(sv) : strpos;
if (do_utf8) {
STRLEN len;
+ /* The ibcmp_utf8() uses to_uni_fold() which is more
+ * correct folding for Unicode than using lowercase.
+ * However, it doesn't work quite fully since the folding
+ * is a one-to-many mapping and the regex optimizer is
+ * unaware of this, so it may throw out good matches.
+ * Fortunately, not getting this right is allowed
+ * for Unicode Regular Expression Support level 1,
+ * only one-to-one matching is required. --jhi */
if (c1 == c2)
while (s <= e) {
if ( utf8_to_uvchr((U8*)s, &len) == c1
- && regtry(prog, s) )
+ && (ln == 1 ||
+ ibcmp_utf8(s, do_utf8, m, UTF, ln)) )
goto got_it;
s += len;
}
else
while (s <= e) {
UV c = utf8_to_uvchr((U8*)s, &len);
- if ( (c == c1 || c == c2) && regtry(prog, s) )
+ if ( (c == c1 || c == c2)
+ && (ln == 1 ||
+ ibcmp_utf8(s, do_utf8, m, UTF, ln)) )
goto got_it;
s += len;
}
SV* oreplsv = GvSV(PL_replgv);
bool do_utf8 = DO_UTF8(sv);
#ifdef DEBUGGING
- SV *dsv = sv_2mortal(newSVpvn("", 0));
+ SV *dsv = PERL_DEBUG_PAD_ZERO(0);
#endif
PL_regcc = 0;
}
minlen = prog->minlen;
- if (do_utf8 && !(prog->reganch & ROPT_CANY_SEEN)) {
- if (utf8_distance((U8*)strend, (U8*)startpos) < minlen) goto phooey;
- }
- else {
- if (strend - startpos < minlen) goto phooey;
+ if (strend - startpos < minlen) {
+ DEBUG_r(PerlIO_printf(Perl_debug_log,
+ "String too short [regexec_flags]...\n"));
+ goto phooey;
}
/* Check validity of program. */
d.scream_olds = &scream_olds;
d.scream_pos = &scream_pos;
s = re_intuit_start(prog, sv, s, strend, flags, &d);
- if (!s)
+ if (!s) {
+ DEBUG_r(PerlIO_printf(Perl_debug_log, "Not present...\n"));
goto phooey; /* not present */
+ }
}
DEBUG_r({
- char *s = UTF ? sv_uni_display(dsv, sv, 60, 0) : startpos;
- STRLEN len = UTF ? strlen(s) : strend - startpos;
+ char *s = do_utf8 ? sv_uni_display(dsv, sv, 60, 0) : startpos;
+ int len = do_utf8 ? strlen(s) : strend - startpos;
if (!PL_colorset)
reginitcolors();
PerlIO_printf(Perl_debug_log,
New(22,PL_reg_start_tmp, PL_reg_start_tmpl, char*);
}
+#ifdef DEBUGGING
+ sv_setpvn(PERL_DEBUG_PAD(0), "", 0);
+ sv_setpvn(PERL_DEBUG_PAD(1), "", 0);
+ sv_setpvn(PERL_DEBUG_PAD(2), "", 0);
+#endif
+
/* XXXX What this code is doing here?!!! There should be no need
to do this again and again, PL_reglastparen should take care of
this! --ilya*/
#endif
register bool do_utf8 = PL_reg_match_utf8;
#ifdef DEBUGGING
- SV *dsv0 = sv_2mortal(newSVpvn("", 0));
- SV *dsv1 = sv_2mortal(newSVpvn("", 0));
- SV *dsv2 = sv_2mortal(newSVpvn("", 0));
+ SV *dsv0 = PERL_DEBUG_PAD_ZERO(0);
+ SV *dsv1 = PERL_DEBUG_PAD_ZERO(1);
+ SV *dsv2 = PERL_DEBUG_PAD_ZERO(2);
#endif
#ifdef DEBUGGING
? (5 + taill) - l : locinput - PL_bostr;
int pref0_len;
- while (UTF8_IS_CONTINUATION(*(U8*)(locinput - pref_len)))
+ while (do_utf8 && UTF8_IS_CONTINUATION(*(U8*)(locinput - pref_len)))
pref_len++;
pref0_len = pref_len - (locinput - PL_reg_starttry);
if (l + pref_len < (5 + taill) && l < PL_regeol - locinput)
l = ( PL_regeol - locinput > (5 + taill) - pref_len
? (5 + taill) - pref_len : PL_regeol - locinput);
- while (UTF8_IS_CONTINUATION(*(U8*)(locinput + l)))
+ while (do_utf8 && UTF8_IS_CONTINUATION(*(U8*)(locinput + l)))
l--;
if (pref0_len < 0)
pref0_len = 0;
regprop(prop, scan);
{
char *s0 =
- UTF ?
+ do_utf8 ?
pv_uni_display(dsv0, (U8*)(locinput - pref_len),
pref0_len, 60, 0) :
locinput - pref_len;
- STRLEN len0 = UTF ? strlen(s0) : pref0_len;
- char *s1 = UTF ?
+ int len0 = do_utf8 ? strlen(s0) : pref0_len;
+ char *s1 = do_utf8 ?
pv_uni_display(dsv1, (U8*)(locinput - pref_len + pref0_len),
pref_len - pref0_len, 60, 0) :
locinput - pref_len + pref0_len;
- STRLEN len1 = UTF ? strlen(s1) : pref_len - pref0_len;
- char *s2 = UTF ?
+ int len1 = do_utf8 ? strlen(s1) : pref_len - pref0_len;
+ char *s2 = do_utf8 ?
pv_uni_display(dsv2, (U8*)locinput,
PL_regeol - locinput, 60, 0) :
locinput;
- STRLEN len2 = UTF ? strlen(s2) : l;
+ int len2 = do_utf8 ? strlen(s2) : l;
PerlIO_printf(Perl_debug_log,
"%4"IVdf" <%s%.*s%s%s%.*s%s%s%s%.*s%s>%*s|%3"IVdf":%*s%s\n",
(IV)(locinput - PL_bostr),
s = STRING(scan);
ln = STR_LEN(scan);
if (do_utf8 != (UTF!=0)) {
+ /* The target and the pattern have differing "utf8ness". */
char *l = locinput;
char *e = s + ln;
STRLEN len;
- if (do_utf8)
+
+ if (do_utf8) {
+ /* The target is utf8, the pattern is not utf8. */
while (s < e) {
if (l >= PL_regeol)
- sayNO;
- if (*((U8*)s) != utf8_to_uvchr((U8*)l, &len))
- sayNO;
- s++;
+ sayNO;
+ if (NATIVE_TO_UNI(*(U8*)s) !=
+ utf8_to_uvchr((U8*)l, &len))
+ sayNO;
l += len;
+ s ++;
}
- else
+ }
+ else {
+ /* The target is not utf8, the pattern is utf8. */
while (s < e) {
if (l >= PL_regeol)
sayNO;
- if (*((U8*)l) != utf8_to_uvchr((U8*)s, &len))
+ if (NATIVE_TO_UNI(*((U8*)l)) !=
+ utf8_to_uvchr((U8*)s, &len))
sayNO;
s += len;
- l++;
+ l ++;
}
+ }
locinput = l;
nextchr = UCHARAT(locinput);
break;
}
+ /* The target and the pattern have the same "utf8ness". */
/* Inline the first character, for speed. */
if (UCHARAT(s) != nextchr)
sayNO;
if (l >= PL_regeol)
sayNO;
toLOWER_utf8((U8*)l, tmpbuf, &ulen);
- if (memNE(s, tmpbuf, ulen))
+ if (memNE(s, (char*)tmpbuf, ulen))
sayNO;
s += UTF8SKIP(s);
l += ulen;
sayNO;
toLOWER_utf8((U8*)s, tmpbuf1, &ulen1);
toLOWER_utf8((U8*)l, tmpbuf2, &ulen2);
- if (ulen1 != ulen2 || memNE(tmpbuf1, tmpbuf2, ulen1))
+ if (ulen1 != ulen2 || memNE((char *)tmpbuf1, (char *)tmpbuf2, ulen1))
sayNO;
s += ulen1;
l += ulen2;
if (ln && l == 0)
n = ln; /* don't backtrack */
locinput = PL_reginput;
- if (NEAR_EXACT(next)) {
+ if (HAS_TEXT(next) || JUMPABLE(next)) {
regnode *text_node = next;
- if (PL_regkind[(U8)OP(next)] != EXACT)
- NEXT_IMPT(text_node);
+ if (! HAS_TEXT(text_node)) FIND_NEXT_IMPT(text_node);
- if (PL_regkind[(U8)OP(text_node)] != EXACT) {
- c1 = c2 = -1000;
- }
+ if (! HAS_TEXT(text_node)) c1 = c2 = -1000;
else {
- c1 = (U8)*STRING(text_node);
- if (OP(next) == EXACTF)
+ 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 (
+ *PL_reglastparen < n ||
+ ln == -1 ||
+ ln == PL_regendp[n]
+ ) {
+ c1 = c2 = -1000;
+ goto assume_ok_MM;
+ }
+ c1 = *(PL_bostr + ln);
+ }
+ else { c1 = (U8)*STRING(text_node); }
+ if (OP(text_node) == EXACTF || OP(text_node) == REFF)
c2 = PL_fold[c1];
- else if (OP(text_node) == EXACTFL)
+ else if (OP(text_node) == EXACTFL || OP(text_node) == REFFL)
c2 = PL_fold_locale[c1];
else
c2 = c1;
}
else
c1 = c2 = -1000;
+ assume_ok_MM:
REGCP_SET(lastcp);
/* This may be improved if l == 0. */
while (n >= ln || (n == REG_INFTY && ln > 0 && l)) { /* ln overflow ? */
(IV) n, (IV)l)
);
if (n >= ln) {
- if (NEAR_EXACT(next)) {
+ if (HAS_TEXT(next) || JUMPABLE(next)) {
regnode *text_node = next;
- if (PL_regkind[(U8)OP(next)] != EXACT)
- NEXT_IMPT(text_node);
+ if (! HAS_TEXT(text_node)) FIND_NEXT_IMPT(text_node);
- if (PL_regkind[(U8)OP(text_node)] != EXACT) {
- c1 = c2 = -1000;
- }
+ if (! HAS_TEXT(text_node)) c1 = c2 = -1000;
else {
- c1 = (U8)*STRING(text_node);
- if (OP(text_node) == EXACTF)
+ 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 (
+ *PL_reglastparen < n ||
+ ln == -1 ||
+ ln == PL_regendp[n]
+ ) {
+ c1 = c2 = -1000;
+ goto assume_ok_REG;
+ }
+ c1 = *(PL_bostr + ln);
+ }
+ else { c1 = (U8)*STRING(text_node); }
+
+ if (OP(text_node) == EXACTF || OP(text_node) == REFF)
c2 = PL_fold[c1];
- else if (OP(text_node) == EXACTFL)
+ else if (OP(text_node) == EXACTFL || OP(text_node) == REFFL)
c2 = PL_fold_locale[c1];
else
c2 = c1;
else
c1 = c2 = -1000;
}
+ assume_ok_REG:
REGCP_SET(lastcp);
while (n >= ln) {
/* If it could work, try it. */
* of the quantifier and the EXACT-like node. -- japhy
*/
- if (NEAR_EXACT(next)) {
+ if (HAS_TEXT(next) || JUMPABLE(next)) {
U8 *s;
regnode *text_node = next;
- if (PL_regkind[(U8)OP(next)] != EXACT)
- NEXT_IMPT(text_node);
+ if (! HAS_TEXT(text_node)) FIND_NEXT_IMPT(text_node);
- if (PL_regkind[(U8)OP(text_node)] != EXACT) {
- c1 = c2 = -1000;
- }
+ if (! HAS_TEXT(text_node)) c1 = c2 = -1000;
else {
- s = (U8*)STRING(text_node);
+ 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 (
+ *PL_reglastparen < n ||
+ ln == -1 ||
+ ln == PL_regendp[n]
+ ) {
+ c1 = c2 = -1000;
+ goto assume_ok_easy;
+ }
+ s = (U8*)PL_bostr + ln;
+ }
+ else { s = (U8*)STRING(text_node); }
if (!UTF) {
c2 = c1 = *s;
- if (OP(text_node) == EXACTF)
+ if (OP(text_node) == EXACTF || OP(text_node) == REFF)
c2 = PL_fold[c1];
- else if (OP(text_node) == EXACTFL)
+ else if (OP(text_node) == EXACTFL || OP(text_node) == REFFL)
c2 = PL_fold_locale[c1];
}
else { /* UTF */
- if (OP(text_node) == EXACTF) {
+ if (OP(text_node) == EXACTF || OP(text_node) == REFF) {
STRLEN ulen1, ulen2;
U8 tmpbuf1[UTF8_MAXLEN*2+1];
U8 tmpbuf2[UTF8_MAXLEN*2+1];
}
else
c1 = c2 = -1000;
+ assume_ok_easy:
PL_reginput = locinput;
if (minmod) {
CHECKPOINT lastcp;