(Fsuspend_emacs): Make tem not register.
[bpt/emacs.git] / src / search.c
CommitLineData
ca1d1d23
JB
1/* String search routines for GNU Emacs.
2 Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
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
21#include "config.h"
22#include "lisp.h"
23#include "syntax.h"
24#include "buffer.h"
25#include "commands.h"
4746118a 26
ca1d1d23
JB
27#include <sys/types.h>
28#include "regex.h"
29
30#define max(a, b) ((a) > (b) ? (a) : (b))
31#define min(a, b) ((a) < (b) ? (a) : (b))
32
33/* We compile regexps into this buffer and then use it for searching. */
34
35struct re_pattern_buffer searchbuf;
36
37char search_fastmap[0400];
38
39/* Last regexp we compiled */
40
41Lisp_Object last_regexp;
42
4746118a
JB
43/* Every call to re_match, etc., must pass &search_regs as the regs
44 argument unless you can show it is unnecessary (i.e., if re_match
45 is certainly going to be called again before region-around-match
46 can be called).
47
48 Since the registers are now dynamically allocated, we need to make
49 sure not to refer to the Nth register before checking that it has
1113d9db
JB
50 been allocated by checking search_regs.num_regs.
51
52 The regex code keeps track of whether it has allocated the search
53 buffer using bits in searchbuf. This means that whenever you
54 compile a new pattern, it completely forgets whether it has
55 allocated any registers, and will allocate new registers the next
56 time you call a searching or matching function. Therefore, we need
57 to call re_set_registers after compiling a new pattern or after
58 setting the match registers, so that the regex functions will be
59 able to free or re-allocate it properly. */
ca1d1d23
JB
60static struct re_registers search_regs;
61
daa37602
JB
62/* The buffer in which the last search was performed, or
63 Qt if the last search was done in a string;
64 Qnil if no searching has been done yet. */
65static Lisp_Object last_thing_searched;
ca1d1d23
JB
66
67/* error condition signalled when regexp compile_pattern fails */
68
69Lisp_Object Qinvalid_regexp;
70
71static void
72matcher_overflow ()
73{
74 error ("Stack overflow in regexp matcher");
75}
76
77#ifdef __STDC__
78#define CONST const
79#else
80#define CONST
81#endif
82
83/* Compile a regexp and signal a Lisp error if anything goes wrong. */
84
1113d9db 85compile_pattern (pattern, bufp, regp, translate)
ca1d1d23
JB
86 Lisp_Object pattern;
87 struct re_pattern_buffer *bufp;
1113d9db 88 struct re_registers *regp;
ca1d1d23
JB
89 char *translate;
90{
91 CONST char *val;
92 Lisp_Object dummy;
93
94 if (EQ (pattern, last_regexp)
95 && translate == bufp->translate)
96 return;
1113d9db 97
ca1d1d23
JB
98 last_regexp = Qnil;
99 bufp->translate = translate;
100 val = re_compile_pattern ((char *) XSTRING (pattern)->data,
101 XSTRING (pattern)->size,
102 bufp);
103 if (val)
104 {
105 dummy = build_string (val);
106 while (1)
107 Fsignal (Qinvalid_regexp, Fcons (dummy, Qnil));
108 }
1113d9db 109
ca1d1d23 110 last_regexp = pattern;
1113d9db
JB
111
112 /* Advise the searching functions about the space we have allocated
113 for register data. */
ebb9e16f
JB
114 if (regp)
115 re_set_registers (bufp, regp, regp->num_regs, regp->start, regp->end);
1113d9db 116
ca1d1d23
JB
117 return;
118}
119
120/* Error condition used for failing searches */
121Lisp_Object Qsearch_failed;
122
123Lisp_Object
124signal_failure (arg)
125 Lisp_Object arg;
126{
127 Fsignal (Qsearch_failed, Fcons (arg, Qnil));
128 return Qnil;
129}
130\f
131DEFUN ("looking-at", Flooking_at, Slooking_at, 1, 1, 0,
e065a56e
JB
132 "Return t if text after point matches regular expression PAT.\n\
133This function modifies the match data that `match-beginning',\n\
134`match-end' and `match-data' access; save and restore the match\n\
fe99283d 135data if you want to preserve them.")
ca1d1d23
JB
136 (string)
137 Lisp_Object string;
138{
139 Lisp_Object val;
140 unsigned char *p1, *p2;
141 int s1, s2;
142 register int i;
143
144 CHECK_STRING (string, 0);
1113d9db 145 compile_pattern (string, &searchbuf, &search_regs,
ca1d1d23
JB
146 !NILP (current_buffer->case_fold_search) ? DOWNCASE_TABLE : 0);
147
148 immediate_quit = 1;
149 QUIT; /* Do a pending quit right away, to avoid paradoxical behavior */
150
151 /* Get pointers and sizes of the two strings
152 that make up the visible portion of the buffer. */
153
154 p1 = BEGV_ADDR;
155 s1 = GPT - BEGV;
156 p2 = GAP_END_ADDR;
157 s2 = ZV - GPT;
158 if (s1 < 0)
159 {
160 p2 = p1;
161 s2 = ZV - BEGV;
162 s1 = 0;
163 }
164 if (s2 < 0)
165 {
166 s1 = ZV - BEGV;
167 s2 = 0;
168 }
169
170 i = re_match_2 (&searchbuf, (char *) p1, s1, (char *) p2, s2,
171 point - BEGV, &search_regs,
172 ZV - BEGV);
173 if (i == -2)
174 matcher_overflow ();
175
176 val = (0 <= i ? Qt : Qnil);
4746118a 177 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
178 if (search_regs.start[i] >= 0)
179 {
180 search_regs.start[i] += BEGV;
181 search_regs.end[i] += BEGV;
182 }
daa37602 183 XSET (last_thing_searched, Lisp_Buffer, current_buffer);
ca1d1d23
JB
184 immediate_quit = 0;
185 return val;
186}
187
188DEFUN ("string-match", Fstring_match, Sstring_match, 2, 3, 0,
189 "Return index of start of first match for REGEXP in STRING, or nil.\n\
190If third arg START is non-nil, start search at that index in STRING.\n\
191For index of first char beyond the match, do (match-end 0).\n\
192`match-end' and `match-beginning' also give indices of substrings\n\
193matched by parenthesis constructs in the pattern.")
194 (regexp, string, start)
195 Lisp_Object regexp, string, start;
196{
197 int val;
198 int s;
199
200 CHECK_STRING (regexp, 0);
201 CHECK_STRING (string, 1);
202
203 if (NILP (start))
204 s = 0;
205 else
206 {
207 int len = XSTRING (string)->size;
208
209 CHECK_NUMBER (start, 2);
210 s = XINT (start);
211 if (s < 0 && -s <= len)
212 s = len - s;
213 else if (0 > s || s > len)
214 args_out_of_range (string, start);
215 }
216
1113d9db 217 compile_pattern (regexp, &searchbuf, &search_regs,
ca1d1d23
JB
218 !NILP (current_buffer->case_fold_search) ? DOWNCASE_TABLE : 0);
219 immediate_quit = 1;
220 val = re_search (&searchbuf, (char *) XSTRING (string)->data,
221 XSTRING (string)->size, s, XSTRING (string)->size - s,
222 &search_regs);
223 immediate_quit = 0;
daa37602 224 last_thing_searched = Qt;
ca1d1d23
JB
225 if (val == -2)
226 matcher_overflow ();
227 if (val < 0) return Qnil;
228 return make_number (val);
229}
e59a8453
RS
230
231/* Match REGEXP against STRING, searching all of STRING,
232 and return the index of the match, or negative on failure.
233 This does not clobber the match data. */
234
235int
236fast_string_match (regexp, string)
237 Lisp_Object regexp, string;
238{
239 int val;
240
241 compile_pattern (regexp, &searchbuf, 0, 0);
242 immediate_quit = 1;
243 val = re_search (&searchbuf, (char *) XSTRING (string)->data,
244 XSTRING (string)->size, 0, XSTRING (string)->size,
245 0);
246 immediate_quit = 0;
247 return val;
248}
ca1d1d23 249\f
ffd56f97
JB
250/* Search for COUNT instances of the character TARGET, starting at START.
251 If COUNT is negative, search backwards.
252
253 If we find COUNT instances, set *SHORTAGE to zero, and return the
5bfe95c9
RS
254 position after the COUNTth match. Note that for reverse motion
255 this is not the same as the usual convention for Emacs motion commands.
ffd56f97
JB
256
257 If we don't find COUNT instances before reaching the end of the
258 buffer (or the beginning, if scanning backwards), set *SHORTAGE to
259 the number of TARGETs left unfound, and return the end of the
260 buffer we bumped up against. */
261
262scan_buffer (target, start, count, shortage)
263 int *shortage, start;
264 register int count, target;
ca1d1d23 265{
ffd56f97
JB
266 int limit = ((count > 0) ? ZV - 1 : BEGV);
267 int direction = ((count > 0) ? 1 : -1);
268
269 register unsigned char *cursor;
ca1d1d23 270 unsigned char *base;
ffd56f97
JB
271
272 register int ceiling;
273 register unsigned char *ceiling_addr;
ca1d1d23
JB
274
275 if (shortage != 0)
276 *shortage = 0;
277
278 immediate_quit = 1;
279
ffd56f97
JB
280 if (count > 0)
281 while (start != limit + 1)
ca1d1d23 282 {
ffd56f97
JB
283 ceiling = BUFFER_CEILING_OF (start);
284 ceiling = min (limit, ceiling);
285 ceiling_addr = &FETCH_CHAR (ceiling) + 1;
286 base = (cursor = &FETCH_CHAR (start));
ca1d1d23
JB
287 while (1)
288 {
ffd56f97 289 while (*cursor != target && ++cursor != ceiling_addr)
ca1d1d23 290 ;
ffd56f97 291 if (cursor != ceiling_addr)
ca1d1d23 292 {
ffd56f97 293 if (--count == 0)
ca1d1d23
JB
294 {
295 immediate_quit = 0;
ffd56f97 296 return (start + cursor - base + 1);
ca1d1d23
JB
297 }
298 else
ffd56f97 299 if (++cursor == ceiling_addr)
ca1d1d23
JB
300 break;
301 }
302 else
303 break;
304 }
ffd56f97 305 start += cursor - base;
ca1d1d23
JB
306 }
307 else
308 {
ffd56f97
JB
309 start--; /* first character we scan */
310 while (start > limit - 1)
311 { /* we WILL scan under start */
312 ceiling = BUFFER_FLOOR_OF (start);
313 ceiling = max (limit, ceiling);
314 ceiling_addr = &FETCH_CHAR (ceiling) - 1;
315 base = (cursor = &FETCH_CHAR (start));
ca1d1d23
JB
316 cursor++;
317 while (1)
318 {
ffd56f97 319 while (--cursor != ceiling_addr && *cursor != target)
ca1d1d23 320 ;
ffd56f97 321 if (cursor != ceiling_addr)
ca1d1d23 322 {
ffd56f97 323 if (++count == 0)
ca1d1d23
JB
324 {
325 immediate_quit = 0;
ffd56f97 326 return (start + cursor - base + 1);
ca1d1d23
JB
327 }
328 }
329 else
330 break;
331 }
ffd56f97 332 start += cursor - base;
ca1d1d23
JB
333 }
334 }
335 immediate_quit = 0;
336 if (shortage != 0)
ffd56f97
JB
337 *shortage = count * direction;
338 return (start + ((direction == 1 ? 0 : 1)));
ca1d1d23
JB
339}
340
341int
342find_next_newline (from, cnt)
343 register int from, cnt;
344{
345 return (scan_buffer ('\n', from, cnt, (int *) 0));
346}
347\f
c1dc99a1
JB
348Lisp_Object skip_chars ();
349
ca1d1d23
JB
350DEFUN ("skip-chars-forward", Fskip_chars_forward, Sskip_chars_forward, 1, 2, 0,
351 "Move point forward, stopping before a char not in CHARS, or at position LIM.\n\
352CHARS is like the inside of a `[...]' in a regular expression\n\
353except that `]' is never special and `\\' quotes `^', `-' or `\\'.\n\
354Thus, with arg \"a-zA-Z\", this skips letters stopping before first nonletter.\n\
c1dc99a1
JB
355With arg \"^a-zA-Z\", skips nonletters stopping before first letter.\n\
356Returns the distance traveled, either zero or positive.")
ca1d1d23
JB
357 (string, lim)
358 Lisp_Object string, lim;
359{
c1dc99a1 360 return skip_chars (1, string, lim);
ca1d1d23
JB
361}
362
363DEFUN ("skip-chars-backward", Fskip_chars_backward, Sskip_chars_backward, 1, 2, 0,
364 "Move point backward, stopping after a char not in CHARS, or at position LIM.\n\
c1dc99a1
JB
365See `skip-chars-forward' for details.\n\
366Returns the distance traveled, either zero or negative.")
ca1d1d23
JB
367 (string, lim)
368 Lisp_Object string, lim;
369{
c1dc99a1 370 return skip_chars (0, string, lim);
ca1d1d23
JB
371}
372
c1dc99a1 373Lisp_Object
ca1d1d23
JB
374skip_chars (forwardp, string, lim)
375 int forwardp;
376 Lisp_Object string, lim;
377{
378 register unsigned char *p, *pend;
379 register unsigned char c;
380 unsigned char fastmap[0400];
381 int negate = 0;
382 register int i;
383
384 CHECK_STRING (string, 0);
385
386 if (NILP (lim))
387 XSET (lim, Lisp_Int, forwardp ? ZV : BEGV);
388 else
389 CHECK_NUMBER_COERCE_MARKER (lim, 1);
390
391#if 0 /* This breaks some things... jla. */
392 /* In any case, don't allow scan outside bounds of buffer. */
393 if (XFASTINT (lim) > ZV)
394 XFASTINT (lim) = ZV;
395 if (XFASTINT (lim) < BEGV)
396 XFASTINT (lim) = BEGV;
397#endif
398
399 p = XSTRING (string)->data;
400 pend = p + XSTRING (string)->size;
401 bzero (fastmap, sizeof fastmap);
402
403 if (p != pend && *p == '^')
404 {
405 negate = 1; p++;
406 }
407
408 /* Find the characters specified and set their elements of fastmap. */
409
410 while (p != pend)
411 {
412 c = *p++;
413 if (c == '\\')
414 {
415 if (p == pend) break;
416 c = *p++;
417 }
418 if (p != pend && *p == '-')
419 {
420 p++;
421 if (p == pend) break;
422 while (c <= *p)
423 {
424 fastmap[c] = 1;
425 c++;
426 }
427 p++;
428 }
429 else
430 fastmap[c] = 1;
431 }
432
433 /* If ^ was the first character, complement the fastmap. */
434
435 if (negate)
436 for (i = 0; i < sizeof fastmap; i++)
437 fastmap[i] ^= 1;
438
c1dc99a1
JB
439 {
440 int start_point = point;
441
442 immediate_quit = 1;
443 if (forwardp)
444 {
445 while (point < XINT (lim) && fastmap[FETCH_CHAR (point)])
446 SET_PT (point + 1);
447 }
448 else
449 {
450 while (point > XINT (lim) && fastmap[FETCH_CHAR (point - 1)])
451 SET_PT (point - 1);
452 }
453 immediate_quit = 0;
454
455 return make_number (point - start_point);
456 }
ca1d1d23
JB
457}
458\f
459/* Subroutines of Lisp buffer search functions. */
460
461static Lisp_Object
462search_command (string, bound, noerror, count, direction, RE)
463 Lisp_Object string, bound, noerror, count;
464 int direction;
465 int RE;
466{
467 register int np;
468 int lim;
469 int n = direction;
470
471 if (!NILP (count))
472 {
473 CHECK_NUMBER (count, 3);
474 n *= XINT (count);
475 }
476
477 CHECK_STRING (string, 0);
478 if (NILP (bound))
479 lim = n > 0 ? ZV : BEGV;
480 else
481 {
482 CHECK_NUMBER_COERCE_MARKER (bound, 1);
483 lim = XINT (bound);
484 if (n > 0 ? lim < point : lim > point)
485 error ("Invalid search bound (wrong side of point)");
486 if (lim > ZV)
487 lim = ZV;
488 if (lim < BEGV)
489 lim = BEGV;
490 }
491
492 np = search_buffer (string, point, lim, n, RE,
493 (!NILP (current_buffer->case_fold_search)
494 ? XSTRING (current_buffer->case_canon_table)->data : 0),
495 (!NILP (current_buffer->case_fold_search)
496 ? XSTRING (current_buffer->case_eqv_table)->data : 0));
497 if (np <= 0)
498 {
499 if (NILP (noerror))
500 return signal_failure (string);
501 if (!EQ (noerror, Qt))
502 {
503 if (lim < BEGV || lim > ZV)
504 abort ();
a5f217b8
RS
505 SET_PT (lim);
506 return Qnil;
507#if 0 /* This would be clean, but maybe programs depend on
508 a value of nil here. */
481399bf 509 np = lim;
a5f217b8 510#endif
ca1d1d23 511 }
481399bf
RS
512 else
513 return Qnil;
ca1d1d23
JB
514 }
515
516 if (np < BEGV || np > ZV)
517 abort ();
518
519 SET_PT (np);
520
521 return make_number (np);
522}
523\f
524/* search for the n'th occurrence of STRING in the current buffer,
525 starting at position POS and stopping at position LIM,
526 treating PAT as a literal string if RE is false or as
527 a regular expression if RE is true.
528
529 If N is positive, searching is forward and LIM must be greater than POS.
530 If N is negative, searching is backward and LIM must be less than POS.
531
532 Returns -x if only N-x occurrences found (x > 0),
533 or else the position at the beginning of the Nth occurrence
534 (if searching backward) or the end (if searching forward). */
535
536search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
537 Lisp_Object string;
538 int pos;
539 int lim;
540 int n;
541 int RE;
542 register unsigned char *trt;
543 register unsigned char *inverse_trt;
544{
545 int len = XSTRING (string)->size;
546 unsigned char *base_pat = XSTRING (string)->data;
547 register int *BM_tab;
548 int *BM_tab_base;
549 register int direction = ((n > 0) ? 1 : -1);
550 register int dirlen;
551 int infinity, limit, k, stride_for_teases;
552 register unsigned char *pat, *cursor, *p_limit;
553 register int i, j;
554 unsigned char *p1, *p2;
555 int s1, s2;
556
557 /* Null string is found at starting position. */
558 if (!len)
559 return pos;
560
561 if (RE)
1113d9db 562 compile_pattern (string, &searchbuf, &search_regs, (char *) trt);
ca1d1d23
JB
563
564 if (RE /* Here we detect whether the */
565 /* generality of an RE search is */
566 /* really needed. */
567 /* first item is "exact match" */
4746118a 568 && *(searchbuf.buffer) == (char) RE_EXACTN_VALUE
ca1d1d23
JB
569 && searchbuf.buffer[1] + 2 == searchbuf.used) /*first is ONLY item */
570 {
571 RE = 0; /* can do straight (non RE) search */
572 pat = (base_pat = (unsigned char *) searchbuf.buffer + 2);
573 /* trt already applied */
574 len = searchbuf.used - 2;
575 }
576 else if (!RE)
577 {
578 pat = (unsigned char *) alloca (len);
579
580 for (i = len; i--;) /* Copy the pattern; apply trt */
581 *pat++ = (((int) trt) ? trt [*base_pat++] : *base_pat++);
582 pat -= len; base_pat = pat;
583 }
584
585 if (RE)
586 {
587 immediate_quit = 1; /* Quit immediately if user types ^G,
588 because letting this function finish
589 can take too long. */
590 QUIT; /* Do a pending quit right away,
591 to avoid paradoxical behavior */
592 /* Get pointers and sizes of the two strings
593 that make up the visible portion of the buffer. */
594
595 p1 = BEGV_ADDR;
596 s1 = GPT - BEGV;
597 p2 = GAP_END_ADDR;
598 s2 = ZV - GPT;
599 if (s1 < 0)
600 {
601 p2 = p1;
602 s2 = ZV - BEGV;
603 s1 = 0;
604 }
605 if (s2 < 0)
606 {
607 s1 = ZV - BEGV;
608 s2 = 0;
609 }
610 while (n < 0)
611 {
612 int val = re_search_2 (&searchbuf, (char *) p1, s1, (char *) p2, s2,
613 pos - BEGV, lim - pos, &search_regs,
614 /* Don't allow match past current point */
615 pos - BEGV);
616 if (val == -2)
617 matcher_overflow ();
618 if (val >= 0)
619 {
620 j = BEGV;
4746118a 621 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
622 if (search_regs.start[i] >= 0)
623 {
624 search_regs.start[i] += j;
625 search_regs.end[i] += j;
626 }
daa37602 627 XSET (last_thing_searched, Lisp_Buffer, current_buffer);
ca1d1d23
JB
628 /* Set pos to the new position. */
629 pos = search_regs.start[0];
630 }
631 else
632 {
633 immediate_quit = 0;
634 return (n);
635 }
636 n++;
637 }
638 while (n > 0)
639 {
640 int val = re_search_2 (&searchbuf, (char *) p1, s1, (char *) p2, s2,
641 pos - BEGV, lim - pos, &search_regs,
642 lim - BEGV);
643 if (val == -2)
644 matcher_overflow ();
645 if (val >= 0)
646 {
647 j = BEGV;
4746118a 648 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
649 if (search_regs.start[i] >= 0)
650 {
651 search_regs.start[i] += j;
652 search_regs.end[i] += j;
653 }
daa37602 654 XSET (last_thing_searched, Lisp_Buffer, current_buffer);
ca1d1d23
JB
655 pos = search_regs.end[0];
656 }
657 else
658 {
659 immediate_quit = 0;
660 return (0 - n);
661 }
662 n--;
663 }
664 immediate_quit = 0;
665 return (pos);
666 }
667 else /* non-RE case */
668 {
669#ifdef C_ALLOCA
670 int BM_tab_space[0400];
671 BM_tab = &BM_tab_space[0];
672#else
673 BM_tab = (int *) alloca (0400 * sizeof (int));
674#endif
675 /* The general approach is that we are going to maintain that we know */
676 /* the first (closest to the present position, in whatever direction */
677 /* we're searching) character that could possibly be the last */
678 /* (furthest from present position) character of a valid match. We */
679 /* advance the state of our knowledge by looking at that character */
680 /* and seeing whether it indeed matches the last character of the */
681 /* pattern. If it does, we take a closer look. If it does not, we */
682 /* move our pointer (to putative last characters) as far as is */
683 /* logically possible. This amount of movement, which I call a */
684 /* stride, will be the length of the pattern if the actual character */
685 /* appears nowhere in the pattern, otherwise it will be the distance */
686 /* from the last occurrence of that character to the end of the */
687 /* pattern. */
688 /* As a coding trick, an enormous stride is coded into the table for */
689 /* characters that match the last character. This allows use of only */
690 /* a single test, a test for having gone past the end of the */
691 /* permissible match region, to test for both possible matches (when */
692 /* the stride goes past the end immediately) and failure to */
693 /* match (where you get nudged past the end one stride at a time). */
694
695 /* Here we make a "mickey mouse" BM table. The stride of the search */
696 /* is determined only by the last character of the putative match. */
697 /* If that character does not match, we will stride the proper */
698 /* distance to propose a match that superimposes it on the last */
699 /* instance of a character that matches it (per trt), or misses */
700 /* it entirely if there is none. */
701
702 dirlen = len * direction;
703 infinity = dirlen - (lim + pos + len + len) * direction;
704 if (direction < 0)
705 pat = (base_pat += len - 1);
706 BM_tab_base = BM_tab;
707 BM_tab += 0400;
708 j = dirlen; /* to get it in a register */
709 /* A character that does not appear in the pattern induces a */
710 /* stride equal to the pattern length. */
711 while (BM_tab_base != BM_tab)
712 {
713 *--BM_tab = j;
714 *--BM_tab = j;
715 *--BM_tab = j;
716 *--BM_tab = j;
717 }
718 i = 0;
719 while (i != infinity)
720 {
721 j = pat[i]; i += direction;
722 if (i == dirlen) i = infinity;
723 if ((int) trt)
724 {
725 k = (j = trt[j]);
726 if (i == infinity)
727 stride_for_teases = BM_tab[j];
728 BM_tab[j] = dirlen - i;
729 /* A translation table is accompanied by its inverse -- see */
730 /* comment following downcase_table for details */
731 while ((j = inverse_trt[j]) != k)
732 BM_tab[j] = dirlen - i;
733 }
734 else
735 {
736 if (i == infinity)
737 stride_for_teases = BM_tab[j];
738 BM_tab[j] = dirlen - i;
739 }
740 /* stride_for_teases tells how much to stride if we get a */
741 /* match on the far character but are subsequently */
742 /* disappointed, by recording what the stride would have been */
743 /* for that character if the last character had been */
744 /* different. */
745 }
746 infinity = dirlen - infinity;
747 pos += dirlen - ((direction > 0) ? direction : 0);
748 /* loop invariant - pos points at where last char (first char if reverse)
749 of pattern would align in a possible match. */
750 while (n != 0)
751 {
752 if ((lim - pos - (direction > 0)) * direction < 0)
753 return (n * (0 - direction));
754 /* First we do the part we can by pointers (maybe nothing) */
755 QUIT;
756 pat = base_pat;
757 limit = pos - dirlen + direction;
758 limit = ((direction > 0)
759 ? BUFFER_CEILING_OF (limit)
760 : BUFFER_FLOOR_OF (limit));
761 /* LIMIT is now the last (not beyond-last!) value
762 POS can take on without hitting edge of buffer or the gap. */
763 limit = ((direction > 0)
764 ? min (lim - 1, min (limit, pos + 20000))
765 : max (lim, max (limit, pos - 20000)));
766 if ((limit - pos) * direction > 20)
767 {
768 p_limit = &FETCH_CHAR (limit);
769 p2 = (cursor = &FETCH_CHAR (pos));
770 /* In this loop, pos + cursor - p2 is the surrogate for pos */
771 while (1) /* use one cursor setting as long as i can */
772 {
773 if (direction > 0) /* worth duplicating */
774 {
775 /* Use signed comparison if appropriate
776 to make cursor+infinity sure to be > p_limit.
777 Assuming that the buffer lies in a range of addresses
778 that are all "positive" (as ints) or all "negative",
779 either kind of comparison will work as long
780 as we don't step by infinity. So pick the kind
781 that works when we do step by infinity. */
782 if ((int) (p_limit + infinity) > (int) p_limit)
783 while ((int) cursor <= (int) p_limit)
784 cursor += BM_tab[*cursor];
785 else
786 while ((unsigned int) cursor <= (unsigned int) p_limit)
787 cursor += BM_tab[*cursor];
788 }
789 else
790 {
791 if ((int) (p_limit + infinity) < (int) p_limit)
792 while ((int) cursor >= (int) p_limit)
793 cursor += BM_tab[*cursor];
794 else
795 while ((unsigned int) cursor >= (unsigned int) p_limit)
796 cursor += BM_tab[*cursor];
797 }
798/* If you are here, cursor is beyond the end of the searched region. */
799 /* This can happen if you match on the far character of the pattern, */
800 /* because the "stride" of that character is infinity, a number able */
801 /* to throw you well beyond the end of the search. It can also */
802 /* happen if you fail to match within the permitted region and would */
803 /* otherwise try a character beyond that region */
804 if ((cursor - p_limit) * direction <= len)
805 break; /* a small overrun is genuine */
806 cursor -= infinity; /* large overrun = hit */
807 i = dirlen - direction;
808 if ((int) trt)
809 {
810 while ((i -= direction) + direction != 0)
811 if (pat[i] != trt[*(cursor -= direction)])
812 break;
813 }
814 else
815 {
816 while ((i -= direction) + direction != 0)
817 if (pat[i] != *(cursor -= direction))
818 break;
819 }
820 cursor += dirlen - i - direction; /* fix cursor */
821 if (i + direction == 0)
822 {
823 cursor -= direction;
1113d9db
JB
824
825 /* Make sure we have registers in which to store
826 the match position. */
827 if (search_regs.num_regs == 0)
828 {
829 regoff_t *starts, *ends;
830
831 starts =
832 (regoff_t *) xmalloc (2 * sizeof (regoff_t));
833 ends =
834 (regoff_t *) xmalloc (2 * sizeof (regoff_t));
835 re_set_registers (&searchbuf,
836 &search_regs,
837 2, starts, ends);
838 }
839
ca1d1d23
JB
840 search_regs.start[0]
841 = pos + cursor - p2 + ((direction > 0)
842 ? 1 - len : 0);
843 search_regs.end[0] = len + search_regs.start[0];
daa37602 844 XSET (last_thing_searched, Lisp_Buffer, current_buffer);
ca1d1d23
JB
845 if ((n -= direction) != 0)
846 cursor += dirlen; /* to resume search */
847 else
848 return ((direction > 0)
849 ? search_regs.end[0] : search_regs.start[0]);
850 }
851 else
852 cursor += stride_for_teases; /* <sigh> we lose - */
853 }
854 pos += cursor - p2;
855 }
856 else
857 /* Now we'll pick up a clump that has to be done the hard */
858 /* way because it covers a discontinuity */
859 {
860 limit = ((direction > 0)
861 ? BUFFER_CEILING_OF (pos - dirlen + 1)
862 : BUFFER_FLOOR_OF (pos - dirlen - 1));
863 limit = ((direction > 0)
864 ? min (limit + len, lim - 1)
865 : max (limit - len, lim));
866 /* LIMIT is now the last value POS can have
867 and still be valid for a possible match. */
868 while (1)
869 {
870 /* This loop can be coded for space rather than */
871 /* speed because it will usually run only once. */
872 /* (the reach is at most len + 21, and typically */
873 /* does not exceed len) */
874 while ((limit - pos) * direction >= 0)
875 pos += BM_tab[FETCH_CHAR(pos)];
876 /* now run the same tests to distinguish going off the */
877 /* end, a match or a phoney match. */
878 if ((pos - limit) * direction <= len)
879 break; /* ran off the end */
880 /* Found what might be a match.
881 Set POS back to last (first if reverse) char pos. */
882 pos -= infinity;
883 i = dirlen - direction;
884 while ((i -= direction) + direction != 0)
885 {
886 pos -= direction;
887 if (pat[i] != (((int) trt)
888 ? trt[FETCH_CHAR(pos)]
889 : FETCH_CHAR (pos)))
890 break;
891 }
892 /* Above loop has moved POS part or all the way
893 back to the first char pos (last char pos if reverse).
894 Set it once again at the last (first if reverse) char. */
895 pos += dirlen - i- direction;
896 if (i + direction == 0)
897 {
898 pos -= direction;
1113d9db
JB
899
900 /* Make sure we have registers in which to store
901 the match position. */
902 if (search_regs.num_regs == 0)
903 {
904 regoff_t *starts, *ends;
905
906 starts =
907 (regoff_t *) xmalloc (2 * sizeof (regoff_t));
908 ends =
909 (regoff_t *) xmalloc (2 * sizeof (regoff_t));
910 re_set_registers (&searchbuf,
911 &search_regs,
912 2, starts, ends);
913 }
914
ca1d1d23
JB
915 search_regs.start[0]
916 = pos + ((direction > 0) ? 1 - len : 0);
917 search_regs.end[0] = len + search_regs.start[0];
daa37602 918 XSET (last_thing_searched, Lisp_Buffer, current_buffer);
ca1d1d23
JB
919 if ((n -= direction) != 0)
920 pos += dirlen; /* to resume search */
921 else
922 return ((direction > 0)
923 ? search_regs.end[0] : search_regs.start[0]);
924 }
925 else
926 pos += stride_for_teases;
927 }
928 }
929 /* We have done one clump. Can we continue? */
930 if ((lim - pos) * direction < 0)
931 return ((0 - n) * direction);
932 }
933 return pos;
934 }
935}
936\f
937/* Given a string of words separated by word delimiters,
938 compute a regexp that matches those exact words
939 separated by arbitrary punctuation. */
940
941static Lisp_Object
942wordify (string)
943 Lisp_Object string;
944{
945 register unsigned char *p, *o;
946 register int i, len, punct_count = 0, word_count = 0;
947 Lisp_Object val;
948
949 CHECK_STRING (string, 0);
950 p = XSTRING (string)->data;
951 len = XSTRING (string)->size;
952
953 for (i = 0; i < len; i++)
954 if (SYNTAX (p[i]) != Sword)
955 {
956 punct_count++;
957 if (i > 0 && SYNTAX (p[i-1]) == Sword) word_count++;
958 }
959 if (SYNTAX (p[len-1]) == Sword) word_count++;
960 if (!word_count) return build_string ("");
961
962 val = make_string (p, len - punct_count + 5 * (word_count - 1) + 4);
963
964 o = XSTRING (val)->data;
965 *o++ = '\\';
966 *o++ = 'b';
967
968 for (i = 0; i < len; i++)
969 if (SYNTAX (p[i]) == Sword)
970 *o++ = p[i];
971 else if (i > 0 && SYNTAX (p[i-1]) == Sword && --word_count)
972 {
973 *o++ = '\\';
974 *o++ = 'W';
975 *o++ = '\\';
976 *o++ = 'W';
977 *o++ = '*';
978 }
979
980 *o++ = '\\';
981 *o++ = 'b';
982
983 return val;
984}
985\f
986DEFUN ("search-backward", Fsearch_backward, Ssearch_backward, 1, 4,
987 "sSearch backward: ",
988 "Search backward from point for STRING.\n\
989Set point to the beginning of the occurrence found, and return point.\n\
990An optional second argument bounds the search; it is a buffer position.\n\
991The match found must not extend before that position.\n\
992Optional third argument, if t, means if fail just return nil (no error).\n\
993 If not nil and not t, position at limit of search and return nil.\n\
994Optional fourth argument is repeat count--search for successive occurrences.\n\
995See also the functions `match-beginning', `match-end' and `replace-match'.")
996 (string, bound, noerror, count)
997 Lisp_Object string, bound, noerror, count;
998{
999 return search_command (string, bound, noerror, count, -1, 0);
1000}
1001
1002DEFUN ("search-forward", Fsearch_forward, Ssearch_forward, 1, 4, "sSearch: ",
1003 "Search forward from point for STRING.\n\
1004Set point to the end of the occurrence found, and return point.\n\
1005An optional second argument bounds the search; it is a buffer position.\n\
1006The match found must not extend after that position. nil is equivalent\n\
1007 to (point-max).\n\
1008Optional third argument, if t, means if fail just return nil (no error).\n\
1009 If not nil and not t, move to limit of search and return nil.\n\
1010Optional fourth argument is repeat count--search for successive occurrences.\n\
1011See also the functions `match-beginning', `match-end' and `replace-match'.")
1012 (string, bound, noerror, count)
1013 Lisp_Object string, bound, noerror, count;
1014{
1015 return search_command (string, bound, noerror, count, 1, 0);
1016}
1017
1018DEFUN ("word-search-backward", Fword_search_backward, Sword_search_backward, 1, 4,
1019 "sWord search backward: ",
1020 "Search backward from point for STRING, ignoring differences in punctuation.\n\
1021Set point to the beginning of the occurrence found, and return point.\n\
1022An optional second argument bounds the search; it is a buffer position.\n\
1023The match found must not extend before that position.\n\
1024Optional third argument, if t, means if fail just return nil (no error).\n\
1025 If not nil and not t, move to limit of search and return nil.\n\
1026Optional fourth argument is repeat count--search for successive occurrences.")
1027 (string, bound, noerror, count)
1028 Lisp_Object string, bound, noerror, count;
1029{
1030 return search_command (wordify (string), bound, noerror, count, -1, 1);
1031}
1032
1033DEFUN ("word-search-forward", Fword_search_forward, Sword_search_forward, 1, 4,
1034 "sWord search: ",
1035 "Search forward from point for STRING, ignoring differences in punctuation.\n\
1036Set point to the end of the occurrence found, and return point.\n\
1037An optional second argument bounds the search; it is a buffer position.\n\
1038The match found must not extend after that position.\n\
1039Optional third argument, if t, means if fail just return nil (no error).\n\
1040 If not nil and not t, move to limit of search and return nil.\n\
1041Optional fourth argument is repeat count--search for successive occurrences.")
1042 (string, bound, noerror, count)
1043 Lisp_Object string, bound, noerror, count;
1044{
1045 return search_command (wordify (string), bound, noerror, count, 1, 1);
1046}
1047
1048DEFUN ("re-search-backward", Fre_search_backward, Sre_search_backward, 1, 4,
1049 "sRE search backward: ",
1050 "Search backward from point for match for regular expression REGEXP.\n\
1051Set point to the beginning of the match, and return point.\n\
1052The match found is the one starting last in the buffer\n\
1053and yet ending before the place the origin of the search.\n\
1054An optional second argument bounds the search; it is a buffer position.\n\
1055The match found must start at or after that position.\n\
1056Optional third argument, if t, means if fail just return nil (no error).\n\
1057 If not nil and not t, move to limit of search and return nil.\n\
1058Optional fourth argument is repeat count--search for successive occurrences.\n\
1059See also the functions `match-beginning', `match-end' and `replace-match'.")
1060 (string, bound, noerror, count)
1061 Lisp_Object string, bound, noerror, count;
1062{
1063 return search_command (string, bound, noerror, count, -1, 1);
1064}
1065
1066DEFUN ("re-search-forward", Fre_search_forward, Sre_search_forward, 1, 4,
1067 "sRE search: ",
1068 "Search forward from point for regular expression REGEXP.\n\
1069Set point to the end of the occurrence found, and return point.\n\
1070An optional second argument bounds the search; it is a buffer position.\n\
1071The match found must not extend after that position.\n\
1072Optional third argument, if t, means if fail just return nil (no error).\n\
1073 If not nil and not t, move to limit of search and return nil.\n\
1074Optional fourth argument is repeat count--search for successive occurrences.\n\
1075See also the functions `match-beginning', `match-end' and `replace-match'.")
1076 (string, bound, noerror, count)
1077 Lisp_Object string, bound, noerror, count;
1078{
1079 return search_command (string, bound, noerror, count, 1, 1);
1080}
1081\f
1082DEFUN ("replace-match", Freplace_match, Sreplace_match, 1, 3, 0,
1083 "Replace text matched by last search with NEWTEXT.\n\
1084If second arg FIXEDCASE is non-nil, do not alter case of replacement text.\n\
1085Otherwise convert to all caps or cap initials, like replaced text.\n\
1086If third arg LITERAL is non-nil, insert NEWTEXT literally.\n\
1087Otherwise treat `\\' as special:\n\
1088 `\\&' in NEWTEXT means substitute original matched text.\n\
1089 `\\N' means substitute what matched the Nth `\\(...\\)'.\n\
1090 If Nth parens didn't match, substitute nothing.\n\
1091 `\\\\' means insert one `\\'.\n\
1113d9db 1092FIXEDCASE and LITERAL are optional arguments.\n\
ca1d1d23
JB
1093Leaves point at end of replacement text.")
1094 (string, fixedcase, literal)
1095 Lisp_Object string, fixedcase, literal;
1096{
1097 enum { nochange, all_caps, cap_initial } case_action;
1098 register int pos, last;
1099 int some_multiletter_word;
1100 int some_letter = 0;
1101 register int c, prevc;
1102 int inslen;
1103
1104 CHECK_STRING (string, 0);
1105
1106 case_action = nochange; /* We tried an initialization */
1107 /* but some C compilers blew it */
4746118a
JB
1108
1109 if (search_regs.num_regs <= 0)
1110 error ("replace-match called before any match found");
1111
ca1d1d23
JB
1112 if (search_regs.start[0] < BEGV
1113 || search_regs.start[0] > search_regs.end[0]
1114 || search_regs.end[0] > ZV)
1115 args_out_of_range(make_number (search_regs.start[0]),
1116 make_number (search_regs.end[0]));
1117
1118 if (NILP (fixedcase))
1119 {
1120 /* Decide how to casify by examining the matched text. */
1121
1122 last = search_regs.end[0];
1123 prevc = '\n';
1124 case_action = all_caps;
1125
1126 /* some_multiletter_word is set nonzero if any original word
1127 is more than one letter long. */
1128 some_multiletter_word = 0;
1129
1130 for (pos = search_regs.start[0]; pos < last; pos++)
1131 {
1132 c = FETCH_CHAR (pos);
1133 if (LOWERCASEP (c))
1134 {
1135 /* Cannot be all caps if any original char is lower case */
1136
1137 case_action = cap_initial;
1138 if (SYNTAX (prevc) != Sword)
1139 {
1140 /* Cannot even be cap initials
1141 if some original initial is lower case */
1142 case_action = nochange;
1143 break;
1144 }
1145 else
1146 some_multiletter_word = 1;
1147 }
1148 else if (!NOCASEP (c))
1149 {
1150 some_letter = 1;
1151 if (!some_multiletter_word && SYNTAX (prevc) == Sword)
1152 some_multiletter_word = 1;
1153 }
1154
1155 prevc = c;
1156 }
1157
1158 /* Do not make new text all caps
1159 if the original text contained only single letter words. */
1160 if (case_action == all_caps && !some_multiletter_word)
1161 case_action = cap_initial;
1162
1163 if (!some_letter) case_action = nochange;
1164 }
1165
1166 SET_PT (search_regs.end[0]);
1167 if (!NILP (literal))
1168 Finsert (1, &string);
1169 else
1170 {
1171 struct gcpro gcpro1;
1172 GCPRO1 (string);
1173
1174 for (pos = 0; pos < XSTRING (string)->size; pos++)
1175 {
1176 c = XSTRING (string)->data[pos];
1177 if (c == '\\')
1178 {
1179 c = XSTRING (string)->data[++pos];
1180 if (c == '&')
1181 Finsert_buffer_substring (Fcurrent_buffer (),
1182 make_number (search_regs.start[0]),
1183 make_number (search_regs.end[0]));
4746118a 1184 else if (c >= '1' && c <= search_regs.num_regs + '0')
ca1d1d23
JB
1185 {
1186 if (search_regs.start[c - '0'] >= 1)
1187 Finsert_buffer_substring (Fcurrent_buffer (),
1188 make_number (search_regs.start[c - '0']),
1189 make_number (search_regs.end[c - '0']));
1190 }
1191 else
1192 insert_char (c);
1193 }
1194 else
1195 insert_char (c);
1196 }
1197 UNGCPRO;
1198 }
1199
1200 inslen = point - (search_regs.end[0]);
1201 del_range (search_regs.start[0], search_regs.end[0]);
1202
1203 if (case_action == all_caps)
1204 Fupcase_region (make_number (point - inslen), make_number (point));
1205 else if (case_action == cap_initial)
1206 upcase_initials_region (make_number (point - inslen), make_number (point));
1207 return Qnil;
1208}
1209\f
1210static Lisp_Object
1211match_limit (num, beginningp)
1212 Lisp_Object num;
1213 int beginningp;
1214{
1215 register int n;
1216
1217 CHECK_NUMBER (num, 0);
1218 n = XINT (num);
4746118a
JB
1219 if (n < 0 || n >= search_regs.num_regs)
1220 args_out_of_range (num, make_number (search_regs.num_regs));
1221 if (search_regs.num_regs <= 0
1222 || search_regs.start[n] < 0)
ca1d1d23
JB
1223 return Qnil;
1224 return (make_number ((beginningp) ? search_regs.start[n]
1225 : search_regs.end[n]));
1226}
1227
1228DEFUN ("match-beginning", Fmatch_beginning, Smatch_beginning, 1, 1, 0,
1229 "Return position of start of text matched by last search.\n\
1230ARG, a number, specifies which parenthesized expression in the last regexp.\n\
1231 Value is nil if ARGth pair didn't match, or there were less than ARG pairs.\n\
1232Zero means the entire text matched by the whole regexp or whole string.")
1233 (num)
1234 Lisp_Object num;
1235{
1236 return match_limit (num, 1);
1237}
1238
1239DEFUN ("match-end", Fmatch_end, Smatch_end, 1, 1, 0,
1240 "Return position of end of text matched by last search.\n\
1241ARG, a number, specifies which parenthesized expression in the last regexp.\n\
1242 Value is nil if ARGth pair didn't match, or there were less than ARG pairs.\n\
1243Zero means the entire text matched by the whole regexp or whole string.")
1244 (num)
1245 Lisp_Object num;
1246{
1247 return match_limit (num, 0);
1248}
1249
1250DEFUN ("match-data", Fmatch_data, Smatch_data, 0, 0, 0,
1251 "Return a list containing all info on what the last search matched.\n\
1252Element 2N is `(match-beginning N)'; element 2N + 1 is `(match-end N)'.\n\
1253All the elements are markers or nil (nil if the Nth pair didn't match)\n\
1254if the last match was on a buffer; integers or nil if a string was matched.\n\
1255Use `store-match-data' to reinstate the data in this list.")
1256 ()
1257{
4746118a 1258 Lisp_Object *data;
ca1d1d23
JB
1259 int i, len;
1260
daa37602
JB
1261 if (NILP (last_thing_searched))
1262 error ("match-data called before any match found");
1263
4746118a
JB
1264 data = (Lisp_Object *) alloca ((2 * search_regs.num_regs)
1265 * sizeof (Lisp_Object));
1266
ca1d1d23 1267 len = -1;
4746118a 1268 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
1269 {
1270 int start = search_regs.start[i];
1271 if (start >= 0)
1272 {
daa37602 1273 if (EQ (last_thing_searched, Qt))
ca1d1d23
JB
1274 {
1275 XFASTINT (data[2 * i]) = start;
1276 XFASTINT (data[2 * i + 1]) = search_regs.end[i];
1277 }
daa37602 1278 else if (XTYPE (last_thing_searched) == Lisp_Buffer)
ca1d1d23
JB
1279 {
1280 data[2 * i] = Fmake_marker ();
daa37602
JB
1281 Fset_marker (data[2 * i],
1282 make_number (start),
1283 last_thing_searched);
ca1d1d23
JB
1284 data[2 * i + 1] = Fmake_marker ();
1285 Fset_marker (data[2 * i + 1],
daa37602
JB
1286 make_number (search_regs.end[i]),
1287 last_thing_searched);
ca1d1d23 1288 }
daa37602
JB
1289 else
1290 /* last_thing_searched must always be Qt, a buffer, or Qnil. */
1291 abort ();
1292
ca1d1d23
JB
1293 len = i;
1294 }
1295 else
1296 data[2 * i] = data [2 * i + 1] = Qnil;
1297 }
1298 return Flist (2 * len + 2, data);
1299}
1300
1301
1302DEFUN ("store-match-data", Fstore_match_data, Sstore_match_data, 1, 1, 0,
1303 "Set internal data on last search match from elements of LIST.\n\
1304LIST should have been created by calling `match-data' previously.")
1305 (list)
1306 register Lisp_Object list;
1307{
1308 register int i;
1309 register Lisp_Object marker;
1310
1311 if (!CONSP (list) && !NILP (list))
1312 list = wrong_type_argument (Qconsp, list, 0);
1313
daa37602
JB
1314 /* Unless we find a marker with a buffer in LIST, assume that this
1315 match data came from a string. */
1316 last_thing_searched = Qt;
1317
4746118a
JB
1318 /* Allocate registers if they don't already exist. */
1319 {
d084e942 1320 int length = XFASTINT (Flength (list)) / 2;
4746118a
JB
1321
1322 if (length > search_regs.num_regs)
1323 {
1113d9db
JB
1324 if (search_regs.num_regs == 0)
1325 {
1326 search_regs.start
1327 = (regoff_t *) xmalloc (length * sizeof (regoff_t));
1328 search_regs.end
1329 = (regoff_t *) xmalloc (length * sizeof (regoff_t));
1330 }
4746118a 1331 else
1113d9db
JB
1332 {
1333 search_regs.start
1334 = (regoff_t *) xrealloc (search_regs.start,
1335 length * sizeof (regoff_t));
1336 search_regs.end
1337 = (regoff_t *) xrealloc (search_regs.end,
1338 length * sizeof (regoff_t));
1339 }
4746118a 1340
1113d9db
JB
1341 re_set_registers (&searchbuf, &search_regs, length,
1342 search_regs.start, search_regs.end);
4746118a
JB
1343 }
1344 }
1345
1346 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
1347 {
1348 marker = Fcar (list);
1349 if (NILP (marker))
1350 {
1351 search_regs.start[i] = -1;
1352 list = Fcdr (list);
1353 }
1354 else
1355 {
daa37602
JB
1356 if (XTYPE (marker) == Lisp_Marker)
1357 {
1358 if (XMARKER (marker)->buffer == 0)
1359 XFASTINT (marker) = 0;
1360 else
1361 XSET (last_thing_searched, Lisp_Buffer,
1362 XMARKER (marker)->buffer);
1363 }
ca1d1d23
JB
1364
1365 CHECK_NUMBER_COERCE_MARKER (marker, 0);
1366 search_regs.start[i] = XINT (marker);
1367 list = Fcdr (list);
1368
1369 marker = Fcar (list);
1370 if (XTYPE (marker) == Lisp_Marker
1371 && XMARKER (marker)->buffer == 0)
1372 XFASTINT (marker) = 0;
1373
1374 CHECK_NUMBER_COERCE_MARKER (marker, 0);
1375 search_regs.end[i] = XINT (marker);
1376 }
1377 list = Fcdr (list);
1378 }
1379
1380 return Qnil;
1381}
1382
1383/* Quote a string to inactivate reg-expr chars */
1384
1385DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
1386 "Return a regexp string which matches exactly STRING and nothing else.")
1387 (str)
1388 Lisp_Object str;
1389{
1390 register unsigned char *in, *out, *end;
1391 register unsigned char *temp;
1392
1393 CHECK_STRING (str, 0);
1394
1395 temp = (unsigned char *) alloca (XSTRING (str)->size * 2);
1396
1397 /* Now copy the data into the new string, inserting escapes. */
1398
1399 in = XSTRING (str)->data;
1400 end = in + XSTRING (str)->size;
1401 out = temp;
1402
1403 for (; in != end; in++)
1404 {
1405 if (*in == '[' || *in == ']'
1406 || *in == '*' || *in == '.' || *in == '\\'
1407 || *in == '?' || *in == '+'
1408 || *in == '^' || *in == '$')
1409 *out++ = '\\';
1410 *out++ = *in;
1411 }
1412
1413 return make_string (temp, out - temp);
1414}
1415\f
1416syms_of_search ()
1417{
1418 register int i;
1419
1420 searchbuf.allocated = 100;
8c0e7b73 1421 searchbuf.buffer = (unsigned char *) malloc (searchbuf.allocated);
ca1d1d23
JB
1422 searchbuf.fastmap = search_fastmap;
1423
1424 Qsearch_failed = intern ("search-failed");
1425 staticpro (&Qsearch_failed);
1426 Qinvalid_regexp = intern ("invalid-regexp");
1427 staticpro (&Qinvalid_regexp);
1428
1429 Fput (Qsearch_failed, Qerror_conditions,
1430 Fcons (Qsearch_failed, Fcons (Qerror, Qnil)));
1431 Fput (Qsearch_failed, Qerror_message,
1432 build_string ("Search failed"));
1433
1434 Fput (Qinvalid_regexp, Qerror_conditions,
1435 Fcons (Qinvalid_regexp, Fcons (Qerror, Qnil)));
1436 Fput (Qinvalid_regexp, Qerror_message,
1437 build_string ("Invalid regexp"));
1438
1439 last_regexp = Qnil;
1440 staticpro (&last_regexp);
1441
daa37602
JB
1442 last_thing_searched = Qnil;
1443 staticpro (&last_thing_searched);
1444
ca1d1d23
JB
1445 defsubr (&Sstring_match);
1446 defsubr (&Slooking_at);
1447 defsubr (&Sskip_chars_forward);
1448 defsubr (&Sskip_chars_backward);
1449 defsubr (&Ssearch_forward);
1450 defsubr (&Ssearch_backward);
1451 defsubr (&Sword_search_forward);
1452 defsubr (&Sword_search_backward);
1453 defsubr (&Sre_search_forward);
1454 defsubr (&Sre_search_backward);
1455 defsubr (&Sreplace_match);
1456 defsubr (&Smatch_beginning);
1457 defsubr (&Smatch_end);
1458 defsubr (&Smatch_data);
1459 defsubr (&Sstore_match_data);
1460 defsubr (&Sregexp_quote);
1461}