X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/e62371e929af0d1d53afeebfbfbb7dfb71739da8..007eef160b0ca65d00f68b2ad18a48a6fe583c4d:/src/search.c diff --git a/src/search.c b/src/search.c index 27b9b8181c..5ce999ef4d 100644 --- a/src/search.c +++ b/src/search.c @@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */ #include "syntax.h" #include "category.h" #include "buffer.h" -#include "charset.h" +#include "character.h" #include "region-cache.h" #include "commands.h" #include "blockinput.h" @@ -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) { @@ -279,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), @@ -333,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); @@ -368,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; @@ -377,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; @@ -417,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); @@ -755,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. */ @@ -880,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) @@ -894,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)"); @@ -949,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++) @@ -963,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': @@ -1031,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; } @@ -1237,7 +1228,7 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n, { /* Keep track of which character set row contains the characters that need translation. */ - int charset_base_code = c & ~CHAR_FIELD3_MASK; + int charset_base_code = c & ~0x3F; if (charset_base == -1) charset_base = charset_base_code; else if (charset_base != charset_base_code) @@ -1527,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 = 0; + int infinity, limit, stride_for_teases = 0; register int *BM_tab; int *BM_tab_base; register unsigned char *cursor, *p_limit; @@ -1624,7 +1615,7 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt, while (! CHAR_HEAD_P (*charstart)) charstart--; untranslated = STRING_CHAR (charstart, ptr - charstart + 1); - if (charset_base == (untranslated & ~CHAR_FIELD3_MASK)) + if (charset_base == (untranslated & ~0x3F)) { TRANSLATE (ch, trt, untranslated); if (! CHAR_HEAD_P (*ptr)) @@ -1648,8 +1639,9 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt, this_translated = 0; } - if (ch > 0400) - j = ((unsigned char) ch) | 0200; + if (this_translated + && ch >= 0200) + j = (ch & 0x3F) | 0200; else j = (unsigned char) ch; @@ -1666,8 +1658,8 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt, while (1) { TRANSLATE (ch, inverse_trt, ch); - if (ch > 0400) - j = ((unsigned char) ch) | 0200; + if (ch > 0200) + j = (ch & 0x3F) | 0200; else j = (unsigned char) ch; @@ -1952,7 +1944,7 @@ wordify (string) int prev_c = 0; int adjust; - CHECK_STRING (string, 0); + CHECK_STRING (string); p = XSTRING (string)->data; len = XSTRING (string)->size; @@ -1975,7 +1967,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)) @@ -2022,176 +2014,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\ -\n\ -Search case-sensitivity is determined by the value of the variable\n\ -`case-fold-search', which see.\n\ -\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\ -\n\ -Search case-sensitivity is determined by the value of the variable\n\ -`case-fold-search', which see.\n\ -\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; @@ -2201,14 +2200,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 */ @@ -2220,7 +2218,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)); @@ -2418,7 +2416,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]) @@ -2426,15 +2424,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; @@ -2442,11 +2434,9 @@ 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, - make_number (0)) - : Qnil); + rev_tbl= Qnil; substed_alloc_size = length * 2 + 100; substed = (unsigned char *) xmalloc (substed_alloc_size + 1); @@ -2483,6 +2473,8 @@ since only regular expressions have distinguished subexpressions.") if (c == '\\') { + really_changed = 1; + if (str_multibyte) { FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, newtext, @@ -2548,21 +2540,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) @@ -2583,7 +2577,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)); @@ -2595,43 +2589,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; @@ -2689,25 +2683,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; @@ -2773,7 +2767,7 @@ LIST should have been created by calling `match-data' previously.") XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer); } - CHECK_NUMBER_COERCE_MARKER (marker, 0); + CHECK_NUMBER_COERCE_MARKER (marker); from = XINT (marker); list = Fcdr (list); @@ -2781,7 +2775,7 @@ LIST should have been created by calling `match-data' previously.") 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); } @@ -2836,15 +2830,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);