(compare-windows): Push mark in both buffers at start.
[bpt/emacs.git] / src / search.c
CommitLineData
ca1d1d23 1/* String search routines for GNU Emacs.
3a22ee35 2 Copyright (C) 1985, 1986, 1987, 1993, 1994 Free Software Foundation, Inc.
ca1d1d23
JB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
18160b98 21#include <config.h>
ca1d1d23
JB
22#include "lisp.h"
23#include "syntax.h"
24#include "buffer.h"
9169c321 25#include "region-cache.h"
ca1d1d23 26#include "commands.h"
9ac0d9e0 27#include "blockinput.h"
4746118a 28
ca1d1d23
JB
29#include <sys/types.h>
30#include "regex.h"
31
487282dc 32#define REGEXP_CACHE_SIZE 5
ca1d1d23 33
487282dc
KH
34/* If the regexp is non-nil, then the buffer contains the compiled form
35 of that regexp, suitable for searching. */
36struct regexp_cache {
37 struct regexp_cache *next;
38 Lisp_Object regexp;
39 struct re_pattern_buffer buf;
40 char fastmap[0400];
b819a390
RS
41 /* Nonzero means regexp was compiled to do full POSIX backtracking. */
42 char posix;
487282dc 43};
ca1d1d23 44
487282dc
KH
45/* The instances of that struct. */
46struct regexp_cache searchbufs[REGEXP_CACHE_SIZE];
ca1d1d23 47
487282dc
KH
48/* The head of the linked list; points to the most recently used buffer. */
49struct regexp_cache *searchbuf_head;
ca1d1d23 50
ca1d1d23 51
4746118a
JB
52/* Every call to re_match, etc., must pass &search_regs as the regs
53 argument unless you can show it is unnecessary (i.e., if re_match
54 is certainly going to be called again before region-around-match
55 can be called).
56
57 Since the registers are now dynamically allocated, we need to make
58 sure not to refer to the Nth register before checking that it has
1113d9db
JB
59 been allocated by checking search_regs.num_regs.
60
61 The regex code keeps track of whether it has allocated the search
487282dc
KH
62 buffer using bits in the re_pattern_buffer. This means that whenever
63 you compile a new pattern, it completely forgets whether it has
1113d9db
JB
64 allocated any registers, and will allocate new registers the next
65 time you call a searching or matching function. Therefore, we need
66 to call re_set_registers after compiling a new pattern or after
67 setting the match registers, so that the regex functions will be
68 able to free or re-allocate it properly. */
ca1d1d23
JB
69static struct re_registers search_regs;
70
daa37602
JB
71/* The buffer in which the last search was performed, or
72 Qt if the last search was done in a string;
73 Qnil if no searching has been done yet. */
74static Lisp_Object last_thing_searched;
ca1d1d23
JB
75
76/* error condition signalled when regexp compile_pattern fails */
77
78Lisp_Object Qinvalid_regexp;
79
ca325161
RS
80static void set_search_regs ();
81
b819a390
RS
82static int search_buffer ();
83
ca1d1d23
JB
84static void
85matcher_overflow ()
86{
87 error ("Stack overflow in regexp matcher");
88}
89
90#ifdef __STDC__
91#define CONST const
92#else
93#define CONST
94#endif
95
b819a390
RS
96/* Compile a regexp and signal a Lisp error if anything goes wrong.
97 PATTERN is the pattern to compile.
98 CP is the place to put the result.
99 TRANSLATE is a translation table for ignoring case, or NULL for none.
100 REGP is the structure that says where to store the "register"
101 values that will result from matching this pattern.
102 If it is 0, we should compile the pattern not to record any
103 subexpression bounds.
104 POSIX is nonzero if we want full backtracking (POSIX style)
105 for this pattern. 0 means backtrack only enough to get a valid match. */
ca1d1d23 106
487282dc 107static void
b819a390 108compile_pattern_1 (cp, pattern, translate, regp, posix)
487282dc 109 struct regexp_cache *cp;
ca1d1d23 110 Lisp_Object pattern;
ca1d1d23 111 char *translate;
487282dc 112 struct re_registers *regp;
b819a390 113 int posix;
ca1d1d23
JB
114{
115 CONST char *val;
b819a390 116 reg_syntax_t old;
ca1d1d23 117
487282dc
KH
118 cp->regexp = Qnil;
119 cp->buf.translate = translate;
b819a390 120 cp->posix = posix;
9ac0d9e0 121 BLOCK_INPUT;
b819a390
RS
122 old = re_set_syntax (RE_SYNTAX_EMACS
123 | (posix ? 0 : RE_NO_POSIX_BACKTRACKING));
b90d9e80 124 val = (CONST char *) re_compile_pattern ((char *) XSTRING (pattern)->data,
487282dc 125 XSTRING (pattern)->size, &cp->buf);
b819a390 126 re_set_syntax (old);
9ac0d9e0 127 UNBLOCK_INPUT;
ca1d1d23 128 if (val)
487282dc 129 Fsignal (Qinvalid_regexp, Fcons (build_string (val), Qnil));
1113d9db 130
487282dc 131 cp->regexp = Fcopy_sequence (pattern);
1113d9db
JB
132
133 /* Advise the searching functions about the space we have allocated
134 for register data. */
9ac0d9e0 135 BLOCK_INPUT;
ebb9e16f 136 if (regp)
487282dc 137 re_set_registers (&cp->buf, regp, regp->num_regs, regp->start, regp->end);
9ac0d9e0 138 UNBLOCK_INPUT;
487282dc
KH
139}
140
141/* Compile a regexp if necessary, but first check to see if there's one in
b819a390
RS
142 the cache.
143 PATTERN is the pattern to compile.
144 TRANSLATE is a translation table for ignoring case, or NULL for none.
145 REGP is the structure that says where to store the "register"
146 values that will result from matching this pattern.
147 If it is 0, we should compile the pattern not to record any
148 subexpression bounds.
149 POSIX is nonzero if we want full backtracking (POSIX style)
150 for this pattern. 0 means backtrack only enough to get a valid match. */
487282dc
KH
151
152struct re_pattern_buffer *
b819a390 153compile_pattern (pattern, regp, translate, posix)
487282dc
KH
154 Lisp_Object pattern;
155 struct re_registers *regp;
156 char *translate;
b819a390 157 int posix;
487282dc
KH
158{
159 struct regexp_cache *cp, **cpp;
160
161 for (cpp = &searchbuf_head; ; cpp = &cp->next)
162 {
163 cp = *cpp;
164 if (!NILP (Fstring_equal (cp->regexp, pattern))
b819a390
RS
165 && cp->buf.translate == translate
166 && cp->posix == posix)
487282dc
KH
167 break;
168
169 /* If we're at the end of the cache, compile into the last cell. */
170 if (cp->next == 0)
171 {
b819a390 172 compile_pattern_1 (cp, pattern, translate, regp, posix);
487282dc
KH
173 break;
174 }
175 }
176
177 /* When we get here, cp (aka *cpp) contains the compiled pattern,
178 either because we found it in the cache or because we just compiled it.
179 Move it to the front of the queue to mark it as most recently used. */
180 *cpp = cp->next;
181 cp->next = searchbuf_head;
182 searchbuf_head = cp;
1113d9db 183
487282dc 184 return &cp->buf;
ca1d1d23
JB
185}
186
187/* Error condition used for failing searches */
188Lisp_Object Qsearch_failed;
189
190Lisp_Object
191signal_failure (arg)
192 Lisp_Object arg;
193{
194 Fsignal (Qsearch_failed, Fcons (arg, Qnil));
195 return Qnil;
196}
197\f
b819a390
RS
198static Lisp_Object
199looking_at_1 (string, posix)
ca1d1d23 200 Lisp_Object string;
b819a390 201 int posix;
ca1d1d23
JB
202{
203 Lisp_Object val;
204 unsigned char *p1, *p2;
205 int s1, s2;
206 register int i;
487282dc 207 struct re_pattern_buffer *bufp;
ca1d1d23
JB
208
209 CHECK_STRING (string, 0);
487282dc
KH
210 bufp = compile_pattern (string, &search_regs,
211 (!NILP (current_buffer->case_fold_search)
b819a390
RS
212 ? DOWNCASE_TABLE : 0),
213 posix);
ca1d1d23
JB
214
215 immediate_quit = 1;
216 QUIT; /* Do a pending quit right away, to avoid paradoxical behavior */
217
218 /* Get pointers and sizes of the two strings
219 that make up the visible portion of the buffer. */
220
221 p1 = BEGV_ADDR;
222 s1 = GPT - BEGV;
223 p2 = GAP_END_ADDR;
224 s2 = ZV - GPT;
225 if (s1 < 0)
226 {
227 p2 = p1;
228 s2 = ZV - BEGV;
229 s1 = 0;
230 }
231 if (s2 < 0)
232 {
233 s1 = ZV - BEGV;
234 s2 = 0;
235 }
236
487282dc 237 i = re_match_2 (bufp, (char *) p1, s1, (char *) p2, s2,
ca1d1d23
JB
238 point - BEGV, &search_regs,
239 ZV - BEGV);
240 if (i == -2)
241 matcher_overflow ();
242
243 val = (0 <= i ? Qt : Qnil);
4746118a 244 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
245 if (search_regs.start[i] >= 0)
246 {
247 search_regs.start[i] += BEGV;
248 search_regs.end[i] += BEGV;
249 }
a3668d92 250 XSETBUFFER (last_thing_searched, current_buffer);
ca1d1d23
JB
251 immediate_quit = 0;
252 return val;
253}
254
b819a390
RS
255DEFUN ("looking-at", Flooking_at, Slooking_at, 1, 1, 0,
256 "Return t if text after point matches regular expression PAT.\n\
257This function modifies the match data that `match-beginning',\n\
258`match-end' and `match-data' access; save and restore the match\n\
259data if you want to preserve them.")
260 (string)
261 Lisp_Object string;
262{
263 return looking_at_1 (string, 0);
264}
265
266DEFUN ("posix-looking-at", Fposix_looking_at, Sposix_looking_at, 1, 1, 0,
267 "Return t if text after point matches regular expression PAT.\n\
268Find the longest match, in accord with Posix regular expression rules.\n\
269This function modifies the match data that `match-beginning',\n\
270`match-end' and `match-data' access; save and restore the match\n\
271data if you want to preserve them.")
272 (string)
273 Lisp_Object string;
274{
275 return looking_at_1 (string, 1);
276}
277\f
278static Lisp_Object
279string_match_1 (regexp, string, start, posix)
ca1d1d23 280 Lisp_Object regexp, string, start;
b819a390 281 int posix;
ca1d1d23
JB
282{
283 int val;
284 int s;
487282dc 285 struct re_pattern_buffer *bufp;
ca1d1d23
JB
286
287 CHECK_STRING (regexp, 0);
288 CHECK_STRING (string, 1);
289
290 if (NILP (start))
291 s = 0;
292 else
293 {
294 int len = XSTRING (string)->size;
295
296 CHECK_NUMBER (start, 2);
297 s = XINT (start);
298 if (s < 0 && -s <= len)
26faf9f4 299 s = len + s;
ca1d1d23
JB
300 else if (0 > s || s > len)
301 args_out_of_range (string, start);
302 }
303
487282dc
KH
304 bufp = compile_pattern (regexp, &search_regs,
305 (!NILP (current_buffer->case_fold_search)
b819a390
RS
306 ? DOWNCASE_TABLE : 0),
307 0);
ca1d1d23 308 immediate_quit = 1;
487282dc 309 val = re_search (bufp, (char *) XSTRING (string)->data,
ca1d1d23
JB
310 XSTRING (string)->size, s, XSTRING (string)->size - s,
311 &search_regs);
312 immediate_quit = 0;
daa37602 313 last_thing_searched = Qt;
ca1d1d23
JB
314 if (val == -2)
315 matcher_overflow ();
316 if (val < 0) return Qnil;
317 return make_number (val);
318}
e59a8453 319
b819a390
RS
320DEFUN ("string-match", Fstring_match, Sstring_match, 2, 3, 0,
321 "Return index of start of first match for REGEXP in STRING, or nil.\n\
322If third arg START is non-nil, start search at that index in STRING.\n\
323For index of first char beyond the match, do (match-end 0).\n\
324`match-end' and `match-beginning' also give indices of substrings\n\
325matched by parenthesis constructs in the pattern.")
326 (regexp, string, start)
327 Lisp_Object regexp, string, start;
328{
329 return string_match_1 (regexp, string, start, 0);
330}
331
332DEFUN ("posix-string-match", Fposix_string_match, Sposix_string_match, 2, 3, 0,
333 "Return index of start of first match for REGEXP in STRING, or nil.\n\
334Find the longest match, in accord with Posix regular expression rules.\n\
335If third arg START is non-nil, start search at that index in STRING.\n\
336For index of first char beyond the match, do (match-end 0).\n\
337`match-end' and `match-beginning' also give indices of substrings\n\
338matched by parenthesis constructs in the pattern.")
339 (regexp, string, start)
340 Lisp_Object regexp, string, start;
341{
342 return string_match_1 (regexp, string, start, 1);
343}
344
e59a8453
RS
345/* Match REGEXP against STRING, searching all of STRING,
346 and return the index of the match, or negative on failure.
347 This does not clobber the match data. */
348
349int
350fast_string_match (regexp, string)
351 Lisp_Object regexp, string;
352{
353 int val;
487282dc 354 struct re_pattern_buffer *bufp;
e59a8453 355
b819a390 356 bufp = compile_pattern (regexp, 0, 0, 0);
e59a8453 357 immediate_quit = 1;
487282dc 358 val = re_search (bufp, (char *) XSTRING (string)->data,
e59a8453
RS
359 XSTRING (string)->size, 0, XSTRING (string)->size,
360 0);
361 immediate_quit = 0;
362 return val;
363}
ca1d1d23 364\f
9169c321
JB
365/* max and min. */
366
367static int
368max (a, b)
369 int a, b;
370{
371 return ((a > b) ? a : b);
372}
373
374static int
375min (a, b)
376 int a, b;
377{
378 return ((a < b) ? a : b);
379}
380
381\f
382/* The newline cache: remembering which sections of text have no newlines. */
383
384/* If the user has requested newline caching, make sure it's on.
385 Otherwise, make sure it's off.
386 This is our cheezy way of associating an action with the change of
387 state of a buffer-local variable. */
388static void
389newline_cache_on_off (buf)
390 struct buffer *buf;
391{
392 if (NILP (buf->cache_long_line_scans))
393 {
394 /* It should be off. */
395 if (buf->newline_cache)
396 {
397 free_region_cache (buf->newline_cache);
398 buf->newline_cache = 0;
399 }
400 }
401 else
402 {
403 /* It should be on. */
404 if (buf->newline_cache == 0)
405 buf->newline_cache = new_region_cache ();
406 }
407}
408
409\f
410/* Search for COUNT instances of the character TARGET between START and END.
411
412 If COUNT is positive, search forwards; END must be >= START.
413 If COUNT is negative, search backwards for the -COUNTth instance;
414 END must be <= START.
415 If COUNT is zero, do anything you please; run rogue, for all I care.
416
417 If END is zero, use BEGV or ZV instead, as appropriate for the
418 direction indicated by COUNT.
ffd56f97
JB
419
420 If we find COUNT instances, set *SHORTAGE to zero, and return the
5bfe95c9
RS
421 position after the COUNTth match. Note that for reverse motion
422 this is not the same as the usual convention for Emacs motion commands.
ffd56f97 423
9169c321
JB
424 If we don't find COUNT instances before reaching END, set *SHORTAGE
425 to the number of TARGETs left unfound, and return END.
ffd56f97 426
087a5f81
RS
427 If ALLOW_QUIT is non-zero, set immediate_quit. That's good to do
428 except when inside redisplay. */
429
9169c321
JB
430scan_buffer (target, start, end, count, shortage, allow_quit)
431 register int target;
432 int start, end;
433 int count;
434 int *shortage;
087a5f81 435 int allow_quit;
ca1d1d23 436{
9169c321
JB
437 struct region_cache *newline_cache;
438 int direction;
ffd56f97 439
9169c321
JB
440 if (count > 0)
441 {
442 direction = 1;
443 if (! end) end = ZV;
444 }
445 else
446 {
447 direction = -1;
448 if (! end) end = BEGV;
449 }
ffd56f97 450
9169c321
JB
451 newline_cache_on_off (current_buffer);
452 newline_cache = current_buffer->newline_cache;
ca1d1d23
JB
453
454 if (shortage != 0)
455 *shortage = 0;
456
087a5f81 457 immediate_quit = allow_quit;
ca1d1d23 458
ffd56f97 459 if (count > 0)
9169c321 460 while (start != end)
ca1d1d23 461 {
9169c321
JB
462 /* Our innermost scanning loop is very simple; it doesn't know
463 about gaps, buffer ends, or the newline cache. ceiling is
464 the position of the last character before the next such
465 obstacle --- the last character the dumb search loop should
466 examine. */
467 register int ceiling = end - 1;
468
469 /* If we're looking for a newline, consult the newline cache
470 to see where we can avoid some scanning. */
471 if (target == '\n' && newline_cache)
472 {
473 int next_change;
474 immediate_quit = 0;
475 while (region_cache_forward
476 (current_buffer, newline_cache, start, &next_change))
477 start = next_change;
cbe0db0d 478 immediate_quit = allow_quit;
9169c321
JB
479
480 /* start should never be after end. */
481 if (start >= end)
482 start = end - 1;
483
484 /* Now the text after start is an unknown region, and
485 next_change is the position of the next known region. */
486 ceiling = min (next_change - 1, ceiling);
487 }
488
489 /* The dumb loop can only scan text stored in contiguous
490 bytes. BUFFER_CEILING_OF returns the last character
491 position that is contiguous, so the ceiling is the
492 position after that. */
493 ceiling = min (BUFFER_CEILING_OF (start), ceiling);
494
495 {
496 /* The termination address of the dumb loop. */
497 register unsigned char *ceiling_addr = &FETCH_CHAR (ceiling) + 1;
498 register unsigned char *cursor = &FETCH_CHAR (start);
499 unsigned char *base = cursor;
500
501 while (cursor < ceiling_addr)
502 {
503 unsigned char *scan_start = cursor;
504
505 /* The dumb loop. */
506 while (*cursor != target && ++cursor < ceiling_addr)
507 ;
508
509 /* If we're looking for newlines, cache the fact that
510 the region from start to cursor is free of them. */
511 if (target == '\n' && newline_cache)
512 know_region_cache (current_buffer, newline_cache,
513 start + scan_start - base,
514 start + cursor - base);
515
516 /* Did we find the target character? */
517 if (cursor < ceiling_addr)
518 {
519 if (--count == 0)
520 {
521 immediate_quit = 0;
522 return (start + cursor - base + 1);
523 }
524 cursor++;
525 }
526 }
527
528 start += cursor - base;
529 }
ca1d1d23
JB
530 }
531 else
9169c321
JB
532 while (start > end)
533 {
534 /* The last character to check before the next obstacle. */
535 register int ceiling = end;
536
537 /* Consult the newline cache, if appropriate. */
538 if (target == '\n' && newline_cache)
539 {
540 int next_change;
541 immediate_quit = 0;
542 while (region_cache_backward
543 (current_buffer, newline_cache, start, &next_change))
544 start = next_change;
cbe0db0d 545 immediate_quit = allow_quit;
9169c321
JB
546
547 /* Start should never be at or before end. */
548 if (start <= end)
549 start = end + 1;
550
551 /* Now the text before start is an unknown region, and
552 next_change is the position of the next known region. */
553 ceiling = max (next_change, ceiling);
554 }
555
556 /* Stop scanning before the gap. */
557 ceiling = max (BUFFER_FLOOR_OF (start - 1), ceiling);
558
559 {
560 /* The termination address of the dumb loop. */
561 register unsigned char *ceiling_addr = &FETCH_CHAR (ceiling);
562 register unsigned char *cursor = &FETCH_CHAR (start - 1);
563 unsigned char *base = cursor;
564
565 while (cursor >= ceiling_addr)
566 {
567 unsigned char *scan_start = cursor;
568
569 while (*cursor != target && --cursor >= ceiling_addr)
570 ;
571
572 /* If we're looking for newlines, cache the fact that
573 the region from after the cursor to start is free of them. */
574 if (target == '\n' && newline_cache)
575 know_region_cache (current_buffer, newline_cache,
576 start + cursor - base,
577 start + scan_start - base);
578
579 /* Did we find the target character? */
580 if (cursor >= ceiling_addr)
581 {
582 if (++count >= 0)
583 {
584 immediate_quit = 0;
585 return (start + cursor - base);
586 }
587 cursor--;
588 }
589 }
590
591 start += cursor - base;
592 }
593 }
594
ca1d1d23
JB
595 immediate_quit = 0;
596 if (shortage != 0)
ffd56f97 597 *shortage = count * direction;
9169c321 598 return start;
ca1d1d23
JB
599}
600
63fa018d
RS
601int
602find_next_newline_no_quit (from, cnt)
603 register int from, cnt;
604{
9169c321 605 return scan_buffer ('\n', from, 0, cnt, (int *) 0, 0);
63fa018d
RS
606}
607
ca1d1d23
JB
608int
609find_next_newline (from, cnt)
610 register int from, cnt;
611{
9169c321
JB
612 return scan_buffer ('\n', from, 0, cnt, (int *) 0, 1);
613}
614
615
616/* Like find_next_newline, but returns position before the newline,
617 not after, and only search up to TO. This isn't just
618 find_next_newline (...)-1, because you might hit TO. */
619int
620find_before_next_newline (from, to, cnt)
cbe0db0d 621 int from, to, cnt;
9169c321
JB
622{
623 int shortage;
624 int pos = scan_buffer ('\n', from, to, cnt, &shortage, 1);
625
626 if (shortage == 0)
627 pos--;
628
629 return pos;
ca1d1d23
JB
630}
631\f
c1dc99a1
JB
632Lisp_Object skip_chars ();
633
ca1d1d23 634DEFUN ("skip-chars-forward", Fskip_chars_forward, Sskip_chars_forward, 1, 2, 0,
3acb9a69
RS
635 "Move point forward, stopping before a char not in STRING, or at pos LIM.\n\
636STRING is like the inside of a `[...]' in a regular expression\n\
ca1d1d23
JB
637except that `]' is never special and `\\' quotes `^', `-' or `\\'.\n\
638Thus, with arg \"a-zA-Z\", this skips letters stopping before first nonletter.\n\
c1dc99a1
JB
639With arg \"^a-zA-Z\", skips nonletters stopping before first letter.\n\
640Returns the distance traveled, either zero or positive.")
ca1d1d23
JB
641 (string, lim)
642 Lisp_Object string, lim;
643{
17431c60 644 return skip_chars (1, 0, string, lim);
ca1d1d23
JB
645}
646
647DEFUN ("skip-chars-backward", Fskip_chars_backward, Sskip_chars_backward, 1, 2, 0,
3acb9a69 648 "Move point backward, stopping after a char not in STRING, or at pos LIM.\n\
c1dc99a1
JB
649See `skip-chars-forward' for details.\n\
650Returns the distance traveled, either zero or negative.")
ca1d1d23
JB
651 (string, lim)
652 Lisp_Object string, lim;
653{
17431c60
RS
654 return skip_chars (0, 0, string, lim);
655}
656
657DEFUN ("skip-syntax-forward", Fskip_syntax_forward, Sskip_syntax_forward, 1, 2, 0,
658 "Move point forward across chars in specified syntax classes.\n\
659SYNTAX is a string of syntax code characters.\n\
660Stop before a char whose syntax is not in SYNTAX, or at position LIM.\n\
661If SYNTAX starts with ^, skip characters whose syntax is NOT in SYNTAX.\n\
662This function returns the distance traveled, either zero or positive.")
663 (syntax, lim)
664 Lisp_Object syntax, lim;
665{
666 return skip_chars (1, 1, syntax, lim);
667}
668
669DEFUN ("skip-syntax-backward", Fskip_syntax_backward, Sskip_syntax_backward, 1, 2, 0,
670 "Move point backward across chars in specified syntax classes.\n\
671SYNTAX is a string of syntax code characters.\n\
672Stop on reaching a char whose syntax is not in SYNTAX, or at position LIM.\n\
673If SYNTAX starts with ^, skip characters whose syntax is NOT in SYNTAX.\n\
674This function returns the distance traveled, either zero or negative.")
675 (syntax, lim)
676 Lisp_Object syntax, lim;
677{
678 return skip_chars (0, 1, syntax, lim);
ca1d1d23
JB
679}
680
c1dc99a1 681Lisp_Object
17431c60
RS
682skip_chars (forwardp, syntaxp, string, lim)
683 int forwardp, syntaxp;
ca1d1d23
JB
684 Lisp_Object string, lim;
685{
686 register unsigned char *p, *pend;
687 register unsigned char c;
688 unsigned char fastmap[0400];
689 int negate = 0;
690 register int i;
691
692 CHECK_STRING (string, 0);
693
694 if (NILP (lim))
a3668d92 695 XSETINT (lim, forwardp ? ZV : BEGV);
ca1d1d23
JB
696 else
697 CHECK_NUMBER_COERCE_MARKER (lim, 1);
698
ca1d1d23 699 /* In any case, don't allow scan outside bounds of buffer. */
c5241910
RS
700 /* jla turned this off, for no known reason.
701 bfox turned the ZV part on, and rms turned the
702 BEGV part back on. */
703 if (XINT (lim) > ZV)
c235cce7 704 XSETFASTINT (lim, ZV);
c5241910 705 if (XINT (lim) < BEGV)
c235cce7 706 XSETFASTINT (lim, BEGV);
ca1d1d23
JB
707
708 p = XSTRING (string)->data;
709 pend = p + XSTRING (string)->size;
710 bzero (fastmap, sizeof fastmap);
711
712 if (p != pend && *p == '^')
713 {
714 negate = 1; p++;
715 }
716
17431c60
RS
717 /* Find the characters specified and set their elements of fastmap.
718 If syntaxp, each character counts as itself.
719 Otherwise, handle backslashes and ranges specially */
ca1d1d23
JB
720
721 while (p != pend)
722 {
723 c = *p++;
17431c60
RS
724 if (syntaxp)
725 fastmap[c] = 1;
726 else
ca1d1d23 727 {
17431c60 728 if (c == '\\')
ca1d1d23 729 {
17431c60
RS
730 if (p == pend) break;
731 c = *p++;
732 }
733 if (p != pend && *p == '-')
734 {
735 p++;
736 if (p == pend) break;
737 while (c <= *p)
738 {
739 fastmap[c] = 1;
740 c++;
741 }
742 p++;
ca1d1d23 743 }
17431c60
RS
744 else
745 fastmap[c] = 1;
ca1d1d23 746 }
ca1d1d23
JB
747 }
748
9239c6c1
RS
749 if (syntaxp && fastmap['-'] != 0)
750 fastmap[' '] = 1;
751
ca1d1d23
JB
752 /* If ^ was the first character, complement the fastmap. */
753
754 if (negate)
755 for (i = 0; i < sizeof fastmap; i++)
756 fastmap[i] ^= 1;
757
c1dc99a1
JB
758 {
759 int start_point = point;
760
761 immediate_quit = 1;
17431c60 762 if (syntaxp)
c1dc99a1 763 {
17431c60
RS
764
765 if (forwardp)
766 {
767 while (point < XINT (lim)
768 && fastmap[(unsigned char) syntax_code_spec[(int) SYNTAX (FETCH_CHAR (point))]])
769 SET_PT (point + 1);
770 }
771 else
772 {
773 while (point > XINT (lim)
774 && fastmap[(unsigned char) syntax_code_spec[(int) SYNTAX (FETCH_CHAR (point - 1))]])
775 SET_PT (point - 1);
776 }
c1dc99a1
JB
777 }
778 else
779 {
17431c60
RS
780 if (forwardp)
781 {
782 while (point < XINT (lim) && fastmap[FETCH_CHAR (point)])
783 SET_PT (point + 1);
784 }
785 else
786 {
787 while (point > XINT (lim) && fastmap[FETCH_CHAR (point - 1)])
788 SET_PT (point - 1);
789 }
c1dc99a1
JB
790 }
791 immediate_quit = 0;
792
793 return make_number (point - start_point);
794 }
ca1d1d23
JB
795}
796\f
797/* Subroutines of Lisp buffer search functions. */
798
799static Lisp_Object
b819a390 800search_command (string, bound, noerror, count, direction, RE, posix)
ca1d1d23
JB
801 Lisp_Object string, bound, noerror, count;
802 int direction;
803 int RE;
b819a390 804 int posix;
ca1d1d23
JB
805{
806 register int np;
807 int lim;
808 int n = direction;
809
810 if (!NILP (count))
811 {
812 CHECK_NUMBER (count, 3);
813 n *= XINT (count);
814 }
815
816 CHECK_STRING (string, 0);
817 if (NILP (bound))
818 lim = n > 0 ? ZV : BEGV;
819 else
820 {
821 CHECK_NUMBER_COERCE_MARKER (bound, 1);
822 lim = XINT (bound);
823 if (n > 0 ? lim < point : lim > point)
824 error ("Invalid search bound (wrong side of point)");
825 if (lim > ZV)
826 lim = ZV;
827 if (lim < BEGV)
828 lim = BEGV;
829 }
830
831 np = search_buffer (string, point, lim, n, RE,
832 (!NILP (current_buffer->case_fold_search)
833 ? XSTRING (current_buffer->case_canon_table)->data : 0),
834 (!NILP (current_buffer->case_fold_search)
b819a390
RS
835 ? XSTRING (current_buffer->case_eqv_table)->data : 0),
836 posix);
ca1d1d23
JB
837 if (np <= 0)
838 {
839 if (NILP (noerror))
840 return signal_failure (string);
841 if (!EQ (noerror, Qt))
842 {
843 if (lim < BEGV || lim > ZV)
844 abort ();
a5f217b8
RS
845 SET_PT (lim);
846 return Qnil;
847#if 0 /* This would be clean, but maybe programs depend on
848 a value of nil here. */
481399bf 849 np = lim;
a5f217b8 850#endif
ca1d1d23 851 }
481399bf
RS
852 else
853 return Qnil;
ca1d1d23
JB
854 }
855
856 if (np < BEGV || np > ZV)
857 abort ();
858
859 SET_PT (np);
860
861 return make_number (np);
862}
863\f
b6d6a51c
KH
864static int
865trivial_regexp_p (regexp)
866 Lisp_Object regexp;
867{
868 int len = XSTRING (regexp)->size;
869 unsigned char *s = XSTRING (regexp)->data;
870 unsigned char c;
871 while (--len >= 0)
872 {
873 switch (*s++)
874 {
875 case '.': case '*': case '+': case '?': case '[': case '^': case '$':
876 return 0;
877 case '\\':
878 if (--len < 0)
879 return 0;
880 switch (*s++)
881 {
882 case '|': case '(': case ')': case '`': case '\'': case 'b':
883 case 'B': case '<': case '>': case 'w': case 'W': case 's':
884 case 'S': case '1': case '2': case '3': case '4': case '5':
885 case '6': case '7': case '8': case '9':
886 return 0;
887 }
888 }
889 }
890 return 1;
891}
892
ca325161 893/* Search for the n'th occurrence of STRING in the current buffer,
ca1d1d23 894 starting at position POS and stopping at position LIM,
b819a390 895 treating STRING as a literal string if RE is false or as
ca1d1d23
JB
896 a regular expression if RE is true.
897
898 If N is positive, searching is forward and LIM must be greater than POS.
899 If N is negative, searching is backward and LIM must be less than POS.
900
901 Returns -x if only N-x occurrences found (x > 0),
902 or else the position at the beginning of the Nth occurrence
b819a390
RS
903 (if searching backward) or the end (if searching forward).
904
905 POSIX is nonzero if we want full backtracking (POSIX style)
906 for this pattern. 0 means backtrack only enough to get a valid match. */
ca1d1d23 907
b819a390
RS
908static int
909search_buffer (string, pos, lim, n, RE, trt, inverse_trt, posix)
ca1d1d23
JB
910 Lisp_Object string;
911 int pos;
912 int lim;
913 int n;
914 int RE;
915 register unsigned char *trt;
916 register unsigned char *inverse_trt;
b819a390 917 int posix;
ca1d1d23
JB
918{
919 int len = XSTRING (string)->size;
920 unsigned char *base_pat = XSTRING (string)->data;
921 register int *BM_tab;
922 int *BM_tab_base;
923 register int direction = ((n > 0) ? 1 : -1);
924 register int dirlen;
925 int infinity, limit, k, stride_for_teases;
926 register unsigned char *pat, *cursor, *p_limit;
927 register int i, j;
928 unsigned char *p1, *p2;
929 int s1, s2;
930
931 /* Null string is found at starting position. */
3f57a499 932 if (len == 0)
ca325161
RS
933 {
934 set_search_regs (pos, 0);
935 return pos;
936 }
3f57a499
RS
937
938 /* Searching 0 times means don't move. */
939 if (n == 0)
ca1d1d23
JB
940 return pos;
941
b6d6a51c 942 if (RE && !trivial_regexp_p (string))
ca1d1d23 943 {
487282dc
KH
944 struct re_pattern_buffer *bufp;
945
b819a390 946 bufp = compile_pattern (string, &search_regs, (char *) trt, posix);
ca1d1d23 947
ca1d1d23
JB
948 immediate_quit = 1; /* Quit immediately if user types ^G,
949 because letting this function finish
950 can take too long. */
951 QUIT; /* Do a pending quit right away,
952 to avoid paradoxical behavior */
953 /* Get pointers and sizes of the two strings
954 that make up the visible portion of the buffer. */
955
956 p1 = BEGV_ADDR;
957 s1 = GPT - BEGV;
958 p2 = GAP_END_ADDR;
959 s2 = ZV - GPT;
960 if (s1 < 0)
961 {
962 p2 = p1;
963 s2 = ZV - BEGV;
964 s1 = 0;
965 }
966 if (s2 < 0)
967 {
968 s1 = ZV - BEGV;
969 s2 = 0;
970 }
971 while (n < 0)
972 {
42db823b 973 int val;
487282dc 974 val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2,
42db823b
RS
975 pos - BEGV, lim - pos, &search_regs,
976 /* Don't allow match past current point */
977 pos - BEGV);
ca1d1d23 978 if (val == -2)
b6d6a51c
KH
979 {
980 matcher_overflow ();
981 }
ca1d1d23
JB
982 if (val >= 0)
983 {
984 j = BEGV;
4746118a 985 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
986 if (search_regs.start[i] >= 0)
987 {
988 search_regs.start[i] += j;
989 search_regs.end[i] += j;
990 }
a3668d92 991 XSETBUFFER (last_thing_searched, current_buffer);
ca1d1d23
JB
992 /* Set pos to the new position. */
993 pos = search_regs.start[0];
994 }
995 else
996 {
997 immediate_quit = 0;
998 return (n);
999 }
1000 n++;
1001 }
1002 while (n > 0)
1003 {
42db823b 1004 int val;
487282dc 1005 val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2,
42db823b
RS
1006 pos - BEGV, lim - pos, &search_regs,
1007 lim - BEGV);
ca1d1d23 1008 if (val == -2)
b6d6a51c
KH
1009 {
1010 matcher_overflow ();
1011 }
ca1d1d23
JB
1012 if (val >= 0)
1013 {
1014 j = BEGV;
4746118a 1015 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
1016 if (search_regs.start[i] >= 0)
1017 {
1018 search_regs.start[i] += j;
1019 search_regs.end[i] += j;
1020 }
a3668d92 1021 XSETBUFFER (last_thing_searched, current_buffer);
ca1d1d23
JB
1022 pos = search_regs.end[0];
1023 }
1024 else
1025 {
1026 immediate_quit = 0;
1027 return (0 - n);
1028 }
1029 n--;
1030 }
1031 immediate_quit = 0;
1032 return (pos);
1033 }
1034 else /* non-RE case */
1035 {
1036#ifdef C_ALLOCA
1037 int BM_tab_space[0400];
1038 BM_tab = &BM_tab_space[0];
1039#else
1040 BM_tab = (int *) alloca (0400 * sizeof (int));
1041#endif
b6d6a51c
KH
1042 {
1043 unsigned char *patbuf = (unsigned char *) alloca (len);
1044 pat = patbuf;
1045 while (--len >= 0)
1046 {
1047 /* If we got here and the RE flag is set, it's because we're
1048 dealing with a regexp known to be trivial, so the backslash
1049 just quotes the next character. */
1050 if (RE && *base_pat == '\\')
1051 {
1052 len--;
1053 base_pat++;
1054 }
1055 *pat++ = (trt ? trt[*base_pat++] : *base_pat++);
1056 }
1057 len = pat - patbuf;
1058 pat = base_pat = patbuf;
1059 }
ca1d1d23
JB
1060 /* The general approach is that we are going to maintain that we know */
1061 /* the first (closest to the present position, in whatever direction */
1062 /* we're searching) character that could possibly be the last */
1063 /* (furthest from present position) character of a valid match. We */
1064 /* advance the state of our knowledge by looking at that character */
1065 /* and seeing whether it indeed matches the last character of the */
1066 /* pattern. If it does, we take a closer look. If it does not, we */
1067 /* move our pointer (to putative last characters) as far as is */
1068 /* logically possible. This amount of movement, which I call a */
1069 /* stride, will be the length of the pattern if the actual character */
1070 /* appears nowhere in the pattern, otherwise it will be the distance */
1071 /* from the last occurrence of that character to the end of the */
1072 /* pattern. */
1073 /* As a coding trick, an enormous stride is coded into the table for */
1074 /* characters that match the last character. This allows use of only */
1075 /* a single test, a test for having gone past the end of the */
1076 /* permissible match region, to test for both possible matches (when */
1077 /* the stride goes past the end immediately) and failure to */
1078 /* match (where you get nudged past the end one stride at a time). */
1079
1080 /* Here we make a "mickey mouse" BM table. The stride of the search */
1081 /* is determined only by the last character of the putative match. */
1082 /* If that character does not match, we will stride the proper */
1083 /* distance to propose a match that superimposes it on the last */
1084 /* instance of a character that matches it (per trt), or misses */
1085 /* it entirely if there is none. */
1086
1087 dirlen = len * direction;
1088 infinity = dirlen - (lim + pos + len + len) * direction;
1089 if (direction < 0)
1090 pat = (base_pat += len - 1);
1091 BM_tab_base = BM_tab;
1092 BM_tab += 0400;
1093 j = dirlen; /* to get it in a register */
1094 /* A character that does not appear in the pattern induces a */
1095 /* stride equal to the pattern length. */
1096 while (BM_tab_base != BM_tab)
1097 {
1098 *--BM_tab = j;
1099 *--BM_tab = j;
1100 *--BM_tab = j;
1101 *--BM_tab = j;
1102 }
1103 i = 0;
1104 while (i != infinity)
1105 {
1106 j = pat[i]; i += direction;
1107 if (i == dirlen) i = infinity;
1108 if ((int) trt)
1109 {
1110 k = (j = trt[j]);
1111 if (i == infinity)
1112 stride_for_teases = BM_tab[j];
1113 BM_tab[j] = dirlen - i;
1114 /* A translation table is accompanied by its inverse -- see */
1115 /* comment following downcase_table for details */
1116 while ((j = inverse_trt[j]) != k)
1117 BM_tab[j] = dirlen - i;
1118 }
1119 else
1120 {
1121 if (i == infinity)
1122 stride_for_teases = BM_tab[j];
1123 BM_tab[j] = dirlen - i;
1124 }
1125 /* stride_for_teases tells how much to stride if we get a */
1126 /* match on the far character but are subsequently */
1127 /* disappointed, by recording what the stride would have been */
1128 /* for that character if the last character had been */
1129 /* different. */
1130 }
1131 infinity = dirlen - infinity;
1132 pos += dirlen - ((direction > 0) ? direction : 0);
1133 /* loop invariant - pos points at where last char (first char if reverse)
1134 of pattern would align in a possible match. */
1135 while (n != 0)
1136 {
b2c71fb4
KH
1137 /* It's been reported that some (broken) compiler thinks that
1138 Boolean expressions in an arithmetic context are unsigned.
1139 Using an explicit ?1:0 prevents this. */
1140 if ((lim - pos - ((direction > 0) ? 1 : 0)) * direction < 0)
ca1d1d23
JB
1141 return (n * (0 - direction));
1142 /* First we do the part we can by pointers (maybe nothing) */
1143 QUIT;
1144 pat = base_pat;
1145 limit = pos - dirlen + direction;
1146 limit = ((direction > 0)
1147 ? BUFFER_CEILING_OF (limit)
1148 : BUFFER_FLOOR_OF (limit));
1149 /* LIMIT is now the last (not beyond-last!) value
1150 POS can take on without hitting edge of buffer or the gap. */
1151 limit = ((direction > 0)
1152 ? min (lim - 1, min (limit, pos + 20000))
1153 : max (lim, max (limit, pos - 20000)));
1154 if ((limit - pos) * direction > 20)
1155 {
1156 p_limit = &FETCH_CHAR (limit);
1157 p2 = (cursor = &FETCH_CHAR (pos));
1158 /* In this loop, pos + cursor - p2 is the surrogate for pos */
1159 while (1) /* use one cursor setting as long as i can */
1160 {
1161 if (direction > 0) /* worth duplicating */
1162 {
1163 /* Use signed comparison if appropriate
1164 to make cursor+infinity sure to be > p_limit.
1165 Assuming that the buffer lies in a range of addresses
1166 that are all "positive" (as ints) or all "negative",
1167 either kind of comparison will work as long
1168 as we don't step by infinity. So pick the kind
1169 that works when we do step by infinity. */
1170 if ((int) (p_limit + infinity) > (int) p_limit)
1171 while ((int) cursor <= (int) p_limit)
1172 cursor += BM_tab[*cursor];
1173 else
1174 while ((unsigned int) cursor <= (unsigned int) p_limit)
1175 cursor += BM_tab[*cursor];
1176 }
1177 else
1178 {
1179 if ((int) (p_limit + infinity) < (int) p_limit)
1180 while ((int) cursor >= (int) p_limit)
1181 cursor += BM_tab[*cursor];
1182 else
1183 while ((unsigned int) cursor >= (unsigned int) p_limit)
1184 cursor += BM_tab[*cursor];
1185 }
1186/* If you are here, cursor is beyond the end of the searched region. */
1187 /* This can happen if you match on the far character of the pattern, */
1188 /* because the "stride" of that character is infinity, a number able */
1189 /* to throw you well beyond the end of the search. It can also */
1190 /* happen if you fail to match within the permitted region and would */
1191 /* otherwise try a character beyond that region */
1192 if ((cursor - p_limit) * direction <= len)
1193 break; /* a small overrun is genuine */
1194 cursor -= infinity; /* large overrun = hit */
1195 i = dirlen - direction;
1196 if ((int) trt)
1197 {
1198 while ((i -= direction) + direction != 0)
1199 if (pat[i] != trt[*(cursor -= direction)])
1200 break;
1201 }
1202 else
1203 {
1204 while ((i -= direction) + direction != 0)
1205 if (pat[i] != *(cursor -= direction))
1206 break;
1207 }
1208 cursor += dirlen - i - direction; /* fix cursor */
1209 if (i + direction == 0)
1210 {
1211 cursor -= direction;
1113d9db 1212
ca325161
RS
1213 set_search_regs (pos + cursor - p2 + ((direction > 0)
1214 ? 1 - len : 0),
1215 len);
1216
ca1d1d23
JB
1217 if ((n -= direction) != 0)
1218 cursor += dirlen; /* to resume search */
1219 else
1220 return ((direction > 0)
1221 ? search_regs.end[0] : search_regs.start[0]);
1222 }
1223 else
1224 cursor += stride_for_teases; /* <sigh> we lose - */
1225 }
1226 pos += cursor - p2;
1227 }
1228 else
1229 /* Now we'll pick up a clump that has to be done the hard */
1230 /* way because it covers a discontinuity */
1231 {
1232 limit = ((direction > 0)
1233 ? BUFFER_CEILING_OF (pos - dirlen + 1)
1234 : BUFFER_FLOOR_OF (pos - dirlen - 1));
1235 limit = ((direction > 0)
1236 ? min (limit + len, lim - 1)
1237 : max (limit - len, lim));
1238 /* LIMIT is now the last value POS can have
1239 and still be valid for a possible match. */
1240 while (1)
1241 {
1242 /* This loop can be coded for space rather than */
1243 /* speed because it will usually run only once. */
1244 /* (the reach is at most len + 21, and typically */
1245 /* does not exceed len) */
1246 while ((limit - pos) * direction >= 0)
1247 pos += BM_tab[FETCH_CHAR(pos)];
1248 /* now run the same tests to distinguish going off the */
eb8c3be9 1249 /* end, a match or a phony match. */
ca1d1d23
JB
1250 if ((pos - limit) * direction <= len)
1251 break; /* ran off the end */
1252 /* Found what might be a match.
1253 Set POS back to last (first if reverse) char pos. */
1254 pos -= infinity;
1255 i = dirlen - direction;
1256 while ((i -= direction) + direction != 0)
1257 {
1258 pos -= direction;
1259 if (pat[i] != (((int) trt)
1260 ? trt[FETCH_CHAR(pos)]
1261 : FETCH_CHAR (pos)))
1262 break;
1263 }
1264 /* Above loop has moved POS part or all the way
1265 back to the first char pos (last char pos if reverse).
1266 Set it once again at the last (first if reverse) char. */
1267 pos += dirlen - i- direction;
1268 if (i + direction == 0)
1269 {
1270 pos -= direction;
1113d9db 1271
ca325161
RS
1272 set_search_regs (pos + ((direction > 0) ? 1 - len : 0),
1273 len);
1274
ca1d1d23
JB
1275 if ((n -= direction) != 0)
1276 pos += dirlen; /* to resume search */
1277 else
1278 return ((direction > 0)
1279 ? search_regs.end[0] : search_regs.start[0]);
1280 }
1281 else
1282 pos += stride_for_teases;
1283 }
1284 }
1285 /* We have done one clump. Can we continue? */
1286 if ((lim - pos) * direction < 0)
1287 return ((0 - n) * direction);
1288 }
1289 return pos;
1290 }
1291}
ca325161
RS
1292
1293/* Record beginning BEG and end BEG + LEN
1294 for a match just found in the current buffer. */
1295
1296static void
1297set_search_regs (beg, len)
1298 int beg, len;
1299{
1300 /* Make sure we have registers in which to store
1301 the match position. */
1302 if (search_regs.num_regs == 0)
1303 {
1304 regoff_t *starts, *ends;
1305
1306 starts = (regoff_t *) xmalloc (2 * sizeof (regoff_t));
1307 ends = (regoff_t *) xmalloc (2 * sizeof (regoff_t));
487282dc 1308 search_regs.num_regs = 2;
ca325161
RS
1309 }
1310
1311 search_regs.start[0] = beg;
1312 search_regs.end[0] = beg + len;
a3668d92 1313 XSETBUFFER (last_thing_searched, current_buffer);
ca325161 1314}
ca1d1d23
JB
1315\f
1316/* Given a string of words separated by word delimiters,
1317 compute a regexp that matches those exact words
1318 separated by arbitrary punctuation. */
1319
1320static Lisp_Object
1321wordify (string)
1322 Lisp_Object string;
1323{
1324 register unsigned char *p, *o;
1325 register int i, len, punct_count = 0, word_count = 0;
1326 Lisp_Object val;
1327
1328 CHECK_STRING (string, 0);
1329 p = XSTRING (string)->data;
1330 len = XSTRING (string)->size;
1331
1332 for (i = 0; i < len; i++)
1333 if (SYNTAX (p[i]) != Sword)
1334 {
1335 punct_count++;
1336 if (i > 0 && SYNTAX (p[i-1]) == Sword) word_count++;
1337 }
1338 if (SYNTAX (p[len-1]) == Sword) word_count++;
1339 if (!word_count) return build_string ("");
1340
1341 val = make_string (p, len - punct_count + 5 * (word_count - 1) + 4);
1342
1343 o = XSTRING (val)->data;
1344 *o++ = '\\';
1345 *o++ = 'b';
1346
1347 for (i = 0; i < len; i++)
1348 if (SYNTAX (p[i]) == Sword)
1349 *o++ = p[i];
1350 else if (i > 0 && SYNTAX (p[i-1]) == Sword && --word_count)
1351 {
1352 *o++ = '\\';
1353 *o++ = 'W';
1354 *o++ = '\\';
1355 *o++ = 'W';
1356 *o++ = '*';
1357 }
1358
1359 *o++ = '\\';
1360 *o++ = 'b';
1361
1362 return val;
1363}
1364\f
1365DEFUN ("search-backward", Fsearch_backward, Ssearch_backward, 1, 4,
1366 "sSearch backward: ",
1367 "Search backward from point for STRING.\n\
1368Set point to the beginning of the occurrence found, and return point.\n\
1369An optional second argument bounds the search; it is a buffer position.\n\
1370The match found must not extend before that position.\n\
1371Optional third argument, if t, means if fail just return nil (no error).\n\
1372 If not nil and not t, position at limit of search and return nil.\n\
1373Optional fourth argument is repeat count--search for successive occurrences.\n\
1374See also the functions `match-beginning', `match-end' and `replace-match'.")
1375 (string, bound, noerror, count)
1376 Lisp_Object string, bound, noerror, count;
1377{
b819a390 1378 return search_command (string, bound, noerror, count, -1, 0, 0);
ca1d1d23
JB
1379}
1380
1381DEFUN ("search-forward", Fsearch_forward, Ssearch_forward, 1, 4, "sSearch: ",
1382 "Search forward from point for STRING.\n\
1383Set point to the end of the occurrence found, and return point.\n\
1384An optional second argument bounds the search; it is a buffer position.\n\
1385The match found must not extend after that position. nil is equivalent\n\
1386 to (point-max).\n\
1387Optional third argument, if t, means if fail just return nil (no error).\n\
1388 If not nil and not t, move to limit of search and return nil.\n\
1389Optional fourth argument is repeat count--search for successive occurrences.\n\
1390See also the functions `match-beginning', `match-end' and `replace-match'.")
1391 (string, bound, noerror, count)
1392 Lisp_Object string, bound, noerror, count;
1393{
b819a390 1394 return search_command (string, bound, noerror, count, 1, 0, 0);
ca1d1d23
JB
1395}
1396
1397DEFUN ("word-search-backward", Fword_search_backward, Sword_search_backward, 1, 4,
1398 "sWord search backward: ",
1399 "Search backward from point for STRING, ignoring differences in punctuation.\n\
1400Set point to the beginning of the occurrence found, and return point.\n\
1401An optional second argument bounds the search; it is a buffer position.\n\
1402The match found must not extend before that position.\n\
1403Optional third argument, if t, means if fail just return nil (no error).\n\
1404 If not nil and not t, move to limit of search and return nil.\n\
1405Optional fourth argument is repeat count--search for successive occurrences.")
1406 (string, bound, noerror, count)
1407 Lisp_Object string, bound, noerror, count;
1408{
b819a390 1409 return search_command (wordify (string), bound, noerror, count, -1, 1, 0);
ca1d1d23
JB
1410}
1411
1412DEFUN ("word-search-forward", Fword_search_forward, Sword_search_forward, 1, 4,
1413 "sWord search: ",
1414 "Search forward from point for STRING, ignoring differences in punctuation.\n\
1415Set point to the end of the occurrence found, and return point.\n\
1416An optional second argument bounds the search; it is a buffer position.\n\
1417The match found must not extend after that position.\n\
1418Optional third argument, if t, means if fail just return nil (no error).\n\
1419 If not nil and not t, move to limit of search and return nil.\n\
1420Optional fourth argument is repeat count--search for successive occurrences.")
1421 (string, bound, noerror, count)
1422 Lisp_Object string, bound, noerror, count;
1423{
b819a390 1424 return search_command (wordify (string), bound, noerror, count, 1, 1, 0);
ca1d1d23
JB
1425}
1426
1427DEFUN ("re-search-backward", Fre_search_backward, Sre_search_backward, 1, 4,
1428 "sRE search backward: ",
1429 "Search backward from point for match for regular expression REGEXP.\n\
1430Set point to the beginning of the match, and return point.\n\
1431The match found is the one starting last in the buffer\n\
19c0a730 1432and yet ending before the origin of the search.\n\
ca1d1d23
JB
1433An optional second argument bounds the search; it is a buffer position.\n\
1434The match found must start at or after that position.\n\
1435Optional third argument, if t, means if fail just return nil (no error).\n\
1436 If not nil and not t, move to limit of search and return nil.\n\
1437Optional fourth argument is repeat count--search for successive occurrences.\n\
1438See also the functions `match-beginning', `match-end' and `replace-match'.")
19c0a730
KH
1439 (regexp, bound, noerror, count)
1440 Lisp_Object regexp, bound, noerror, count;
ca1d1d23 1441{
b819a390 1442 return search_command (regexp, bound, noerror, count, -1, 1, 0);
ca1d1d23
JB
1443}
1444
1445DEFUN ("re-search-forward", Fre_search_forward, Sre_search_forward, 1, 4,
1446 "sRE search: ",
1447 "Search forward from point for regular expression REGEXP.\n\
1448Set point to the end of the occurrence found, and return point.\n\
1449An optional second argument bounds the search; it is a buffer position.\n\
1450The match found must not extend after that position.\n\
1451Optional third argument, if t, means if fail just return nil (no error).\n\
1452 If not nil and not t, move to limit of search and return nil.\n\
1453Optional fourth argument is repeat count--search for successive occurrences.\n\
1454See also the functions `match-beginning', `match-end' and `replace-match'.")
19c0a730
KH
1455 (regexp, bound, noerror, count)
1456 Lisp_Object regexp, bound, noerror, count;
ca1d1d23 1457{
b819a390
RS
1458 return search_command (regexp, bound, noerror, count, 1, 1, 0);
1459}
1460
1461DEFUN ("posix-search-backward", Fposix_search_backward, Sposix_search_backward, 1, 4,
1462 "sPosix search backward: ",
1463 "Search backward from point for match for regular expression REGEXP.\n\
1464Find the longest match in accord with Posix regular expression rules.\n\
1465Set point to the beginning of the match, and return point.\n\
1466The match found is the one starting last in the buffer\n\
1467and yet ending before the origin of the search.\n\
1468An optional second argument bounds the search; it is a buffer position.\n\
1469The match found must start at or after that position.\n\
1470Optional third argument, if t, means if fail just return nil (no error).\n\
1471 If not nil and not t, move to limit of search and return nil.\n\
1472Optional fourth argument is repeat count--search for successive occurrences.\n\
1473See also the functions `match-beginning', `match-end' and `replace-match'.")
1474 (regexp, bound, noerror, count)
1475 Lisp_Object regexp, bound, noerror, count;
1476{
1477 return search_command (regexp, bound, noerror, count, -1, 1, 1);
1478}
1479
1480DEFUN ("posix-search-forward", Fposix_search_forward, Sposix_search_forward, 1, 4,
1481 "sPosix search: ",
1482 "Search forward from point for regular expression REGEXP.\n\
1483Find the longest match in accord with Posix regular expression rules.\n\
1484Set point to the end of the occurrence found, and return point.\n\
1485An optional second argument bounds the search; it is a buffer position.\n\
1486The match found must not extend after that position.\n\
1487Optional third argument, if t, means if fail just return nil (no error).\n\
1488 If not nil and not t, move to limit of search and return nil.\n\
1489Optional fourth argument is repeat count--search for successive occurrences.\n\
1490See also the functions `match-beginning', `match-end' and `replace-match'.")
1491 (regexp, bound, noerror, count)
1492 Lisp_Object regexp, bound, noerror, count;
1493{
1494 return search_command (regexp, bound, noerror, count, 1, 1, 1);
ca1d1d23
JB
1495}
1496\f
080c45fd 1497DEFUN ("replace-match", Freplace_match, Sreplace_match, 1, 4, 0,
ca1d1d23
JB
1498 "Replace text matched by last search with NEWTEXT.\n\
1499If second arg FIXEDCASE is non-nil, do not alter case of replacement text.\n\
5b9cf4b2
RS
1500Otherwise maybe capitalize the whole text, or maybe just word initials,\n\
1501based on the replaced text.\n\
1502If the replaced text has only capital letters\n\
1503and has at least one multiletter word, convert NEWTEXT to all caps.\n\
1504If the replaced text has at least one word starting with a capital letter,\n\
1505then capitalize each word in NEWTEXT.\n\n\
ca1d1d23
JB
1506If third arg LITERAL is non-nil, insert NEWTEXT literally.\n\
1507Otherwise treat `\\' as special:\n\
1508 `\\&' in NEWTEXT means substitute original matched text.\n\
1509 `\\N' means substitute what matched the Nth `\\(...\\)'.\n\
1510 If Nth parens didn't match, substitute nothing.\n\
1511 `\\\\' means insert one `\\'.\n\
1113d9db 1512FIXEDCASE and LITERAL are optional arguments.\n\
080c45fd
RS
1513Leaves point at end of replacement text.\n\
1514\n\
1515The optional fourth argument STRING can be a string to modify.\n\
1516In that case, this function creates and returns a new string\n\
1517which is made by replacing the part of STRING that was matched.")
1518 (newtext, fixedcase, literal, string)
1519 Lisp_Object newtext, fixedcase, literal, string;
ca1d1d23
JB
1520{
1521 enum { nochange, all_caps, cap_initial } case_action;
1522 register int pos, last;
1523 int some_multiletter_word;
97832bd0 1524 int some_lowercase;
73dc8771 1525 int some_uppercase;
208767c3 1526 int some_nonuppercase_initial;
ca1d1d23
JB
1527 register int c, prevc;
1528 int inslen;
1529
16fdc568 1530 CHECK_STRING (newtext, 0);
ca1d1d23 1531
080c45fd
RS
1532 if (! NILP (string))
1533 CHECK_STRING (string, 4);
1534
ca1d1d23
JB
1535 case_action = nochange; /* We tried an initialization */
1536 /* but some C compilers blew it */
4746118a
JB
1537
1538 if (search_regs.num_regs <= 0)
1539 error ("replace-match called before any match found");
1540
080c45fd
RS
1541 if (NILP (string))
1542 {
1543 if (search_regs.start[0] < BEGV
1544 || search_regs.start[0] > search_regs.end[0]
1545 || search_regs.end[0] > ZV)
1546 args_out_of_range (make_number (search_regs.start[0]),
1547 make_number (search_regs.end[0]));
1548 }
1549 else
1550 {
1551 if (search_regs.start[0] < 0
1552 || search_regs.start[0] > search_regs.end[0]
1553 || search_regs.end[0] > XSTRING (string)->size)
1554 args_out_of_range (make_number (search_regs.start[0]),
1555 make_number (search_regs.end[0]));
1556 }
ca1d1d23
JB
1557
1558 if (NILP (fixedcase))
1559 {
1560 /* Decide how to casify by examining the matched text. */
1561
1562 last = search_regs.end[0];
1563 prevc = '\n';
1564 case_action = all_caps;
1565
1566 /* some_multiletter_word is set nonzero if any original word
1567 is more than one letter long. */
1568 some_multiletter_word = 0;
97832bd0 1569 some_lowercase = 0;
208767c3 1570 some_nonuppercase_initial = 0;
73dc8771 1571 some_uppercase = 0;
ca1d1d23
JB
1572
1573 for (pos = search_regs.start[0]; pos < last; pos++)
1574 {
080c45fd
RS
1575 if (NILP (string))
1576 c = FETCH_CHAR (pos);
1577 else
1578 c = XSTRING (string)->data[pos];
1579
ca1d1d23
JB
1580 if (LOWERCASEP (c))
1581 {
1582 /* Cannot be all caps if any original char is lower case */
1583
97832bd0 1584 some_lowercase = 1;
ca1d1d23 1585 if (SYNTAX (prevc) != Sword)
208767c3 1586 some_nonuppercase_initial = 1;
ca1d1d23
JB
1587 else
1588 some_multiletter_word = 1;
1589 }
1590 else if (!NOCASEP (c))
1591 {
73dc8771 1592 some_uppercase = 1;
97832bd0 1593 if (SYNTAX (prevc) != Sword)
c4d460ce 1594 ;
97832bd0 1595 else
ca1d1d23
JB
1596 some_multiletter_word = 1;
1597 }
208767c3
RS
1598 else
1599 {
1600 /* If the initial is a caseless word constituent,
1601 treat that like a lowercase initial. */
1602 if (SYNTAX (prevc) != Sword)
1603 some_nonuppercase_initial = 1;
1604 }
ca1d1d23
JB
1605
1606 prevc = c;
1607 }
1608
97832bd0
RS
1609 /* Convert to all caps if the old text is all caps
1610 and has at least one multiletter word. */
1611 if (! some_lowercase && some_multiletter_word)
1612 case_action = all_caps;
c4d460ce 1613 /* Capitalize each word, if the old text has all capitalized words. */
208767c3 1614 else if (!some_nonuppercase_initial && some_multiletter_word)
ca1d1d23 1615 case_action = cap_initial;
208767c3 1616 else if (!some_nonuppercase_initial && some_uppercase)
73dc8771
KH
1617 /* Should x -> yz, operating on X, give Yz or YZ?
1618 We'll assume the latter. */
1619 case_action = all_caps;
97832bd0
RS
1620 else
1621 case_action = nochange;
ca1d1d23
JB
1622 }
1623
080c45fd
RS
1624 /* Do replacement in a string. */
1625 if (!NILP (string))
1626 {
1627 Lisp_Object before, after;
1628
1629 before = Fsubstring (string, make_number (0),
1630 make_number (search_regs.start[0]));
1631 after = Fsubstring (string, make_number (search_regs.end[0]), Qnil);
1632
1633 /* Do case substitution into NEWTEXT if desired. */
1634 if (NILP (literal))
1635 {
1636 int lastpos = -1;
1637 /* We build up the substituted string in ACCUM. */
1638 Lisp_Object accum;
1639 Lisp_Object middle;
1640
1641 accum = Qnil;
1642
1643 for (pos = 0; pos < XSTRING (newtext)->size; pos++)
1644 {
1645 int substart = -1;
1646 int subend;
1647
1648 c = XSTRING (newtext)->data[pos];
1649 if (c == '\\')
1650 {
1651 c = XSTRING (newtext)->data[++pos];
1652 if (c == '&')
1653 {
1654 substart = search_regs.start[0];
1655 subend = search_regs.end[0];
1656 }
1657 else if (c >= '1' && c <= '9' && c <= search_regs.num_regs + '0')
1658 {
1659 if (search_regs.start[c - '0'] >= 1)
1660 {
1661 substart = search_regs.start[c - '0'];
1662 subend = search_regs.end[c - '0'];
1663 }
1664 }
1665 }
1666 if (substart >= 0)
1667 {
1668 if (pos - 1 != lastpos + 1)
1669 middle = Fsubstring (newtext, lastpos + 1, pos - 1);
1670 else
1671 middle = Qnil;
1672 accum = concat3 (accum, middle,
1673 Fsubstring (string, make_number (substart),
1674 make_number (subend)));
1675 lastpos = pos;
1676 }
1677 }
1678
1679 if (pos != lastpos + 1)
1680 middle = Fsubstring (newtext, lastpos + 1, pos);
1681 else
1682 middle = Qnil;
1683
1684 newtext = concat2 (accum, middle);
1685 }
1686
1687 if (case_action == all_caps)
1688 newtext = Fupcase (newtext);
1689 else if (case_action == cap_initial)
1690 newtext = upcase_initials (newtext);
1691
1692 return concat3 (before, newtext, after);
1693 }
1694
9a76659d
JB
1695 /* We insert the replacement text before the old text, and then
1696 delete the original text. This means that markers at the
1697 beginning or end of the original will float to the corresponding
1698 position in the replacement. */
1699 SET_PT (search_regs.start[0]);
ca1d1d23 1700 if (!NILP (literal))
16fdc568 1701 Finsert_and_inherit (1, &newtext);
ca1d1d23
JB
1702 else
1703 {
1704 struct gcpro gcpro1;
16fdc568 1705 GCPRO1 (newtext);
ca1d1d23 1706
16fdc568 1707 for (pos = 0; pos < XSTRING (newtext)->size; pos++)
ca1d1d23 1708 {
9a76659d
JB
1709 int offset = point - search_regs.start[0];
1710
16fdc568 1711 c = XSTRING (newtext)->data[pos];
ca1d1d23
JB
1712 if (c == '\\')
1713 {
16fdc568 1714 c = XSTRING (newtext)->data[++pos];
ca1d1d23 1715 if (c == '&')
9a76659d
JB
1716 Finsert_buffer_substring
1717 (Fcurrent_buffer (),
1718 make_number (search_regs.start[0] + offset),
1719 make_number (search_regs.end[0] + offset));
78445046 1720 else if (c >= '1' && c <= '9' && c <= search_regs.num_regs + '0')
ca1d1d23
JB
1721 {
1722 if (search_regs.start[c - '0'] >= 1)
9a76659d
JB
1723 Finsert_buffer_substring
1724 (Fcurrent_buffer (),
1725 make_number (search_regs.start[c - '0'] + offset),
1726 make_number (search_regs.end[c - '0'] + offset));
ca1d1d23
JB
1727 }
1728 else
1729 insert_char (c);
1730 }
1731 else
1732 insert_char (c);
1733 }
1734 UNGCPRO;
1735 }
1736
9a76659d
JB
1737 inslen = point - (search_regs.start[0]);
1738 del_range (search_regs.start[0] + inslen, search_regs.end[0] + inslen);
ca1d1d23
JB
1739
1740 if (case_action == all_caps)
1741 Fupcase_region (make_number (point - inslen), make_number (point));
1742 else if (case_action == cap_initial)
1743 upcase_initials_region (make_number (point - inslen), make_number (point));
1744 return Qnil;
1745}
1746\f
1747static Lisp_Object
1748match_limit (num, beginningp)
1749 Lisp_Object num;
1750 int beginningp;
1751{
1752 register int n;
1753
1754 CHECK_NUMBER (num, 0);
1755 n = XINT (num);
4746118a
JB
1756 if (n < 0 || n >= search_regs.num_regs)
1757 args_out_of_range (num, make_number (search_regs.num_regs));
1758 if (search_regs.num_regs <= 0
1759 || search_regs.start[n] < 0)
ca1d1d23
JB
1760 return Qnil;
1761 return (make_number ((beginningp) ? search_regs.start[n]
1762 : search_regs.end[n]));
1763}
1764
1765DEFUN ("match-beginning", Fmatch_beginning, Smatch_beginning, 1, 1, 0,
1766 "Return position of start of text matched by last search.\n\
16fdc568
BF
1767NUM specifies which parenthesized expression in the last regexp.\n\
1768 Value is nil if NUMth pair didn't match, or there were less than NUM pairs.\n\
ca1d1d23
JB
1769Zero means the entire text matched by the whole regexp or whole string.")
1770 (num)
1771 Lisp_Object num;
1772{
1773 return match_limit (num, 1);
1774}
1775
1776DEFUN ("match-end", Fmatch_end, Smatch_end, 1, 1, 0,
1777 "Return position of end of text matched by last search.\n\
1778ARG, a number, specifies which parenthesized expression in the last regexp.\n\
1779 Value is nil if ARGth pair didn't match, or there were less than ARG pairs.\n\
1780Zero means the entire text matched by the whole regexp or whole string.")
1781 (num)
1782 Lisp_Object num;
1783{
1784 return match_limit (num, 0);
1785}
1786
1787DEFUN ("match-data", Fmatch_data, Smatch_data, 0, 0, 0,
1788 "Return a list containing all info on what the last search matched.\n\
1789Element 2N is `(match-beginning N)'; element 2N + 1 is `(match-end N)'.\n\
1790All the elements are markers or nil (nil if the Nth pair didn't match)\n\
1791if the last match was on a buffer; integers or nil if a string was matched.\n\
1792Use `store-match-data' to reinstate the data in this list.")
1793 ()
1794{
4746118a 1795 Lisp_Object *data;
ca1d1d23
JB
1796 int i, len;
1797
daa37602
JB
1798 if (NILP (last_thing_searched))
1799 error ("match-data called before any match found");
1800
4746118a
JB
1801 data = (Lisp_Object *) alloca ((2 * search_regs.num_regs)
1802 * sizeof (Lisp_Object));
1803
ca1d1d23 1804 len = -1;
4746118a 1805 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
1806 {
1807 int start = search_regs.start[i];
1808 if (start >= 0)
1809 {
daa37602 1810 if (EQ (last_thing_searched, Qt))
ca1d1d23 1811 {
c235cce7
KH
1812 XSETFASTINT (data[2 * i], start);
1813 XSETFASTINT (data[2 * i + 1], search_regs.end[i]);
ca1d1d23 1814 }
0ed62dc7 1815 else if (BUFFERP (last_thing_searched))
ca1d1d23
JB
1816 {
1817 data[2 * i] = Fmake_marker ();
daa37602
JB
1818 Fset_marker (data[2 * i],
1819 make_number (start),
1820 last_thing_searched);
ca1d1d23
JB
1821 data[2 * i + 1] = Fmake_marker ();
1822 Fset_marker (data[2 * i + 1],
daa37602
JB
1823 make_number (search_regs.end[i]),
1824 last_thing_searched);
ca1d1d23 1825 }
daa37602
JB
1826 else
1827 /* last_thing_searched must always be Qt, a buffer, or Qnil. */
1828 abort ();
1829
ca1d1d23
JB
1830 len = i;
1831 }
1832 else
1833 data[2 * i] = data [2 * i + 1] = Qnil;
1834 }
1835 return Flist (2 * len + 2, data);
1836}
1837
1838
1839DEFUN ("store-match-data", Fstore_match_data, Sstore_match_data, 1, 1, 0,
1840 "Set internal data on last search match from elements of LIST.\n\
1841LIST should have been created by calling `match-data' previously.")
1842 (list)
1843 register Lisp_Object list;
1844{
1845 register int i;
1846 register Lisp_Object marker;
1847
1848 if (!CONSP (list) && !NILP (list))
b37902c8 1849 list = wrong_type_argument (Qconsp, list);
ca1d1d23 1850
daa37602
JB
1851 /* Unless we find a marker with a buffer in LIST, assume that this
1852 match data came from a string. */
1853 last_thing_searched = Qt;
1854
4746118a
JB
1855 /* Allocate registers if they don't already exist. */
1856 {
d084e942 1857 int length = XFASTINT (Flength (list)) / 2;
4746118a
JB
1858
1859 if (length > search_regs.num_regs)
1860 {
1113d9db
JB
1861 if (search_regs.num_regs == 0)
1862 {
1863 search_regs.start
1864 = (regoff_t *) xmalloc (length * sizeof (regoff_t));
1865 search_regs.end
1866 = (regoff_t *) xmalloc (length * sizeof (regoff_t));
1867 }
4746118a 1868 else
1113d9db
JB
1869 {
1870 search_regs.start
1871 = (regoff_t *) xrealloc (search_regs.start,
1872 length * sizeof (regoff_t));
1873 search_regs.end
1874 = (regoff_t *) xrealloc (search_regs.end,
1875 length * sizeof (regoff_t));
1876 }
4746118a 1877
487282dc 1878 search_regs.num_regs = length;
4746118a
JB
1879 }
1880 }
1881
1882 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
1883 {
1884 marker = Fcar (list);
1885 if (NILP (marker))
1886 {
1887 search_regs.start[i] = -1;
1888 list = Fcdr (list);
1889 }
1890 else
1891 {
0ed62dc7 1892 if (MARKERP (marker))
daa37602
JB
1893 {
1894 if (XMARKER (marker)->buffer == 0)
c235cce7 1895 XSETFASTINT (marker, 0);
daa37602 1896 else
a3668d92 1897 XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer);
daa37602 1898 }
ca1d1d23
JB
1899
1900 CHECK_NUMBER_COERCE_MARKER (marker, 0);
1901 search_regs.start[i] = XINT (marker);
1902 list = Fcdr (list);
1903
1904 marker = Fcar (list);
0ed62dc7 1905 if (MARKERP (marker) && XMARKER (marker)->buffer == 0)
c235cce7 1906 XSETFASTINT (marker, 0);
ca1d1d23
JB
1907
1908 CHECK_NUMBER_COERCE_MARKER (marker, 0);
1909 search_regs.end[i] = XINT (marker);
1910 }
1911 list = Fcdr (list);
1912 }
1913
1914 return Qnil;
1915}
1916
1917/* Quote a string to inactivate reg-expr chars */
1918
1919DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
1920 "Return a regexp string which matches exactly STRING and nothing else.")
1921 (str)
1922 Lisp_Object str;
1923{
1924 register unsigned char *in, *out, *end;
1925 register unsigned char *temp;
1926
1927 CHECK_STRING (str, 0);
1928
1929 temp = (unsigned char *) alloca (XSTRING (str)->size * 2);
1930
1931 /* Now copy the data into the new string, inserting escapes. */
1932
1933 in = XSTRING (str)->data;
1934 end = in + XSTRING (str)->size;
1935 out = temp;
1936
1937 for (; in != end; in++)
1938 {
1939 if (*in == '[' || *in == ']'
1940 || *in == '*' || *in == '.' || *in == '\\'
1941 || *in == '?' || *in == '+'
1942 || *in == '^' || *in == '$')
1943 *out++ = '\\';
1944 *out++ = *in;
1945 }
1946
1947 return make_string (temp, out - temp);
1948}
1949\f
1950syms_of_search ()
1951{
1952 register int i;
1953
487282dc
KH
1954 for (i = 0; i < REGEXP_CACHE_SIZE; ++i)
1955 {
1956 searchbufs[i].buf.allocated = 100;
1957 searchbufs[i].buf.buffer = (unsigned char *) malloc (100);
1958 searchbufs[i].buf.fastmap = searchbufs[i].fastmap;
1959 searchbufs[i].regexp = Qnil;
1960 staticpro (&searchbufs[i].regexp);
1961 searchbufs[i].next = (i == REGEXP_CACHE_SIZE-1 ? 0 : &searchbufs[i+1]);
1962 }
1963 searchbuf_head = &searchbufs[0];
ca1d1d23
JB
1964
1965 Qsearch_failed = intern ("search-failed");
1966 staticpro (&Qsearch_failed);
1967 Qinvalid_regexp = intern ("invalid-regexp");
1968 staticpro (&Qinvalid_regexp);
1969
1970 Fput (Qsearch_failed, Qerror_conditions,
1971 Fcons (Qsearch_failed, Fcons (Qerror, Qnil)));
1972 Fput (Qsearch_failed, Qerror_message,
1973 build_string ("Search failed"));
1974
1975 Fput (Qinvalid_regexp, Qerror_conditions,
1976 Fcons (Qinvalid_regexp, Fcons (Qerror, Qnil)));
1977 Fput (Qinvalid_regexp, Qerror_message,
1978 build_string ("Invalid regexp"));
1979
daa37602
JB
1980 last_thing_searched = Qnil;
1981 staticpro (&last_thing_searched);
1982
ca1d1d23 1983 defsubr (&Slooking_at);
b819a390
RS
1984 defsubr (&Sposix_looking_at);
1985 defsubr (&Sstring_match);
1986 defsubr (&Sposix_string_match);
ca1d1d23
JB
1987 defsubr (&Sskip_chars_forward);
1988 defsubr (&Sskip_chars_backward);
17431c60
RS
1989 defsubr (&Sskip_syntax_forward);
1990 defsubr (&Sskip_syntax_backward);
ca1d1d23
JB
1991 defsubr (&Ssearch_forward);
1992 defsubr (&Ssearch_backward);
1993 defsubr (&Sword_search_forward);
1994 defsubr (&Sword_search_backward);
1995 defsubr (&Sre_search_forward);
1996 defsubr (&Sre_search_backward);
b819a390
RS
1997 defsubr (&Sposix_search_forward);
1998 defsubr (&Sposix_search_backward);
ca1d1d23
JB
1999 defsubr (&Sreplace_match);
2000 defsubr (&Smatch_beginning);
2001 defsubr (&Smatch_end);
2002 defsubr (&Smatch_data);
2003 defsubr (&Sstore_match_data);
2004 defsubr (&Sregexp_quote);
2005}