Fix a syntax error in test
[p5sagit/p5-mst-13.2.git] / regcomp.c
index 2c5ff0a..7849bd3 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -1865,7 +1865,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap,
                                     SvPV_nolen_const(mysv));
                                 }
                                 PerlIO_printf( Perl_debug_log, "0x%p,0x%p,0x%p)\n",
-                                   first, last, cur );
+                                   (void*)first, (void*)last, (void*)cur );
                             });
                             if ( ( first ? OP( noper ) == optype
                                          : PL_regkind[ (U8)OP( noper ) ] == EXACT )
@@ -1922,7 +1922,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, I32 *deltap,
                             regprop(RExC_rx, mysv, cur);
                             PerlIO_printf( Perl_debug_log,
                               "%*s%s\t(0x%p,0x%p,0x%p)\n", (int)depth * 2 + 2,
-                              "  ", SvPV_nolen_const( mysv ), first, last, cur);
+                              "  ", SvPV_nolen_const( mysv ), (void*)first, (void*)last, (void*)cur);
 
                         });
                         if ( last ) {
@@ -3543,10 +3543,16 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp)
        }
        regtail(pRExC_state, lastbr, ender);
 
-       if (have_branch) {
+       if (have_branch && !SIZE_ONLY) {
            /* Hook the tails of the branches to the closing node. */
-           for (br = ret; br != NULL; br = regnext(br)) {
-               regoptail(pRExC_state, br, ender);
+           for (br = ret; br; br = regnext(br)) {
+               const U8 op = PL_regkind[OP(br)];
+               if (op == BRANCH) {
+                   regtail(pRExC_state, NEXTOPER(br), ender);
+               }
+               else if (op == BRANCHJ) {
+                   regtail(pRExC_state, NEXTOPER(NEXTOPER(br)), ender);
+               }
            }
        }
     }
@@ -3840,7 +3846,9 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp)
  * faster to run.  Backslashed characters are exceptions, each becoming a
  * separate node; the code is simpler that way and it's not worth fixing.
  *
- * [Yes, it is worth fixing, some scripts can run twice the speed.] */
+ * [Yes, it is worth fixing, some scripts can run twice the speed.]
+ * [It looks like its ok, as in S_study_chunk we merge adjacent EXACT nodes]
+ */
 STATIC regnode *
 S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp)
 {
@@ -4277,8 +4285,6 @@ tryagain:
                    if (len)
                        p = oldp;
                    else if (UTF) {
-                        STRLEN unilen;
-
                         if (FOLD) {
                              /* Emit all the Unicode characters. */
                              STRLEN numlen;
@@ -4287,7 +4293,7 @@ tryagain:
                                   foldlen -= numlen) {
                                   ender = utf8_to_uvchr(foldbuf, &numlen);
                                   if (numlen > 0) {
-                                       reguni(pRExC_state, ender, s, &unilen);
+                                       const STRLEN unilen = reguni(pRExC_state, ender, s);
                                        s       += unilen;
                                        len     += unilen;
                                        /* In EBCDIC the numlen
@@ -4301,7 +4307,7 @@ tryagain:
                              }
                         }
                         else {
-                             reguni(pRExC_state, ender, s, &unilen);
+                             const STRLEN unilen = reguni(pRExC_state, ender, s);
                              if (unilen > 0) {
                                   s   += unilen;
                                   len += unilen;
@@ -4315,8 +4321,6 @@ tryagain:
                    break;
                }
                if (UTF) {
-                    STRLEN unilen;
-
                     if (FOLD) {
                          /* Emit all the Unicode characters. */
                          STRLEN numlen;
@@ -4325,7 +4329,7 @@ tryagain:
                               foldlen -= numlen) {
                               ender = utf8_to_uvchr(foldbuf, &numlen);
                               if (numlen > 0) {
-                                   reguni(pRExC_state, ender, s, &unilen);
+                                   const STRLEN unilen = reguni(pRExC_state, ender, s);
                                    len     += unilen;
                                    s       += unilen;
                                    /* In EBCDIC the numlen
@@ -4339,7 +4343,7 @@ tryagain:
                          }
                     }
                     else {
-                         reguni(pRExC_state, ender, s, &unilen);
+                         const STRLEN unilen = reguni(pRExC_state, ender, s);
                          if (unilen > 0) {
                               s   += unilen;
                               len += unilen;
@@ -4619,6 +4623,12 @@ S_checkposixcc(pTHX_ RExC_state_t *pRExC_state)
     }
 }
 
+
+/*
+   parse a class specification and produce either an ANYOF node that
+   matches the pattern. If the pattern matches a single char only and
+   that char is < 256 then we produce an EXACT node instead.
+*/
 STATIC regnode *
 S_regclass(pTHX_ RExC_state_t *pRExC_state)
 {
@@ -4640,7 +4650,12 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
 #ifdef EBCDIC
     UV literal_endpoint = 0;
 #endif
+    UV stored = 0;  /* number of chars stored in the class */
 
+    regnode *orig_emit = RExC_emit; /* Save the original RExC_emit in
+        case we need to change the emitted regop to an EXACT. */
+
+    /* Assume we are going to generate an ANYOF node. */
     ret = reganode(pRExC_state, ANYOF, 0);
 
     if (!SIZE_ONLY)
@@ -4692,6 +4707,7 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
        }
        else
            value = UCHARAT(RExC_parse++);
+
        nextvalue = RExC_parse < RExC_end ? UCHARAT(RExC_parse) : 0;
        if (value == '[' && POSIXCC(nextvalue))
            namedclass = regpposixcc(pRExC_state, value);
@@ -5242,9 +5258,9 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
        }
 
        /* now is the next time */
+        stored += (value - prevvalue + 1);
        if (!SIZE_ONLY) {
            IV i;
-
            if (prevvalue < 256) {
                const IV ceilvalue = value < 256 ? value : 255;
 
@@ -5349,9 +5365,26 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
            RExC_emit += ANYOF_CLASS_ADD_SKIP;
     }
 
+
+    if (SIZE_ONLY)
+        return ret;
+    /****** !SIZE_ONLY AFTER HERE *********/
+
+    if( stored == 1 && value < 256
+        && !( ANYOF_FLAGS(ret) & ( ANYOF_FLAGS_ALL ^ ANYOF_FOLD ) )
+    ) {
+        /* optimize single char class to an EXACT node
+           but *only* when its not a UTF/high char  */
+        RExC_emit = orig_emit;
+        ret = reg_node(pRExC_state,
+                       (U8)((ANYOF_FLAGS(ret) & ANYOF_FOLD) ? EXACTF : EXACT));
+        *STRING(ret)= (char)value;
+        STR_LEN(ret)= 1;
+        RExC_emit += STR_SZ(1);
+        return ret;
+    }
     /* optimize case-insensitive simple patterns (e.g. /[a-z]/i) */
-    if (!SIZE_ONLY &&
-        /* If the only flag is folding (plus possibly inversion). */
+    if ( /* If the only flag is folding (plus possibly inversion). */
        ((ANYOF_FLAGS(ret) & (ANYOF_FLAGS_ALL ^ ANYOF_INVERT)) == ANYOF_FOLD)
        ) {
        for (value = 0; value < 256; ++value) {
@@ -5366,18 +5399,16 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
     }
 
     /* optimize inverted simple patterns (e.g. [^a-z]) */
-    if (!SIZE_ONLY && optimize_invert &&
+    if (optimize_invert &&
        /* If the only flag is inversion. */
        (ANYOF_FLAGS(ret) & ANYOF_FLAGS_ALL) == ANYOF_INVERT) {
        for (value = 0; value < ANYOF_BITMAP_SIZE; ++value)
            ANYOF_BITMAP(ret)[value] ^= ANYOF_FLAGS_ALL;
        ANYOF_FLAGS(ret) = ANYOF_UNICODE_ALL;
     }
-
-    if (!SIZE_ONLY) {
+    {
        AV * const av = newAV();
        SV *rv;
-
        /* The 0th element stores the character class description
         * in its textual form: used later (regexec.c:Perl_regclass_swash())
         * to initialize the appropriate swash (which gets stored in
@@ -5392,7 +5423,6 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state)
        RExC_rx->data->data[n] = (void*)rv;
        ARG_SET(ret, n);
     }
-
     return ret;
 }
 
@@ -5503,11 +5533,11 @@ S_reganode(pTHX_ RExC_state_t *pRExC_state, U8 op, U32 arg)
 /*
 - reguni - emit (if appropriate) a Unicode character
 */
-STATIC void
-S_reguni(pTHX_ const RExC_state_t *pRExC_state, UV uv, char* s, STRLEN* lenp)
+STATIC STRLEN
+S_reguni(pTHX_ const RExC_state_t *pRExC_state, UV uv, char* s)
 {
     dVAR;
-    *lenp = SIZE_ONLY ? UNISKIP(uv) : (uvchr_to_utf8((U8*)s, uv) - (U8*)s);
+    return SIZE_ONLY ? UNISKIP(uv) : (uvchr_to_utf8((U8*)s, uv) - (U8*)s);
 }
 
 /*
@@ -5602,27 +5632,6 @@ S_regtail(pTHX_ const RExC_state_t *pRExC_state, regnode *p, const regnode *val)
 }
 
 /*
-- regoptail - regtail on operand of first argument; nop if operandless
-*/
-/* TODO: All three parms should be const */
-STATIC void
-S_regoptail(pTHX_ const RExC_state_t *pRExC_state, regnode *p, const regnode *val)
-{
-    dVAR;
-    /* "Operandless" and "op != BRANCH" are synonymous in practice. */
-    if (p == NULL || SIZE_ONLY)
-       return;
-    if (PL_regkind[(U8)OP(p)] == BRANCH) {
-       regtail(pRExC_state, NEXTOPER(p), val);
-    }
-    else if ( PL_regkind[(U8)OP(p)] == BRANCHJ) {
-       regtail(pRExC_state, NEXTOPER(NEXTOPER(p)), val);
-    }
-    else
-       return;
-}
-
-/*
  - regcurly - a little FSA that accepts {\d+,?\d*}
  */
 STATIC I32
@@ -5863,7 +5872,7 @@ Perl_regprop(pTHX_ const regexp *prog, SV *sv, const regnode *o)
        }
 
        if (o->flags & ANYOF_CLASS)
-           for (i = 0; i < sizeof(anyofs)/sizeof(char*); i++)
+           for (i = 0; i < (int)(sizeof(anyofs)/sizeof(char*)); i++)
                if (ANYOF_CLASS_TEST(o,i))
                    sv_catpv(sv, anyofs[i]);
 
@@ -6184,7 +6193,7 @@ Perl_save_re_context(pTHX)
            U32 i;
            for (i = 1; i <= rx->nparens; i++) {
                char digits[TYPE_CHARS(long)];
-               const STRLEN len = my_sprintf(digits, "%lu", (long)i);
+               const STRLEN len = my_snprintf(digits, sizeof(digits), "%lu", (long)i);
                GV *const *const gvp
                    = (GV**)hv_fetch(PL_defstash, digits, len, 0);