summaryrefslogtreecommitdiff
path: root/src/search.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/search.c')
-rw-r--r--src/search.c143
1 files changed, 78 insertions, 65 deletions
diff --git a/src/search.c b/src/search.c
index 88ab1df7791..a7f958c362b 100644
--- a/src/search.c
+++ b/src/search.c
@@ -260,7 +260,7 @@ compile_pattern (Lisp_Object pattern, struct re_registers *regp,
static Lisp_Object
-looking_at_1 (Lisp_Object string, bool posix)
+looking_at_1 (Lisp_Object string, bool posix, bool modify_data)
{
Lisp_Object val;
unsigned char *p1, *p2;
@@ -278,11 +278,11 @@ looking_at_1 (Lisp_Object string, bool posix)
CHECK_STRING (string);
/* Snapshot in case Lisp changes the value. */
- bool preserve_match_data = NILP (Vinhibit_changing_match_data);
+ bool modify_match_data = NILP (Vinhibit_changing_match_data) && modify_data;
struct regexp_cache *cache_entry = compile_pattern (
string,
- preserve_match_data ? &search_regs : NULL,
+ modify_match_data ? &search_regs : NULL,
(!NILP (BVAR (current_buffer, case_fold_search))
? BVAR (current_buffer, case_canon_table) : Qnil),
posix,
@@ -310,13 +310,13 @@ looking_at_1 (Lisp_Object string, bool posix)
s2 = 0;
}
- ptrdiff_t count = SPECPDL_INDEX ();
+ specpdl_ref count = SPECPDL_INDEX ();
freeze_buffer_relocation ();
freeze_pattern (cache_entry);
re_match_object = Qnil;
i = re_match_2 (&cache_entry->buf, (char *) p1, s1, (char *) p2, s2,
PT_BYTE - BEGV_BYTE,
- preserve_match_data ? &search_regs : NULL,
+ modify_match_data ? &search_regs : NULL,
ZV_BYTE - BEGV_BYTE);
if (i == -2)
@@ -326,7 +326,7 @@ looking_at_1 (Lisp_Object string, bool posix)
}
val = (i >= 0 ? Qt : Qnil);
- if (preserve_match_data && i >= 0)
+ if (modify_match_data && i >= 0)
{
for (i = 0; i < search_regs.num_regs; i++)
if (search_regs.start[i] >= 0)
@@ -343,35 +343,36 @@ looking_at_1 (Lisp_Object string, bool posix)
return unbind_to (count, val);
}
-DEFUN ("looking-at", Flooking_at, Slooking_at, 1, 1, 0,
+DEFUN ("looking-at", Flooking_at, Slooking_at, 1, 2, 0,
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. */)
- (Lisp_Object regexp)
+By default, this function modifies the match data that
+`match-beginning', `match-end' and `match-data' access. If
+INHIBIT-MODIFY is non-nil, don't modify the match data. */)
+ (Lisp_Object regexp, Lisp_Object inhibit_modify)
{
- return looking_at_1 (regexp, 0);
+ return looking_at_1 (regexp, 0, NILP (inhibit_modify));
}
-DEFUN ("posix-looking-at", Fposix_looking_at, Sposix_looking_at, 1, 1, 0,
+DEFUN ("posix-looking-at", Fposix_looking_at, Sposix_looking_at, 1, 2, 0,
doc: /* Return t if text after point matches REGEXP according to Posix rules.
Find the longest match, in accordance 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. */)
- (Lisp_Object regexp)
+
+By default, this function modifies the match data that
+`match-beginning', `match-end' and `match-data' access. If
+INHIBIT-MODIFY is non-nil, don't modify the match data. */)
+ (Lisp_Object regexp, Lisp_Object inhibit_modify)
{
- return looking_at_1 (regexp, 1);
+ return looking_at_1 (regexp, 1, NILP (inhibit_modify));
}
static Lisp_Object
string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
- bool posix)
+ bool posix, bool modify_data)
{
ptrdiff_t val;
- struct re_pattern_buffer *bufp;
EMACS_INT pos;
ptrdiff_t pos_byte, i;
+ bool modify_match_data = NILP (Vinhibit_changing_match_data) && modify_data;
if (running_asynch_code)
save_search_regs ();
@@ -399,29 +400,32 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
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)
- ? &search_regs : NULL),
- (!NILP (BVAR (current_buffer, case_fold_search))
- ? BVAR (current_buffer, case_canon_table) : Qnil),
- posix,
- STRING_MULTIBYTE (string))->buf;
+ specpdl_ref count = SPECPDL_INDEX ();
+ struct regexp_cache *cache_entry
+ = compile_pattern (regexp,
+ modify_match_data ? &search_regs : NULL,
+ (!NILP (BVAR (current_buffer, case_fold_search))
+ ? BVAR (current_buffer, case_canon_table)
+ : Qnil),
+ posix,
+ STRING_MULTIBYTE (string));
+ freeze_pattern (cache_entry);
re_match_object = string;
- val = re_search (bufp, SSDATA (string),
+ val = re_search (&cache_entry->buf, SSDATA (string),
SBYTES (string), pos_byte,
SBYTES (string) - pos_byte,
- (NILP (Vinhibit_changing_match_data)
- ? &search_regs : NULL));
+ (modify_match_data ? &search_regs : NULL));
+ unbind_to (count, Qnil);
/* Set last_thing_searched only when match data is changed. */
- if (NILP (Vinhibit_changing_match_data))
+ if (modify_match_data)
last_thing_searched = Qt;
if (val == -2)
matcher_overflow ();
if (val < 0) return Qnil;
- if (NILP (Vinhibit_changing_match_data))
+ if (modify_match_data)
for (i = 0; i < search_regs.num_regs; i++)
if (search_regs.start[i] >= 0)
{
@@ -434,32 +438,42 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
return make_fixnum (string_byte_to_char (string, val));
}
-DEFUN ("string-match", Fstring_match, Sstring_match, 2, 3, 0,
+DEFUN ("string-match", Fstring_match, Sstring_match, 2, 4, 0,
doc: /* Return index of start of first match for REGEXP in STRING, or nil.
Matching ignores case if `case-fold-search' is non-nil.
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.
-You can use the function `match-string' to extract the substrings
-matched by the parenthesis constructions in REGEXP. */)
- (Lisp_Object regexp, Lisp_Object string, Lisp_Object start)
+If INHIBIT-MODIFY is non-nil, match data is not changed.
+
+If INHIBIT-MODIFY is nil or missing, match data is changed, and
+`match-end' and `match-beginning' give indices of substrings matched
+by parenthesis constructs in the pattern. You can use the function
+`match-string' to extract the substrings matched by the parenthesis
+constructions in REGEXP. For index of first char beyond the match, do
+(match-end 0). */)
+ (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
+ Lisp_Object inhibit_modify)
{
- return string_match_1 (regexp, string, start, 0);
+ return string_match_1 (regexp, string, start, 0, NILP (inhibit_modify));
}
-DEFUN ("posix-string-match", Fposix_string_match, Sposix_string_match, 2, 3, 0,
+DEFUN ("posix-string-match", Fposix_string_match, Sposix_string_match, 2, 4, 0,
doc: /* Return index of start of first match for Posix 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. */)
- (Lisp_Object regexp, Lisp_Object string, Lisp_Object start)
+
+If INHIBIT-MODIFY is non-nil, match data is not changed.
+
+If INHIBIT-MODIFY is nil or missing, match data is changed, and
+`match-end' and `match-beginning' give indices of substrings matched
+by parenthesis constructs in the pattern. You can use the function
+`match-string' to extract the substrings matched by the parenthesis
+constructions in REGEXP. For index of first char beyond the match, do
+(match-end 0). */)
+ (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
+ Lisp_Object inhibit_modify)
{
- return string_match_1 (regexp, string, start, 1);
+ return string_match_1 (regexp, string, start, 1, NILP (inhibit_modify));
}
/* Match REGEXP against STRING using translation table TABLE,
@@ -470,15 +484,15 @@ ptrdiff_t
fast_string_match_internal (Lisp_Object regexp, Lisp_Object string,
Lisp_Object table)
{
- ptrdiff_t val;
- struct re_pattern_buffer *bufp;
-
- bufp = &compile_pattern (regexp, 0, table,
- 0, STRING_MULTIBYTE (string))->buf;
re_match_object = string;
- val = re_search (bufp, SSDATA (string),
- SBYTES (string), 0,
- SBYTES (string), 0);
+ specpdl_ref count = SPECPDL_INDEX ();
+ struct regexp_cache *cache_entry
+ = compile_pattern (regexp, 0, table, 0, STRING_MULTIBYTE (string));
+ freeze_pattern (cache_entry);
+ ptrdiff_t val = re_search (&cache_entry->buf, SSDATA (string),
+ SBYTES (string), 0,
+ SBYTES (string), 0);
+ unbind_to (count, Qnil);
return val;
}
@@ -491,15 +505,14 @@ ptrdiff_t
fast_c_string_match_ignore_case (Lisp_Object regexp,
const char *string, ptrdiff_t len)
{
- ptrdiff_t val;
- struct re_pattern_buffer *bufp;
-
regexp = string_make_unibyte (regexp);
- bufp = &compile_pattern (regexp, 0,
- Vascii_canon_table, 0,
- 0)->buf;
+ specpdl_ref count = SPECPDL_INDEX ();
+ struct regexp_cache *cache_entry
+ = compile_pattern (regexp, 0, Vascii_canon_table, 0, 0);
+ freeze_pattern (cache_entry);
re_match_object = Qt;
- val = re_search (bufp, string, len, 0, len, 0);
+ ptrdiff_t val = re_search (&cache_entry->buf, string, len, 0, len, 0);
+ unbind_to (count, Qnil);
return val;
}
@@ -558,7 +571,7 @@ fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte,
struct regexp_cache *cache_entry =
compile_pattern (regexp, 0, Qnil, 0, multibyte);
- ptrdiff_t count = SPECPDL_INDEX ();
+ specpdl_ref count = SPECPDL_INDEX ();
freeze_buffer_relocation ();
freeze_pattern (cache_entry);
re_match_object = STRINGP (string) ? string : Qnil;
@@ -1188,7 +1201,7 @@ search_buffer_re (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
s2 = 0;
}
- ptrdiff_t count = SPECPDL_INDEX ();
+ specpdl_ref count = SPECPDL_INDEX ();
freeze_buffer_relocation ();
freeze_pattern (cache_entry);
@@ -3186,7 +3199,7 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
}
/* Like find_newline, but doesn't use the cache, and only searches forward. */
-static ptrdiff_t
+ptrdiff_t
find_newline1 (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end,
ptrdiff_t end_byte, ptrdiff_t count, ptrdiff_t *counted,
ptrdiff_t *bytepos, bool allow_quit)