X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=regex.c;h=8b26a7375599a9cae188ffa27f5f8f0058a20d93;hb=58d50470ab1a18a4334189fdf4ab9cd95f440c66;hp=74fca1cbbae6c8823db708f393b87b544a4158b7;hpb=d5dda41714dfd46d53e2b1b7efc64a1b2289e8a7;p=gnulib.git diff --git a/regex.c b/regex.c index 74fca1cbb..8b26a7375 100644 --- a/regex.c +++ b/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) @@ -56,17 +55,28 @@ even if config.h says that we can. */ #undef REL_ALLOC -#ifdef STDC_HEADERS +#if defined (STDC_HEADERS) || defined (_LIBC) #include #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 #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', @@ -244,13 +254,14 @@ char *alloca (); destination) /* No need to do anything to free, after alloca. */ -#define REGEX_FREE(arg) (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 +269,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 +287,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 +1022,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 +1037,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 +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); \ @@ -1196,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) @@ -1256,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++); \ @@ -2752,7 +2772,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? */ @@ -3016,7 +3036,7 @@ re_compile_fastmap (bufp) case at_dot: case after_dot: continue; -#endif /* not emacs */ +#endif /* emacs */ case no_op: @@ -3080,7 +3100,7 @@ re_compile_fastmap (bufp) { if (!PUSH_PATTERN_OP (p + j, fail_stack)) { - REGEX_FREE_STACK (fail_stack.stack); + RESET_FAIL_STACK (); return -2; } } @@ -3141,8 +3161,7 @@ re_compile_fastmap (bufp) bufp->can_be_null |= path_can_be_null; done: - if (!FAIL_STACK_EMPTY ()) - REGEX_FREE_STACK (fail_stack.stack); + RESET_FAIL_STACK (); return 0; } /* re_compile_fastmap */ @@ -3240,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; @@ -3256,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) @@ -3412,7 +3443,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 @@ -4659,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);