#define LOAD_UTF8_CHARCLASS(a,b) STMT_START { if (!CAT2(PL_utf8_,a)) (void)CAT2(is_utf8_, a)((U8*)b); } STMT_END
+/* 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 \
+)
+
+#define NEAR_EXACT(rn) (PL_regkind[(U8)OP(rn)] == EXACT || JUMPABLE(rn))
+
+#define NEXT_IMPT(rn) STMT_START { \
+ while (JUMPABLE(rn)) \
+ if (OP(rn) == SUSPEND || OP(rn) == IFMATCH) \
+ rn = NEXTOPER(NEXTOPER(rn)); \
+ else rn += NEXT_OFF(rn); \
+} STMT_END
+
static void restore_pos(pTHX_ void *arg);
STATIC CHECKPOINT
if (ln && l == 0)
n = ln; /* don't backtrack */
locinput = PL_reginput;
- if (PL_regkind[(U8)OP(next)] == EXACT) {
- c1 = (U8)*STRING(next);
- if (OP(next) == EXACTF)
- c2 = PL_fold[c1];
- else if (OP(next) == EXACTFL)
- c2 = PL_fold_locale[c1];
- else
- c2 = c1;
+ if (NEAR_EXACT(next)) {
+ regnode *text_node = next;
+
+ if (PL_regkind[(U8)OP(next)] != EXACT)
+ NEXT_IMPT(text_node);
+
+ if (PL_regkind[(U8)OP(text_node)] != EXACT) {
+ c1 = c2 = -1000;
+ }
+ else {
+ c1 = (U8)*STRING(text_node);
+ if (OP(next) == EXACTF)
+ c2 = PL_fold[c1];
+ else if (OP(text_node) == EXACTFL)
+ c2 = PL_fold_locale[c1];
+ else
+ c2 = c1;
+ }
}
else
c1 = c2 = -1000;
(IV) n, (IV)l)
);
if (n >= ln) {
- if (PL_regkind[(U8)OP(next)] == EXACT) {
- c1 = (U8)*STRING(next);
- if (OP(next) == EXACTF)
- c2 = PL_fold[c1];
- else if (OP(next) == EXACTFL)
- c2 = PL_fold_locale[c1];
- else
- c2 = c1;
+ if (NEAR_EXACT(next)) {
+ regnode *text_node = next;
+
+ if (PL_regkind[(U8)OP(next)] != EXACT)
+ NEXT_IMPT(text_node);
+
+ if (PL_regkind[(U8)OP(text_node)] != EXACT) {
+ c1 = c2 = -1000;
+ }
+ else {
+ c1 = (U8)*STRING(text_node);
+ if (OP(text_node) == EXACTF)
+ c2 = PL_fold[c1];
+ else if (OP(text_node) == EXACTFL)
+ c2 = PL_fold_locale[c1];
+ else
+ c2 = c1;
+ }
}
else
c1 = c2 = -1000;
* Lookahead to avoid useless match attempts
* when we know what character comes next.
*/
- if (PL_regkind[(U8)OP(next)] == EXACT) {
- U8 *s = (U8*)STRING(next);
- if (!UTF) {
- c2 = c1 = *s;
- if (OP(next) == EXACTF)
- c2 = PL_fold[c1];
- else if (OP(next) == EXACTFL)
- c2 = PL_fold_locale[c1];
- }
- else { /* UTF */
- if (OP(next) == EXACTF) {
- c1 = to_utf8_lower(s);
- c2 = to_utf8_upper(s);
+
+ /*
+ * Used to only do .*x and .*?x, but now it allows
+ * for )'s, ('s and (?{ ... })'s to be in the way
+ * of the quantifier and the EXACT-like node. -- japhy
+ */
+
+ if (NEAR_EXACT(next)) {
+ U8 *s;
+ regnode *text_node = next;
+
+ if (PL_regkind[(U8)OP(next)] != EXACT)
+ NEXT_IMPT(text_node);
+
+ if (PL_regkind[(U8)OP(text_node)] != EXACT) {
+ c1 = c2 = -1000;
+ }
+ else {
+ s = (U8*)STRING(text_node);
+
+ if (!UTF) {
+ c2 = c1 = *s;
+ if (OP(text_node) == EXACTF)
+ c2 = PL_fold[c1];
+ else if (OP(text_node) == EXACTFL)
+ c2 = PL_fold_locale[c1];
}
- else {
- c2 = c1 = utf8_to_uvchr(s, NULL);
+ else { /* UTF */
+ if (OP(text_node) == EXACTF) {
+ c1 = to_utf8_lower(s);
+ c2 = to_utf8_upper(s);
+ }
+ else {
+ c2 = c1 = utf8_to_uvchr(s, NULL);
+ }
}
}
}
/* Find place 'next' could work */
if (!do_utf8) {
if (c1 == c2) {
- while (locinput <= e && *locinput != c1)
+ while (locinput <= e &&
+ UCHARAT(locinput) != c1)
locinput++;
} else {
while (locinput <= e
- && *locinput != c1
- && *locinput != c2)
+ && UCHARAT(locinput) != c1
+ && UCHARAT(locinput) != c2)
locinput++;
}
count = locinput - old;