Re: [PATCH] Lighten up glob
[p5sagit/p5-mst-13.2.git] / regexec.c
index 1fa26c9..625f8eb 100644 (file)
--- a/regexec.c
+++ b/regexec.c
 #define HOP3c(pos,off,lim) ((char*)HOP3(pos,off,lim))
 #define HOPMAYBE3c(pos,off,lim) ((char*)HOPMAYBE3(pos,off,lim))
 
-static void restore_pos(pTHXo_ void *arg);
+#define LOAD_UTF8_CHARCLASS(a,b) STMT_START { if (!CAT2(PL_utf8_,a)) (void)CAT2(is_utf8_, a)((U8*)b); } STMT_END
 
+static void restore_pos(pTHXo_ void *arg);
 
 STATIC CHECKPOINT
 S_regcppush(pTHX_ I32 parenfloor)
@@ -949,10 +950,11 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
                else {
                    U8 *r = reghop3((U8*)s, -1, (U8*)startpos);
                
-                   tmp = (I32)utf8n_to_uvuni(r, s - (char*)r, 0, 0);
+                   tmp = (I32)utf8n_to_uvchr(r, s - (char*)r, 0, 0);
                }
                tmp = ((OP(c) == BOUND ?
                        isALNUM_uni(tmp) : isALNUM_LC_uvchr(UNI_TO_NATIVE(tmp))) != 0);
+               LOAD_UTF8_CHARCLASS(alnum,"a");
                while (s < strend) {
                    if (tmp == !(OP(c) == BOUND ?
                                 swash_fetch(PL_utf8_alnum, (U8*)s) :
@@ -991,10 +993,11 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
                else {
                    U8 *r = reghop3((U8*)s, -1, (U8*)startpos);
                
-                   tmp = (I32)utf8n_to_uvuni(r, s - (char*)r, 0, 0);
+                   tmp = (I32)utf8n_to_uvchr(r, s - (char*)r, 0, 0);
                }
                tmp = ((OP(c) == NBOUND ?
                        isALNUM_uni(tmp) : isALNUM_LC_uvchr(UNI_TO_NATIVE(tmp))) != 0);
+               LOAD_UTF8_CHARCLASS(alnum,"a");
                while (s < strend) {
                    if (tmp == !(OP(c) == NBOUND ?
                                 swash_fetch(PL_utf8_alnum, (U8*)s) :
@@ -1023,6 +1026,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
            break;
        case ALNUM:
            if (do_utf8) {
+               LOAD_UTF8_CHARCLASS(alnum,"a");
                while (s < strend) {
                    if (swash_fetch(PL_utf8_alnum, (U8*)s)) {
                        if (tmp && (norun || regtry(prog, s)))
@@ -1080,6 +1084,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
            break;
        case NALNUM:
            if (do_utf8) {
+               LOAD_UTF8_CHARCLASS(alnum,"a");
                while (s < strend) {
                    if (!swash_fetch(PL_utf8_alnum, (U8*)s)) {
                        if (tmp && (norun || regtry(prog, s)))
@@ -1137,6 +1142,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
            break;
        case SPACE:
            if (do_utf8) {
+               LOAD_UTF8_CHARCLASS(space," ");
                while (s < strend) {
                    if (*s == ' ' || swash_fetch(PL_utf8_space,(U8*)s)) {
                        if (tmp && (norun || regtry(prog, s)))
@@ -1194,6 +1200,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
            break;
        case NSPACE:
            if (do_utf8) {
+               LOAD_UTF8_CHARCLASS(space," ");
                while (s < strend) {
                    if (!(*s == ' ' || swash_fetch(PL_utf8_space,(U8*)s))) {
                        if (tmp && (norun || regtry(prog, s)))
@@ -1251,6 +1258,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
            break;
        case DIGIT:
            if (do_utf8) {
+               LOAD_UTF8_CHARCLASS(digit,"0");
                while (s < strend) {
                    if (swash_fetch(PL_utf8_digit,(U8*)s)) {
                        if (tmp && (norun || regtry(prog, s)))
@@ -1308,6 +1316,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
            break;
        case NDIGIT:
            if (do_utf8) {
+               LOAD_UTF8_CHARCLASS(digit,"0");
                while (s < strend) {
                    if (!swash_fetch(PL_utf8_digit,(U8*)s)) {
                        if (tmp && (norun || regtry(prog, s)))
@@ -1424,7 +1433,7 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
     else {
         if (prog->reganch & ROPT_UTF8 && do_utf8) {
            U8 *s = reghop3((U8*)stringarg, -1, (U8*)strbeg);
-           PL_regprev = utf8n_to_uvuni(s, (U8*)stringarg - s, NULL, 0);
+           PL_regprev = utf8n_to_uvchr(s, (U8*)stringarg - s, NULL, 0);
        }
        else
            PL_regprev = (U32)stringarg[-1];
@@ -2152,7 +2161,7 @@ S_regmatch(pTHX_ regnode *prog)
                    if (l >= PL_regeol) {
                        sayNO;
                    }
-                   if ((UTF ? utf8n_to_uvuni((U8*)s, e - s, 0, 0) : *((U8*)s)) !=
+                   if ((UTF ? utf8n_to_uvchr((U8*)s, e - s, 0, 0) : *((U8*)s)) !=
                        (c1 ? toLOWER_utf8((U8*)l) : toLOWER_LC_utf8((U8*)l)))
                            sayNO;
                    s += UTF ? UTF8SKIP(s) : 1;
@@ -2225,6 +2234,7 @@ S_regmatch(pTHX_ regnode *prog)
            if (!nextchr && locinput >= PL_regeol)
                sayNO;
            if (do_utf8) {
+               LOAD_UTF8_CHARCLASS(alnum,"a");
                if (OP(scan) == NALNUM
                    ? swash_fetch(PL_utf8_alnum, (U8*)locinput)
                    : isALNUM_LC_utf8((U8*)locinput))
@@ -2253,10 +2263,11 @@ S_regmatch(pTHX_ regnode *prog)
                else {
                    U8 *r = reghop((U8*)locinput, -1);
                
-                   ln = utf8n_to_uvuni(r, s - (char*)r, 0, 0);
+                   ln = utf8n_to_uvchr(r, s - (char*)r, 0, 0);
                }
                if (OP(scan) == BOUND || OP(scan) == NBOUND) {
                    ln = isALNUM_uni(ln);
+                   LOAD_UTF8_CHARCLASS(alnum,"a");
                    n = swash_fetch(PL_utf8_alnum, (U8*)locinput);
                }
                else {
@@ -2288,6 +2299,7 @@ S_regmatch(pTHX_ regnode *prog)
                sayNO;
            if (do_utf8) {
                if (UTF8_IS_CONTINUED(nextchr)) {
+                   LOAD_UTF8_CHARCLASS(space," ");
                    if (!(OP(scan) == SPACE
                          ? swash_fetch(PL_utf8_space, (U8*)locinput)
                          : isSPACE_LC_utf8((U8*)locinput)))
@@ -2317,6 +2329,7 @@ S_regmatch(pTHX_ regnode *prog)
            if (!nextchr && locinput >= PL_regeol)
                sayNO;
            if (do_utf8) {
+               LOAD_UTF8_CHARCLASS(space," ");
                if (OP(scan) == NSPACE
                    ? swash_fetch(PL_utf8_space, (U8*)locinput)
                    : isSPACE_LC_utf8((U8*)locinput))
@@ -2339,6 +2352,7 @@ S_regmatch(pTHX_ regnode *prog)
            if (!nextchr)
                sayNO;
            if (do_utf8) {
+               LOAD_UTF8_CHARCLASS(digit,"0");
                if (!(OP(scan) == DIGIT
                      ? swash_fetch(PL_utf8_digit, (U8*)locinput)
                      : isDIGIT_LC_utf8((U8*)locinput)))
@@ -2361,6 +2375,7 @@ S_regmatch(pTHX_ regnode *prog)
            if (!nextchr && locinput >= PL_regeol)
                sayNO;
            if (do_utf8) {
+               LOAD_UTF8_CHARCLASS(digit,"0");
                if (OP(scan) == NDIGIT
                    ? swash_fetch(PL_utf8_digit, (U8*)locinput)
                    : isDIGIT_LC_utf8((U8*)locinput))
@@ -2377,6 +2392,7 @@ S_regmatch(pTHX_ regnode *prog)
            nextchr = UCHARAT(++locinput);
            break;
        case CLUMP:
+           LOAD_UTF8_CHARCLASS(mark,"~");
            if (locinput >= PL_regeol || swash_fetch(PL_utf8_mark,(U8*)locinput))
                sayNO;
            locinput += PL_utf8skip[nextchr];
@@ -2504,7 +2520,7 @@ S_regmatch(pTHX_ regnode *prog)
                        I32 osize = PL_regsize;
                        I32 onpar = PL_regnpar;
 
-                       pm.op_pmflags = 0;
+                       Zero(&pm, 1, PMOP);
                        re = CALLREGCOMP(aTHX_ t, t + len, &pm);
                        if (!(SvFLAGS(ret)
                              & (SVs_TEMP | SVs_PADTMP | SVf_READONLY)))
@@ -3229,9 +3245,15 @@ S_regmatch(pTHX_ regnode *prog)
                            c = utf8_to_uvchr((U8*)PL_reginput, NULL);
                        else
                            c = UCHARAT(PL_reginput);
+                       /* If it could work, try it. */
+                       if (c == c1 || c == c2)
+                       {
+                           TRYPAREN(paren, n, PL_reginput);
+                           REGCP_UNWIND(lastcp);
+                       }
                    }
                    /* If it could work, try it. */
-                   if (c1 == -1000 || c == c1 || c == c2)
+                   else if (c1 == -1000)
                    {
                        TRYPAREN(paren, n, PL_reginput);
                        REGCP_UNWIND(lastcp);
@@ -3598,6 +3620,7 @@ S_regrepeat(pTHX_ regnode *p, I32 max)
     case ALNUM:
        if (do_utf8) {
            loceol = PL_regeol;
+           LOAD_UTF8_CHARCLASS(alnum,"a");
            while (hardcount < max && scan < loceol &&
                   swash_fetch(PL_utf8_alnum, (U8*)scan)) {
                scan += UTF8SKIP(scan);
@@ -3625,6 +3648,7 @@ S_regrepeat(pTHX_ regnode *p, I32 max)
     case NALNUM:
        if (do_utf8) {
            loceol = PL_regeol;
+           LOAD_UTF8_CHARCLASS(alnum,"a");
            while (hardcount < max && scan < loceol &&
                   !swash_fetch(PL_utf8_alnum, (U8*)scan)) {
                scan += UTF8SKIP(scan);
@@ -3652,6 +3676,7 @@ S_regrepeat(pTHX_ regnode *p, I32 max)
     case SPACE:
        if (do_utf8) {
            loceol = PL_regeol;
+           LOAD_UTF8_CHARCLASS(space," ");
            while (hardcount < max && scan < loceol &&
                   (*scan == ' ' || swash_fetch(PL_utf8_space,(U8*)scan))) {
                scan += UTF8SKIP(scan);
@@ -3679,6 +3704,7 @@ S_regrepeat(pTHX_ regnode *p, I32 max)
     case NSPACE:
        if (do_utf8) {
            loceol = PL_regeol;
+           LOAD_UTF8_CHARCLASS(space," ");
            while (hardcount < max && scan < loceol &&
                   !(*scan == ' ' || swash_fetch(PL_utf8_space,(U8*)scan))) {
                scan += UTF8SKIP(scan);
@@ -3706,6 +3732,7 @@ S_regrepeat(pTHX_ regnode *p, I32 max)
     case DIGIT:
        if (do_utf8) {
            loceol = PL_regeol;
+           LOAD_UTF8_CHARCLASS(digit,"0");
            while (hardcount < max && scan < loceol &&
                   swash_fetch(PL_utf8_digit,(U8*)scan)) {
                scan += UTF8SKIP(scan);
@@ -3719,6 +3746,7 @@ S_regrepeat(pTHX_ regnode *p, I32 max)
     case NDIGIT:
        if (do_utf8) {
            loceol = PL_regeol;
+           LOAD_UTF8_CHARCLASS(digit,"0");
            while (hardcount < max && scan < loceol &&
                   !swash_fetch(PL_utf8_digit,(U8*)scan)) {
                scan += UTF8SKIP(scan);