[PATCH 5.004_60] Fix to MM_VMS.PM
[p5sagit/p5-mst-13.2.git] / regcomp.c
index 6489b78..55576d0 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -60,9 +60,9 @@
 #define REG_COMP_C
 #include "regcomp.h"
 
-#ifdef USE_THREADS
+#ifdef op
 #undef op
-#endif /* USE_THREADS */
+#endif /* op */
 
 static regnode regdummy;
 static char *  regparse;       /* Input-scan pointer. */
@@ -182,6 +182,7 @@ static scan_data_t zero_scan_data = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 #define SF_HAS_PAR             0x80
 #define SF_IN_PAR              0x100
 #define SF_HAS_EVAL            0x200
+#define SCF_DO_SUBSTR          0x400
 
 static void
 scan_commit(scan_data_t *data)
@@ -215,8 +216,6 @@ scan_commit(scan_data_t *data)
     data->flags &= ~SF_BEFORE_EOL;
 }
 
-#define SCF_DO_SUBSTR 1
-
 /* Stops at toplevel WHILEM as well as at `last'. At end *scanp is set
    to the position after last scanned or to NULL. */
 
@@ -340,7 +339,7 @@ study_chunk(regnode **scanp, I32 *deltap, regnode *last, scan_data_t *data, U32
                    scan = next;
                    if (data_fake.flags & (SF_HAS_PAR|SF_IN_PAR))
                        pars++;
-                   if (data_fake.flags & SF_HAS_EVAL)
+                   if (data && (data_fake.flags & SF_HAS_EVAL))
                        data->flags |= SF_HAS_EVAL;
                    if (code == SUSPEND) 
                        break;
@@ -372,7 +371,7 @@ study_chunk(regnode **scanp, I32 *deltap, regnode *last, scan_data_t *data, U32
                    data->last_start_max = is_inf
                        ? I32_MAX : data->pos_min + data->pos_delta; 
                }
-               sv_catpvn(data->last_found, OPERAND(scan)+1, l);
+               sv_catpvn(data->last_found, (char *)(OPERAND(scan)+1), l);
                data->last_end = data->pos_min + l;
                data->pos_min += l; /* As in the first entry. */
                data->flags &= ~SF_BEFORE_EOL;
@@ -586,7 +585,7 @@ study_chunk(regnode **scanp, I32 *deltap, regnode *last, scan_data_t *data, U32
                        data->longest = &(data->longest_float);
                    }
                }
-               if (fl & SF_HAS_EVAL)
+               if (data && (fl & SF_HAS_EVAL))
                    data->flags |= SF_HAS_EVAL;
              optimize_curly_tail:
 #ifdef REGALIGN
@@ -635,7 +634,7 @@ study_chunk(regnode **scanp, I32 *deltap, regnode *last, scan_data_t *data, U32
            }
            if (data && data_fake.flags & (SF_HAS_PAR|SF_IN_PAR))
                pars++;
-           if (data_fake.flags & SF_HAS_EVAL)
+           if (data && (data_fake.flags & SF_HAS_EVAL))
                data->flags |= SF_HAS_EVAL;
        } else if (OP(scan) == OPEN) {
            pars++;
@@ -750,7 +749,7 @@ pregcomp(char *exp, char *xend, PMOP *pm)
     DEBUG_r(
        if (!colorset) {
            int i = 0;
-           char *s = getenv("TERMCAP_COLORS");
+           char *s = PerlEnv_getenv("TERMCAP_COLORS");
            
            colorset = 1;
            if (s) {
@@ -815,6 +814,7 @@ pregcomp(char *exp, char *xend, PMOP *pm)
     if (OP(scan) != BRANCH) {  /* Only one top-level choice. */
        scan_data_t data;
        I32 fake;
+       STRLEN longest_float_length, longest_fixed_length;
 
        StructCopy(&zero_scan_data, &data, scan_data_t);
        first = scan;
@@ -893,7 +893,8 @@ pregcomp(char *exp, char *xend, PMOP *pm)
        scan_commit(&data);
        SvREFCNT_dec(data.last_found);
 
-       if (SvCUR(data.longest_float)
+       longest_float_length = SvCUR(data.longest_float);
+       if (longest_float_length
            || (data.flags & SF_FL_BEFORE_EOL
                && (!(data.flags & SF_FL_BEFORE_MEOL)
                    || (regflags & PMf_MULTILINE)))) {
@@ -914,9 +915,11 @@ pregcomp(char *exp, char *xend, PMOP *pm)
          remove:
            r->float_substr = Nullsv;
            SvREFCNT_dec(data.longest_float);
+           longest_float_length = 0;
        }
 
-       if (SvCUR(data.longest_fixed)
+       longest_fixed_length = SvCUR(data.longest_fixed);
+       if (longest_fixed_length
            || (data.flags & SF_FIX_BEFORE_EOL /* Cannot have SEOL and MULTI */
                && (!(data.flags & SF_FIX_BEFORE_MEOL)
                    || (regflags & PMf_MULTILINE)))) {
@@ -931,10 +934,11 @@ pregcomp(char *exp, char *xend, PMOP *pm)
        } else {
            r->anchored_substr = Nullsv;
            SvREFCNT_dec(data.longest_fixed);
+           longest_fixed_length = 0;
        }
 
        /* A temporary algorithm prefers floated substr to fixed one to dig more info. */
-       if (SvCUR(data.longest_fixed) > SvCUR(data.longest_float)) {
+       if (longest_fixed_length > longest_float_length) {
            r->check_substr = r->anchored_substr;
            r->check_offset_min = r->check_offset_max = r->anchored_offset;
            if (r->reganch & ROPT_ANCH_SINGLE)
@@ -1060,11 +1064,12 @@ reg(I32 paren, I32 *flagp)
                    rx->data->data[n+1] = (void*)av;
                    rx->data->data[n+2] = (void*)sop;
                    SvREFCNT_dec(sv);
+               } else {                /* First pass */
+                   if (tainted)
+                       FAIL("Eval-group in insecure regular expression");
                }
                
                nextchar();
-               if (tainted)
-                   FAIL("Eval-group in insecure regular expression");
                return reganode(EVAL, n);
            }
            case '(':
@@ -1668,7 +1673,7 @@ tryagain:
            ret = reg_node((regflags & PMf_FOLD)
                          ? ((regflags & PMf_LOCALE) ? EXACTFL : EXACTF)
                          : EXACT);
-           s = OPERAND(ret);
+           s = (char *) OPERAND(ret);
            regc(0, s++);               /* save spot for len */
            for (len = 0, p = regparse - 1;
              len < 127 && p < regxend;
@@ -1836,7 +1841,7 @@ regclass(void)
     register I32 def;
     I32 numlen;
 
-    s = opnd = OPERAND(regcode);
+    s = opnd = (char *) OPERAND(regcode);
     ret = reg_node(ANYOF);
     for (Class = 0; Class < 33; Class++)
        regc(0, s++);
@@ -1860,6 +1865,30 @@ regclass(void)
     while (regparse < regxend && *regparse != ']') {
        skipcond:
        Class = UCHARAT(regparse++);
+       if (Class == '[' && regparse + 1 < regxend &&
+           /* I smell either [: or [= or [. -- POSIX has been here, right? */
+           (*regparse == ':' || *regparse == '=' || *regparse == '.')) {
+           char  posixccc = *regparse;
+           char* posixccs = regparse++;
+           
+           while (regparse < regxend && *regparse != posixccc)
+               regparse++;
+           if (regparse == regxend)
+               /* Grandfather lone [:, [=, [. */
+               regparse = posixccs;
+           else {
+               regparse++; /* skip over the posixccc */
+               if (*regparse == ']') {
+                   /* Not Implemented Yet.
+                    * (POSIX Extended Character Classes, that is)
+                    * The text between e.g. [: and :] would start
+                    * at posixccs + 1 and stop at regparse - 2. */
+                   if (dowarn && !SIZE_ONLY)
+                       warn("Character class syntax [%c %c] is reserved for future extensions", posixccc, posixccc);
+                   regparse++; /* skip over the ending ] */
+               }
+           }
+       }
        if (Class == '\\') {
            Class = UCHARAT(regparse++);
            switch (Class) {
@@ -2016,12 +2045,7 @@ nextchar(void)
 - reg_node - emit a node
 */
 static regnode *                       /* Location. */
-#ifdef CAN_PROTOTYPE
 reg_node(U8 op)
-#else
-reg_node(op)
-U8 op;
-#endif
 {
     register regnode *ret;
     register regnode *ptr;
@@ -2049,13 +2073,7 @@ U8 op;
 - reganode - emit a node with an argument
 */
 static regnode *                       /* Location. */
-#ifdef CAN_PROTOTYPE
 reganode(U8 op, U32 arg)
-#else
-reganode(op, arg)
-U8 op;
-U32 arg;
-#endif
 {
     register regnode *ret;
     register regnode *ptr;
@@ -2082,15 +2100,8 @@ U32 arg;
 /*
 - regc - emit (if appropriate) a byte of code
 */
-#ifdef CAN_PROTOTYPE
 static void
 regc(U8 b, char* s)
-#else
-static void
-regc(b, s)
-U8 b;
-char *s;
-#endif
 {
     if (!SIZE_ONLY)
        *s = b;
@@ -2101,15 +2112,8 @@ char *s;
 *
 * Means relocating the operand.
 */
-#ifdef CAN_PROTOTYPE
 static void
 reginsert(U8 op, regnode *opnd)
-#else
-static void
-reginsert(op, opnd)
-U8 op;
-regnode *opnd;
-#endif
 {
     register regnode *src;
     register regnode *dst;
@@ -2656,4 +2660,3 @@ re_croak2(const char* pat1,const char* pat2, va_alist)
     buf[l1] = '\0';                    /* Overwrite \n */
     croak("%s", buf);
 }
-