[REL_ALLOC]: #ifdef-out dcls of unused variables.
[gnulib.git] / lib / regex.c
index cb7e96e..ca485a8 100644 (file)
@@ -3,7 +3,7 @@
    (Implements POSIX draft P10003.2/D11.2, except for
    internationalization features.)
 
-   Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1994, 1995 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
@@ -33,9 +33,8 @@
 /* We need this for `regex.h', and perhaps for the Emacs include files.  */
 #include <sys/types.h>
 
-/* This is for other GNU distributions with internationalized messages.
-   The GNU C Library itself does not yet support such messages.  */
-#if HAVE_LIBINTL_H
+/* This is for other GNU distributions with internationalized messages.  */
+#if HAVE_LIBINTL_H || defined (_LIBC)
 # include <libintl.h>
 #else
 # define gettext(msgid) (msgid)
    even if config.h says that we can.  */
 #undef REL_ALLOC
 
-#ifdef STDC_HEADERS
+#if defined (STDC_HEADERS) || defined (_LIBC)
 #include <stdlib.h>
 #else
 char *malloc ();
 char *realloc ();
 #endif
 
-/* 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.  */
+/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow.
+   If nothing else has been done, use the method below.  */
+#ifdef INHIBIT_STRING_HEADER
+#if !(defined (HAVE_BZERO) && defined (HAVE_BCOPY))
+#if !defined (bzero) && !defined (bcopy)
+#undef INHIBIT_STRING_HEADER
+#endif
+#endif
+#endif
+
+/* This is the normal way of making sure we have a bcopy and a bzero.
+   This is used in most programs--a few other programs avoid this
+   by defining INHIBIT_STRING_HEADER.  */
 #ifndef INHIBIT_STRING_HEADER
-#if HAVE_STRING_H || STDC_HEADERS
+#if defined (HAVE_STRING_H) || defined (STDC_HEADERS) || defined (_LIBC)
 #include <string.h>
 #ifndef bcmp
 #define bcmp(s1, s2, n)        memcmp ((s1), (s2), (n))
@@ -184,7 +194,7 @@ init_syntax_once ()
 #define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
 
 #ifndef NULL
-#define NULL 0
+#define NULL (void *)0
 #endif
 
 /* We remove any previous definition of `SIGN_EXTEND_CHAR',
@@ -228,7 +238,11 @@ init_syntax_once ()
 #include <alloca.h>
 #else /* not __GNUC__ or HAVE_ALLOCA_H */
 #ifndef _AIX /* Already did AIX, up at the top.  */
+#if defined (__STDC__) && __STDC__
+void *alloca ();
+#else
 char *alloca ();
+#endif
 #endif /* not _AIX */
 #endif /* not HAVE_ALLOCA_H */ 
 #endif /* not __GNUC__ */
@@ -244,13 +258,14 @@ char *alloca ();
    destination)
 
 /* No need to do anything to free, after alloca.  */
-#define REGEX_FREE(arg) while (0)
+#define REGEX_FREE(arg) ((void)0) /* Do nothing!  But inhibit gcc warning.  */
 
 #endif /* not REGEX_MALLOC */
 
 /* Define how to allocate the failure stack.  */
 
-#ifdef REL_ALLOC
+#if defined (REL_ALLOC) && defined (REGEX_MALLOC)
+
 #define REGEX_ALLOCATE_STACK(size)                             \
   r_alloc (&failure_stack_ptr, (size))
 #define REGEX_REALLOCATE_STACK(source, osize, nsize)           \
@@ -258,7 +273,7 @@ char *alloca ();
 #define REGEX_FREE_STACK(ptr)                                  \
   r_alloc_free (&failure_stack_ptr)
 
-#else /* not REL_ALLOC */
+#else /* not using relocating allocator */
 
 #ifdef REGEX_MALLOC
 
@@ -276,7 +291,7 @@ char *alloca ();
 #define REGEX_FREE_STACK(arg)
 
 #endif /* not REGEX_MALLOC */
-#endif /* not REL_ALLOC */
+#endif /* not using relocating allocator */
 
 
 /* True if `size1' is non-NULL and PTR is pointing anywhere inside
@@ -1011,7 +1026,8 @@ typedef struct
 #define FAIL_STACK_FULL()      (fail_stack.avail == fail_stack.size)
 
 
-/* Initialize `fail_stack'.  Do `return -2' if the alloc fails.  */
+/* Define macros to initialize and free the failure stack.
+   Do `return -2' if the alloc fails.  */
 
 #ifdef MATCH_MAY_ALLOCATE
 #define INIT_FAIL_STACK()                                              \
@@ -1025,11 +1041,15 @@ typedef struct
     fail_stack.size = INIT_FAILURE_ALLOC;                              \
     fail_stack.avail = 0;                                              \
   } while (0)
+
+#define RESET_FAIL_STACK()  REGEX_FREE_STACK (fail_stack.stack)
 #else
 #define INIT_FAIL_STACK()                                              \
   do {                                                                 \
     fail_stack.avail = 0;                                              \
   } while (0)
+
+#define RESET_FAIL_STACK()
 #endif
 
 
@@ -1137,29 +1157,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);                              \
@@ -1196,9 +1217,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)
@@ -1256,19 +1279,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++);                          \
@@ -2752,7 +2776,7 @@ at_endline_loc_p (p, pend, syntax)
 {
   const char *next = p;
   boolean next_backslash = *next == '\\';
-  const char *next_next = p + 1 < pend ? p + 1 : NULL;
+  const char *next_next = p + 1 < pend ? p + 1 : 0;
   
   return
        /* Before a subexpression?  */
@@ -3018,7 +3042,7 @@ re_compile_fastmap (bufp)
        case at_dot:
        case after_dot:
           continue;
-#endif /* not emacs */
+#endif /* emacs */
 
 
         case no_op:
@@ -3082,7 +3106,7 @@ re_compile_fastmap (bufp)
             {
               if (!PUSH_PATTERN_OP (p + j, fail_stack))
                {
-                 REGEX_FREE_STACK (fail_stack.stack);
+                 RESET_FAIL_STACK ();
                  return -2;
                }
             }
@@ -3143,7 +3167,7 @@ re_compile_fastmap (bufp)
   bufp->can_be_null |= path_can_be_null;
 
  done:
-  REGEX_FREE_STACK (fail_stack.stack);
+  RESET_FAIL_STACK ();
   return 0;
 } /* re_compile_fastmap */
 \f
@@ -3257,6 +3281,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)
@@ -3413,7 +3448,7 @@ static boolean alt_match_null_string_p (),
     FREE_VAR (reg_info_dummy);                                         \
   } while (0)
 #else
-#define FREE_VARIABLES() /* Do nothing!  */
+#define FREE_VARIABLES() ((void)0) /* Do nothing!  But inhibit gcc warning.  */
 #endif /* not MATCH_MAY_ALLOCATE */
 
 /* These values must meet several constraints.  They must not be valid
@@ -4662,13 +4697,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);