X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/9dddb23f46d05fc1586ef5d2be1babbac518f7e9..845975f566069b9b48c21dc2ba239d23c2bd823c:/src/search.c diff --git a/src/search.c b/src/search.c index 246f9cbdf4..722af7afa4 100644 --- a/src/search.c +++ b/src/search.c @@ -33,9 +33,6 @@ Boston, MA 02111-1307, USA. */ #include #include "regex.h" -#define min(a, b) ((a) < (b) ? (a) : (b)) -#define max(a, b) ((a) > (b) ? (a) : (b)) - #define REGEXP_CACHE_SIZE 20 /* If the regexp is non-nil, then the buffer contains the compiled form @@ -180,7 +177,7 @@ compile_pattern_1 (cp, pattern, translate, regp, posix, multibyte) void shrink_regexp_cache () { - struct regexp_cache *cp, **cpp; + struct regexp_cache *cp; for (cp = searchbuf_head; cp != 0; cp = cp->next) { @@ -221,6 +218,7 @@ compile_pattern (pattern, regp, translate, posix, multibyte) if (NILP (cp->regexp)) goto compile_it; if (XSTRING (cp->regexp)->size == XSTRING (pattern)->size + && STRING_MULTIBYTE (cp->regexp) == STRING_MULTIBYTE (pattern) && !NILP (Fstring_equal (cp->regexp, pattern)) && EQ (cp->buf.translate, (! NILP (translate) ? translate : make_number (0))) && cp->posix == posix @@ -278,7 +276,7 @@ looking_at_1 (string, posix) if (running_asynch_code) save_search_regs (); - CHECK_STRING (string, 0); + CHECK_STRING (string); bufp = compile_pattern (string, &search_regs, (!NILP (current_buffer->case_fold_search) ? DOWNCASE_TABLE : Qnil), @@ -332,23 +330,23 @@ looking_at_1 (string, posix) } DEFUN ("looking-at", Flooking_at, Slooking_at, 1, 1, 0, - "Return t if text after point matches regular expression REGEXP.\n\ -This function modifies the match data that `match-beginning',\n\ -`match-end' and `match-data' access; save and restore the match\n\ -data if you want to preserve them.") - (regexp) + doc: /* Return t if text after point matches regular expression REGEXP. +This function modifies the match data that `match-beginning', +`match-end' and `match-data' access; save and restore the match +data if you want to preserve them. */) + (regexp) Lisp_Object regexp; { return looking_at_1 (regexp, 0); } DEFUN ("posix-looking-at", Fposix_looking_at, Sposix_looking_at, 1, 1, 0, - "Return t if text after point matches regular expression REGEXP.\n\ -Find the longest match, in accord with Posix regular expression rules.\n\ -This function modifies the match data that `match-beginning',\n\ -`match-end' and `match-data' access; save and restore the match\n\ -data if you want to preserve them.") - (regexp) + doc: /* Return t if text after point matches regular expression REGEXP. +Find the longest match, in accord with Posix regular expression rules. +This function modifies the match data that `match-beginning', +`match-end' and `match-data' access; save and restore the match +data if you want to preserve them. */) + (regexp) Lisp_Object regexp; { return looking_at_1 (regexp, 1); @@ -367,8 +365,8 @@ string_match_1 (regexp, string, start, posix) if (running_asynch_code) save_search_regs (); - CHECK_STRING (regexp, 0); - CHECK_STRING (string, 1); + CHECK_STRING (regexp); + CHECK_STRING (string); if (NILP (start)) pos = 0, pos_byte = 0; @@ -376,7 +374,7 @@ string_match_1 (regexp, string, start, posix) { int len = XSTRING (string)->size; - CHECK_NUMBER (start, 2); + CHECK_NUMBER (start); pos = XINT (start); if (pos < 0 && -pos <= len) pos = len + pos; @@ -416,27 +414,27 @@ string_match_1 (regexp, string, start, posix) } DEFUN ("string-match", Fstring_match, Sstring_match, 2, 3, 0, - "Return index of start of first match for REGEXP in STRING, or nil.\n\ -Case is ignored if `case-fold-search' is non-nil in the current buffer.\n\ -If third arg START is non-nil, start search at that index in STRING.\n\ -For index of first char beyond the match, do (match-end 0).\n\ -`match-end' and `match-beginning' also give indices of substrings\n\ -matched by parenthesis constructs in the pattern.") - (regexp, string, start) + doc: /* Return index of start of first match for REGEXP in STRING, or nil. +Case is ignored if `case-fold-search' is non-nil in the current buffer. +If third arg START is non-nil, start search at that index in STRING. +For index of first char beyond the match, do (match-end 0). +`match-end' and `match-beginning' also give indices of substrings +matched by parenthesis constructs in the pattern. */) + (regexp, string, start) Lisp_Object regexp, string, start; { return string_match_1 (regexp, string, start, 0); } DEFUN ("posix-string-match", Fposix_string_match, Sposix_string_match, 2, 3, 0, - "Return index of start of first match for REGEXP in STRING, or nil.\n\ -Find the longest match, in accord with Posix regular expression rules.\n\ -Case is ignored if `case-fold-search' is non-nil in the current buffer.\n\ -If third arg START is non-nil, start search at that index in STRING.\n\ -For index of first char beyond the match, do (match-end 0).\n\ -`match-end' and `match-beginning' also give indices of substrings\n\ -matched by parenthesis constructs in the pattern.") - (regexp, string, start) + doc: /* Return index of start of first match for REGEXP in STRING, or nil. +Find the longest match, in accord with Posix regular expression rules. +Case is ignored if `case-fold-search' is non-nil in the current buffer. +If third arg START is non-nil, start search at that index in STRING. +For index of first char beyond the match, do (match-end 0). +`match-end' and `match-beginning' also give indices of substrings +matched by parenthesis constructs in the pattern. */) + (regexp, string, start) Lisp_Object regexp, string, start; { return string_match_1 (regexp, string, start, 1); @@ -754,11 +752,6 @@ scan_newline (start, start_byte, limit, limit_byte, count, allow_quit) int old_immediate_quit = immediate_quit; - /* If we are not in selective display mode, - check only for newlines. */ - int selective_display = (!NILP (current_buffer->selective_display) - && !INTEGERP (current_buffer->selective_display)); - /* The code that follows is like scan_buffer but checks for either newline or carriage return. */ @@ -879,11 +872,11 @@ search_command (string, bound, noerror, count, direction, RE, posix) if (!NILP (count)) { - CHECK_NUMBER (count, 3); + CHECK_NUMBER (count); n *= XINT (count); } - CHECK_STRING (string, 0); + CHECK_STRING (string); if (NILP (bound)) { if (n > 0) @@ -893,7 +886,7 @@ search_command (string, bound, noerror, count, direction, RE, posix) } else { - CHECK_NUMBER_COERCE_MARKER (bound, 1); + CHECK_NUMBER_COERCE_MARKER (bound); lim = XINT (bound); if (n > 0 ? lim < PT : lim > PT) error ("Invalid search bound (wrong side of point)"); @@ -948,7 +941,6 @@ trivial_regexp_p (regexp) { int len = STRING_BYTES (XSTRING (regexp)); unsigned char *s = XSTRING (regexp)->data; - unsigned char c; while (--len >= 0) { switch (*s++) @@ -962,7 +954,7 @@ trivial_regexp_p (regexp) { case '|': case '(': case ')': case '`': case '\'': case 'b': case 'B': case '<': case '>': case 'w': case 'W': case 's': - case 'S': case '=': + case 'S': case '=': case '{': case '}': case 'c': case 'C': /* for categoryspec and notcategoryspec */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': @@ -1030,7 +1022,7 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n, /* Null string is found at starting position. */ if (len == 0 || n == 0) { - set_search_regs (pos, 0); + set_search_regs (pos_byte, 0); return pos; } @@ -1526,7 +1518,7 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt, { int direction = ((n > 0) ? 1 : -1); register int dirlen; - int infinity, limit, k, stride_for_teases; + int infinity, limit, stride_for_teases = 0; register int *BM_tab; int *BM_tab_base; register unsigned char *cursor, *p_limit; @@ -1535,8 +1527,8 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt, int multibyte = ! NILP (current_buffer->enable_multibyte_characters); unsigned char simple_translate[0400]; - int translate_prev_byte; - int translate_anteprev_byte; + int translate_prev_byte = 0; + int translate_anteprev_byte = 0; #ifdef C_ALLOCA int BM_tab_space[0400]; @@ -1951,7 +1943,7 @@ wordify (string) int prev_c = 0; int adjust; - CHECK_STRING (string, 0); + CHECK_STRING (string); p = XSTRING (string)->data; len = XSTRING (string)->size; @@ -1974,7 +1966,7 @@ wordify (string) if (SYNTAX (prev_c) == Sword) word_count++; if (!word_count) - return build_string (""); + return empty_string; adjust = - punct_count + 5 * (word_count - 1) + 4; if (STRING_MULTIBYTE (string)) @@ -2021,168 +2013,183 @@ wordify (string) } DEFUN ("search-backward", Fsearch_backward, Ssearch_backward, 1, 4, - "MSearch backward: ", - "Search backward from point for STRING.\n\ -Set point to the beginning of the occurrence found, and return point.\n\ -An optional second argument bounds the search; it is a buffer position.\n\ -The match found must not extend before that position.\n\ -Optional third argument, if t, means if fail just return nil (no error).\n\ - If not nil and not t, position at limit of search and return nil.\n\ -Optional fourth argument is repeat count--search for successive occurrences.\n\ -See also the functions `match-beginning', `match-end' and `replace-match'.") - (string, bound, noerror, count) + "MSearch backward: ", + doc: /* Search backward from point for STRING. +Set point to the beginning of the occurrence found, and return point. +An optional second argument bounds the search; it is a buffer position. +The match found must not extend before that position. +Optional third argument, if t, means if fail just return nil (no error). + If not nil and not t, position at limit of search and return nil. +Optional fourth argument is repeat count--search for successive occurrences. + +Search case-sensitivity is determined by the value of the variable +`case-fold-search', which see. + +See also the functions `match-beginning', `match-end' and `replace-match'. */) + (string, bound, noerror, count) Lisp_Object string, bound, noerror, count; { return search_command (string, bound, noerror, count, -1, 0, 0); } DEFUN ("search-forward", Fsearch_forward, Ssearch_forward, 1, 4, "MSearch: ", - "Search forward from point for STRING.\n\ -Set point to the end of the occurrence found, and return point.\n\ -An optional second argument bounds the search; it is a buffer position.\n\ -The match found must not extend after that position. nil is equivalent\n\ - to (point-max).\n\ -Optional third argument, if t, means if fail just return nil (no error).\n\ - If not nil and not t, move to limit of search and return nil.\n\ -Optional fourth argument is repeat count--search for successive occurrences.\n\ -See also the functions `match-beginning', `match-end' and `replace-match'.") - (string, bound, noerror, count) + doc: /* Search forward from point for STRING. +Set point to the end of the occurrence found, and return point. +An optional second argument bounds the search; it is a buffer position. +The match found must not extend after that position. nil is equivalent + to (point-max). +Optional third argument, if t, means if fail just return nil (no error). + If not nil and not t, move to limit of search and return nil. +Optional fourth argument is repeat count--search for successive occurrences. + +Search case-sensitivity is determined by the value of the variable +`case-fold-search', which see. + +See also the functions `match-beginning', `match-end' and `replace-match'. */) + (string, bound, noerror, count) Lisp_Object string, bound, noerror, count; { return search_command (string, bound, noerror, count, 1, 0, 0); } DEFUN ("word-search-backward", Fword_search_backward, Sword_search_backward, 1, 4, - "sWord search backward: ", - "Search backward from point for STRING, ignoring differences in punctuation.\n\ -Set point to the beginning of the occurrence found, and return point.\n\ -An optional second argument bounds the search; it is a buffer position.\n\ -The match found must not extend before that position.\n\ -Optional third argument, if t, means if fail just return nil (no error).\n\ - If not nil and not t, move to limit of search and return nil.\n\ -Optional fourth argument is repeat count--search for successive occurrences.") - (string, bound, noerror, count) + "sWord search backward: ", + doc: /* Search backward from point for STRING, ignoring differences in punctuation. +Set point to the beginning of the occurrence found, and return point. +An optional second argument bounds the search; it is a buffer position. +The match found must not extend before that position. +Optional third argument, if t, means if fail just return nil (no error). + If not nil and not t, move to limit of search and return nil. +Optional fourth argument is repeat count--search for successive occurrences. */) + (string, bound, noerror, count) Lisp_Object string, bound, noerror, count; { return search_command (wordify (string), bound, noerror, count, -1, 1, 0); } DEFUN ("word-search-forward", Fword_search_forward, Sword_search_forward, 1, 4, - "sWord search: ", - "Search forward from point for STRING, ignoring differences in punctuation.\n\ -Set point to the end of the occurrence found, and return point.\n\ -An optional second argument bounds the search; it is a buffer position.\n\ -The match found must not extend after that position.\n\ -Optional third argument, if t, means if fail just return nil (no error).\n\ - If not nil and not t, move to limit of search and return nil.\n\ -Optional fourth argument is repeat count--search for successive occurrences.") - (string, bound, noerror, count) + "sWord search: ", + doc: /* Search forward from point for STRING, ignoring differences in punctuation. +Set point to the end of the occurrence found, and return point. +An optional second argument bounds the search; it is a buffer position. +The match found must not extend after that position. +Optional third argument, if t, means if fail just return nil (no error). + If not nil and not t, move to limit of search and return nil. +Optional fourth argument is repeat count--search for successive occurrences. */) + (string, bound, noerror, count) Lisp_Object string, bound, noerror, count; { return search_command (wordify (string), bound, noerror, count, 1, 1, 0); } DEFUN ("re-search-backward", Fre_search_backward, Sre_search_backward, 1, 4, - "sRE search backward: ", - "Search backward from point for match for regular expression REGEXP.\n\ -Set point to the beginning of the match, and return point.\n\ -The match found is the one starting last in the buffer\n\ -and yet ending before the origin of the search.\n\ -An optional second argument bounds the search; it is a buffer position.\n\ -The match found must start at or after that position.\n\ -Optional third argument, if t, means if fail just return nil (no error).\n\ - If not nil and not t, move to limit of search and return nil.\n\ -Optional fourth argument is repeat count--search for successive occurrences.\n\ -See also the functions `match-beginning', `match-end', `match-string',\n\ -and `replace-match'.") - (regexp, bound, noerror, count) + "sRE search backward: ", + doc: /* Search backward from point for match for regular expression REGEXP. +Set point to the beginning of the match, and return point. +The match found is the one starting last in the buffer +and yet ending before the origin of the search. +An optional second argument bounds the search; it is a buffer position. +The match found must start at or after that position. +Optional third argument, if t, means if fail just return nil (no error). + If not nil and not t, move to limit of search and return nil. +Optional fourth argument is repeat count--search for successive occurrences. +See also the functions `match-beginning', `match-end', `match-string', +and `replace-match'. */) + (regexp, bound, noerror, count) Lisp_Object regexp, bound, noerror, count; { return search_command (regexp, bound, noerror, count, -1, 1, 0); } DEFUN ("re-search-forward", Fre_search_forward, Sre_search_forward, 1, 4, - "sRE search: ", - "Search forward from point for regular expression REGEXP.\n\ -Set point to the end of the occurrence found, and return point.\n\ -An optional second argument bounds the search; it is a buffer position.\n\ -The match found must not extend after that position.\n\ -Optional third argument, if t, means if fail just return nil (no error).\n\ - If not nil and not t, move to limit of search and return nil.\n\ -Optional fourth argument is repeat count--search for successive occurrences.\n\ -See also the functions `match-beginning', `match-end', `match-string',\n\ -and `replace-match'.") - (regexp, bound, noerror, count) + "sRE search: ", + doc: /* Search forward from point for regular expression REGEXP. +Set point to the end of the occurrence found, and return point. +An optional second argument bounds the search; it is a buffer position. +The match found must not extend after that position. +Optional third argument, if t, means if fail just return nil (no error). + If not nil and not t, move to limit of search and return nil. +Optional fourth argument is repeat count--search for successive occurrences. +See also the functions `match-beginning', `match-end', `match-string', +and `replace-match'. */) + (regexp, bound, noerror, count) Lisp_Object regexp, bound, noerror, count; { return search_command (regexp, bound, noerror, count, 1, 1, 0); } DEFUN ("posix-search-backward", Fposix_search_backward, Sposix_search_backward, 1, 4, - "sPosix search backward: ", - "Search backward from point for match for regular expression REGEXP.\n\ -Find the longest match in accord with Posix regular expression rules.\n\ -Set point to the beginning of the match, and return point.\n\ -The match found is the one starting last in the buffer\n\ -and yet ending before the origin of the search.\n\ -An optional second argument bounds the search; it is a buffer position.\n\ -The match found must start at or after that position.\n\ -Optional third argument, if t, means if fail just return nil (no error).\n\ - If not nil and not t, move to limit of search and return nil.\n\ -Optional fourth argument is repeat count--search for successive occurrences.\n\ -See also the functions `match-beginning', `match-end', `match-string',\n\ -and `replace-match'.") - (regexp, bound, noerror, count) + "sPosix search backward: ", + doc: /* Search backward from point for match for regular expression REGEXP. +Find the longest match in accord with Posix regular expression rules. +Set point to the beginning of the match, and return point. +The match found is the one starting last in the buffer +and yet ending before the origin of the search. +An optional second argument bounds the search; it is a buffer position. +The match found must start at or after that position. +Optional third argument, if t, means if fail just return nil (no error). + If not nil and not t, move to limit of search and return nil. +Optional fourth argument is repeat count--search for successive occurrences. +See also the functions `match-beginning', `match-end', `match-string', +and `replace-match'. */) + (regexp, bound, noerror, count) Lisp_Object regexp, bound, noerror, count; { return search_command (regexp, bound, noerror, count, -1, 1, 1); } DEFUN ("posix-search-forward", Fposix_search_forward, Sposix_search_forward, 1, 4, - "sPosix search: ", - "Search forward from point for regular expression REGEXP.\n\ -Find the longest match in accord with Posix regular expression rules.\n\ -Set point to the end of the occurrence found, and return point.\n\ -An optional second argument bounds the search; it is a buffer position.\n\ -The match found must not extend after that position.\n\ -Optional third argument, if t, means if fail just return nil (no error).\n\ - If not nil and not t, move to limit of search and return nil.\n\ -Optional fourth argument is repeat count--search for successive occurrences.\n\ -See also the functions `match-beginning', `match-end', `match-string',\n\ -and `replace-match'.") - (regexp, bound, noerror, count) + "sPosix search: ", + doc: /* Search forward from point for regular expression REGEXP. +Find the longest match in accord with Posix regular expression rules. +Set point to the end of the occurrence found, and return point. +An optional second argument bounds the search; it is a buffer position. +The match found must not extend after that position. +Optional third argument, if t, means if fail just return nil (no error). + If not nil and not t, move to limit of search and return nil. +Optional fourth argument is repeat count--search for successive occurrences. +See also the functions `match-beginning', `match-end', `match-string', +and `replace-match'. */) + (regexp, bound, noerror, count) Lisp_Object regexp, bound, noerror, count; { return search_command (regexp, bound, noerror, count, 1, 1, 1); } DEFUN ("replace-match", Freplace_match, Sreplace_match, 1, 5, 0, - "Replace text matched by last search with NEWTEXT.\n\ -If second arg FIXEDCASE is non-nil, do not alter case of replacement text.\n\ -Otherwise maybe capitalize the whole text, or maybe just word initials,\n\ -based on the replaced text.\n\ -If the replaced text has only capital letters\n\ -and has at least one multiletter word, convert NEWTEXT to all caps.\n\ -If the replaced text has at least one word starting with a capital letter,\n\ -then capitalize each word in NEWTEXT.\n\n\ -If third arg LITERAL is non-nil, insert NEWTEXT literally.\n\ -Otherwise treat `\\' as special:\n\ - `\\&' in NEWTEXT means substitute original matched text.\n\ - `\\N' means substitute what matched the Nth `\\(...\\)'.\n\ - If Nth parens didn't match, substitute nothing.\n\ - `\\\\' means insert one `\\'.\n\ -FIXEDCASE and LITERAL are optional arguments.\n\ -Leaves point at end of replacement text.\n\ -\n\ -The optional fourth argument STRING can be a string to modify.\n\ -In that case, this function creates and returns a new string\n\ -which is made by replacing the part of STRING that was matched.\n\ -\n\ -The optional fifth argument SUBEXP specifies a subexpression of the match.\n\ -It says to replace just that subexpression instead of the whole match.\n\ -This is useful only after a regular expression search or match\n\ -since only regular expressions have distinguished subexpressions.") - (newtext, fixedcase, literal, string, subexp) + doc: /* Replace text matched by last search with NEWTEXT. +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. +If the replaced text has at least one word starting with a capital letter, +then capitalize each word in NEWTEXT. + +If 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 `\\'. +FIXEDCASE and LITERAL are optional arguments. +Leaves point at end of replacement text. + +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. + +The optional fifth argument SUBEXP specifies a subexpression; +it says to replace just that subexpression with NEWTEXT, +rather than replacing the entire matched text. +This is, in a vague sense, the inverse of using `\\N' in NEWTEXT; +`\\N' copies subexp N into NEWTEXT, but using N as SUBEXP puts +NEWTEXT in place of subexp N. +This is useful only after a regular expression search or match, +since only regular expressions have distinguished subexpressions. */) + (newtext, fixedcase, literal, string, subexp) Lisp_Object newtext, fixedcase, literal, string, subexp; { enum { nochange, all_caps, cap_initial } case_action; @@ -2192,14 +2199,13 @@ since only regular expressions have distinguished subexpressions.") int some_uppercase; int some_nonuppercase_initial; register int c, prevc; - int inslen; int sub; int opoint, newpoint; - CHECK_STRING (newtext, 0); + CHECK_STRING (newtext); if (! NILP (string)) - CHECK_STRING (string, 4); + CHECK_STRING (string); case_action = nochange; /* We tried an initialization */ /* but some C compilers blew it */ @@ -2211,7 +2217,7 @@ since only regular expressions have distinguished subexpressions.") sub = 0; else { - CHECK_NUMBER (subexp, 3); + CHECK_NUMBER (subexp); sub = XINT (subexp); if (sub < 0 || sub >= search_regs.num_regs) args_out_of_range (subexp, make_number (search_regs.num_regs)); @@ -2336,7 +2342,7 @@ since only regular expressions have distinguished subexpressions.") for (pos_byte = 0, pos = 0; pos_byte < length;) { int substart = -1; - int subend; + int subend = 0; int delbackslash = 0; FETCH_STRING_CHAR_ADVANCE (c, newtext, pos, pos_byte); @@ -2409,7 +2415,7 @@ since only regular expressions have distinguished subexpressions.") return concat3 (before, newtext, after); } - /* Record point, the move (quietly) to the start of the match. */ + /* Record point, then move (quietly) to the start of the match. */ if (PT >= search_regs.end[sub]) opoint = PT - ZV; else if (PT > search_regs.start[sub]) @@ -2417,15 +2423,9 @@ since only regular expressions have distinguished subexpressions.") else opoint = PT; - TEMP_SET_PT (search_regs.start[sub]); - - /* We insert the replacement text before the old text, and then - delete the original text. This means that markers at the - beginning or end of the original will float to the corresponding - position in the replacement. */ - if (!NILP (literal)) - Finsert_and_inherit (1, &newtext); - else + /* If we want non-literal replacement, + perform substitution on the replacement string. */ + if (NILP (literal)) { int length = STRING_BYTES (XSTRING (newtext)); unsigned char *substed; @@ -2433,6 +2433,7 @@ since only regular expressions have distinguished subexpressions.") int buf_multibyte = !NILP (current_buffer->enable_multibyte_characters); int str_multibyte = STRING_MULTIBYTE (newtext); Lisp_Object rev_tbl; + int really_changed = 0; rev_tbl= (!buf_multibyte && CHAR_TABLE_P (Vnonascii_translation_table) ? Fchar_table_extra_slot (Vnonascii_translation_table, @@ -2474,6 +2475,8 @@ since only regular expressions have distinguished subexpressions.") if (c == '\\') { + really_changed = 1; + if (str_multibyte) { FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, newtext, @@ -2539,21 +2542,23 @@ since only regular expressions have distinguished subexpressions.") } } - /* Now insert what we accumulated. */ - insert_and_inherit (substed, substed_len); + if (really_changed) + newtext = make_string (substed, substed_len); xfree (substed); } - inslen = PT - (search_regs.start[sub]); - del_range (search_regs.start[sub] + inslen, search_regs.end[sub] + inslen); + /* Replace the old text with the new in the cleanest possible way. */ + replace_range (search_regs.start[sub], search_regs.end[sub], + newtext, 1, 0, 1); + newpoint = search_regs.start[sub] + XSTRING (newtext)->size; if (case_action == all_caps) - Fupcase_region (make_number (PT - inslen), make_number (PT)); + Fupcase_region (make_number (search_regs.start[sub]), + make_number (newpoint)); else if (case_action == cap_initial) - Fupcase_initials_region (make_number (PT - inslen), make_number (PT)); - - newpoint = PT; + Fupcase_initials_region (make_number (search_regs.start[sub]), + make_number (newpoint)); /* Put point back where it was in the text. */ if (opoint <= 0) @@ -2574,7 +2579,7 @@ match_limit (num, beginningp) { register int n; - CHECK_NUMBER (num, 0); + CHECK_NUMBER (num); n = XINT (num); if (n < 0 || n >= search_regs.num_regs) args_out_of_range (num, make_number (search_regs.num_regs)); @@ -2586,43 +2591,43 @@ match_limit (num, beginningp) } DEFUN ("match-beginning", Fmatch_beginning, Smatch_beginning, 1, 1, 0, - "Return position of start of text matched by last search.\n\ -SUBEXP, a number, specifies which parenthesized expression in the last\n\ - regexp.\n\ -Value is nil if SUBEXPth pair didn't match, or there were less than\n\ - SUBEXP pairs.\n\ -Zero means the entire text matched by the whole regexp or whole string.") - (subexp) + doc: /* Return position of start of text matched by last search. +SUBEXP, a number, specifies which parenthesized expression in the last + regexp. +Value is nil if SUBEXPth pair didn't match, or there were less than + SUBEXP pairs. +Zero means the entire text matched by the whole regexp or whole string. */) + (subexp) Lisp_Object subexp; { return match_limit (subexp, 1); } DEFUN ("match-end", Fmatch_end, Smatch_end, 1, 1, 0, - "Return position of end of text matched by last search.\n\ -SUBEXP, a number, specifies which parenthesized expression in the last\n\ - regexp.\n\ -Value is nil if SUBEXPth pair didn't match, or there were less than\n\ - SUBEXP pairs.\n\ -Zero means the entire text matched by the whole regexp or whole string.") - (subexp) + doc: /* Return position of end of text matched by last search. +SUBEXP, a number, specifies which parenthesized expression in the last + regexp. +Value is nil if SUBEXPth pair didn't match, or there were less than + SUBEXP pairs. +Zero means the entire text matched by the whole regexp or whole string. */) + (subexp) Lisp_Object subexp; { return match_limit (subexp, 0); } DEFUN ("match-data", Fmatch_data, Smatch_data, 0, 2, 0, - "Return a list containing all info on what the last search matched.\n\ -Element 2N is `(match-beginning N)'; element 2N + 1 is `(match-end N)'.\n\ -All the elements are markers or nil (nil if the Nth pair didn't match)\n\ -if the last match was on a buffer; integers or nil if a string was matched.\n\ -Use `store-match-data' to reinstate the data in this list.\n\ -\n\ -If INTEGERS (the optional first argument) is non-nil, always use integers\n\ -\(rather than markers) to represent buffer positions.\n\ -If REUSE is a list, reuse it as part of the value. If REUSE is long enough\n\ -to hold all the values, and if INTEGERS is non-nil, no consing is done.") - (integers, reuse) + doc: /* Return a list containing all info on what the last search matched. +Element 2N is `(match-beginning N)'; element 2N + 1 is `(match-end N)'. +All the elements are markers or nil (nil if the Nth pair didn't match) +if the last match was on a buffer; integers or nil if a string was matched. +Use `store-match-data' to reinstate the data in this list. + +If INTEGERS (the optional first argument) is non-nil, always use integers +\(rather than markers) to represent buffer positions. +If REUSE is a list, reuse it as part of the value. If REUSE is long enough +to hold all the values, and if INTEGERS is non-nil, no consing is done. */) + (integers, reuse) Lisp_Object integers, reuse; { Lisp_Object tail, prev; @@ -2632,6 +2637,8 @@ to hold all the values, and if INTEGERS is non-nil, no consing is done.") if (NILP (last_thing_searched)) return Qnil; + prev = Qnil; + data = (Lisp_Object *) alloca ((2 * search_regs.num_regs) * sizeof (Lisp_Object)); @@ -2678,25 +2685,25 @@ to hold all the values, and if INTEGERS is non-nil, no consing is done.") i++, tail = XCDR (tail)) { if (i < 2 * len + 2) - XCAR (tail) = data[i]; + XSETCAR (tail, data[i]); else - XCAR (tail) = Qnil; + XSETCAR (tail, Qnil); prev = tail; } /* If we couldn't fit all value elements into REUSE, cons up the rest of them and add them to the end of REUSE. */ if (i < 2 * len + 2) - XCDR (prev) = Flist (2 * len + 2 - i, data + i); + XSETCDR (prev, Flist (2 * len + 2 - i, data + i)); return reuse; } DEFUN ("set-match-data", Fset_match_data, Sset_match_data, 1, 1, 0, - "Set internal data on last search match from elements of LIST.\n\ -LIST should have been created by calling `match-data' previously.") - (list) + doc: /* Set internal data on last search match from elements of LIST. +LIST should have been created by calling `match-data' previously. */) + (list) register Lisp_Object list; { register int i; @@ -2735,6 +2742,9 @@ LIST should have been created by calling `match-data' previously.") length * sizeof (regoff_t)); } + for (i = search_regs.num_regs; i < length; i++) + search_regs.start[i] = -1; + search_regs.num_regs = length; } } @@ -2749,6 +2759,8 @@ LIST should have been created by calling `match-data' previously.") } else { + int from; + if (MARKERP (marker)) { if (XMARKER (marker)->buffer == 0) @@ -2757,15 +2769,16 @@ LIST should have been created by calling `match-data' previously.") XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer); } - CHECK_NUMBER_COERCE_MARKER (marker, 0); - search_regs.start[i] = XINT (marker); + CHECK_NUMBER_COERCE_MARKER (marker); + from = XINT (marker); list = Fcdr (list); marker = Fcar (list); if (MARKERP (marker) && XMARKER (marker)->buffer == 0) XSETFASTINT (marker, 0); - CHECK_NUMBER_COERCE_MARKER (marker, 0); + CHECK_NUMBER_COERCE_MARKER (marker); + search_regs.start[i] = from; search_regs.end[i] = XINT (marker); } list = Fcdr (list); @@ -2819,15 +2832,15 @@ restore_match_data () /* Quote a string to inactivate reg-expr chars */ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0, - "Return a regexp string which matches exactly STRING and nothing else.") - (string) + doc: /* Return a regexp string which matches exactly STRING and nothing else. */) + (string) Lisp_Object string; { register unsigned char *in, *out, *end; register unsigned char *temp; int backslashes_added = 0; - CHECK_STRING (string, 0); + CHECK_STRING (string); temp = (unsigned char *) alloca (STRING_BYTES (XSTRING (string)) * 2);