X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/33017fafd17d722e82a268e9b272f27df261e09d..fb39b937b0628f4592b07d0aa61a41cf696abd30:/src/search.c diff --git a/src/search.c b/src/search.c index 5608e344e7..7c084c62e2 100644 --- a/src/search.c +++ b/src/search.c @@ -20,12 +20,12 @@ along with GNU Emacs. If not, see . */ #include -#include + #include "lisp.h" #include "syntax.h" #include "category.h" -#include "buffer.h" #include "character.h" +#include "buffer.h" #include "charset.h" #include "region-cache.h" #include "commands.h" @@ -101,9 +101,8 @@ static EMACS_INT boyer_moore (EMACS_INT, unsigned char *, ptrdiff_t, static EMACS_INT search_buffer (Lisp_Object, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, EMACS_INT, int, Lisp_Object, Lisp_Object, int); -static void matcher_overflow (void) NO_RETURN; -static void +static _Noreturn void matcher_overflow (void) { error ("Stack overflow in regexp matcher"); @@ -157,7 +156,7 @@ compile_pattern_1 (struct regexp_cache *cp, Lisp_Object pattern, Lisp_Object tra re_set_whitespace_regexp (NULL); re_set_syntax (old); - /* UNBLOCK_INPUT; */ + /* unblock_input (); */ if (val) xsignal1 (Qinvalid_regexp, build_string (val)); @@ -176,8 +175,7 @@ shrink_regexp_cache (void) for (cp = searchbuf_head; cp != 0; cp = cp->next) { cp->buf.allocated = cp->buf.used; - cp->buf.buffer - = (unsigned char *) xrealloc (cp->buf.buffer, cp->buf.used); + cp->buf.buffer = xrealloc (cp->buf.buffer, cp->buf.used); } } @@ -280,8 +278,8 @@ looking_at_1 (Lisp_Object string, int posix) save_search_regs (); /* This is so set_image_of_range_1 in regex.c can find the EQV table. */ - XCHAR_TABLE (BVAR (current_buffer, case_canon_table))->extras[2] - = BVAR (current_buffer, case_eqv_table); + set_char_table_extras (BVAR (current_buffer, case_canon_table), 2, + BVAR (current_buffer, case_eqv_table)); CHECK_STRING (string); bufp = compile_pattern (string, @@ -395,8 +393,8 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start, int p } /* This is so set_image_of_range_1 in regex.c can find the EQV table. */ - XCHAR_TABLE (BVAR (current_buffer, case_canon_table))->extras[2] - = BVAR (current_buffer, case_eqv_table); + set_char_table_extras (BVAR (current_buffer, case_canon_table), 2, + BVAR (current_buffer, case_eqv_table)); bufp = compile_pattern (regexp, (NILP (Vinhibit_changing_match_data) @@ -492,11 +490,11 @@ fast_string_match (Lisp_Object regexp, Lisp_Object string) We assume that STRING contains single-byte characters. */ ptrdiff_t -fast_c_string_match_ignore_case (Lisp_Object regexp, const char *string) +fast_c_string_match_ignore_case (Lisp_Object regexp, + const char *string, ptrdiff_t len) { ptrdiff_t val; struct re_pattern_buffer *bufp; - size_t len = strlen (string); regexp = string_make_unibyte (regexp); re_match_object = Qt; @@ -676,7 +674,7 @@ scan_buffer (register int target, ptrdiff_t start, ptrdiff_t end, obstacle --- the last character the dumb search loop should examine. */ ptrdiff_t ceiling_byte = CHAR_TO_BYTE (end) - 1; - ptrdiff_t start_byte = CHAR_TO_BYTE (start); + ptrdiff_t start_byte; ptrdiff_t tem; /* If we're looking for a newline, consult the newline cache @@ -686,18 +684,22 @@ scan_buffer (register int target, ptrdiff_t start, ptrdiff_t end, ptrdiff_t next_change; immediate_quit = 0; while (region_cache_forward - (current_buffer, newline_cache, start_byte, &next_change)) - start_byte = next_change; + (current_buffer, newline_cache, start, &next_change)) + start = next_change; immediate_quit = allow_quit; + start_byte = CHAR_TO_BYTE (start); + /* START should never be after END. */ if (start_byte > ceiling_byte) start_byte = ceiling_byte; /* Now the text after start is an unknown region, and next_change is the position of the next known region. */ - ceiling_byte = min (next_change - 1, ceiling_byte); + ceiling_byte = min (CHAR_TO_BYTE (next_change) - 1, ceiling_byte); } + else + start_byte = CHAR_TO_BYTE (start); /* The dumb loop can only scan text stored in contiguous bytes. BUFFER_CEILING_OF returns the last character @@ -749,7 +751,7 @@ scan_buffer (register int target, ptrdiff_t start, ptrdiff_t end, { /* The last character to check before the next obstacle. */ ptrdiff_t ceiling_byte = CHAR_TO_BYTE (end); - ptrdiff_t start_byte = CHAR_TO_BYTE (start); + ptrdiff_t start_byte; ptrdiff_t tem; /* Consult the newline cache, if appropriate. */ @@ -758,18 +760,22 @@ scan_buffer (register int target, ptrdiff_t start, ptrdiff_t end, ptrdiff_t next_change; immediate_quit = 0; while (region_cache_backward - (current_buffer, newline_cache, start_byte, &next_change)) - start_byte = next_change; + (current_buffer, newline_cache, start, &next_change)) + start = next_change; immediate_quit = allow_quit; + start_byte = CHAR_TO_BYTE (start); + /* Start should never be at or before end. */ if (start_byte <= ceiling_byte) start_byte = ceiling_byte + 1; /* Now the text before start is an unknown region, and next_change is the position of the next known region. */ - ceiling_byte = max (next_change, ceiling_byte); + ceiling_byte = max (CHAR_TO_BYTE (next_change), ceiling_byte); } + else + start_byte = CHAR_TO_BYTE (start); /* Stop scanning before the gap. */ tem = BUFFER_FLOOR_OF (start_byte - 1); @@ -992,8 +998,8 @@ search_command (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, } /* This is so set_image_of_range_1 in regex.c can find the EQV table. */ - XCHAR_TABLE (BVAR (current_buffer, case_canon_table))->extras[2] - = BVAR (current_buffer, case_eqv_table); + set_char_table_extras (BVAR (current_buffer, case_canon_table), 2, + BVAR (current_buffer, case_eqv_table)); np = search_buffer (string, PT, PT_BYTE, lim, lim_byte, n, RE, (!NILP (BVAR (current_buffer, case_fold_search)) @@ -1011,7 +1017,7 @@ search_command (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, if (!EQ (noerror, Qt)) { if (lim < BEGV || lim > ZV) - abort (); + emacs_abort (); SET_PT_BOTH (lim, lim_byte); return Qnil; #if 0 /* This would be clean, but maybe programs depend on @@ -1024,7 +1030,7 @@ search_command (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, } if (np < BEGV || np > ZV) - abort (); + emacs_abort (); SET_PT (np); @@ -1160,24 +1166,12 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, { ptrdiff_t val; -#ifdef REL_ALLOC - /* re_search_2 below is passed C pointers to buffer text. - If some code called by it causes memory (re)allocation, - buffer text could be relocated on platforms that use - REL_ALLOC, which invalidates those C pointers. So we - inhibit relocation of buffer text for as long as - re_search_2 runs. */ - r_alloc_inhibit_buffer_relocation (1); -#endif val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, pos_byte - BEGV_BYTE, lim_byte - pos_byte, (NILP (Vinhibit_changing_match_data) ? &search_regs : &search_regs_1), /* Don't allow match past current point */ pos_byte - BEGV_BYTE); -#ifdef REL_ALLOC - r_alloc_inhibit_buffer_relocation (0); -#endif if (val == -2) { matcher_overflow (); @@ -1217,19 +1211,11 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, { ptrdiff_t val; -#ifdef REL_ALLOC - /* See commentary above for the reasons for inhibiting - buffer text relocation here. */ - r_alloc_inhibit_buffer_relocation (1); -#endif val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, pos_byte - BEGV_BYTE, lim_byte - pos_byte, (NILP (Vinhibit_changing_match_data) ? &search_regs : &search_regs_1), lim_byte - BEGV_BYTE); -#ifdef REL_ALLOC - r_alloc_inhibit_buffer_relocation (0); -#endif if (val == -2) { matcher_overflow (); @@ -1295,7 +1281,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, raw_pattern_size_byte = count_size_as_multibyte (SDATA (string), raw_pattern_size); - raw_pattern = (unsigned char *) alloca (raw_pattern_size_byte + 1); + raw_pattern = alloca (raw_pattern_size_byte + 1); copy_text (SDATA (string), raw_pattern, SCHARS (string), 0, 1); } @@ -1309,7 +1295,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, the chosen single-byte character set can possibly match. */ raw_pattern_size = SCHARS (string); raw_pattern_size_byte = SCHARS (string); - raw_pattern = (unsigned char *) alloca (raw_pattern_size + 1); + raw_pattern = alloca (raw_pattern_size + 1); copy_text (SDATA (string), raw_pattern, SBYTES (string), 1, 0); } @@ -1317,7 +1303,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, /* Copy and optionally translate the pattern. */ len = raw_pattern_size; len_byte = raw_pattern_size_byte; - patbuf = (unsigned char *) alloca (len * MAX_MULTIBYTE_LENGTH); + patbuf = alloca (len * MAX_MULTIBYTE_LENGTH); pat = patbuf; base_pat = raw_pattern; if (multibyte) @@ -1472,7 +1458,7 @@ simple_search (EMACS_INT n, unsigned char *pat, int forward = n > 0; /* Number of buffer bytes matched. Note that this may be different from len_byte in a multibyte buffer. */ - ptrdiff_t match_byte; + ptrdiff_t match_byte = PTRDIFF_MIN; if (lim > pos && multibyte) while (n > 0) @@ -1643,6 +1629,7 @@ simple_search (EMACS_INT n, unsigned char *pat, stop: if (n == 0) { + eassert (match_byte != PTRDIFF_MIN); if (forward) set_search_regs ((multibyte ? pos_byte : pos) - match_byte, match_byte); else @@ -2084,8 +2071,8 @@ set_search_regs (ptrdiff_t beg_byte, ptrdiff_t nbytes) the match position. */ if (search_regs.num_regs == 0) { - search_regs.start = (regoff_t *) xmalloc (2 * sizeof (regoff_t)); - search_regs.end = (regoff_t *) xmalloc (2 * sizeof (regoff_t)); + search_regs.start = xmalloc (2 * sizeof (regoff_t)); + search_regs.end = xmalloc (2 * sizeof (regoff_t)); search_regs.num_regs = 2; } @@ -2233,29 +2220,29 @@ DEFUN ("replace-match", Freplace_match, Sreplace_match, 1, 5, 0, doc: /* Replace text matched by last search with NEWTEXT. Leave point at the end of the replacement text. -If second arg FIXEDCASE is non-nil, do not alter case of replacement text. -Otherwise maybe capitalize the whole text, or maybe just word initials, -based on the replaced text. -If the replaced text has only capital letters -and has at least one multiletter word, convert NEWTEXT to all caps. -Otherwise if all words are capitalized in the replaced text, -capitalize each word in NEWTEXT. +If optional second arg FIXEDCASE is non-nil, do not alter the case of +the replacement text. Otherwise, maybe capitalize the whole text, or +maybe just word initials, based on the replaced text. If the replaced +text has only capital letters and has at least one multiletter word, +convert NEWTEXT to all caps. Otherwise if all words are capitalized +in the replaced text, capitalize each word in NEWTEXT. -If third arg LITERAL is non-nil, insert NEWTEXT literally. +If optional third arg LITERAL is non-nil, insert NEWTEXT literally. Otherwise treat `\\' as special: `\\&' in NEWTEXT means substitute original matched text. `\\N' means substitute what matched the Nth `\\(...\\)'. If Nth parens didn't match, substitute nothing. `\\\\' means insert one `\\'. + `\\?' is treated literally + (for compatibility with `query-replace-regexp'). + Any other character following `\\' signals an error. Case conversion does not apply to these substitutions. -FIXEDCASE and LITERAL are optional arguments. - -The optional fourth argument STRING can be a string to modify. -This is meaningful when the previous match was done against STRING, -using `string-match'. When used this way, `replace-match' -creates and returns a new string made by copying STRING and replacing -the part of STRING that was matched. +If optional fourth argument STRING is non-nil, it should be a string +to act on; this should be the string on which the previous match was +done via `string-match'. In this case, `replace-match' creates and +returns a new string, made by copying STRING and replacing the part of +STRING that was matched (the original STRING itself is not altered). The optional fifth argument SUBEXP specifies a subexpression; it says to replace just that subexpression with NEWTEXT, @@ -2449,7 +2436,7 @@ since only regular expressions have distinguished subexpressions. */) } else if (c == '\\') delbackslash = 1; - else + else if (c != '?') error ("Invalid use of `\\' in replacement text"); } if (substart >= 0) @@ -2520,7 +2507,7 @@ since only regular expressions have distinguished subexpressions. */) substed_alloc_size = ((STRING_BYTES_BOUND - 100) / 2 < length ? STRING_BYTES_BOUND : length * 2 + 100); - substed = (unsigned char *) xmalloc (substed_alloc_size); + substed = xmalloc (substed_alloc_size); substed_len = 0; /* Go thru NEWTEXT, producing the actual text to insert in @@ -2761,8 +2748,7 @@ Return value is undefined if the last search failed. */) prev = Qnil; - data = (Lisp_Object *) alloca ((2 * search_regs.num_regs + 1) - * sizeof (Lisp_Object)); + data = alloca ((2 * search_regs.num_regs + 1) * sizeof *data); len = 0; for (i = 0; i < search_regs.num_regs; i++) @@ -2789,7 +2775,7 @@ Return value is undefined if the last search failed. */) } else /* last_thing_searched must always be Qt, a buffer, or Qnil. */ - abort (); + emacs_abort (); len = 2 * i + 2; } @@ -3028,7 +3014,7 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0, CHECK_STRING (string); - temp = (char *) alloca (SBYTES (string) * 2); + temp = alloca (SBYTES (string) * 2); /* Now copy the data into the new string, inserting escapes. */ @@ -3060,7 +3046,7 @@ syms_of_search (void) for (i = 0; i < REGEXP_CACHE_SIZE; ++i) { searchbufs[i].buf.allocated = 100; - searchbufs[i].buf.buffer = (unsigned char *) xmalloc (100); + searchbufs[i].buf.buffer = xmalloc (100); searchbufs[i].buf.fastmap = searchbufs[i].fastmap; searchbufs[i].regexp = Qnil; searchbufs[i].whitespace_regexp = Qnil; @@ -3076,14 +3062,14 @@ syms_of_search (void) DEFSYM (Qinvalid_regexp, "invalid-regexp"); Fput (Qsearch_failed, Qerror_conditions, - pure_cons (Qsearch_failed, pure_cons (Qerror, Qnil))); + listn (CONSTYPE_PURE, 2, Qsearch_failed, Qerror)); Fput (Qsearch_failed, Qerror_message, - make_pure_c_string ("Search failed")); + build_pure_c_string ("Search failed")); Fput (Qinvalid_regexp, Qerror_conditions, - pure_cons (Qinvalid_regexp, pure_cons (Qerror, Qnil))); + listn (CONSTYPE_PURE, 2, Qinvalid_regexp, Qerror)); Fput (Qinvalid_regexp, Qerror_message, - make_pure_c_string ("Invalid regexp")); + build_pure_c_string ("Invalid regexp")); last_thing_searched = Qnil; staticpro (&last_thing_searched);