X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fregex.c;h=354aba807fbb3cc80cd3c48398df2800a7c2df7b;hb=b80c3874f57e48b2f44192cc3cc1cc93cef6e8d4;hp=ec1b17ddf1a3f668e1a610df5e4a3ac3461927e0;hpb=b5da073416f93f9f145ac9eb44794775fbf6a752;p=gnulib.git diff --git a/lib/regex.c b/lib/regex.c index ec1b17ddf..354aba807 100644 --- a/lib/regex.c +++ b/lib/regex.c @@ -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 -/* 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 #else # define gettext(msgid) (msgid) @@ -49,26 +48,24 @@ #include "buffer.h" #include "syntax.h" -#define WIDE_INT EMACS_INT - #else /* not emacs */ -#ifdef STDC_HEADERS +/* If we are not linking with Emacs proper, + we can't use the relocating allocator + even if config.h says that we can. */ +#undef REL_ALLOC + +#if defined (STDC_HEADERS) || defined (_LIBC) #include #else char *malloc (); char *realloc (); #endif -/* This isn't right--it needs to check for machines with 64-bit pointers - and do something different. But I don't know what, and I don't - need to deal with it right now. -- rms. */ -#define WIDE_INT int - /* 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 +#if HAVE_STRING_H || STDC_HEADERS || defined (_LIBC) #include #ifndef bcmp #define bcmp(s1, s2, n) memcmp ((s1), (s2), (n)) @@ -246,7 +243,7 @@ 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 */ @@ -962,8 +959,11 @@ static const char *re_error_msgid[] = #endif /* The match routines may not allocate if (1) they would do it with malloc - and (2) it's not safe for them to use malloc. */ -#if (defined (C_ALLOCA) || defined (REGEX_MALLOC)) && (defined (emacs) || defined (REL_ALLOC)) + and (2) it's not safe for them to use malloc. + Note that if REL_ALLOC is defined, matching would not use malloc for the + failure stack, but we would still use it for the register vectors; + so REL_ALLOC should not affect this. */ +#if (defined (C_ALLOCA) || defined (REGEX_MALLOC)) && defined (emacs) #undef MATCH_MAY_ALLOCATE #endif @@ -984,13 +984,19 @@ static const char *re_error_msgid[] = exactly that if always used MAX_FAILURE_SPACE each time we failed. This is a variable only so users of regex can assign to it; we never change it ourselves. */ -#ifdef REL_ALLOC -int re_max_failures = 20000000; +#if defined (MATCH_MAY_ALLOCATE) +int re_max_failures = 200000; #else int re_max_failures = 2000; #endif -typedef unsigned char *fail_stack_elt_t; +union fail_stack_elt +{ + unsigned char *pointer; + int integer; +}; + +typedef union fail_stack_elt fail_stack_elt_t; typedef struct { @@ -1002,10 +1008,10 @@ typedef struct #define FAIL_STACK_EMPTY() (fail_stack.avail == 0) #define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0) #define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size) -#define FAIL_STACK_TOP() (fail_stack.stack[fail_stack.avail]) -/* 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() \ @@ -1019,11 +1025,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 @@ -1048,34 +1058,39 @@ typedef struct 1))) -/* Push PATTERN_OP on FAIL_STACK. - +/* Push pointer POINTER on FAIL_STACK. Return 1 if was able to do so and 0 if ran out of memory allocating space to do so. */ -#define PUSH_PATTERN_OP(pattern_op, fail_stack) \ +#define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \ ((FAIL_STACK_FULL () \ - && !DOUBLE_FAIL_STACK (fail_stack)) \ + && !DOUBLE_FAIL_STACK (FAIL_STACK)) \ ? 0 \ - : ((fail_stack).stack[(fail_stack).avail++] = pattern_op, \ + : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \ 1)) /* Push a pointer value onto the failure stack. Assumes the variable `fail_stack'. Probably should only be called from within `PUSH_FAILURE_POINT'. */ #define PUSH_FAILURE_POINTER(item) \ - fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) (item) + fail_stack.stack[fail_stack.avail++].pointer = (unsigned char *) (item) /* This pushes an integer-valued item onto the failure stack. Assumes the variable `fail_stack'. Probably should only be called from within `PUSH_FAILURE_POINT'. */ #define PUSH_FAILURE_INT(item) \ - fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) (WIDE_INT) (item) + fail_stack.stack[fail_stack.avail++].integer = (item) -/* The complement operation. Assumes `fail_stack' is nonempty. */ -#define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail] +/* Push a fail_stack_elt_t value onto the failure stack. + Assumes the variable `fail_stack'. Probably should only + be called from within `PUSH_FAILURE_POINT'. */ +#define PUSH_FAILURE_ELT(item) \ + fail_stack.stack[fail_stack.avail++] = (item) -/* The complement operation. Assumes `fail_stack' is nonempty. */ -#define POP_FAILURE_INT() (WIDE_INT) fail_stack.stack[--fail_stack.avail] +/* These three POP... operations complement the three PUSH... operations. + All assume that `fail_stack' is nonempty. */ +#define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer +#define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer +#define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail] /* Used to omit pushing failure point id's when we're not debugging. */ #ifdef DEBUG @@ -1147,7 +1162,7 @@ typedef struct DEBUG_PRINT2 (" ever_matched=%d", \ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \ DEBUG_PRINT1 ("\n"); \ - PUSH_FAILURE_POINTER (reg_info[this_reg].word); \ + PUSH_FAILURE_ELT (reg_info[this_reg].word); \ } \ \ DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\ @@ -1249,7 +1264,7 @@ typedef struct { \ DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \ \ - reg_info[this_reg].word = POP_FAILURE_POINTER (); \ + 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 (); \ @@ -1266,8 +1281,7 @@ typedef struct /* Structure for per-register (a.k.a. per-group) information. - This must not be longer than one word, because we push this value - onto the failure stack. Other register information, such as the + Other register information, such as the starting and ending positions (which are addresses), and the list of inner groups (which is a bits list) are maintained in separate variables. @@ -1276,6 +1290,7 @@ typedef struct the compiler will pack our bit fields into something that fits into the type of `word', i.e., is something that fits into one item on the failure stack. */ + typedef union { fail_stack_elt_t word; @@ -2897,7 +2912,7 @@ re_compile_fastmap (bufp) /* Reset for next path. */ path_can_be_null = true; - p = fail_stack.stack[--fail_stack.avail]; + p = fail_stack.stack[--fail_stack.avail].pointer; continue; } @@ -3049,7 +3064,7 @@ re_compile_fastmap (bufp) /* If what's on the stack is where we are now, pop it. */ if (!FAIL_STACK_EMPTY () - && fail_stack.stack[fail_stack.avail - 1] == p) + && fail_stack.stack[fail_stack.avail - 1].pointer == p) fail_stack.avail--; continue; @@ -3071,7 +3086,7 @@ re_compile_fastmap (bufp) { if (!PUSH_PATTERN_OP (p + j, fail_stack)) { - REGEX_FREE_STACK (fail_stack.stack); + RESET_FAIL_STACK (); return -2; } } @@ -3132,7 +3147,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 */ @@ -3402,7 +3417,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