Mercurial > emacs
changeset 11622:eba5c25341ff
(PUSH_FAILURE_INT, POP_FAILURE_INT): Use WIDE_INT.
(WIDE_INT): Defined (two alternate definitions).
(C_ALLOCA): Undef it, if __GNUC__.
(REGEX_ALLOCATE_STACK, REGEX_REALLOCATE_STACK)
(REGEX_FREE_STACK): New macros.
(INIT_FAIL_STACK, DOUBLE_FAIL_STACK, FREE_VARIABLES): Use them.
(re_max_failures) [REL_ALLOC]: Alternative larger initial value.
(re_compile_fastmap): Use REGEX_FREE_STACK.
(re_match_2_internal): Always call FREE_VARIABLES before returning.
Always init regstart, old_regstart, etc. whenever MATCH_MAY_ALLOCATE
is defined.
(FREE_VARIABLES) [REL_ALLOC]: Define non-trivially.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sat, 29 Apr 1995 20:21:41 +0000 |
parents | 710b5ce824c2 |
children | 584362605c5e |
files | src/regex.c |
diffstat | 1 files changed, 138 insertions(+), 53 deletions(-) [+] |
line wrap: on
line diff
--- a/src/regex.c Sat Apr 29 19:25:19 1995 +0000 +++ b/src/regex.c Sat Apr 29 20:21:41 1995 +0000 @@ -49,6 +49,8 @@ #include "buffer.h" #include "syntax.h" +#define WIDE_INT EMACS_INT + #else /* not emacs */ #ifdef STDC_HEADERS @@ -58,6 +60,10 @@ 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. */ @@ -209,6 +215,7 @@ #define REGEX_ALLOCATE malloc #define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize) +#define REGEX_FREE free #else /* not REGEX_MALLOC */ @@ -238,8 +245,41 @@ bcopy (source, destination, osize), \ destination) +/* No need to do anything to free, after alloca. */ +#define REGEX_FREE(arg) (0) + #endif /* not REGEX_MALLOC */ +/* Define how to allocate the failure stack. */ + +#ifdef REL_ALLOC +#define REGEX_ALLOCATE_STACK(size) \ + r_alloc (&failure_stack_ptr, (size)) +#define REGEX_REALLOCATE_STACK(source, osize, nsize) \ + r_re_alloc (&failure_stack_ptr, (nsize)) +#define REGEX_FREE_STACK(ptr) \ + r_alloc_free (&failure_stack_ptr) + +#else /* not REL_ALLOC */ + +#ifdef REGEX_MALLOC + +#define REGEX_ALLOCATE_STACK malloc +#define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize) +#define REGEX_FREE_STACK free + +#else /* not REGEX_MALLOC */ + +#define REGEX_ALLOCATE_STACK alloca + +#define REGEX_REALLOCATE_STACK(source, osize, nsize) \ + REGEX_REALLOCATE (source, osize, nsize) +/* No need to explicitly free anything. */ +#define REGEX_FREE_STACK(arg) + +#endif /* not REGEX_MALLOC */ +#endif /* not REL_ALLOC */ + /* True if `size1' is non-NULL and PTR is pointing anywhere inside `string1' or just past its end. This works if PTR is NULL, which is @@ -915,6 +955,12 @@ /* Normally, this is fine. */ #define MATCH_MAY_ALLOCATE +/* When using GNU C, we are not REALLY using the C alloca, no matter + what config.h may say. So don't take precautions for it. */ +#ifdef __GNUC__ +#undef C_ALLOCA +#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)) @@ -924,7 +970,7 @@ /* Failure stack declarations and macros; both re_compile_fastmap and re_match_2 use a failure stack. These have to be macros because of - REGEX_ALLOCATE. */ + REGEX_ALLOCATE_STACK. */ /* Number of failure points for which to initially allocate space @@ -938,7 +984,11 @@ 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; +#else int re_max_failures = 2000; +#endif typedef unsigned char *fail_stack_elt_t; @@ -961,7 +1011,7 @@ #define INIT_FAIL_STACK() \ do { \ fail_stack.stack = (fail_stack_elt_t *) \ - REGEX_ALLOCATE (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \ + REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \ \ if (fail_stack.stack == NULL) \ return -2; \ @@ -982,13 +1032,13 @@ Return 1 if succeeds, and 0 if either ran out of memory allocating space for it or it was already too large. - REGEX_REALLOCATE requires `destination' be declared. */ + REGEX_REALLOCATE_STACK requires `destination' be declared. */ #define DOUBLE_FAIL_STACK(fail_stack) \ ((fail_stack).size > re_max_failures * MAX_FAILURE_ITEMS \ ? 0 \ : ((fail_stack).stack = (fail_stack_elt_t *) \ - REGEX_REALLOCATE ((fail_stack).stack, \ + REGEX_REALLOCATE_STACK ((fail_stack).stack, \ (fail_stack).size * sizeof (fail_stack_elt_t), \ ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \ \ @@ -1005,9 +1055,9 @@ #define PUSH_PATTERN_OP(pattern_op, fail_stack) \ ((FAIL_STACK_FULL () \ && !DOUBLE_FAIL_STACK (fail_stack)) \ - ? 0 \ - : ((fail_stack).stack[(fail_stack).avail++] = pattern_op, \ - 1)) + ? 0 \ + : ((fail_stack).stack[(fail_stack).avail++] = pattern_op, \ + 1)) /* Push a pointer value onto the failure stack. Assumes the variable `fail_stack'. Probably should only @@ -1019,13 +1069,13 @@ 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) (EMACS_INT) (item) + fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) (WIDE_INT) (item) /* The complement operation. Assumes `fail_stack' is nonempty. */ #define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail] /* The complement operation. Assumes `fail_stack' is nonempty. */ -#define POP_FAILURE_INT() (EMACS_INT) fail_stack.stack[--fail_stack.avail] +#define POP_FAILURE_INT() (WIDE_INT) fail_stack.stack[--fail_stack.avail] /* Used to omit pushing failure point id's when we're not debugging. */ #ifdef DEBUG @@ -1065,7 +1115,7 @@ /* Ensure we have enough space allocated for what we will push. */ \ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \ { \ - if (!DOUBLE_FAIL_STACK (fail_stack)) \ + if (!DOUBLE_FAIL_STACK (fail_stack)) \ return failure_code; \ \ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \ @@ -1271,23 +1321,6 @@ static char reg_unset_dummy; #define REG_UNSET_VALUE (®_unset_dummy) #define REG_UNSET(e) ((e) == REG_UNSET_VALUE) - - - -/* How do we implement a missing MATCH_MAY_ALLOCATE? - We make the fail stack a global thing, and then grow it to - re_max_failures when we compile. */ -#ifndef MATCH_MAY_ALLOCATE -static fail_stack_type fail_stack; - -static const char ** regstart, ** regend; -static const char ** old_regstart, ** old_regend; -static const char **best_regstart, **best_regend; -static register_info_type *reg_info; -static const char **reg_dummy; -static register_info_type *reg_info_dummy; -#endif - /* Subroutine declarations and macros for regex_compile. */ @@ -1492,6 +1525,54 @@ || STREQ (string, "punct") || STREQ (string, "graph") \ || STREQ (string, "cntrl") || STREQ (string, "blank")) +#ifndef MATCH_MAY_ALLOCATE + +/* If we cannot allocate large objects within re_match_2_internal, + we make the fail stack and register vectors global. + The fail stack, we grow to the maximum size when a regexp + is compiled. + The register vectors, we adjust in size each time we + compile a regexp, according to the number of registers it needs. */ + +static fail_stack_type fail_stack; + +/* Size with which the following vectors are currently allocated. + That is so we can make them bigger as needed, + but never make them smaller. */ +static int regs_allocated_size; + +static const char ** regstart, ** regend; +static const char ** old_regstart, ** old_regend; +static const char **best_regstart, **best_regend; +static register_info_type *reg_info; +static const char **reg_dummy; +static register_info_type *reg_info_dummy; + +/* Make the register vectors big enough for NUM_REGS registers, + but don't make them smaller. */ + +static +regex_grow_registers (num_regs) + int num_regs; +{ + if (num_regs > regs_allocated_size) + { + RETALLOC_IF (regstart, num_regs, const char *); + RETALLOC_IF (regend, num_regs, const char *); + RETALLOC_IF (old_regstart, num_regs, const char *); + RETALLOC_IF (old_regend, num_regs, const char *); + RETALLOC_IF (best_regstart, num_regs, const char *); + RETALLOC_IF (best_regend, num_regs, const char *); + RETALLOC_IF (reg_info, num_regs, register_info_type); + RETALLOC_IF (reg_dummy, num_regs, const char *); + RETALLOC_IF (reg_info_dummy, num_regs, register_info_type); + + regs_allocated_size = num_regs; + } +} + +#endif /* not MATCH_MAY_ALLOCATE */ + /* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. Returns one of error codes defined in `regex.h', or zero for success. @@ -2555,18 +2636,9 @@ #endif /* not emacs */ } - /* Initialize some other variables the matcher uses. */ - RETALLOC_IF (regstart, num_regs, const char *); - RETALLOC_IF (regend, num_regs, const char *); - RETALLOC_IF (old_regstart, num_regs, const char *); - RETALLOC_IF (old_regend, num_regs, const char *); - RETALLOC_IF (best_regstart, num_regs, const char *); - RETALLOC_IF (best_regend, num_regs, const char *); - RETALLOC_IF (reg_info, num_regs, register_info_type); - RETALLOC_IF (reg_dummy, num_regs, const char *); - RETALLOC_IF (reg_info_dummy, num_regs, register_info_type); + regex_grow_registers (num_regs); } -#endif +#endif /* not MATCH_MAY_ALLOCATE */ return REG_NOERROR; } /* regex_compile */ @@ -2791,6 +2863,10 @@ unsigned char *p = pattern; register unsigned char *pend = pattern + size; + /* This holds the pointer to the failure stack, when + it is allocated relocatably. */ + fail_stack_elt_t *failure_stack_ptr; + /* Assume that each path through the pattern can be null until proven otherwise. We set this false at the bottom of switch statement, to which we get only if a particular path doesn't @@ -2840,7 +2916,7 @@ that is all we do. */ case duplicate: bufp->can_be_null = 1; - return 0; + goto done; /* Following are the cases which match a character. These end @@ -2898,7 +2974,7 @@ /* Return if we have already set `can_be_null'; if we have, then the fastmap is irrelevant. Something's wrong here. */ else if (bufp->can_be_null) - return 0; + goto done; /* Otherwise, have to check alternative paths. */ break; @@ -2992,7 +3068,10 @@ if (p + j < pend) { if (!PUSH_PATTERN_OP (p + j, fail_stack)) - return -2; + { + REGEX_FREE_STACK (fail_stack.stack); + return -2; + } } else bufp->can_be_null = 1; @@ -3049,6 +3128,9 @@ /* Set `can_be_null' for the last path (also the first path, if the pattern is empty). */ bufp->can_be_null |= path_can_be_null; + + done: + REGEX_FREE_STACK (fail_stack.stack); return 0; } /* re_compile_fastmap */ @@ -3303,11 +3385,10 @@ /* Free everything we malloc. */ #ifdef MATCH_MAY_ALLOCATE -#ifdef REGEX_MALLOC -#define FREE_VAR(var) if (var) free (var); var = NULL +#define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL #define FREE_VARIABLES() \ do { \ - FREE_VAR (fail_stack.stack); \ + REGEX_FREE_STACK (fail_stack.stack); \ FREE_VAR (regstart); \ FREE_VAR (regend); \ FREE_VAR (old_regstart); \ @@ -3318,10 +3399,6 @@ FREE_VAR (reg_dummy); \ FREE_VAR (reg_info_dummy); \ } while (0) -#else /* not REGEX_MALLOC */ -/* 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! */ #endif /* not MATCH_MAY_ALLOCATE */ @@ -3437,6 +3514,10 @@ unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0; #endif + /* This holds the pointer to the failure stack, when + it is allocated relocatably. */ + fail_stack_elt_t *failure_stack_ptr; + /* We fill all the registers internally, independent of what we return, for use in backreferences. The number here includes an element for register zero. */ @@ -3538,7 +3619,6 @@ return -2; } } -#if defined (REGEX_MALLOC) else { /* We must initialize all our variables to NULL, so that @@ -3547,7 +3627,6 @@ = best_regend = reg_dummy = NULL; reg_info = reg_info_dummy = (register_info_type *) NULL; } -#endif /* REGEX_MALLOC */ #endif /* MATCH_MAY_ALLOCATE */ /* The starting position is bogus. */ @@ -3709,7 +3788,10 @@ regs->start = TALLOC (regs->num_regs, regoff_t); regs->end = TALLOC (regs->num_regs, regoff_t); if (regs->start == NULL || regs->end == NULL) - return -2; + { + FREE_VARIABLES (); + return -2; + } bufp->regs_allocated = REGS_REALLOCATE; } else if (bufp->regs_allocated == REGS_REALLOCATE) @@ -3722,7 +3804,10 @@ RETALLOC (regs->start, regs->num_regs, regoff_t); RETALLOC (regs->end, regs->num_regs, regoff_t); if (regs->start == NULL || regs->end == NULL) - return -2; + { + FREE_VARIABLES (); + return -2; + } } } else @@ -3767,7 +3852,6 @@ regs->start[mcnt] = regs->end[mcnt] = -1; } /* regs && !bufp->no_sub */ - FREE_VARIABLES (); DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n", nfailure_points_pushed, nfailure_points_popped, nfailure_points_pushed - nfailure_points_popped); @@ -3779,6 +3863,7 @@ DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); + FREE_VARIABLES (); return mcnt; }