This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Correct lround situation comment in POSIX
[perl5.git] / regexec.c
index c1674e2..cdaa95c 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -3640,7 +3640,7 @@ S_regtry(pTHX_ regmatch_info *reginfo, char **startposp)
    messages are inline with the regop output that created them.
 */
 #define REPORT_CODE_OFF 29
-#define INDENT_CHARS(depth) ((depth) % 20)
+#define INDENT_CHARS(depth) ((int)(depth) % 20)
 #ifdef DEBUGGING
 int
 Perl_re_exec_indentf(pTHX_ const char *fmt, U32 depth, ...)
@@ -3650,7 +3650,7 @@ Perl_re_exec_indentf(pTHX_ const char *fmt, U32 depth, ...)
     PerlIO *f= Perl_debug_log;
     PERL_ARGS_ASSERT_RE_EXEC_INDENTF;
     va_start(ap, depth);
-    PerlIO_printf(f, "%*s|%4d| %*s", REPORT_CODE_OFF, "", depth, INDENT_CHARS(depth), "" );
+    PerlIO_printf(f, "%*s|%4"UVuf"| %*s", REPORT_CODE_OFF, "", (UV)depth, INDENT_CHARS(depth), "" );
     result = PerlIO_vprintf(f, fmt, ap);
     va_end(ap);
     return result;
@@ -5135,6 +5135,28 @@ S_backup_one_WB(pTHX_ WB_enum * previous, const U8 * const strbeg, U8 ** curpos,
     return wb;
 }
 
+#define EVAL_CLOSE_PAREN_IS(st,expr)                        \
+(                                                           \
+    (   ( st )                                         ) && \
+    (   ( st )->u.eval.close_paren                     ) && \
+    ( ( ( st )->u.eval.close_paren ) == ( (expr) + 1 ) )    \
+)
+
+#define EVAL_CLOSE_PAREN_IS_TRUE(st,expr)                   \
+(                                                           \
+    (   ( st )                                         ) && \
+    (   ( st )->u.eval.close_paren                     ) && \
+    (   ( expr )                                       ) && \
+    ( ( ( st )->u.eval.close_paren ) == ( (expr) + 1 ) )    \
+)
+
+
+#define EVAL_CLOSE_PAREN_SET(st,expr) \
+    (st)->u.eval.close_paren = ( (expr) + 1 )
+
+#define EVAL_CLOSE_PAREN_CLEAR(st) \
+    (st)->u.eval.close_paren = 0
+
 /* returns -1 on failure, $+[0] on success */
 STATIC SSize_t
 S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
@@ -5210,6 +5232,13 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
     bool is_utf8_pat = reginfo->is_utf8_pat;
     bool match = FALSE;
 
+/* Solaris Studio 12.3 messes up fetching PL_charclass['\n'] */
+#if (defined(__SUNPRO_C) && (__SUNPRO_C == 0x5120) && defined(__x86_64) && defined(USE_64_BIT_ALL))
+#  define SOLARIS_BAD_OPTIMIZER
+    const U32 *pl_charclass_dup = PL_charclass;
+#  define PL_charclass pl_charclass_dup
+#endif
+
 #ifdef DEBUGGING
     GET_RE_DEBUG_FLAGS_DECL;
 #endif
@@ -6861,6 +6890,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
        }
 
        case EVAL_AB: /* cleanup after a successful (??{A})B */
+            /* note: this is called twice; first after popping B, then A */
             DEBUG_STACK_r({
                 Perl_re_exec_indentf( aTHX_  "EVAL_AB cur_eval=%p prev_eval=%p\n",
                     depth, cur_eval, ST.prev_eval);
@@ -7011,6 +7041,8 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
 
         case INSUBP:   /*  (?(R))  */
             n = ARG(scan);
+            /* this does not need to use EVAL_CLOSE_PAREN macros, as the arg
+             * of SCAN is already set up as matches a eval.close_paren */
             sw = cur_eval && (n == 0 || CUR_EVAL.close_paren == n);
             break;
 
@@ -7535,7 +7567,7 @@ NULL
                           depth, (IV) ST.count, (IV)ST.alen)
            );
 
-            if (EVAL_CLOSE_PAREN_IS(cur_eval,(U32)ST.me->flags))
+            if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.me->flags))
                goto fake_end;
                
            {
@@ -7550,7 +7582,7 @@ NULL
 
 
            if (ST.minmod || ST.count < ARG1(ST.me) /* min*/ 
-                || EVAL_CLOSE_PAREN_IS(cur_eval,(U32)ST.me->flags))
+                || EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.me->flags))
                sayNO;
 
          curlym_do_B: /* execute the B in /A{m,n}B/  */
@@ -7630,7 +7662,7 @@ NULL
                else
                    rex->offs[paren].end = -1;
 
-                if (EVAL_CLOSE_PAREN_IS(cur_eval,(U32)ST.me->flags))
+                if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.me->flags))
                {
                    if (ST.count) 
                        goto fake_end;
@@ -7699,7 +7731,7 @@ NULL
                maxopenparen = ST.paren;
            ST.min = ARG1(scan);  /* min to match */
            ST.max = ARG2(scan);  /* max to match */
-            if (EVAL_CLOSE_PAREN_IS(cur_eval,(U32)ST.paren))
+            if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.paren))
             {
                ST.min=1;
                ST.max=1;
@@ -7887,7 +7919,7 @@ NULL
                     assert(n == REG_INFTY || locinput == li);
                }
                CURLY_SETPAREN(ST.paren, ST.count);
-                if (EVAL_CLOSE_PAREN_IS(cur_eval,(U32)ST.paren))
+                if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.paren))
                    goto fake_end;
                PUSH_STATE_GOTO(CURLY_B_min_known, ST.B, locinput);
            }
@@ -7915,7 +7947,7 @@ NULL
                {
                  curly_try_B_min:
                    CURLY_SETPAREN(ST.paren, ST.count);
-                    if (EVAL_CLOSE_PAREN_IS(cur_eval,(U32)ST.paren))
+                    if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.paren))
                         goto fake_end;
                    PUSH_STATE_GOTO(CURLY_B_min, ST.B, locinput);
                }
@@ -7925,7 +7957,7 @@ NULL
 
           curly_try_B_max:
            /* a successful greedy match: now try to match B */
-            if (EVAL_CLOSE_PAREN_IS(cur_eval,(U32)ST.paren))
+            if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.paren))
                 goto fake_end;
            {
                bool could_match = locinput < reginfo->strend;
@@ -8291,6 +8323,9 @@ NULL
             /* NOTREACHED */
        }
     }
+#ifdef SOLARIS_BAD_OPTIMIZER
+#  undef PL_charclass
+#endif
 
     /*
     * We get here only if there's trouble -- normally "case END" is