(re_search_2): Use 0, not -1, as the lower bound
[gnulib.git] / regex.c
diff --git a/regex.c b/regex.c
index 1af5ab0..8b26a73 100644 (file)
--- a/regex.c
+++ b/regex.c
@@ -260,7 +260,7 @@ char *alloca ();
 
 /* Define how to allocate the failure stack.  */
 
-#if defined (REL_ALLOC) && !defined (REGEX_MALLOC)
+#if defined (REL_ALLOC) && defined (REGEX_MALLOC)
 
 #define REGEX_ALLOCATE_STACK(size)                             \
   r_alloc (&failure_stack_ptr, (size))
@@ -1153,29 +1153,30 @@ typedef struct
     /* Push the info, starting with the registers.  */                 \
     DEBUG_PRINT1 ("\n");                                               \
                                                                        \
-    for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
-         this_reg++)                                                   \
-      {                                                                        \
-       DEBUG_PRINT2 ("  Pushing reg: %d\n", this_reg);                 \
-        DEBUG_STATEMENT (num_regs_pushed++);                           \
+    if (!RE_NO_POSIX_BACKTRACKING & bufp->syntax)                      \
+      for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
+          this_reg++)                                                  \
+       {                                                               \
+         DEBUG_PRINT2 ("  Pushing reg: %d\n", this_reg);               \
+         DEBUG_STATEMENT (num_regs_pushed++);                          \
                                                                        \
-       DEBUG_PRINT2 ("    start: 0x%x\n", regstart[this_reg]);         \
-        PUSH_FAILURE_POINTER (regstart[this_reg]);                     \
-                                                                        \
-       DEBUG_PRINT2 ("    end: 0x%x\n", regend[this_reg]);             \
-        PUSH_FAILURE_POINTER (regend[this_reg]);                       \
+         DEBUG_PRINT2 ("    start: 0x%x\n", regstart[this_reg]);       \
+         PUSH_FAILURE_POINTER (regstart[this_reg]);                    \
                                                                        \
-       DEBUG_PRINT2 ("    info: 0x%x\n      ", reg_info[this_reg]);    \
-        DEBUG_PRINT2 (" match_null=%d",                                        \
-                      REG_MATCH_NULL_STRING_P (reg_info[this_reg]));   \
-        DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg]));   \
-        DEBUG_PRINT2 (" matched_something=%d",                         \
-                      MATCHED_SOMETHING (reg_info[this_reg]));         \
-        DEBUG_PRINT2 (" ever_matched=%d",                              \
-                      EVER_MATCHED_SOMETHING (reg_info[this_reg]));    \
-       DEBUG_PRINT1 ("\n");                                            \
-        PUSH_FAILURE_ELT (reg_info[this_reg].word);                    \
-      }                                                                        \
+         DEBUG_PRINT2 ("    end: 0x%x\n", regend[this_reg]);           \
+         PUSH_FAILURE_POINTER (regend[this_reg]);                      \
+                                                                       \
+         DEBUG_PRINT2 ("    info: 0x%x\n      ", reg_info[this_reg]);  \
+         DEBUG_PRINT2 (" match_null=%d",                               \
+                       REG_MATCH_NULL_STRING_P (reg_info[this_reg]));  \
+         DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg]));  \
+         DEBUG_PRINT2 (" matched_something=%d",                        \
+                       MATCHED_SOMETHING (reg_info[this_reg]));        \
+         DEBUG_PRINT2 (" ever_matched=%d",                             \
+                       EVER_MATCHED_SOMETHING (reg_info[this_reg]));   \
+         DEBUG_PRINT1 ("\n");                                          \
+         PUSH_FAILURE_ELT (reg_info[this_reg].word);                   \
+       }                                                               \
                                                                        \
     DEBUG_PRINT2 ("  Pushing  low active reg: %d\n", lowest_active_reg);\
     PUSH_FAILURE_INT (lowest_active_reg);                              \
@@ -1212,9 +1213,11 @@ typedef struct
 #define MAX_FAILURE_ITEMS ((num_regs - 1) * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
 
 /* We actually push this many items.  */
-#define NUM_FAILURE_ITEMS                                              \
-  ((highest_active_reg - lowest_active_reg + 1) * NUM_REG_ITEMS        \
-    + NUM_NONREG_ITEMS)
+#define NUM_FAILURE_ITEMS                              \
+  (((RE_NO_POSIX_BACKTRACKING & bufp->syntax           \
+     ? 0 : highest_active_reg - lowest_active_reg + 1) \
+    * NUM_REG_ITEMS)                                   \
+   + NUM_NONREG_ITEMS)
 
 /* How many items can still be added to the stack without overflowing it.  */
 #define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
@@ -1272,19 +1275,20 @@ typedef struct
   low_reg = (unsigned) POP_FAILURE_INT ();                             \
   DEBUG_PRINT2 ("  Popping  low active reg: %d\n", low_reg);           \
                                                                        \
-  for (this_reg = high_reg; this_reg >= low_reg; this_reg--)           \
-    {                                                                  \
-      DEBUG_PRINT2 ("    Popping reg: %d\n", this_reg);                        \
+  if (!RE_NO_POSIX_BACKTRACKING & bufp->syntax)                                \
+    for (this_reg = high_reg; this_reg >= low_reg; this_reg--)         \
+      {                                                                        \
+       DEBUG_PRINT2 ("    Popping reg: %d\n", this_reg);               \
                                                                        \
-      reg_info[this_reg].word = POP_FAILURE_ELT ();                    \
-      DEBUG_PRINT2 ("      info: 0x%x\n", reg_info[this_reg]);         \
+       reg_info[this_reg].word = POP_FAILURE_ELT ();                   \
+       DEBUG_PRINT2 ("      info: 0x%x\n", reg_info[this_reg]);        \
                                                                        \
-      regend[this_reg] = (const char *) POP_FAILURE_POINTER ();                \
-      DEBUG_PRINT2 ("      end: 0x%x\n", regend[this_reg]);            \
+       regend[this_reg] = (const char *) POP_FAILURE_POINTER ();       \
+       DEBUG_PRINT2 ("      end: 0x%x\n", regend[this_reg]);           \
                                                                        \
-      regstart[this_reg] = (const char *) POP_FAILURE_POINTER ();      \
-      DEBUG_PRINT2 ("      start: 0x%x\n", regstart[this_reg]);                \
-    }                                                                  \
+       regstart[this_reg] = (const char *) POP_FAILURE_POINTER ();     \
+       DEBUG_PRINT2 ("      start: 0x%x\n", regstart[this_reg]);       \
+      }                                                                        \
                                                                        \
   set_regs_matched_done = 0;                                           \
   DEBUG_STATEMENT (nfailure_points_popped++);                          \
@@ -3032,7 +3036,7 @@ re_compile_fastmap (bufp)
        case at_dot:
        case after_dot:
           continue;
-#endif /* not emacs */
+#endif /* emacs */
 
 
         case no_op:
@@ -3255,9 +3259,10 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
     return -1;
     
   /* Fix up RANGE if it might eventually take us outside
-     the virtual concatenation of STRING1 and STRING2.  */
-  if (endpos < -1)
-    range = -1 - startpos;
+     the virtual concatenation of STRING1 and STRING2.
+     Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE.  */ 
+  if (endpos < 0)
+    range = 0 - startpos;
   else if (endpos > total_size)
     range = total_size - startpos;
 
@@ -3271,6 +3276,17 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
        range = 1;
     }
 
+#ifdef emacs
+  /* In a forward search for something that starts with \=.
+     don't keep searching past point.  */
+  if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0)
+    {
+      range = PT - startpos;
+      if (range <= 0)
+       return -1;
+    }
+#endif /* emacs */
+
   /* Update the fastmap now if not correct already.  */
   if (fastmap && !bufp->fastmap_accurate)
     if (re_compile_fastmap (bufp) == -2)
@@ -4674,13 +4690,6 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
           if (PTR_CHAR_POS ((unsigned char *) d) <= point)
            goto fail;
          break;
-#if 0 /* not emacs19 */
-       case at_dot:
-          DEBUG_PRINT1 ("EXECUTING at_dot.\n");
-         if (PTR_CHAR_POS ((unsigned char *) d) + 1 != point)
-           goto fail;
-         break;
-#endif /* not emacs19 */
 
        case syntaxspec:
           DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);