summaryrefslogtreecommitdiff
path: root/src/search.c
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>1994-11-19 10:00:14 +0000
committerRichard M. Stallman <rms@gnu.org>1994-11-19 10:00:14 +0000
commit35cf5d60339a3128b04f8410b8ba2820676c06a7 (patch)
tree3db9f6104a12be606f0ad9a0046735d1b381640c /src/search.c
parent06771f65a03b281883aae1f0707fad3f23395c30 (diff)
downloademacs-35cf5d60339a3128b04f8410b8ba2820676c06a7.tar.gz
(struct regexp_cache): New field `posix'.
(compile_pattern_1): New arg `posix'. Controls the syntax spec for parsing; also record it in the cache. (compile_pattern): New arg `posix'. (looking_at_1, string_match_1, fast_string_match): Pass 0 for new arg. (search_buffer): New arg `posix'. Now static. (search_command): New arg `posix'. All callers changed. (Fposix_search_forward, Fposix_search_backward): New functions. (string_match_1, looking_at_1): New subroutines broken out. (Fstring_match, Flooking_at): Use them. (Fposix_string_match, Fposix_looking_at): New functions. (syms_of_search): defsubr new functions.
Diffstat (limited to 'src/search.c')
-rw-r--r--src/search.c189
1 files changed, 154 insertions, 35 deletions
diff --git a/src/search.c b/src/search.c
index a0050190931..622df821c70 100644
--- a/src/search.c
+++ b/src/search.c
@@ -38,6 +38,8 @@ struct regexp_cache {
Lisp_Object regexp;
struct re_pattern_buffer buf;
char fastmap[0400];
+ /* Nonzero means regexp was compiled to do full POSIX backtracking. */
+ char posix;
};
/* The instances of that struct. */
@@ -77,6 +79,8 @@ Lisp_Object Qinvalid_regexp;
static void set_search_regs ();
+static int search_buffer ();
+
static void
matcher_overflow ()
{
@@ -89,22 +93,37 @@ matcher_overflow ()
#define CONST
#endif
-/* Compile a regexp and signal a Lisp error if anything goes wrong. */
+/* Compile a regexp and signal a Lisp error if anything goes wrong.
+ PATTERN is the pattern to compile.
+ CP is the place to put the result.
+ TRANSLATE is a translation table for ignoring case, or NULL for none.
+ REGP is the structure that says where to store the "register"
+ values that will result from matching this pattern.
+ If it is 0, we should compile the pattern not to record any
+ subexpression bounds.
+ POSIX is nonzero if we want full backtracking (POSIX style)
+ for this pattern. 0 means backtrack only enough to get a valid match. */
static void
-compile_pattern_1 (cp, pattern, translate, regp)
+compile_pattern_1 (cp, pattern, translate, regp, posix)
struct regexp_cache *cp;
Lisp_Object pattern;
char *translate;
struct re_registers *regp;
+ int posix;
{
CONST char *val;
+ reg_syntax_t old;
cp->regexp = Qnil;
cp->buf.translate = translate;
+ cp->posix = posix;
BLOCK_INPUT;
+ old = re_set_syntax (RE_SYNTAX_EMACS
+ | (posix ? 0 : RE_NO_POSIX_BACKTRACKING));
val = (CONST char *) re_compile_pattern ((char *) XSTRING (pattern)->data,
XSTRING (pattern)->size, &cp->buf);
+ re_set_syntax (old);
UNBLOCK_INPUT;
if (val)
Fsignal (Qinvalid_regexp, Fcons (build_string (val), Qnil));
@@ -120,13 +139,22 @@ compile_pattern_1 (cp, pattern, translate, regp)
}
/* Compile a regexp if necessary, but first check to see if there's one in
- the cache. */
+ the cache.
+ PATTERN is the pattern to compile.
+ TRANSLATE is a translation table for ignoring case, or NULL for none.
+ REGP is the structure that says where to store the "register"
+ values that will result from matching this pattern.
+ If it is 0, we should compile the pattern not to record any
+ subexpression bounds.
+ POSIX is nonzero if we want full backtracking (POSIX style)
+ for this pattern. 0 means backtrack only enough to get a valid match. */
struct re_pattern_buffer *
-compile_pattern (pattern, regp, translate)
+compile_pattern (pattern, regp, translate, posix)
Lisp_Object pattern;
struct re_registers *regp;
char *translate;
+ int posix;
{
struct regexp_cache *cp, **cpp;
@@ -134,13 +162,14 @@ compile_pattern (pattern, regp, translate)
{
cp = *cpp;
if (!NILP (Fstring_equal (cp->regexp, pattern))
- && cp->buf.translate == translate)
+ && cp->buf.translate == translate
+ && cp->posix == posix)
break;
/* If we're at the end of the cache, compile into the last cell. */
if (cp->next == 0)
{
- compile_pattern_1 (cp, pattern, translate, regp);
+ compile_pattern_1 (cp, pattern, translate, regp, posix);
break;
}
}
@@ -166,13 +195,10 @@ signal_failure (arg)
return Qnil;
}
-DEFUN ("looking-at", Flooking_at, Slooking_at, 1, 1, 0,
- "Return t if text after point matches regular expression PAT.\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.")
- (string)
+static Lisp_Object
+looking_at_1 (string, posix)
Lisp_Object string;
+ int posix;
{
Lisp_Object val;
unsigned char *p1, *p2;
@@ -183,7 +209,8 @@ data if you want to preserve them.")
CHECK_STRING (string, 0);
bufp = compile_pattern (string, &search_regs,
(!NILP (current_buffer->case_fold_search)
- ? DOWNCASE_TABLE : 0));
+ ? DOWNCASE_TABLE : 0),
+ posix);
immediate_quit = 1;
QUIT; /* Do a pending quit right away, to avoid paradoxical behavior */
@@ -225,14 +252,33 @@ data if you want to preserve them.")
return val;
}
-DEFUN ("string-match", Fstring_match, Sstring_match, 2, 3, 0,
- "Return index of start of first match for REGEXP in STRING, or nil.\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)
+DEFUN ("looking-at", Flooking_at, Slooking_at, 1, 1, 0,
+ "Return t if text after point matches regular expression PAT.\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.")
+ (string)
+ Lisp_Object string;
+{
+ return looking_at_1 (string, 0);
+}
+
+DEFUN ("posix-looking-at", Fposix_looking_at, Sposix_looking_at, 1, 1, 0,
+ "Return t if text after point matches regular expression PAT.\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.")
+ (string)
+ Lisp_Object string;
+{
+ return looking_at_1 (string, 1);
+}
+
+static Lisp_Object
+string_match_1 (regexp, string, start, posix)
Lisp_Object regexp, string, start;
+ int posix;
{
int val;
int s;
@@ -257,7 +303,8 @@ matched by parenthesis constructs in the pattern.")
bufp = compile_pattern (regexp, &search_regs,
(!NILP (current_buffer->case_fold_search)
- ? DOWNCASE_TABLE : 0));
+ ? DOWNCASE_TABLE : 0),
+ 0);
immediate_quit = 1;
val = re_search (bufp, (char *) XSTRING (string)->data,
XSTRING (string)->size, s, XSTRING (string)->size - s,
@@ -270,6 +317,31 @@ matched by parenthesis constructs in the pattern.")
return make_number (val);
}
+DEFUN ("string-match", Fstring_match, Sstring_match, 2, 3, 0,
+ "Return index of start of first match for REGEXP in STRING, or nil.\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)
+ 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\
+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)
+ Lisp_Object regexp, string, start;
+{
+ return string_match_1 (regexp, string, start, 1);
+}
+
/* Match REGEXP against STRING, searching all of STRING,
and return the index of the match, or negative on failure.
This does not clobber the match data. */
@@ -281,7 +353,7 @@ fast_string_match (regexp, string)
int val;
struct re_pattern_buffer *bufp;
- bufp = compile_pattern (regexp, 0, 0);
+ bufp = compile_pattern (regexp, 0, 0, 0);
immediate_quit = 1;
val = re_search (bufp, (char *) XSTRING (string)->data,
XSTRING (string)->size, 0, XSTRING (string)->size,
@@ -725,10 +797,11 @@ skip_chars (forwardp, syntaxp, string, lim)
/* Subroutines of Lisp buffer search functions. */
static Lisp_Object
-search_command (string, bound, noerror, count, direction, RE)
+search_command (string, bound, noerror, count, direction, RE, posix)
Lisp_Object string, bound, noerror, count;
int direction;
int RE;
+ int posix;
{
register int np;
int lim;
@@ -759,7 +832,8 @@ search_command (string, bound, noerror, count, direction, RE)
(!NILP (current_buffer->case_fold_search)
? XSTRING (current_buffer->case_canon_table)->data : 0),
(!NILP (current_buffer->case_fold_search)
- ? XSTRING (current_buffer->case_eqv_table)->data : 0));
+ ? XSTRING (current_buffer->case_eqv_table)->data : 0),
+ posix);
if (np <= 0)
{
if (NILP (noerror))
@@ -818,7 +892,7 @@ trivial_regexp_p (regexp)
/* Search for the n'th occurrence of STRING in the current buffer,
starting at position POS and stopping at position LIM,
- treating PAT as a literal string if RE is false or as
+ treating STRING as a literal string if RE is false or as
a regular expression if RE is true.
If N is positive, searching is forward and LIM must be greater than POS.
@@ -826,9 +900,13 @@ trivial_regexp_p (regexp)
Returns -x if only N-x occurrences found (x > 0),
or else the position at the beginning of the Nth occurrence
- (if searching backward) or the end (if searching forward). */
+ (if searching backward) or the end (if searching forward).
+
+ POSIX is nonzero if we want full backtracking (POSIX style)
+ for this pattern. 0 means backtrack only enough to get a valid match. */
-search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
+static int
+search_buffer (string, pos, lim, n, RE, trt, inverse_trt, posix)
Lisp_Object string;
int pos;
int lim;
@@ -836,6 +914,7 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
int RE;
register unsigned char *trt;
register unsigned char *inverse_trt;
+ int posix;
{
int len = XSTRING (string)->size;
unsigned char *base_pat = XSTRING (string)->data;
@@ -864,7 +943,7 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
{
struct re_pattern_buffer *bufp;
- bufp = compile_pattern (string, &search_regs, (char *) trt);
+ bufp = compile_pattern (string, &search_regs, (char *) trt, posix);
immediate_quit = 1; /* Quit immediately if user types ^G,
because letting this function finish
@@ -1296,7 +1375,7 @@ 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);
+ return search_command (string, bound, noerror, count, -1, 0, 0);
}
DEFUN ("search-forward", Fsearch_forward, Ssearch_forward, 1, 4, "sSearch: ",
@@ -1312,7 +1391,7 @@ 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);
+ return search_command (string, bound, noerror, count, 1, 0, 0);
}
DEFUN ("word-search-backward", Fword_search_backward, Sword_search_backward, 1, 4,
@@ -1327,7 +1406,7 @@ 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);
+ return search_command (wordify (string), bound, noerror, count, -1, 1, 0);
}
DEFUN ("word-search-forward", Fword_search_forward, Sword_search_forward, 1, 4,
@@ -1342,7 +1421,7 @@ 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);
+ return search_command (wordify (string), bound, noerror, count, 1, 1, 0);
}
DEFUN ("re-search-backward", Fre_search_backward, Sre_search_backward, 1, 4,
@@ -1360,7 +1439,7 @@ See also the functions `match-beginning', `match-end' and `replace-match'.")
(regexp, bound, noerror, count)
Lisp_Object regexp, bound, noerror, count;
{
- return search_command (regexp, bound, noerror, count, -1, 1);
+ return search_command (regexp, bound, noerror, count, -1, 1, 0);
}
DEFUN ("re-search-forward", Fre_search_forward, Sre_search_forward, 1, 4,
@@ -1376,7 +1455,43 @@ See also the functions `match-beginning', `match-end' and `replace-match'.")
(regexp, bound, noerror, count)
Lisp_Object regexp, bound, noerror, count;
{
- return search_command (regexp, bound, noerror, count, 1, 1);
+ 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' 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' 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, 4, 0,
@@ -1865,8 +1980,10 @@ syms_of_search ()
last_thing_searched = Qnil;
staticpro (&last_thing_searched);
- defsubr (&Sstring_match);
defsubr (&Slooking_at);
+ defsubr (&Sposix_looking_at);
+ defsubr (&Sstring_match);
+ defsubr (&Sposix_string_match);
defsubr (&Sskip_chars_forward);
defsubr (&Sskip_chars_backward);
defsubr (&Sskip_syntax_forward);
@@ -1877,6 +1994,8 @@ syms_of_search ()
defsubr (&Sword_search_backward);
defsubr (&Sre_search_forward);
defsubr (&Sre_search_backward);
+ defsubr (&Sposix_search_forward);
+ defsubr (&Sposix_search_backward);
defsubr (&Sreplace_match);
defsubr (&Smatch_beginning);
defsubr (&Smatch_end);