.
[gnulib.git] / lib / regex.c
index 2d28eda..2edcc42 100644 (file)
@@ -3,7 +3,7 @@
    (Implements POSIX draft P10003.2/D11.2, except for
    internationalization features.)
 
-   Copyright (C) 1993 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1994 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@
 #define _GNU_SOURCE
 
 #ifdef HAVE_CONFIG_H
-#if defined (CONFIG_BROKETS)
+#if defined (emacs) || defined (CONFIG_BROKETS)
 /* We use <config.h> instead of "config.h" so that a compilation
    using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
    (which it would do because it found this file in $srcdir).  */
 /* We need this for `regex.h', and perhaps for the Emacs include files.  */
 #include <sys/types.h>
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 /* The `emacs' switch turns on certain matching commands
    that make sense only in Emacs. */
 #ifdef emacs
@@ -67,6 +63,7 @@ char *realloc ();
 
 /* We used to test for `BSTRING' here, but only GCC and Emacs define
    `BSTRING', as far as I know, and neither of them use this code.  */
+#ifndef INHIBIT_STRING_HEADER
 #if HAVE_STRING_H || STDC_HEADERS
 #include <string.h>
 #ifndef bcmp
@@ -81,6 +78,7 @@ char *realloc ();
 #else
 #include <strings.h>
 #endif
+#endif
 
 /* Define the syntax stuff for \<, \>, etc.  */
 
@@ -256,12 +254,16 @@ char *alloca ();
 
 #define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
 
+#undef MAX
+#undef MIN
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 
 typedef char boolean;
 #define false 0
 #define true 1
+
+static int re_match_2_internal ();
 \f
 /* These are the command codes that appear in compiled regular
    expressions.  Some opcodes are followed by argument bytes.  A
@@ -778,7 +780,7 @@ print_compiled_pattern (bufp)
   unsigned char *buffer = bufp->buffer;
 
   print_partial_compiled_pattern (buffer, buffer + bufp->used);
-  printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated);
+  printf ("%ld bytes used/%ld bytes allocated.\n", bufp->used, bufp->allocated);
 
   if (bufp->fastmap_accurate && bufp->fastmap)
     {
@@ -888,7 +890,7 @@ static const char *re_error_msg[] =
 \f
 /* Avoiding alloca during matching, to placate r_alloc.  */
 
-/* Define MATCH_MAY_ALLOCATE if we need to make sure that the
+/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
    searching and matching functions should not call alloca.  On some
    systems, alloca is implemented in terms of malloc, and if we're
    using the relocating allocator routines, then malloc could cause a
@@ -1001,11 +1003,15 @@ typedef struct
     : ((fail_stack).stack[(fail_stack).avail++] = pattern_op,          \
        1))
 
-/* This pushes an item onto the failure stack.  Must be a four-byte
-   value.  Assumes the variable `fail_stack'.  Probably should only
-   be called from within `PUSH_FAILURE_POINT'.  */
+/* This pushes an item onto the failure stack.  sizeof(ITEM) must be no
+   larger than sizeof (unsigned char *).  Assumes the variable `fail_stack'.
+   Probably should only be called from within `PUSH_FAILURE_POINT'.  */
 #define PUSH_FAILURE_ITEM(item)                                                \
-  fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) item
+  do                                                                   \
+    {                                                                  \
+      fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) item;  \
+    }                                                                  \
+  while (0)                                                            \
 
 /* The complement operation.  Assumes `fail_stack' is nonempty.  */
 #define POP_FAILURE_ITEM() fail_stack.stack[--fail_stack.avail]
@@ -1172,10 +1178,10 @@ typedef struct
   DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend);                      \
                                                                        \
   /* Restore register info.  */                                                \
-  high_reg = (unsigned) POP_FAILURE_ITEM ();                           \
+  high_reg = (unsigned long) POP_FAILURE_ITEM ();                      \
   DEBUG_PRINT2 ("  Popping high active reg: %d\n", high_reg);          \
                                                                        \
-  low_reg = (unsigned) POP_FAILURE_ITEM ();                            \
+  low_reg = (unsigned long) POP_FAILURE_ITEM ();                       \
   DEBUG_PRINT2 ("  Popping  low active reg: %d\n", low_reg);           \
                                                                        \
   for (this_reg = high_reg; this_reg >= low_reg; this_reg--)           \
@@ -1500,7 +1506,7 @@ regex_compile (pattern, size, syntax, bufp)
      they can be reliably used as array indices.  */
   register unsigned char c, c1;
   
-  /* A random tempory spot in PATTERN.  */
+  /* A random temporary spot in PATTERN.  */
   const char *p1;
 
   /* Points to the end of the buffer, where we should append.  */
@@ -2249,7 +2255,7 @@ regex_compile (pattern, size, syntax, bufp)
                     we're all done, the pattern will look like:
                       set_number_at <jump count> <upper bound>
                       set_number_at <succeed_n count> <lower bound>
-                      succeed_n <after jump addr> <succed_n count>
+                      succeed_n <after jump addr> <succeed_n count>
                       <body of loop>
                       jump_n <succeed_n addr> <jump count>
                     (The upper bound and `jump_n' are omitted if
@@ -2492,16 +2498,32 @@ regex_compile (pattern, size, syntax, bufp)
     /* Since DOUBLE_FAIL_STACK refuses to double only if the current size
        is strictly greater than re_max_failures, the largest possible stack
        is 2 * re_max_failures failure points.  */
-    fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
-    if (fail_stack.stack)
-      fail_stack.stack =
-       (fail_stack_elt_t *) realloc (fail_stack.stack,
-                                     (fail_stack.size
-                                      * sizeof (fail_stack_elt_t)));
-    else
-      fail_stack.stack =
-       (fail_stack_elt_t *) malloc (fail_stack.size 
-                                    * sizeof (fail_stack_elt_t));
+    if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS))
+      {
+       fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
+
+#ifdef emacs
+       if (! fail_stack.stack)
+         fail_stack.stack
+           = (fail_stack_elt_t *) xmalloc (fail_stack.size 
+                                           * sizeof (fail_stack_elt_t));
+       else
+         fail_stack.stack
+           = (fail_stack_elt_t *) xrealloc (fail_stack.stack,
+                                            (fail_stack.size
+                                             * sizeof (fail_stack_elt_t)));
+#else /* not emacs */
+       if (! fail_stack.stack)
+         fail_stack.stack
+           = (fail_stack_elt_t *) malloc (fail_stack.size 
+                                          * sizeof (fail_stack_elt_t));
+       else
+         fail_stack.stack
+           = (fail_stack_elt_t *) realloc (fail_stack.stack,
+                                           (fail_stack.size
+                                            * sizeof (fail_stack_elt_t)));
+#endif /* not emacs */
+      }
 
     /* Initialize some other variables the matcher uses.  */
     RETALLOC_IF (regstart,      num_regs, const char *);
@@ -3156,8 +3178,14 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
           && !bufp->can_be_null)
        return -1;
 
-      val = re_match_2 (bufp, string1, size1, string2, size2,
-                       startpos, regs, stop);
+      val = re_match_2_internal (bufp, string1, size1, string2, size2,
+                                startpos, regs, stop);
+#ifndef REGEX_MALLOC
+#ifdef C_ALLOCA
+      alloca (0);
+#endif
+#endif
+
       if (val >= 0)
        return startpos;
         
@@ -3253,8 +3281,8 @@ static boolean alt_match_null_string_p (),
     FREE_VAR (reg_info_dummy);                                         \
   } while (0)
 #else /* not REGEX_MALLOC */
-/* Some MIPS systems (at least) want this to free alloca'd storage.  */
-#define FREE_VARIABLES() alloca (0)
+/* This used to do alloca (0), but now we do that in the caller.  */
+#define FREE_VARIABLES() /* Nothing */
 #endif /* not REGEX_MALLOC */
 #else
 #define FREE_VARIABLES() /* Do nothing!  */
@@ -3281,8 +3309,11 @@ re_match (bufp, string, size, pos, regs)
      const char *string;
      int size, pos;
      struct re_registers *regs;
- {
-  return re_match_2 (bufp, NULL, 0, string, size, pos, regs, size); 
+{
+  int result = re_match_2_internal (bufp, NULL, 0, string, size,
+                                   pos, regs, size);
+  alloca (0);
+  return result;
 }
 #endif /* not emacs */
 
@@ -3309,6 +3340,23 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
      struct re_registers *regs;
      int stop;
 {
+  int result = re_match_2_internal (bufp, string1, size1, string2, size2,
+                                   pos, regs, stop);
+  alloca (0);
+  return result;
+}
+
+/* This is a separate function so that we can force an alloca cleanup
+   afterwards.  */
+static int
+re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
+     struct re_pattern_buffer *bufp;
+     const char *string1, *string2;
+     int size1, size2;
+     int pos;
+     struct re_registers *regs;
+     int stop;
+{
   /* General temporaries.  */
   int mcnt;
   unsigned char *p1;
@@ -3327,6 +3375,10 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
   unsigned char *p = bufp->buffer;
   register unsigned char *pend = p + bufp->used;
 
+  /* Mark the opcode just after a start_memory, so we can test for an
+     empty subpattern when we get to the stop_memory.  */
+  unsigned char *just_past_start_mem = 0;
+
   /* We use this to map every character in the string.  */
   char *translate = bufp->translate;
 
@@ -3807,6 +3859,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
 
           /* Move past the register number and inner group count.  */
           p += 2;
+         just_past_start_mem = p;
           break;
 
 
@@ -3871,7 +3924,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
              information for this group that we had before trying this
              last match.  */
           if ((!MATCHED_SOMETHING (reg_info[*p])
-               || (re_opcode_t) p[-3] == start_memory)
+               || just_past_start_mem == p - 1)
              && (p + 2) < pend)              
             {
               boolean is_a_jump_n = false;
@@ -3926,7 +3979,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
                           regstart[r] = old_regstart[r];
 
                           /* xx why this test?  */
-                          if ((int) old_regend[r] >= (int) regstart[r])
+                          if (old_regend[r] >= regstart[r])
                             regend[r] = old_regend[r];
                         }     
                     }
@@ -4223,8 +4276,10 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
              }
             else if ((re_opcode_t) *p2 == charset)
              {
+#ifdef DEBUG
                register unsigned char c
                   = *p2 == (unsigned char) endline ? '\n' : p2[2];
+#endif
 
                 if ((re_opcode_t) p1[3] == exactn
                    && ! (p2[1] * BYTEWIDTH > p1[4]
@@ -4293,7 +4348,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
                actual values.  Otherwise, we will restore only one
                register from the stack, since lowest will == highest in
                `pop_failure_point'.  */
-            unsigned dummy_low_reg, dummy_high_reg;
+            unsigned long dummy_low_reg, dummy_high_reg;
             unsigned char *pdummy;
             const char *sdummy;
 
@@ -4425,7 +4480,6 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
           goto fail;
 
 #ifdef emacs
-#ifdef emacs19
        case before_dot:
           DEBUG_PRINT1 ("EXECUTING before_dot.\n");
          if (PTR_CHAR_POS ((unsigned char *) d) >= point)
@@ -4443,7 +4497,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
           if (PTR_CHAR_POS ((unsigned char *) d) <= point)
            goto fail;
          break;
-#else /* not emacs19 */
+#if 0 /* not emacs19 */
        case at_dot:
           DEBUG_PRINT1 ("EXECUTING at_dot.\n");
          if (PTR_CHAR_POS ((unsigned char *) d) + 1 != point)
@@ -4461,8 +4515,10 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
          mcnt = (int) Sword;
         matchsyntax:
          PREFETCH ();
-         if (SYNTAX (*d++) != (enum syntaxcode) mcnt)
-            goto fail;
+         /* Can't use *d++ here; SYNTAX may be an unsafe macro.  */
+         d++;
+         if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt)
+           goto fail;
           SET_REGS_MATCHED ();
          break;
 
@@ -4476,8 +4532,10 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
          mcnt = (int) Sword;
         matchnotsyntax:
          PREFETCH ();
-         if (SYNTAX (*d++) == (enum syntaxcode) mcnt)
-            goto fail;
+         /* Can't use *d++ here; SYNTAX may be an unsafe macro.  */
+         d++;
+         if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt)
+           goto fail;
          SET_REGS_MATCHED ();
           break;