- case EXACT: {
- char *s = STRING(scan);
- ln = STR_LEN(scan);
- if (do_utf8 != UTF) {
- /* The target and the pattern have differing utf8ness. */
- char *l = locinput;
- const char * const e = s + ln;
-
- if (do_utf8) {
- /* The target is utf8, the pattern is not utf8. */
- while (s < e) {
- STRLEN ulen;
- if (l >= PL_regeol)
- sayNO;
- if (NATIVE_TO_UNI(*(U8*)s) !=
- utf8n_to_uvuni((U8*)l, UTF8_MAXBYTES, &ulen,
- uniflags))
- sayNO;
- l += ulen;
- s ++;
- }
- }
- else {
- /* The target is not utf8, the pattern is utf8. */
- while (s < e) {
- STRLEN ulen;
- if (l >= PL_regeol)
- sayNO;
- if (NATIVE_TO_UNI(*((U8*)l)) !=
- utf8n_to_uvuni((U8*)s, UTF8_MAXBYTES, &ulen,
- uniflags))
- sayNO;
- s += ulen;
- 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 (PL_regeol - locinput < ln)
- sayNO;
- if (ln > 1 && memNE(s, locinput, ln))
- sayNO;
- locinput += ln;
- nextchr = UCHARAT(locinput);
- break;
- }
- case EXACTFL:
- PL_reg_flags |= RF_tainted;
- /* FALL THROUGH */
- case EXACTF: {
- char * const s = STRING(scan);
- ln = STR_LEN(scan);
-
- if (do_utf8 || UTF) {
- /* Either target or the pattern are utf8. */
- const char * const l = locinput;
- char *e = PL_regeol;
-
- if (ibcmp_utf8(s, 0, ln, (bool)UTF,
- l, &e, 0, do_utf8)) {
- /* One more case for the sharp s:
- * pack("U0U*", 0xDF) =~ /ss/i,
- * the 0xC3 0x9F are the UTF-8
- * byte sequence for the U+00DF. */
-
- if (!(do_utf8 &&
- toLOWER(s[0]) == 's' &&
- ln >= 2 &&
- toLOWER(s[1]) == 's' &&
- (U8)l[0] == 0xC3 &&
- e - l >= 2 &&
- (U8)l[1] == 0x9F))
- sayNO;
- }
- locinput = e;
- nextchr = UCHARAT(locinput);
- break;
- }
-
- /* Neither the target and the pattern are utf8. */
-
- /* Inline the first character, for speed. */
- if (UCHARAT(s) != nextchr &&
- UCHARAT(s) != ((OP(scan) == EXACTF)
- ? PL_fold : PL_fold_locale)[nextchr])
- sayNO;
- if (PL_regeol - locinput < ln)
- sayNO;
- if (ln > 1 && (OP(scan) == EXACTF
- ? ibcmp(s, locinput, ln)
- : ibcmp_locale(s, locinput, ln)))
- sayNO;
- locinput += ln;
- nextchr = UCHARAT(locinput);
- break;
- }
- case ANYOF:
- if (do_utf8) {
- STRLEN inclasslen = PL_regeol - locinput;
-
- if (!reginclass(rex, scan, (U8*)locinput, &inclasslen, do_utf8))
- goto anyof_fail;
- if (locinput >= PL_regeol)
- sayNO;
- locinput += inclasslen ? inclasslen : UTF8SKIP(locinput);
- nextchr = UCHARAT(locinput);
- break;
- }
- else {
- if (nextchr < 0)
- nextchr = UCHARAT(locinput);
- if (!REGINCLASS(rex, scan, (U8*)locinput))
- goto anyof_fail;
- if (!nextchr && locinput >= PL_regeol)
- sayNO;
- nextchr = UCHARAT(++locinput);
- break;
- }
- anyof_fail:
- /* If we might have the case of the German sharp s
- * in a casefolding Unicode character class. */
-
- if (ANYOF_FOLD_SHARP_S(scan, locinput, PL_regeol)) {
- locinput += SHARP_S_SKIP;
- nextchr = UCHARAT(locinput);
- }
- else
- sayNO;
- break;
- case ALNUML:
- PL_reg_flags |= RF_tainted;
- /* FALL THROUGH */
- case ALNUM:
- if (!nextchr)
- sayNO;
- if (do_utf8) {
- LOAD_UTF8_CHARCLASS_ALNUM();
- if (!(OP(scan) == ALNUM
- ? (bool)swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8)
- : isALNUM_LC_utf8((U8*)locinput)))
- {
- sayNO;
- }
- locinput += PL_utf8skip[nextchr];
- nextchr = UCHARAT(locinput);
- break;
- }
- if (!(OP(scan) == ALNUM
- ? isALNUM(nextchr) : isALNUM_LC(nextchr)))
- sayNO;
- nextchr = UCHARAT(++locinput);
- break;
- case NALNUML:
- PL_reg_flags |= RF_tainted;
- /* FALL THROUGH */
- case NALNUM:
- if (!nextchr && locinput >= PL_regeol)
- sayNO;
- if (do_utf8) {
- LOAD_UTF8_CHARCLASS_ALNUM();
- if (OP(scan) == NALNUM
- ? (bool)swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8)
- : isALNUM_LC_utf8((U8*)locinput))
- {
- sayNO;
- }
- locinput += PL_utf8skip[nextchr];
- nextchr = UCHARAT(locinput);
- break;
- }
- if (OP(scan) == NALNUM
- ? isALNUM(nextchr) : isALNUM_LC(nextchr))
- sayNO;
- nextchr = UCHARAT(++locinput);
- break;
- case BOUNDL:
- case NBOUNDL:
- PL_reg_flags |= RF_tainted;
- /* FALL THROUGH */
- case BOUND:
- case NBOUND:
- /* was last char in word? */
- if (do_utf8) {
- if (locinput == PL_bostr)
- ln = '\n';
- else {
- const U8 * const r = reghop3((U8*)locinput, -1, (U8*)PL_bostr);
-
- ln = utf8n_to_uvchr(r, UTF8SKIP(r), 0, uniflags);
- }
- if (OP(scan) == BOUND || OP(scan) == NBOUND) {
- ln = isALNUM_uni(ln);
- LOAD_UTF8_CHARCLASS_ALNUM();
- n = swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8);
- }
- else {
- ln = isALNUM_LC_uvchr(UNI_TO_NATIVE(ln));
- n = isALNUM_LC_utf8((U8*)locinput);
- }
- }
- else {
- ln = (locinput != PL_bostr) ?
- UCHARAT(locinput - 1) : '\n';
- if (OP(scan) == BOUND || OP(scan) == NBOUND) {
- ln = isALNUM(ln);
- n = isALNUM(nextchr);
- }
- else {
- ln = isALNUM_LC(ln);
- n = isALNUM_LC(nextchr);
- }
- }
- if (((!ln) == (!n)) == (OP(scan) == BOUND ||
- OP(scan) == BOUNDL))
- sayNO;
- break;
- case SPACEL:
- PL_reg_flags |= RF_tainted;
- /* FALL THROUGH */
- case SPACE:
- if (!nextchr)
- sayNO;
- if (do_utf8) {
- if (UTF8_IS_CONTINUED(nextchr)) {
- LOAD_UTF8_CHARCLASS_SPACE();
- if (!(OP(scan) == SPACE
- ? (bool)swash_fetch(PL_utf8_space, (U8*)locinput, do_utf8)
- : isSPACE_LC_utf8((U8*)locinput)))
- {
- sayNO;
- }
- locinput += PL_utf8skip[nextchr];
- nextchr = UCHARAT(locinput);
- break;
- }
- if (!(OP(scan) == SPACE
- ? isSPACE(nextchr) : isSPACE_LC(nextchr)))
- sayNO;
- nextchr = UCHARAT(++locinput);
- }
- else {
- if (!(OP(scan) == SPACE
- ? isSPACE(nextchr) : isSPACE_LC(nextchr)))
- sayNO;
- nextchr = UCHARAT(++locinput);
- }
- break;
- case NSPACEL:
- PL_reg_flags |= RF_tainted;
- /* FALL THROUGH */
- case NSPACE:
- if (!nextchr && locinput >= PL_regeol)
- sayNO;
- if (do_utf8) {
- LOAD_UTF8_CHARCLASS_SPACE();
- if (OP(scan) == NSPACE
- ? (bool)swash_fetch(PL_utf8_space, (U8*)locinput, do_utf8)
- : isSPACE_LC_utf8((U8*)locinput))
- {
- sayNO;
- }
- locinput += PL_utf8skip[nextchr];
- nextchr = UCHARAT(locinput);
- break;
- }
- if (OP(scan) == NSPACE
- ? isSPACE(nextchr) : isSPACE_LC(nextchr))
- sayNO;
- nextchr = UCHARAT(++locinput);
- break;
- case DIGITL:
- PL_reg_flags |= RF_tainted;
- /* FALL THROUGH */
- case DIGIT:
- if (!nextchr)
- sayNO;
- if (do_utf8) {
- LOAD_UTF8_CHARCLASS_DIGIT();
- if (!(OP(scan) == DIGIT
- ? (bool)swash_fetch(PL_utf8_digit, (U8*)locinput, do_utf8)
- : isDIGIT_LC_utf8((U8*)locinput)))
- {
- sayNO;
- }
- locinput += PL_utf8skip[nextchr];
- nextchr = UCHARAT(locinput);
- break;
- }
- if (!(OP(scan) == DIGIT
- ? isDIGIT(nextchr) : isDIGIT_LC(nextchr)))
- sayNO;
- nextchr = UCHARAT(++locinput);
- break;
- case NDIGITL:
- PL_reg_flags |= RF_tainted;
- /* FALL THROUGH */
- case NDIGIT:
- if (!nextchr && locinput >= PL_regeol)
- sayNO;
- if (do_utf8) {
- LOAD_UTF8_CHARCLASS_DIGIT();
- if (OP(scan) == NDIGIT
- ? (bool)swash_fetch(PL_utf8_digit, (U8*)locinput, do_utf8)
- : isDIGIT_LC_utf8((U8*)locinput))
- {
- sayNO;
- }
- locinput += PL_utf8skip[nextchr];
- nextchr = UCHARAT(locinput);
- break;
- }
- if (OP(scan) == NDIGIT
- ? isDIGIT(nextchr) : isDIGIT_LC(nextchr))
- sayNO;
- nextchr = UCHARAT(++locinput);
- break;
- case CLUMP:
- if (locinput >= PL_regeol)
- sayNO;
- if (do_utf8) {
- LOAD_UTF8_CHARCLASS_MARK();
- if (swash_fetch(PL_utf8_mark,(U8*)locinput, do_utf8))
- sayNO;
- locinput += PL_utf8skip[nextchr];
- while (locinput < PL_regeol &&
- swash_fetch(PL_utf8_mark,(U8*)locinput, do_utf8))
- locinput += UTF8SKIP(locinput);
- if (locinput > PL_regeol)
- sayNO;
- }
- else
- locinput++;
- nextchr = UCHARAT(locinput);
- break;
-
- case NREFFL:
- {
- char *s;
- char type;
- PL_reg_flags |= RF_tainted;
- /* FALL THROUGH */
- case NREF:
- case NREFF:
- type = OP(scan);
- n = reg_check_named_buff_matched(rex,scan);
-
- if ( n ) {
- type = REF + ( type - NREF );
- goto do_ref;
- } else {
- sayNO;
- }
- /* unreached */
- case REFFL:
- PL_reg_flags |= RF_tainted;
- /* FALL THROUGH */
- case REF:
- case REFF:
- n = ARG(scan); /* which paren pair */
- type = OP(scan);
- do_ref:
- ln = PL_regoffs[n].start;
- PL_reg_leftiter = PL_reg_maxiter; /* Void cache */
- if (*PL_reglastparen < n || ln == -1)
- sayNO; /* Do not match unless seen CLOSEn. */
- if (ln == PL_regoffs[n].end)
- break;
-
- s = PL_bostr + ln;
- if (do_utf8 && type != REF) { /* REF can do byte comparison */
- char *l = locinput;
- const char *e = PL_bostr + PL_regoffs[n].end;
- /*
- * Note that we can't do the "other character" lookup trick as
- * in the 8-bit case (no pun intended) because in Unicode we
- * have to map both upper and title case to lower case.
- */
- if (type == REFF) {
- while (s < e) {
- STRLEN ulen1, ulen2;
- U8 tmpbuf1[UTF8_MAXBYTES_CASE+1];
- U8 tmpbuf2[UTF8_MAXBYTES_CASE+1];
-
- if (l >= PL_regeol)
- sayNO;
- toLOWER_utf8((U8*)s, tmpbuf1, &ulen1);
- toLOWER_utf8((U8*)l, tmpbuf2, &ulen2);
- if (ulen1 != ulen2 || memNE((char *)tmpbuf1, (char *)tmpbuf2, ulen1))
- sayNO;
- s += ulen1;
- l += ulen2;
- }
- }
- locinput = l;
- nextchr = UCHARAT(locinput);
- break;
- }
-
- /* Inline the first character, for speed. */
- if (UCHARAT(s) != nextchr &&
- (type == REF ||
- (UCHARAT(s) != (type == REFF
- ? PL_fold : PL_fold_locale)[nextchr])))
- sayNO;
- ln = PL_regoffs[n].end - ln;
- if (locinput + ln > PL_regeol)
- sayNO;
- if (ln > 1 && (type == REF
- ? memNE(s, locinput, ln)
- : (type == REFF
- ? ibcmp(s, locinput, ln)
- : ibcmp_locale(s, locinput, ln))))
- sayNO;
- locinput += ln;
- nextchr = UCHARAT(locinput);
- break;
- }
- case NOTHING:
- case TAIL:
- break;
- case BACK:
- break;
+ case EXACT: {
+ char *s = STRING(scan);
+ ln = STR_LEN(scan);
+ if (do_utf8 != UTF) {
+ /* The target and the pattern have differing utf8ness. */
+ char *l = locinput;
+ const char * const e = s + ln;
+
+ if (do_utf8) {
+ /* The target is utf8, the pattern is not utf8. */
+ while (s < e) {
+ STRLEN ulen;
+ if (l >= PL_regeol)
+ sayNO;
+ if (NATIVE_TO_UNI(*(U8*)s) !=
+ utf8n_to_uvuni((U8*)l, UTF8_MAXBYTES, &ulen,
+ uniflags))
+ sayNO;
+ l += ulen;
+ s ++;
+ }
+ }
+ else {
+ /* The target is not utf8, the pattern is utf8. */
+ while (s < e) {
+ STRLEN ulen;
+ if (l >= PL_regeol)
+ sayNO;
+ if (NATIVE_TO_UNI(*((U8*)l)) !=
+ utf8n_to_uvuni((U8*)s, UTF8_MAXBYTES, &ulen,
+ uniflags))
+ sayNO;
+ s += ulen;
+ 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 (PL_regeol - locinput < ln)
+ sayNO;
+ if (ln > 1 && memNE(s, locinput, ln))
+ sayNO;
+ locinput += ln;
+ nextchr = UCHARAT(locinput);
+ break;
+ }
+ case EXACTFL:
+ PL_reg_flags |= RF_tainted;
+ /* FALL THROUGH */
+ case EXACTF: {
+ char * const s = STRING(scan);
+ ln = STR_LEN(scan);
+
+ if (do_utf8 || UTF) {
+ /* Either target or the pattern are utf8. */
+ const char * const l = locinput;
+ char *e = PL_regeol;
+
+ if (ibcmp_utf8(s, 0, ln, (bool)UTF,
+ l, &e, 0, do_utf8)) {
+ /* One more case for the sharp s:
+ * pack("U0U*", 0xDF) =~ /ss/i,
+ * the 0xC3 0x9F are the UTF-8
+ * byte sequence for the U+00DF. */
+
+ if (!(do_utf8 &&
+ toLOWER(s[0]) == 's' &&
+ ln >= 2 &&
+ toLOWER(s[1]) == 's' &&
+ (U8)l[0] == 0xC3 &&
+ e - l >= 2 &&
+ (U8)l[1] == 0x9F))
+ sayNO;
+ }
+ locinput = e;
+ nextchr = UCHARAT(locinput);
+ break;
+ }
+
+ /* Neither the target and the pattern are utf8. */
+
+ /* Inline the first character, for speed. */
+ if (UCHARAT(s) != nextchr &&
+ UCHARAT(s) != ((OP(scan) == EXACTF)
+ ? PL_fold : PL_fold_locale)[nextchr])
+ sayNO;
+ if (PL_regeol - locinput < ln)
+ sayNO;
+ if (ln > 1 && (OP(scan) == EXACTF
+ ? ibcmp(s, locinput, ln)
+ : ibcmp_locale(s, locinput, ln)))
+ sayNO;
+ locinput += ln;
+ nextchr = UCHARAT(locinput);
+ break;
+ }
+ case ANYOF:
+ if (do_utf8) {
+ STRLEN inclasslen = PL_regeol - locinput;
+
+ if (!reginclass(rex, scan, (U8*)locinput, &inclasslen, do_utf8))
+ goto anyof_fail;
+ if (locinput >= PL_regeol)
+ sayNO;
+ locinput += inclasslen ? inclasslen : UTF8SKIP(locinput);
+ nextchr = UCHARAT(locinput);
+ break;
+ }
+ else {
+ if (nextchr < 0)
+ nextchr = UCHARAT(locinput);
+ if (!REGINCLASS(rex, scan, (U8*)locinput))
+ goto anyof_fail;
+ if (!nextchr && locinput >= PL_regeol)
+ sayNO;
+ nextchr = UCHARAT(++locinput);
+ break;
+ }
+ anyof_fail:
+ /* If we might have the case of the German sharp s
+ * in a casefolding Unicode character class. */
+
+ if (ANYOF_FOLD_SHARP_S(scan, locinput, PL_regeol)) {
+ locinput += SHARP_S_SKIP;
+ nextchr = UCHARAT(locinput);
+ }
+ else
+ sayNO;
+ break;
+ case ALNUML:
+ PL_reg_flags |= RF_tainted;
+ /* FALL THROUGH */
+ case ALNUM:
+ if (!nextchr)
+ sayNO;
+ if (do_utf8) {
+ LOAD_UTF8_CHARCLASS_ALNUM();
+ if (!(OP(scan) == ALNUM
+ ? (bool)swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8)
+ : isALNUM_LC_utf8((U8*)locinput)))
+ {
+ sayNO;
+ }
+ locinput += PL_utf8skip[nextchr];
+ nextchr = UCHARAT(locinput);
+ break;
+ }
+ if (!(OP(scan) == ALNUM
+ ? isALNUM(nextchr) : isALNUM_LC(nextchr)))
+ sayNO;
+ nextchr = UCHARAT(++locinput);
+ break;
+ case NALNUML:
+ PL_reg_flags |= RF_tainted;
+ /* FALL THROUGH */
+ case NALNUM:
+ if (!nextchr && locinput >= PL_regeol)
+ sayNO;
+ if (do_utf8) {
+ LOAD_UTF8_CHARCLASS_ALNUM();
+ if (OP(scan) == NALNUM
+ ? (bool)swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8)
+ : isALNUM_LC_utf8((U8*)locinput))
+ {
+ sayNO;
+ }
+ locinput += PL_utf8skip[nextchr];
+ nextchr = UCHARAT(locinput);
+ break;
+ }
+ if (OP(scan) == NALNUM
+ ? isALNUM(nextchr) : isALNUM_LC(nextchr))
+ sayNO;
+ nextchr = UCHARAT(++locinput);
+ break;
+ case BOUNDL:
+ case NBOUNDL:
+ PL_reg_flags |= RF_tainted;
+ /* FALL THROUGH */
+ case BOUND:
+ case NBOUND:
+ /* was last char in word? */
+ if (do_utf8) {
+ if (locinput == PL_bostr)
+ ln = '\n';
+ else {
+ const U8 * const r = reghop3((U8*)locinput, -1, (U8*)PL_bostr);
+
+ ln = utf8n_to_uvchr(r, UTF8SKIP(r), 0, uniflags);
+ }
+ if (OP(scan) == BOUND || OP(scan) == NBOUND) {
+ ln = isALNUM_uni(ln);
+ LOAD_UTF8_CHARCLASS_ALNUM();
+ n = swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8);
+ }
+ else {
+ ln = isALNUM_LC_uvchr(UNI_TO_NATIVE(ln));
+ n = isALNUM_LC_utf8((U8*)locinput);
+ }
+ }
+ else {
+ ln = (locinput != PL_bostr) ?
+ UCHARAT(locinput - 1) : '\n';
+ if (OP(scan) == BOUND || OP(scan) == NBOUND) {
+ ln = isALNUM(ln);
+ n = isALNUM(nextchr);
+ }
+ else {
+ ln = isALNUM_LC(ln);
+ n = isALNUM_LC(nextchr);
+ }
+ }
+ if (((!ln) == (!n)) == (OP(scan) == BOUND ||
+ OP(scan) == BOUNDL))
+ sayNO;
+ break;
+ case SPACEL:
+ PL_reg_flags |= RF_tainted;
+ /* FALL THROUGH */
+ case SPACE:
+ if (!nextchr)
+ sayNO;
+ if (do_utf8) {
+ if (UTF8_IS_CONTINUED(nextchr)) {
+ LOAD_UTF8_CHARCLASS_SPACE();
+ if (!(OP(scan) == SPACE
+ ? (bool)swash_fetch(PL_utf8_space, (U8*)locinput, do_utf8)
+ : isSPACE_LC_utf8((U8*)locinput)))
+ {
+ sayNO;
+ }
+ locinput += PL_utf8skip[nextchr];
+ nextchr = UCHARAT(locinput);
+ break;
+ }
+ if (!(OP(scan) == SPACE
+ ? isSPACE(nextchr) : isSPACE_LC(nextchr)))
+ sayNO;
+ nextchr = UCHARAT(++locinput);
+ }
+ else {
+ if (!(OP(scan) == SPACE
+ ? isSPACE(nextchr) : isSPACE_LC(nextchr)))
+ sayNO;
+ nextchr = UCHARAT(++locinput);
+ }
+ break;
+ case NSPACEL:
+ PL_reg_flags |= RF_tainted;
+ /* FALL THROUGH */
+ case NSPACE:
+ if (!nextchr && locinput >= PL_regeol)
+ sayNO;
+ if (do_utf8) {
+ LOAD_UTF8_CHARCLASS_SPACE();
+ if (OP(scan) == NSPACE
+ ? (bool)swash_fetch(PL_utf8_space, (U8*)locinput, do_utf8)
+ : isSPACE_LC_utf8((U8*)locinput))
+ {
+ sayNO;
+ }
+ locinput += PL_utf8skip[nextchr];
+ nextchr = UCHARAT(locinput);
+ break;
+ }
+ if (OP(scan) == NSPACE
+ ? isSPACE(nextchr) : isSPACE_LC(nextchr))
+ sayNO;
+ nextchr = UCHARAT(++locinput);
+ break;
+ case DIGITL:
+ PL_reg_flags |= RF_tainted;
+ /* FALL THROUGH */
+ case DIGIT:
+ if (!nextchr)
+ sayNO;
+ if (do_utf8) {
+ LOAD_UTF8_CHARCLASS_DIGIT();
+ if (!(OP(scan) == DIGIT
+ ? (bool)swash_fetch(PL_utf8_digit, (U8*)locinput, do_utf8)
+ : isDIGIT_LC_utf8((U8*)locinput)))
+ {
+ sayNO;
+ }
+ locinput += PL_utf8skip[nextchr];
+ nextchr = UCHARAT(locinput);
+ break;
+ }
+ if (!(OP(scan) == DIGIT
+ ? isDIGIT(nextchr) : isDIGIT_LC(nextchr)))
+ sayNO;
+ nextchr = UCHARAT(++locinput);
+ break;
+ case NDIGITL:
+ PL_reg_flags |= RF_tainted;
+ /* FALL THROUGH */
+ case NDIGIT:
+ if (!nextchr && locinput >= PL_regeol)
+ sayNO;
+ if (do_utf8) {
+ LOAD_UTF8_CHARCLASS_DIGIT();
+ if (OP(scan) == NDIGIT
+ ? (bool)swash_fetch(PL_utf8_digit, (U8*)locinput, do_utf8)
+ : isDIGIT_LC_utf8((U8*)locinput))
+ {
+ sayNO;
+ }
+ locinput += PL_utf8skip[nextchr];
+ nextchr = UCHARAT(locinput);
+ break;
+ }
+ if (OP(scan) == NDIGIT
+ ? isDIGIT(nextchr) : isDIGIT_LC(nextchr))
+ sayNO;
+ nextchr = UCHARAT(++locinput);
+ break;
+ case CLUMP:
+ if (locinput >= PL_regeol)
+ sayNO;
+ if (do_utf8) {
+ LOAD_UTF8_CHARCLASS_MARK();
+ if (swash_fetch(PL_utf8_mark,(U8*)locinput, do_utf8))
+ sayNO;
+ locinput += PL_utf8skip[nextchr];
+ while (locinput < PL_regeol &&
+ swash_fetch(PL_utf8_mark,(U8*)locinput, do_utf8))
+ locinput += UTF8SKIP(locinput);
+ if (locinput > PL_regeol)
+ sayNO;
+ }
+ else
+ locinput++;
+ nextchr = UCHARAT(locinput);
+ break;
+
+ case NREFFL:
+ {
+ char *s;
+ char type;
+ PL_reg_flags |= RF_tainted;
+ /* FALL THROUGH */
+ case NREF:
+ case NREFF:
+ type = OP(scan);
+ n = reg_check_named_buff_matched(rex,scan);
+
+ if ( n ) {
+ type = REF + ( type - NREF );
+ goto do_ref;
+ } else {
+ sayNO;
+ }
+ /* unreached */
+ case REFFL:
+ PL_reg_flags |= RF_tainted;
+ /* FALL THROUGH */
+ case REF:
+ case REFF:
+ n = ARG(scan); /* which paren pair */
+ type = OP(scan);
+ do_ref:
+ ln = PL_regoffs[n].start;
+ PL_reg_leftiter = PL_reg_maxiter; /* Void cache */
+ if (*PL_reglastparen < n || ln == -1)
+ sayNO; /* Do not match unless seen CLOSEn. */
+ if (ln == PL_regoffs[n].end)
+ break;
+
+ s = PL_bostr + ln;
+ if (do_utf8 && type != REF) { /* REF can do byte comparison */
+ char *l = locinput;
+ const char *e = PL_bostr + PL_regoffs[n].end;
+ /*
+ * Note that we can't do the "other character" lookup trick as
+ * in the 8-bit case (no pun intended) because in Unicode we
+ * have to map both upper and title case to lower case.
+ */
+ if (type == REFF) {
+ while (s < e) {
+ STRLEN ulen1, ulen2;
+ U8 tmpbuf1[UTF8_MAXBYTES_CASE+1];
+ U8 tmpbuf2[UTF8_MAXBYTES_CASE+1];
+
+ if (l >= PL_regeol)
+ sayNO;
+ toLOWER_utf8((U8*)s, tmpbuf1, &ulen1);
+ toLOWER_utf8((U8*)l, tmpbuf2, &ulen2);
+ if (ulen1 != ulen2 || memNE((char *)tmpbuf1, (char *)tmpbuf2, ulen1))
+ sayNO;
+ s += ulen1;
+ l += ulen2;
+ }
+ }
+ locinput = l;
+ nextchr = UCHARAT(locinput);
+ break;
+ }
+
+ /* Inline the first character, for speed. */
+ if (UCHARAT(s) != nextchr &&
+ (type == REF ||
+ (UCHARAT(s) != (type == REFF
+ ? PL_fold : PL_fold_locale)[nextchr])))
+ sayNO;
+ ln = PL_regoffs[n].end - ln;
+ if (locinput + ln > PL_regeol)
+ sayNO;
+ if (ln > 1 && (type == REF
+ ? memNE(s, locinput, ln)
+ : (type == REFF
+ ? ibcmp(s, locinput, ln)
+ : ibcmp_locale(s, locinput, ln))))
+ sayNO;
+ locinput += ln;
+ nextchr = UCHARAT(locinput);
+ break;
+ }
+ case NOTHING:
+ case TAIL:
+ break;
+ case BACK:
+ break;