The new smart match dispatch table for 5.10.1 onwards
[p5sagit/p5-mst-13.2.git] / regexec.c
index f959121..45ece8e 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -1007,15 +1007,16 @@ Perl_re_intuit_start(pTHX_ REGEXP * const rx, SV *sv, char *strpos,
 
 #define REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc, uscan, len,  \
 uvc, charid, foldlen, foldbuf, uniflags) STMT_START {                       \
+    UV uvc_unfolded = 0;                                                   \
     switch (trie_type) {                                                    \
     case trie_utf8_fold:                                                    \
        if ( foldlen>0 ) {                                                  \
-           uvc = utf8n_to_uvuni( uscan, UTF8_MAXLEN, &len, uniflags );     \
+           uvc_unfolded = uvc = utf8n_to_uvuni( uscan, UTF8_MAXLEN, &len, uniflags ); \
            foldlen -= len;                                                 \
            uscan += len;                                                   \
            len=0;                                                          \
        } else {                                                            \
-           uvc = utf8n_to_uvuni( (U8*)uc, UTF8_MAXLEN, &len, uniflags );   \
+           uvc_unfolded = uvc = utf8n_to_uvuni( (U8*)uc, UTF8_MAXLEN, &len, uniflags ); \
            uvc = to_uni_fold( uvc, foldbuf, &foldlen );                    \
            foldlen -= UNISKIP( uvc );                                      \
            uscan = foldbuf + UNISKIP( uvc );                               \
@@ -1054,6 +1055,9 @@ uvc, charid, foldlen, foldbuf, uniflags) STMT_START {                       \
                charid = (U16)SvIV(*svpp);                                  \
        }                                                                   \
     }                                                                       \
+    if (!charid && trie_type == trie_utf8_fold && !UTF) {                  \
+       charid = trie->charmap[uvc_unfolded];                               \
+    }                                                                      \
 } STMT_END
 
 #define REXEC_FBC_EXACTISH_CHECK(CoNd)                 \
@@ -5771,7 +5775,14 @@ S_reginclass(pTHX_ const regexp *prog, register const regnode *n, register const
            SV * const sw = regclass_swash(prog, n, TRUE, 0, (SV**)&av);
        
            if (sw) {
-               if (swash_fetch(sw, p, do_utf8))
+               U8 * utf8_p;
+               if (do_utf8) {
+                   utf8_p = (U8 *) p;
+               } else {
+                   STRLEN len = 1;
+                   utf8_p = bytes_to_utf8(p, &len);
+               }
+               if (swash_fetch(sw, utf8_p, 1))
                    match = TRUE;
                else if (flags & ANYOF_FOLD) {
                    if (!match && lenp && av) {
@@ -5780,8 +5791,7 @@ S_reginclass(pTHX_ const regexp *prog, register const regnode *n, register const
                            SV* const sv = *av_fetch(av, i, FALSE);
                            STRLEN len;
                            const char * const s = SvPV_const(sv, len);
-                       
-                           if (len <= plen && memEQ(s, (char*)p, len)) {
+                           if (len <= plen && memEQ(s, (char*)utf8_p, len)) {
                                *lenp = len;
                                match = TRUE;
                                break;
@@ -5790,13 +5800,16 @@ S_reginclass(pTHX_ const regexp *prog, register const regnode *n, register const
                    }
                    if (!match) {
                        U8 tmpbuf[UTF8_MAXBYTES_CASE+1];
-                       STRLEN tmplen;
 
-                       to_utf8_fold(p, tmpbuf, &tmplen);
-                       if (swash_fetch(sw, tmpbuf, do_utf8))
+                       STRLEN tmplen;
+                       to_utf8_fold(utf8_p, tmpbuf, &tmplen);
+                       if (swash_fetch(sw, tmpbuf, 1))
                            match = TRUE;
                    }
                }
+
+               /* If we allocated a string above, free it */
+               if (! do_utf8) Safefree(utf8_p);
            }
        }
        if (match && lenp && *lenp == 0)