X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=regex.c;h=3f951afe637af260675c552be6fcf58b3d4401c9;hb=34755e3ad9af170b23223058725e9bd11a5db2ac;hp=5f79663f2314c1f4422fc75bdd922c2666b13c06;hpb=f4b339a2f68d3f2b890becb0a0ff153ad27a97ac;p=gnulib.git diff --git a/regex.c b/regex.c index 5f79663f2..3f951afe6 100644 --- a/regex.c +++ b/regex.c @@ -2,7 +2,7 @@ 0.12. (Implements POSIX draft P10003.2/D11.2, except for internationalization features.) - Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998 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 @@ -27,11 +27,15 @@ #undef _GNU_SOURCE #define _GNU_SOURCE +#ifdef emacs /* Converts the pointer to the char to BEG-based offset from the start. */ #define PTR_TO_OFFSET(d) \ POS_AS_IN_BUFFER (MATCHING_IN_FIRST_STRING \ ? (d) - string1 : (d) - (string2 - size1)) -#define POS_AS_IN_BUFFER(p) ((p) + 1) +#define POS_AS_IN_BUFFER(p) ((p) + (NILP (re_match_object) || BUFFERP (re_match_object))) +#else +#define PTR_TO_OFFSET(d) 0 +#endif #ifdef HAVE_CONFIG_H #include @@ -68,6 +72,7 @@ #include "category.h" #define malloc xmalloc +#define realloc xrealloc #define free xfree #else /* not emacs */ @@ -1539,7 +1544,7 @@ static reg_errcode_t compile_range (); #define PATFETCH(c) \ do {if (p == pend) return REG_EEND; \ c = (unsigned char) *p++; \ - if (translate) c = RE_TRANSLATE (translate, c); \ + if (RE_TRANSLATE_P (translate)) c = RE_TRANSLATE (translate, c); \ } while (0) #endif @@ -1560,7 +1565,8 @@ static reg_errcode_t compile_range (); when we use a character as a subscript we must make it unsigned. */ #ifndef TRANSLATE #define TRANSLATE(d) \ - (translate ? (unsigned) RE_TRANSLATE (translate, (unsigned) (d)) : (d)) + (RE_TRANSLATE_P (translate) \ + ? (unsigned) RE_TRANSLATE (translate, (unsigned) (d)) : (d)) #endif @@ -1872,7 +1878,12 @@ regex_compile (pattern, size, syntax, bufp) compile_stack_type compile_stack; /* Points to the current (ending) position in the pattern. */ +#ifdef AIX + /* `const' makes AIX compiler fail. */ + char *p = pattern; +#else const char *p = pattern; +#endif const char *pend = pattern + size; /* How to translate the characters in the pattern. */ @@ -2892,8 +2903,12 @@ regex_compile (pattern, size, syntax, bufp) p1 = p - 1; /* P1 points the head of C. */ #ifdef emacs if (bufp->multibyte) - /* Set P to the next character boundary. */ - p += MULTIBYTE_FORM_LENGTH (p1, pend - p1) - 1; + { + c = STRING_CHAR (p1, pend - p1); + c = TRANSLATE (c); + /* Set P to the next character boundary. */ + p += MULTIBYTE_FORM_LENGTH (p1, pend - p1) - 1; + } #endif /* If no exactn currently being built. */ if (!pending_exact @@ -2905,14 +2920,14 @@ regex_compile (pattern, size, syntax, bufp) || *pending_exact >= (1 << BYTEWIDTH) - (p - p1) /* If followed by a repetition operator. */ - || *p == '*' || *p == '^' + || (p != pend && (*p == '*' || *p == '^')) || ((syntax & RE_BK_PLUS_QM) - ? *p == '\\' && (p[1] == '+' || p[1] == '?') - : (*p == '+' || *p == '?')) + ? p + 1 < pend && *p == '\\' && (p[1] == '+' || p[1] == '?') + : p != pend && (*p == '+' || *p == '?')) || ((syntax & RE_INTERVALS) && ((syntax & RE_NO_BK_BRACES) - ? *p == '{' - : (p[0] == '\\' && p[1] == '{')))) + ? p != pend && *p == '{' + : p + 1 < pend && p[0] == '\\' && p[1] == '{'))) { /* Start building a new exactn. */ @@ -2922,16 +2937,23 @@ regex_compile (pattern, size, syntax, bufp) pending_exact = b - 1; } - /* Here, C may translated, therefore C may not equal to *P1. */ - while (1) +#ifdef emacs + if (! SINGLE_BYTE_CHAR_P (c)) + { + unsigned char work[4], *str; + int i = CHAR_STRING (c, work, str); + int j; + for (j = 0; j < i; j++) + { + BUF_PUSH (str[j]); + (*pending_exact)++; + } + } + else +#endif { BUF_PUSH (c); (*pending_exact)++; - if (++p1 == p) - break; - - /* Rest of multibyte form should be copied literally. */ - c = *(unsigned char *)p1; } break; } /* switch (c) */ @@ -3301,9 +3323,11 @@ re_compile_fastmap (bufp) case charset_not: - /* Chars beyond end of map must be allowed. End of map is - `127' if bufp->multibyte is nonzero. */ - simple_char_max = bufp->multibyte ? 0x80 : (1 << BYTEWIDTH); + /* Chars beyond end of bitmap are possible matches. + All the single-byte codes can occur in multibyte buffers. + So any that are not listed in the charset + are possible matches, even in multibyte buffers. */ + simple_char_max = (1 << BYTEWIDTH); for (j = CHARSET_BITMAP_SIZE (&p[-1]) * BYTEWIDTH; j < simple_char_max; j++) fastmap[j] = 1; @@ -3330,7 +3354,9 @@ re_compile_fastmap (bufp) case wordchar: - simple_char_max = bufp->multibyte ? 0x80 : (1 << BYTEWIDTH); + /* All the single-byte codes can occur in multibyte buffers, + and they may have word syntax. So do consider them. */ + simple_char_max = (1 << BYTEWIDTH); for (j = 0; j < simple_char_max; j++) if (SYNTAX (j) == Sword) fastmap[j] = 1; @@ -3343,7 +3369,9 @@ re_compile_fastmap (bufp) case notwordchar: - simple_char_max = bufp->multibyte ? 0x80 : (1 << BYTEWIDTH); + /* All the single-byte codes can occur in multibyte buffers, + and they may not have word syntax. So do consider them. */ + simple_char_max = (1 << BYTEWIDTH); for (j = 0; j < simple_char_max; j++) if (SYNTAX (j) != Sword) fastmap[j] = 1; @@ -3359,21 +3387,13 @@ re_compile_fastmap (bufp) { int fastmap_newline = fastmap['\n']; - /* `.' matches anything (but if bufp->multibyte is - nonzero, matches `\000' .. `\127' and possible multibyte - character) ... */ + /* `.' matches anything, except perhaps newline. + Even in a multibyte buffer, it should match any + conceivable byte value for the fastmap. */ if (bufp->multibyte) - { - simple_char_max = 0x80; - - for (j = 0x80; j < 0xA0; j++) - if (BASE_LEADING_CODE_P (j)) - fastmap[j] = 1; - match_any_multibyte_characters = true; - } - else - simple_char_max = (1 << BYTEWIDTH); + match_any_multibyte_characters = true; + simple_char_max = (1 << BYTEWIDTH); for (j = 0; j < simple_char_max; j++) fastmap[j] = 1; @@ -3431,7 +3451,7 @@ re_compile_fastmap (bufp) case categoryspec: k = *p++; - simple_char_max = bufp->multibyte ? 0x80 : (1 << BYTEWIDTH); + simple_char_max = (1 << BYTEWIDTH); for (j = 0; j < simple_char_max; j++) if (CHAR_HAS_CATEGORY (j, k)) fastmap[j] = 1; @@ -3445,7 +3465,7 @@ re_compile_fastmap (bufp) case notcategoryspec: k = *p++; - simple_char_max = bufp->multibyte ? 0x80 : (1 << BYTEWIDTH); + simple_char_max = (1 << BYTEWIDTH); for (j = 0; j < simple_char_max; j++) if (!CHAR_HAS_CATEGORY (j, k)) fastmap[j] = 1; @@ -3708,13 +3728,13 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) range = total_size - startpos; /* If the search isn't to be a backwards one, don't waste time in a - search for a pattern that must be anchored. */ + search for a pattern anchored at beginning of buffer. */ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0) { if (startpos > 0) return -1; else - range = 1; + range = 0; } #ifdef emacs @@ -3722,8 +3742,8 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) 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) + range = PT_BYTE - BEGV_BYTE - startpos; + if (range < 0) return -1; } #endif /* emacs */ @@ -3738,10 +3758,13 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) anchored_start = 1; #ifdef emacs - SETUP_SYNTAX_TABLE_FOR_OBJECT (re_match_object, - POS_AS_IN_BUFFER (startpos > 0 - ? startpos - 1 : startpos), - 1); + gl_state.object = re_match_object; + { + int adjpos = NILP (re_match_object) || BUFFERP (re_match_object); + int charpos = SYNTAX_TABLE_BYTE_TO_CHAR (startpos + adjpos); + + SETUP_SYNTAX_TABLE_FOR_OBJECT (re_match_object, charpos, 1); + } #endif /* Loop through the string, looking for a place to start matching. */ @@ -3781,7 +3804,7 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) /* Written out as an if-else to avoid testing `translate' inside the loop. */ - if (translate) + if (RE_TRANSLATE_P (translate)) { if (multibyte) while (range > lim) @@ -3802,12 +3825,18 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) else while (range > lim && !fastmap[(unsigned char) - RE_TRANSLATE (translate, (unsigned char) *d++)]) - range--; + RE_TRANSLATE (translate, (unsigned char) *d)]) + { + d++; + range--; + } } else - while (range > lim && !fastmap[(unsigned char) *d++]) - range--; + while (range > lim && !fastmap[(unsigned char) *d]) + { + d++; + range--; + } startpos += irange - range; } @@ -3818,7 +3847,7 @@ re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) : size1 - startpos); buf_ch = STRING_CHAR (d, room); - if (translate) + if (RE_TRANSLATE_P (translate)) buf_ch = RE_TRANSLATE (translate, buf_ch); if (! (buf_ch >= 0400 @@ -4051,13 +4080,15 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) int result; #ifdef emacs - SETUP_SYNTAX_TABLE_FOR_OBJECT (re_match_object, - POS_AS_IN_BUFFER (pos > 0 ? pos - 1 : pos), - 1); + int charpos; + int adjpos = NILP (re_match_object) || BUFFERP (re_match_object); + gl_state.object = re_match_object; + charpos = SYNTAX_TABLE_BYTE_TO_CHAR (pos + adjpos); + SETUP_SYNTAX_TABLE_FOR_OBJECT (re_match_object, charpos, 1); #endif result = re_match_2_internal (bufp, string1, size1, string2, size2, - pos, regs, stop); + pos, regs, stop); alloca (0); return result; } @@ -4493,14 +4524,14 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) /* This is written out as an if-else so we don't waste time testing `translate' inside the loop. */ - if (translate) + if (RE_TRANSLATE_P (translate)) { #ifdef emacs if (multibyte) do { int pat_charlen, buf_charlen; - int pat_ch, buf_ch; + unsigned int pat_ch, buf_ch; PREFETCH (); pat_ch = STRING_CHAR_AND_LENGTH (p, pend - p, pat_charlen); @@ -4520,9 +4551,10 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) do { PREFETCH (); - if ((unsigned char) RE_TRANSLATE (translate, (unsigned char) *d++) + if ((unsigned char) RE_TRANSLATE (translate, (unsigned char) *d) != (unsigned char) *p++) goto fail; + d++; } while (--mcnt); } @@ -4543,7 +4575,7 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) case anychar: { int buf_charlen; - int buf_ch; + unsigned int buf_ch; DEBUG_PRINT1 ("EXECUTING anychar.\n"); @@ -4555,7 +4587,7 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) else #endif /* not emacs */ { - buf_ch = *d; + buf_ch = (unsigned char) *d; buf_charlen = 1; } @@ -4868,7 +4900,7 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) /* Compare that many; failure if mismatch, else move past them. */ - if (translate + if (RE_TRANSLATE_P (translate) ? bcmp_translate (d, d2, mcnt, translate) : bcmp (d, d2, mcnt)) goto fail; @@ -4975,6 +5007,10 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) on_failure: DEBUG_PRINT1 ("EXECUTING on_failure_jump"); +#if defined (WINDOWSNT) && defined (emacs) + QUIT; +#endif + EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt); @@ -5015,6 +5051,9 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) /* A smart repeat ends with `maybe_pop_jump'. We change it to either `pop_failure_jump' or `jump'. */ case maybe_pop_jump: +#if defined (WINDOWSNT) && defined (emacs) + QUIT; +#endif EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt); { @@ -5235,6 +5274,9 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) /* Unconditionally jump (without popping any failure points). */ case jump: unconditional_jump: +#if defined (WINDOWSNT) && defined (emacs) + QUIT; +#endif EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt); p += mcnt; /* Do the jump. */ @@ -5345,7 +5387,7 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2); GET_CHAR_AFTER_2 (c2, d, string1, end1, string2, end2); #ifdef emacs - charpos = SYNTAX_TABLE_BYTE_TO_CHAR (pos1 ? pos1 : 1); + charpos = SYNTAX_TABLE_BYTE_TO_CHAR (pos1); UPDATE_SYNTAX_TABLE (charpos); #endif s1 = SYNTAX (c1); @@ -5638,6 +5680,9 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) /* We goto here if a matching operation fails. */ fail: +#if defined (WINDOWSNT) && defined (emacs) + QUIT; +#endif if (!FAIL_STACK_EMPTY ()) { /* A restart point is known. Restore to that state. */ DEBUG_PRINT1 ("\nFAIL:\n");