This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
ExtUtils::MakeMaker 6.02 -> 6.03
[perl5.git] / regexec.c
index f2d4b3d..002112f 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -87,7 +87,7 @@
 #define RF_evaled      4               /* Did an EVAL with setting? */
 #define RF_utf8                8               /* String contains multibyte chars? */
 
-#define UTF (PL_reg_flags & RF_utf8)
+#define UTF ((PL_reg_flags & RF_utf8) != 0)
 
 #define RS_init                1               /* eval environment created */
 #define RS_set         2               /* replsv value is set */
@@ -239,7 +239,7 @@ S_regcppop(pTHX)
        );
     }
     DEBUG_r(
-       if (*PL_reglastparen + 1 <= PL_regnpar) {
+       if ((I32)(*PL_reglastparen + 1) <= PL_regnpar) {
            PerlIO_printf(Perl_debug_log,
                          "     restoring \\%"IVdf"..\\%"IVdf" to undef\n",
                          (IV)(*PL_reglastparen + 1), (IV)PL_regnpar);
@@ -256,8 +256,8 @@ S_regcppop(pTHX)
      * building DynaLoader will fail:
      * "Error: '*' not in typemap in DynaLoader.xs, line 164"
      * --jhi */
-    for (paren = *PL_reglastparen + 1; paren <= PL_regnpar; paren++) {
-       if (paren > PL_regsize)
+    for (paren = *PL_reglastparen + 1; (I32)paren <= PL_regnpar; paren++) {
+       if ((I32)paren > PL_regsize)
            PL_regstartp[paren] = -1;
        PL_regendp[paren] = -1;
     }
@@ -999,8 +999,10 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
                to_utf8_lower((U8*)m, tmpbuf1, &ulen1);
                to_utf8_upper((U8*)m, tmpbuf2, &ulen2);
 
-               c1 = utf8_to_uvchr(tmpbuf1, 0);
-               c2 = utf8_to_uvchr(tmpbuf2, 0);
+               c1 = utf8n_to_uvchr(tmpbuf1, UTF8_MAXLEN_UCLC, 
+                                   0, ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
+               c2 = utf8n_to_uvchr(tmpbuf2, UTF8_MAXLEN_UCLC,
+                                   0, ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
            }
            else {
                c1 = *(U8*)m;
@@ -1013,7 +1015,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
            c1 = *(U8*)m;
            c2 = PL_fold_locale[c1];
          do_exactf:
-           e = do_utf8 ? s + ln : strend - ln;
+           e = HOP3c(strend, -(I32)ln, s);
 
            if (norun && e < s)
                e = s;                  /* Due to minlen logic of intuit() */
@@ -1037,11 +1039,13 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
                
                if (c1 == c2) {
                    while (s <= e) {
-                       c = utf8_to_uvchr((U8*)s, &len);
+                       c = utf8n_to_uvchr((U8*)s, UTF8_MAXLEN, &len,
+                                          ckWARN(WARN_UTF8) ?
+                                          0 : UTF8_ALLOW_ANY);
                        if ( c == c1
                             && (ln == len ||
                                 ibcmp_utf8(s, (char **)0, 0,  do_utf8,
-                                           m, (char **)0, ln, UTF))
+                                           m, (char **)0, ln, (bool)UTF))
                             && (norun || regtry(prog, s)) )
                            goto got_it;
                        else {
@@ -1053,7 +1057,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
                                      !ibcmp_utf8((char *) foldbuf,
                                                  (char **)0, foldlen, do_utf8,
                                                  m,
-                                                 (char **)0, ln,      UTF))
+                                                 (char **)0, ln, (bool)UTF))
                                  && (norun || regtry(prog, s)) )
                                  goto got_it;
                        }
@@ -1062,7 +1066,9 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
                }
                else {
                    while (s <= e) {
-                       c = utf8_to_uvchr((U8*)s, &len);
+                     c = utf8n_to_uvchr((U8*)s, UTF8_MAXLEN, &len,
+                                          ckWARN(WARN_UTF8) ?
+                                          0 : UTF8_ALLOW_ANY);
 
                        /* Handle some of the three Greek sigmas cases.
                         * Note that not all the possible combinations
@@ -1078,7 +1084,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
                        if ( (c == c1 || c == c2)
                             && (ln == len ||
                                 ibcmp_utf8(s, (char **)0, 0,  do_utf8,
-                                           m, (char **)0, ln, UTF))
+                                           m, (char **)0, ln, (bool)UTF))
                             && (norun || regtry(prog, s)) )
                            goto got_it;
                        else {
@@ -1090,7 +1096,7 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
                                      !ibcmp_utf8((char *) foldbuf,
                                                  (char **)0, foldlen, do_utf8,
                                                  m,
-                                                 (char **)0, ln,      UTF))
+                                                 (char **)0, ln, (bool)UTF))
                                  && (norun || regtry(prog, s)) )
                                  goto got_it;
                        }
@@ -2128,7 +2134,7 @@ S_regtry(pTHX_ regexp *prog, char *startpos)
     sp = prog->startp;
     ep = prog->endp;
     if (prog->nparens) {
-       for (i = prog->nparens; i > *PL_reglastparen; i--) {
+       for (i = prog->nparens; i > (I32)*PL_reglastparen; i--) {
            *++sp = -1;
            *++ep = -1;
        }
@@ -2378,7 +2384,7 @@ S_regmatch(pTHX_ regnode *prog)
        case EXACT:
            s = STRING(scan);
            ln = STR_LEN(scan);
-           if (do_utf8 != (UTF!=0)) {
+           if (do_utf8 != UTF) {
                /* The target and the pattern have differing utf8ness. */
                char *l = locinput;
                char *e = s + ln;
@@ -2390,7 +2396,9 @@ S_regmatch(pTHX_ regnode *prog)
                        if (l >= PL_regeol)
                             sayNO;
                        if (NATIVE_TO_UNI(*(U8*)s) !=
-                           utf8_to_uvuni((U8*)l, &ulen))
+                           utf8n_to_uvuni((U8*)l, UTF8_MAXLEN, &ulen,
+                                          ckWARN(WARN_UTF8) ?
+                                          0 : UTF8_ALLOW_ANY))
                             sayNO;
                        l += ulen;
                        s ++;
@@ -2402,7 +2410,9 @@ S_regmatch(pTHX_ regnode *prog)
                        if (l >= PL_regeol)
                            sayNO;
                        if (NATIVE_TO_UNI(*((U8*)l)) !=
-                           utf8_to_uvuni((U8*)s, &ulen))
+                           utf8n_to_uvuni((U8*)s, UTF8_MAXLEN, &ulen,
+                                          ckWARN(WARN_UTF8) ?
+                                          0 : UTF8_ALLOW_ANY))
                            sayNO;
                        s += ulen;
                        l ++;
@@ -2435,7 +2445,7 @@ S_regmatch(pTHX_ regnode *prog)
                char *l = locinput;
                char *e = PL_regeol;
 
-               if (ibcmp_utf8(s, 0,  ln, UTF,
+               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,
@@ -2717,7 +2727,7 @@ S_regmatch(pTHX_ regnode *prog)
            n = ARG(scan);  /* which paren pair */
            ln = PL_regstartp[n];
            PL_reg_leftiter = PL_reg_maxiter;           /* Void cache */
-           if (*PL_reglastparen < n || ln == -1)
+           if ((I32)*PL_reglastparen < n || ln == -1)
                sayNO;                  /* Do not match unless seen CLOSEn. */
            if (ln == PL_regendp[n])
                break;
@@ -2916,13 +2926,13 @@ S_regmatch(pTHX_ regnode *prog)
            n = ARG(scan);  /* which paren pair */
            PL_regstartp[n] = PL_reg_start_tmp[n] - PL_bostr;
            PL_regendp[n] = locinput - PL_bostr;
-           if (n > *PL_reglastparen)
+           if (n > (I32)*PL_reglastparen)
                *PL_reglastparen = n;
            *PL_reglastcloseparen = n;
            break;
        case GROUPP:
            n = ARG(scan);  /* which paren pair */
-           sw = (*PL_reglastparen >= n && PL_regendp[n] != -1);
+           sw = ((I32)*PL_reglastparen >= n && PL_regendp[n] != -1);
            break;
        case IFTHEN:
            PL_reg_leftiter = PL_reg_maxiter;           /* Void cache */
@@ -3024,7 +3034,7 @@ S_regmatch(pTHX_ regnode *prog)
                PL_regcc = &cc;
                /* XXXX Probably it is better to teach regpush to support
                   parenfloor > PL_regsize... */
-               if (parenfloor > *PL_reglastparen)
+               if (parenfloor > (I32)*PL_reglastparen)
                    parenfloor = *PL_reglastparen; /* Pessimization... */
                cc.parenfloor = parenfloor;
                cc.cur = -1;
@@ -3060,10 +3070,10 @@ S_regmatch(pTHX_ regnode *prog)
 
                DEBUG_r(
                    PerlIO_printf(Perl_debug_log,
-                                 "%*s  %ld out of %ld..%ld  cc=%lx\n",
+                                 "%*s  %ld out of %ld..%ld  cc=%"UVxf"\n",
                                  REPORT_CODE_OFF+PL_regindent*2, "",
                                  (long)n, (long)cc->min,
-                                 (long)cc->max, (long)cc)
+                                 (long)cc->max, PTR2UV(cc))
                    );
 
                /* If degenerate scan matches "", assume scan done. */
@@ -3108,7 +3118,7 @@ S_regmatch(pTHX_ regnode *prog)
                if (PL_reg_leftiter-- == 0) {
                    I32 size = (PL_reg_maxiter + 7)/8;
                    if (PL_reg_poscache) {
-                       if (PL_reg_poscache_size < size) {
+                       if ((I32)PL_reg_poscache_size < size) {
                            Renew(PL_reg_poscache, size, char);
                            PL_reg_poscache_size = size;
                        }
@@ -3293,7 +3303,7 @@ S_regmatch(pTHX_ regnode *prog)
            if (paren) {
                if (paren > PL_regsize)
                    PL_regsize = paren;
-               if (paren > *PL_reglastparen)
+               if (paren > (I32)*PL_reglastparen)
                    *PL_reglastparen = paren;
            }
            scan = NEXTOPER(scan) + NODE_STEP_REGNODE;
@@ -3327,7 +3337,7 @@ S_regmatch(pTHX_ regnode *prog)
                            ln = PL_regstartp[n];
                            /* assume yes if we haven't seen CLOSEn */
                            if (
-                               *PL_reglastparen < n ||
+                               (I32)*PL_reglastparen < n ||
                                ln == -1 ||
                                ln == PL_regendp[n]
                            ) {
@@ -3409,7 +3419,7 @@ S_regmatch(pTHX_ regnode *prog)
                                ln = PL_regstartp[n];
                                /* assume yes if we haven't seen CLOSEn */
                                if (
-                                   *PL_reglastparen < n ||
+                                   (I32)*PL_reglastparen < n ||
                                    ln == -1 ||
                                    ln == PL_regendp[n]
                                ) {
@@ -3469,7 +3479,7 @@ S_regmatch(pTHX_ regnode *prog)
            paren = scan->flags;        /* Which paren to set */
            if (paren > PL_regsize)
                PL_regsize = paren;
-           if (paren > *PL_reglastparen)
+           if (paren > (I32)*PL_reglastparen)
                *PL_reglastparen = paren;
            ln = ARG1(scan);  /* min to match */
            n  = ARG2(scan);  /* max to match */
@@ -3518,7 +3528,7 @@ S_regmatch(pTHX_ regnode *prog)
                        ln = PL_regstartp[n];
                        /* assume yes if we haven't seen CLOSEn */
                        if (
-                           *PL_reglastparen < n ||
+                           (I32)*PL_reglastparen < n ||
                            ln == -1 ||
                            ln == PL_regendp[n]
                        ) {
@@ -3545,11 +3555,17 @@ S_regmatch(pTHX_ regnode *prog)
                             to_utf8_lower((U8*)s, tmpbuf1, &ulen1);
                             to_utf8_upper((U8*)s, tmpbuf2, &ulen2);
 
-                            c1 = utf8_to_uvuni(tmpbuf1, 0);
-                            c2 = utf8_to_uvuni(tmpbuf2, 0);
+                            c1 = utf8n_to_uvuni(tmpbuf1, UTF8_MAXLEN, 0,
+                                                ckWARN(WARN_UTF8) ?
+                                                0 : UTF8_ALLOW_ANY);
+                            c2 = utf8n_to_uvuni(tmpbuf2, UTF8_MAXLEN, 0,
+                                                ckWARN(WARN_UTF8) ?
+                                                0 : UTF8_ALLOW_ANY);
                        }
                        else {
-                           c2 = c1 = utf8_to_uvchr(s, NULL);
+                           c2 = c1 = utf8n_to_uvchr(s, UTF8_MAXLEN, 0,
+                                                    ckWARN(WARN_UTF8) ?
+                                                    0 : UTF8_ALLOW_ANY);
                        }
                    }
                }
@@ -3568,6 +3584,7 @@ S_regmatch(pTHX_ regnode *prog)
                if (c1 != -1000) {
                    char *e; /* Should not check after this */
                    char *old = locinput;
+                   int count = 0;
 
                    if  (n == REG_INFTY) {
                        e = PL_regeol - 1;
@@ -3587,7 +3604,6 @@ S_regmatch(pTHX_ regnode *prog)
                            e = PL_regeol - 1;
                    }
                    while (1) {
-                       int count;
                        /* Find place 'next' could work */
                        if (!do_utf8) {
                            if (c1 == c2) {
@@ -3605,18 +3621,28 @@ S_regmatch(pTHX_ regnode *prog)
                        else {
                            STRLEN len;
                            if (c1 == c2) {
-                               for (count = 0;
-                                    locinput <= e &&
-                                        utf8_to_uvchr((U8*)locinput, &len) != c1;
-                                    count++)
+                               /* count initialised to
+                                * utf8_distance(old, locinput) */
+                               while (locinput <= e &&
+                                      utf8n_to_uvchr((U8*)locinput,
+                                                     UTF8_MAXLEN, &len,
+                                                     ckWARN(WARN_UTF8) ?
+                                                     0 : UTF8_ALLOW_ANY) != (UV)c1) {
                                    locinput += len;
-                               
+                                   count++;
+                               }
                            } else {
-                               for (count = 0; locinput <= e; count++) {
-                                   UV c = utf8_to_uvchr((U8*)locinput, &len);
-                                   if (c == c1 || c == c2)
+                               /* count initialised to
+                                * utf8_distance(old, locinput) */
+                               while (locinput <= e) {
+                                   UV c = utf8n_to_uvchr((U8*)locinput,
+                                                         UTF8_MAXLEN, &len,
+                                                         ckWARN(WARN_UTF8) ?
+                                                         0 : UTF8_ALLOW_ANY);
+                                   if (c == (UV)c1 || c == (UV)c2)
                                        break;
-                                   locinput += len;                    
+                                   locinput += len;
+                                   count++;
                                }
                            }
                        }
@@ -3638,6 +3664,7 @@ S_regmatch(pTHX_ regnode *prog)
                            locinput += UTF8SKIP(locinput);
                        else
                            locinput++;
+                       count = 1;
                    }
                }
                else
@@ -3645,11 +3672,14 @@ S_regmatch(pTHX_ regnode *prog)
                    UV c;
                    if (c1 != -1000) {
                        if (do_utf8)
-                           c = utf8_to_uvchr((U8*)PL_reginput, NULL);
+                           c = utf8n_to_uvchr((U8*)PL_reginput,
+                                              UTF8_MAXLEN, 0,
+                                              ckWARN(WARN_UTF8) ?
+                                              0 : UTF8_ALLOW_ANY);
                        else
                            c = UCHARAT(PL_reginput);
                        /* If it could work, try it. */
-                       if (c == c1 || c == c2)
+                       if (c == (UV)c1 || c == (UV)c2)
                        {
                            TRYPAREN(paren, n, PL_reginput);
                            REGCP_UNWIND(lastcp);
@@ -3692,12 +3722,15 @@ S_regmatch(pTHX_ regnode *prog)
                    while (n >= ln) {
                        if (c1 != -1000) {
                            if (do_utf8)
-                               c = utf8_to_uvchr((U8*)PL_reginput, NULL);
+                               c = utf8n_to_uvchr((U8*)PL_reginput,
+                                                  UTF8_MAXLEN, 0,
+                                                  ckWARN(WARN_UTF8) ?
+                                                  0 : UTF8_ALLOW_ANY);
                            else
                                c = UCHARAT(PL_reginput);
                        }
                        /* If it could work, try it. */
-                       if (c1 == -1000 || c == c1 || c == c2)
+                       if (c1 == -1000 || c == (UV)c1 || c == (UV)c2)
                            {
                                TRYPAREN(paren, n, PL_reginput);
                                REGCP_UNWIND(lastcp);
@@ -3712,12 +3745,15 @@ S_regmatch(pTHX_ regnode *prog)
                    while (n >= ln) {
                        if (c1 != -1000) {
                            if (do_utf8)
-                               c = utf8_to_uvchr((U8*)PL_reginput, NULL);
+                               c = utf8n_to_uvchr((U8*)PL_reginput,
+                                                  UTF8_MAXLEN, 0,
+                                                  ckWARN(WARN_UTF8) ?
+                                                  0 : UTF8_ALLOW_ANY);
                            else
                                c = UCHARAT(PL_reginput);
                        }
                        /* If it could work, try it. */
-                       if (c1 == -1000 || c == c1 || c == c2)
+                       if (c1 == -1000 || c == (UV)c1 || c == (UV)c2)
                            {
                                TRYPAREN(paren, n, PL_reginput);
                                REGCP_UNWIND(lastcp);
@@ -4294,7 +4330,8 @@ S_reginclass(pTHX_ register regnode *n, register U8* p, STRLEN* lenp, register b
     STRLEN len = 0;
     STRLEN plen;
 
-    c = do_utf8 ? utf8_to_uvchr(p, &len) : *p;
+    c = do_utf8 ? utf8n_to_uvchr(p, UTF8_MAXLEN, &len,
+                                ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY) : *p;
 
     plen = lenp ? *lenp : UNISKIP(NATIVE_TO_UNI(c));
     if (do_utf8 || (flags & ANYOF_UNICODE)) {
@@ -4347,7 +4384,7 @@ S_reginclass(pTHX_ register regnode *n, register U8* p, STRLEN* lenp, register b
        if (ANYOF_BITMAP_TEST(n, c))
            match = TRUE;
        else if (flags & ANYOF_FOLD) {
-         I32 f;
+           U8 f;
 
            if (flags & ANYOF_LOCALE) {
                PL_reg_flags |= RF_tainted;