(Frename_buffer): Make prefix arg set UNIQUE.
[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 ();
505 SET_PT (lim);
506 }
507 return Qnil;
508 }
509
510 if (np < BEGV || np > ZV)
511 abort ();
512
513 SET_PT (np);
514
515 return make_number (np);
516}
517\f
518/* search for the n'th occurrence of STRING in the current buffer,
519 starting at position POS and stopping at position LIM,
520 treating PAT as a literal string if RE is false or as
521 a regular expression if RE is true.
522
523 If N is positive, searching is forward and LIM must be greater than POS.
524 If N is negative, searching is backward and LIM must be less than POS.
525
526 Returns -x if only N-x occurrences found (x > 0),
527 or else the position at the beginning of the Nth occurrence
528 (if searching backward) or the end (if searching forward). */
529
530search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
531 Lisp_Object string;
532 int pos;
533 int lim;
534 int n;
535 int RE;
536 register unsigned char *trt;
537 register unsigned char *inverse_trt;
538{
539 int len = XSTRING (string)->size;
540 unsigned char *base_pat = XSTRING (string)->data;
541 register int *BM_tab;
542 int *BM_tab_base;
543 register int direction = ((n > 0) ? 1 : -1);
544 register int dirlen;
545 int infinity, limit, k, stride_for_teases;
546 register unsigned char *pat, *cursor, *p_limit;
547 register int i, j;
548 unsigned char *p1, *p2;
549 int s1, s2;
550
551 /* Null string is found at starting position. */
552 if (!len)
553 return pos;
554
555 if (RE)
1113d9db 556 compile_pattern (string, &searchbuf, &search_regs, (char *) trt);
ca1d1d23
JB
557
558 if (RE /* Here we detect whether the */
559 /* generality of an RE search is */
560 /* really needed. */
561 /* first item is "exact match" */
4746118a 562 && *(searchbuf.buffer) == (char) RE_EXACTN_VALUE
ca1d1d23
JB
563 && searchbuf.buffer[1] + 2 == searchbuf.used) /*first is ONLY item */
564 {
565 RE = 0; /* can do straight (non RE) search */
566 pat = (base_pat = (unsigned char *) searchbuf.buffer + 2);
567 /* trt already applied */
568 len = searchbuf.used - 2;
569 }
570 else if (!RE)
571 {
572 pat = (unsigned char *) alloca (len);
573
574 for (i = len; i--;) /* Copy the pattern; apply trt */
575 *pat++ = (((int) trt) ? trt [*base_pat++] : *base_pat++);
576 pat -= len; base_pat = pat;
577 }
578
579 if (RE)
580 {
581 immediate_quit = 1; /* Quit immediately if user types ^G,
582 because letting this function finish
583 can take too long. */
584 QUIT; /* Do a pending quit right away,
585 to avoid paradoxical behavior */
586 /* Get pointers and sizes of the two strings
587 that make up the visible portion of the buffer. */
588
589 p1 = BEGV_ADDR;
590 s1 = GPT - BEGV;
591 p2 = GAP_END_ADDR;
592 s2 = ZV - GPT;
593 if (s1 < 0)
594 {
595 p2 = p1;
596 s2 = ZV - BEGV;
597 s1 = 0;
598 }
599 if (s2 < 0)
600 {
601 s1 = ZV - BEGV;
602 s2 = 0;
603 }
604 while (n < 0)
605 {
606 int val = re_search_2 (&searchbuf, (char *) p1, s1, (char *) p2, s2,
607 pos - BEGV, lim - pos, &search_regs,
608 /* Don't allow match past current point */
609 pos - BEGV);
610 if (val == -2)
611 matcher_overflow ();
612 if (val >= 0)
613 {
614 j = BEGV;
4746118a 615 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
616 if (search_regs.start[i] >= 0)
617 {
618 search_regs.start[i] += j;
619 search_regs.end[i] += j;
620 }
daa37602 621 XSET (last_thing_searched, Lisp_Buffer, current_buffer);
ca1d1d23
JB
622 /* Set pos to the new position. */
623 pos = search_regs.start[0];
624 }
625 else
626 {
627 immediate_quit = 0;
628 return (n);
629 }
630 n++;
631 }
632 while (n > 0)
633 {
634 int val = re_search_2 (&searchbuf, (char *) p1, s1, (char *) p2, s2,
635 pos - BEGV, lim - pos, &search_regs,
636 lim - BEGV);
637 if (val == -2)
638 matcher_overflow ();
639 if (val >= 0)
640 {
641 j = BEGV;
4746118a 642 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
643 if (search_regs.start[i] >= 0)
644 {
645 search_regs.start[i] += j;
646 search_regs.end[i] += j;
647 }
daa37602 648 XSET (last_thing_searched, Lisp_Buffer, current_buffer);
ca1d1d23
JB
649 pos = search_regs.end[0];
650 }
651 else
652 {
653 immediate_quit = 0;
654 return (0 - n);
655 }
656 n--;
657 }
658 immediate_quit = 0;
659 return (pos);
660 }
661 else /* non-RE case */
662 {
663#ifdef C_ALLOCA
664 int BM_tab_space[0400];
665 BM_tab = &BM_tab_space[0];
666#else
667 BM_tab = (int *) alloca (0400 * sizeof (int));
668#endif
669 /* The general approach is that we are going to maintain that we know */
670 /* the first (closest to the present position, in whatever direction */
671 /* we're searching) character that could possibly be the last */
672 /* (furthest from present position) character of a valid match. We */
673 /* advance the state of our knowledge by looking at that character */
674 /* and seeing whether it indeed matches the last character of the */
675 /* pattern. If it does, we take a closer look. If it does not, we */
676 /* move our pointer (to putative last characters) as far as is */
677 /* logically possible. This amount of movement, which I call a */
678 /* stride, will be the length of the pattern if the actual character */
679 /* appears nowhere in the pattern, otherwise it will be the distance */
680 /* from the last occurrence of that character to the end of the */
681 /* pattern. */
682 /* As a coding trick, an enormous stride is coded into the table for */
683 /* characters that match the last character. This allows use of only */
684 /* a single test, a test for having gone past the end of the */
685 /* permissible match region, to test for both possible matches (when */
686 /* the stride goes past the end immediately) and failure to */
687 /* match (where you get nudged past the end one stride at a time). */
688
689 /* Here we make a "mickey mouse" BM table. The stride of the search */
690 /* is determined only by the last character of the putative match. */
691 /* If that character does not match, we will stride the proper */
692 /* distance to propose a match that superimposes it on the last */
693 /* instance of a character that matches it (per trt), or misses */
694 /* it entirely if there is none. */
695
696 dirlen = len * direction;
697 infinity = dirlen - (lim + pos + len + len) * direction;
698 if (direction < 0)
699 pat = (base_pat += len - 1);
700 BM_tab_base = BM_tab;
701 BM_tab += 0400;
702 j = dirlen; /* to get it in a register */
703 /* A character that does not appear in the pattern induces a */
704 /* stride equal to the pattern length. */
705 while (BM_tab_base != BM_tab)
706 {
707 *--BM_tab = j;
708 *--BM_tab = j;
709 *--BM_tab = j;
710 *--BM_tab = j;
711 }
712 i = 0;
713 while (i != infinity)
714 {
715 j = pat[i]; i += direction;
716 if (i == dirlen) i = infinity;
717 if ((int) trt)
718 {
719 k = (j = trt[j]);
720 if (i == infinity)
721 stride_for_teases = BM_tab[j];
722 BM_tab[j] = dirlen - i;
723 /* A translation table is accompanied by its inverse -- see */
724 /* comment following downcase_table for details */
725 while ((j = inverse_trt[j]) != k)
726 BM_tab[j] = dirlen - i;
727 }
728 else
729 {
730 if (i == infinity)
731 stride_for_teases = BM_tab[j];
732 BM_tab[j] = dirlen - i;
733 }
734 /* stride_for_teases tells how much to stride if we get a */
735 /* match on the far character but are subsequently */
736 /* disappointed, by recording what the stride would have been */
737 /* for that character if the last character had been */
738 /* different. */
739 }
740 infinity = dirlen - infinity;
741 pos += dirlen - ((direction > 0) ? direction : 0);
742 /* loop invariant - pos points at where last char (first char if reverse)
743 of pattern would align in a possible match. */
744 while (n != 0)
745 {
746 if ((lim - pos - (direction > 0)) * direction < 0)
747 return (n * (0 - direction));
748 /* First we do the part we can by pointers (maybe nothing) */
749 QUIT;
750 pat = base_pat;
751 limit = pos - dirlen + direction;
752 limit = ((direction > 0)
753 ? BUFFER_CEILING_OF (limit)
754 : BUFFER_FLOOR_OF (limit));
755 /* LIMIT is now the last (not beyond-last!) value
756 POS can take on without hitting edge of buffer or the gap. */
757 limit = ((direction > 0)
758 ? min (lim - 1, min (limit, pos + 20000))
759 : max (lim, max (limit, pos - 20000)));
760 if ((limit - pos) * direction > 20)
761 {
762 p_limit = &FETCH_CHAR (limit);
763 p2 = (cursor = &FETCH_CHAR (pos));
764 /* In this loop, pos + cursor - p2 is the surrogate for pos */
765 while (1) /* use one cursor setting as long as i can */
766 {
767 if (direction > 0) /* worth duplicating */
768 {
769 /* Use signed comparison if appropriate
770 to make cursor+infinity sure to be > p_limit.
771 Assuming that the buffer lies in a range of addresses
772 that are all "positive" (as ints) or all "negative",
773 either kind of comparison will work as long
774 as we don't step by infinity. So pick the kind
775 that works when we do step by infinity. */
776 if ((int) (p_limit + infinity) > (int) p_limit)
777 while ((int) cursor <= (int) p_limit)
778 cursor += BM_tab[*cursor];
779 else
780 while ((unsigned int) cursor <= (unsigned int) p_limit)
781 cursor += BM_tab[*cursor];
782 }
783 else
784 {
785 if ((int) (p_limit + infinity) < (int) p_limit)
786 while ((int) cursor >= (int) p_limit)
787 cursor += BM_tab[*cursor];
788 else
789 while ((unsigned int) cursor >= (unsigned int) p_limit)
790 cursor += BM_tab[*cursor];
791 }
792/* If you are here, cursor is beyond the end of the searched region. */
793 /* This can happen if you match on the far character of the pattern, */
794 /* because the "stride" of that character is infinity, a number able */
795 /* to throw you well beyond the end of the search. It can also */
796 /* happen if you fail to match within the permitted region and would */
797 /* otherwise try a character beyond that region */
798 if ((cursor - p_limit) * direction <= len)
799 break; /* a small overrun is genuine */
800 cursor -= infinity; /* large overrun = hit */
801 i = dirlen - direction;
802 if ((int) trt)
803 {
804 while ((i -= direction) + direction != 0)
805 if (pat[i] != trt[*(cursor -= direction)])
806 break;
807 }
808 else
809 {
810 while ((i -= direction) + direction != 0)
811 if (pat[i] != *(cursor -= direction))
812 break;
813 }
814 cursor += dirlen - i - direction; /* fix cursor */
815 if (i + direction == 0)
816 {
817 cursor -= direction;
1113d9db
JB
818
819 /* Make sure we have registers in which to store
820 the match position. */
821 if (search_regs.num_regs == 0)
822 {
823 regoff_t *starts, *ends;
824
825 starts =
826 (regoff_t *) xmalloc (2 * sizeof (regoff_t));
827 ends =
828 (regoff_t *) xmalloc (2 * sizeof (regoff_t));
829 re_set_registers (&searchbuf,
830 &search_regs,
831 2, starts, ends);
832 }
833
ca1d1d23
JB
834 search_regs.start[0]
835 = pos + cursor - p2 + ((direction > 0)
836 ? 1 - len : 0);
837 search_regs.end[0] = len + search_regs.start[0];
daa37602 838 XSET (last_thing_searched, Lisp_Buffer, current_buffer);
ca1d1d23
JB
839 if ((n -= direction) != 0)
840 cursor += dirlen; /* to resume search */
841 else
842 return ((direction > 0)
843 ? search_regs.end[0] : search_regs.start[0]);
844 }
845 else
846 cursor += stride_for_teases; /* <sigh> we lose - */
847 }
848 pos += cursor - p2;
849 }
850 else
851 /* Now we'll pick up a clump that has to be done the hard */
852 /* way because it covers a discontinuity */
853 {
854 limit = ((direction > 0)
855 ? BUFFER_CEILING_OF (pos - dirlen + 1)
856 : BUFFER_FLOOR_OF (pos - dirlen - 1));
857 limit = ((direction > 0)
858 ? min (limit + len, lim - 1)
859 : max (limit - len, lim));
860 /* LIMIT is now the last value POS can have
861 and still be valid for a possible match. */
862 while (1)
863 {
864 /* This loop can be coded for space rather than */
865 /* speed because it will usually run only once. */
866 /* (the reach is at most len + 21, and typically */
867 /* does not exceed len) */
868 while ((limit - pos) * direction >= 0)
869 pos += BM_tab[FETCH_CHAR(pos)];
870 /* now run the same tests to distinguish going off the */
871 /* end, a match or a phoney match. */
872 if ((pos - limit) * direction <= len)
873 break; /* ran off the end */
874 /* Found what might be a match.
875 Set POS back to last (first if reverse) char pos. */
876 pos -= infinity;
877 i = dirlen - direction;
878 while ((i -= direction) + direction != 0)
879 {
880 pos -= direction;
881 if (pat[i] != (((int) trt)
882 ? trt[FETCH_CHAR(pos)]
883 : FETCH_CHAR (pos)))
884 break;
885 }
886 /* Above loop has moved POS part or all the way
887 back to the first char pos (last char pos if reverse).
888 Set it once again at the last (first if reverse) char. */
889 pos += dirlen - i- direction;
890 if (i + direction == 0)
891 {
892 pos -= direction;
1113d9db
JB
893
894 /* Make sure we have registers in which to store
895 the match position. */
896 if (search_regs.num_regs == 0)
897 {
898 regoff_t *starts, *ends;
899
900 starts =
901 (regoff_t *) xmalloc (2 * sizeof (regoff_t));
902 ends =
903 (regoff_t *) xmalloc (2 * sizeof (regoff_t));
904 re_set_registers (&searchbuf,
905 &search_regs,
906 2, starts, ends);
907 }
908
ca1d1d23
JB
909 search_regs.start[0]
910 = pos + ((direction > 0) ? 1 - len : 0);
911 search_regs.end[0] = len + search_regs.start[0];
daa37602 912 XSET (last_thing_searched, Lisp_Buffer, current_buffer);
ca1d1d23
JB
913 if ((n -= direction) != 0)
914 pos += dirlen; /* to resume search */
915 else
916 return ((direction > 0)
917 ? search_regs.end[0] : search_regs.start[0]);
918 }
919 else
920 pos += stride_for_teases;
921 }
922 }
923 /* We have done one clump. Can we continue? */
924 if ((lim - pos) * direction < 0)
925 return ((0 - n) * direction);
926 }
927 return pos;
928 }
929}
930\f
931/* Given a string of words separated by word delimiters,
932 compute a regexp that matches those exact words
933 separated by arbitrary punctuation. */
934
935static Lisp_Object
936wordify (string)
937 Lisp_Object string;
938{
939 register unsigned char *p, *o;
940 register int i, len, punct_count = 0, word_count = 0;
941 Lisp_Object val;
942
943 CHECK_STRING (string, 0);
944 p = XSTRING (string)->data;
945 len = XSTRING (string)->size;
946
947 for (i = 0; i < len; i++)
948 if (SYNTAX (p[i]) != Sword)
949 {
950 punct_count++;
951 if (i > 0 && SYNTAX (p[i-1]) == Sword) word_count++;
952 }
953 if (SYNTAX (p[len-1]) == Sword) word_count++;
954 if (!word_count) return build_string ("");
955
956 val = make_string (p, len - punct_count + 5 * (word_count - 1) + 4);
957
958 o = XSTRING (val)->data;
959 *o++ = '\\';
960 *o++ = 'b';
961
962 for (i = 0; i < len; i++)
963 if (SYNTAX (p[i]) == Sword)
964 *o++ = p[i];
965 else if (i > 0 && SYNTAX (p[i-1]) == Sword && --word_count)
966 {
967 *o++ = '\\';
968 *o++ = 'W';
969 *o++ = '\\';
970 *o++ = 'W';
971 *o++ = '*';
972 }
973
974 *o++ = '\\';
975 *o++ = 'b';
976
977 return val;
978}
979\f
980DEFUN ("search-backward", Fsearch_backward, Ssearch_backward, 1, 4,
981 "sSearch backward: ",
982 "Search backward from point for STRING.\n\
983Set point to the beginning of the occurrence found, and return point.\n\
984An optional second argument bounds the search; it is a buffer position.\n\
985The match found must not extend before that position.\n\
986Optional third argument, if t, means if fail just return nil (no error).\n\
987 If not nil and not t, position at limit of search and return nil.\n\
988Optional fourth argument is repeat count--search for successive occurrences.\n\
989See also the functions `match-beginning', `match-end' and `replace-match'.")
990 (string, bound, noerror, count)
991 Lisp_Object string, bound, noerror, count;
992{
993 return search_command (string, bound, noerror, count, -1, 0);
994}
995
996DEFUN ("search-forward", Fsearch_forward, Ssearch_forward, 1, 4, "sSearch: ",
997 "Search forward from point for STRING.\n\
998Set point to the end of the occurrence found, and return point.\n\
999An optional second argument bounds the search; it is a buffer position.\n\
1000The match found must not extend after that position. nil is equivalent\n\
1001 to (point-max).\n\
1002Optional third argument, if t, means if fail just return nil (no error).\n\
1003 If not nil and not t, move to limit of search and return nil.\n\
1004Optional fourth argument is repeat count--search for successive occurrences.\n\
1005See also the functions `match-beginning', `match-end' and `replace-match'.")
1006 (string, bound, noerror, count)
1007 Lisp_Object string, bound, noerror, count;
1008{
1009 return search_command (string, bound, noerror, count, 1, 0);
1010}
1011
1012DEFUN ("word-search-backward", Fword_search_backward, Sword_search_backward, 1, 4,
1013 "sWord search backward: ",
1014 "Search backward from point for STRING, ignoring differences in punctuation.\n\
1015Set point to the beginning of the occurrence found, and return point.\n\
1016An optional second argument bounds the search; it is a buffer position.\n\
1017The match found must not extend before that position.\n\
1018Optional third argument, if t, means if fail just return nil (no error).\n\
1019 If not nil and not t, move to limit of search and return nil.\n\
1020Optional fourth argument is repeat count--search for successive occurrences.")
1021 (string, bound, noerror, count)
1022 Lisp_Object string, bound, noerror, count;
1023{
1024 return search_command (wordify (string), bound, noerror, count, -1, 1);
1025}
1026
1027DEFUN ("word-search-forward", Fword_search_forward, Sword_search_forward, 1, 4,
1028 "sWord search: ",
1029 "Search forward from point for STRING, ignoring differences in punctuation.\n\
1030Set point to the end of the occurrence found, and return point.\n\
1031An optional second argument bounds the search; it is a buffer position.\n\
1032The match found must not extend after that position.\n\
1033Optional third argument, if t, means if fail just return nil (no error).\n\
1034 If not nil and not t, move to limit of search and return nil.\n\
1035Optional fourth argument is repeat count--search for successive occurrences.")
1036 (string, bound, noerror, count)
1037 Lisp_Object string, bound, noerror, count;
1038{
1039 return search_command (wordify (string), bound, noerror, count, 1, 1);
1040}
1041
1042DEFUN ("re-search-backward", Fre_search_backward, Sre_search_backward, 1, 4,
1043 "sRE search backward: ",
1044 "Search backward from point for match for regular expression REGEXP.\n\
1045Set point to the beginning of the match, and return point.\n\
1046The match found is the one starting last in the buffer\n\
1047and yet ending before the place the origin of the search.\n\
1048An optional second argument bounds the search; it is a buffer position.\n\
1049The match found must start at or after that position.\n\
1050Optional third argument, if t, means if fail just return nil (no error).\n\
1051 If not nil and not t, move to limit of search and return nil.\n\
1052Optional fourth argument is repeat count--search for successive occurrences.\n\
1053See also the functions `match-beginning', `match-end' and `replace-match'.")
1054 (string, bound, noerror, count)
1055 Lisp_Object string, bound, noerror, count;
1056{
1057 return search_command (string, bound, noerror, count, -1, 1);
1058}
1059
1060DEFUN ("re-search-forward", Fre_search_forward, Sre_search_forward, 1, 4,
1061 "sRE search: ",
1062 "Search forward from point for regular expression REGEXP.\n\
1063Set point to the end of the occurrence found, and return point.\n\
1064An optional second argument bounds the search; it is a buffer position.\n\
1065The match found must not extend after that position.\n\
1066Optional third argument, if t, means if fail just return nil (no error).\n\
1067 If not nil and not t, move to limit of search and return nil.\n\
1068Optional fourth argument is repeat count--search for successive occurrences.\n\
1069See also the functions `match-beginning', `match-end' and `replace-match'.")
1070 (string, bound, noerror, count)
1071 Lisp_Object string, bound, noerror, count;
1072{
1073 return search_command (string, bound, noerror, count, 1, 1);
1074}
1075\f
1076DEFUN ("replace-match", Freplace_match, Sreplace_match, 1, 3, 0,
1077 "Replace text matched by last search with NEWTEXT.\n\
1078If second arg FIXEDCASE is non-nil, do not alter case of replacement text.\n\
1079Otherwise convert to all caps or cap initials, like replaced text.\n\
1080If third arg LITERAL is non-nil, insert NEWTEXT literally.\n\
1081Otherwise treat `\\' as special:\n\
1082 `\\&' in NEWTEXT means substitute original matched text.\n\
1083 `\\N' means substitute what matched the Nth `\\(...\\)'.\n\
1084 If Nth parens didn't match, substitute nothing.\n\
1085 `\\\\' means insert one `\\'.\n\
1113d9db 1086FIXEDCASE and LITERAL are optional arguments.\n\
ca1d1d23
JB
1087Leaves point at end of replacement text.")
1088 (string, fixedcase, literal)
1089 Lisp_Object string, fixedcase, literal;
1090{
1091 enum { nochange, all_caps, cap_initial } case_action;
1092 register int pos, last;
1093 int some_multiletter_word;
1094 int some_letter = 0;
1095 register int c, prevc;
1096 int inslen;
1097
1098 CHECK_STRING (string, 0);
1099
1100 case_action = nochange; /* We tried an initialization */
1101 /* but some C compilers blew it */
4746118a
JB
1102
1103 if (search_regs.num_regs <= 0)
1104 error ("replace-match called before any match found");
1105
ca1d1d23
JB
1106 if (search_regs.start[0] < BEGV
1107 || search_regs.start[0] > search_regs.end[0]
1108 || search_regs.end[0] > ZV)
1109 args_out_of_range(make_number (search_regs.start[0]),
1110 make_number (search_regs.end[0]));
1111
1112 if (NILP (fixedcase))
1113 {
1114 /* Decide how to casify by examining the matched text. */
1115
1116 last = search_regs.end[0];
1117 prevc = '\n';
1118 case_action = all_caps;
1119
1120 /* some_multiletter_word is set nonzero if any original word
1121 is more than one letter long. */
1122 some_multiletter_word = 0;
1123
1124 for (pos = search_regs.start[0]; pos < last; pos++)
1125 {
1126 c = FETCH_CHAR (pos);
1127 if (LOWERCASEP (c))
1128 {
1129 /* Cannot be all caps if any original char is lower case */
1130
1131 case_action = cap_initial;
1132 if (SYNTAX (prevc) != Sword)
1133 {
1134 /* Cannot even be cap initials
1135 if some original initial is lower case */
1136 case_action = nochange;
1137 break;
1138 }
1139 else
1140 some_multiletter_word = 1;
1141 }
1142 else if (!NOCASEP (c))
1143 {
1144 some_letter = 1;
1145 if (!some_multiletter_word && SYNTAX (prevc) == Sword)
1146 some_multiletter_word = 1;
1147 }
1148
1149 prevc = c;
1150 }
1151
1152 /* Do not make new text all caps
1153 if the original text contained only single letter words. */
1154 if (case_action == all_caps && !some_multiletter_word)
1155 case_action = cap_initial;
1156
1157 if (!some_letter) case_action = nochange;
1158 }
1159
1160 SET_PT (search_regs.end[0]);
1161 if (!NILP (literal))
1162 Finsert (1, &string);
1163 else
1164 {
1165 struct gcpro gcpro1;
1166 GCPRO1 (string);
1167
1168 for (pos = 0; pos < XSTRING (string)->size; pos++)
1169 {
1170 c = XSTRING (string)->data[pos];
1171 if (c == '\\')
1172 {
1173 c = XSTRING (string)->data[++pos];
1174 if (c == '&')
1175 Finsert_buffer_substring (Fcurrent_buffer (),
1176 make_number (search_regs.start[0]),
1177 make_number (search_regs.end[0]));
4746118a 1178 else if (c >= '1' && c <= search_regs.num_regs + '0')
ca1d1d23
JB
1179 {
1180 if (search_regs.start[c - '0'] >= 1)
1181 Finsert_buffer_substring (Fcurrent_buffer (),
1182 make_number (search_regs.start[c - '0']),
1183 make_number (search_regs.end[c - '0']));
1184 }
1185 else
1186 insert_char (c);
1187 }
1188 else
1189 insert_char (c);
1190 }
1191 UNGCPRO;
1192 }
1193
1194 inslen = point - (search_regs.end[0]);
1195 del_range (search_regs.start[0], search_regs.end[0]);
1196
1197 if (case_action == all_caps)
1198 Fupcase_region (make_number (point - inslen), make_number (point));
1199 else if (case_action == cap_initial)
1200 upcase_initials_region (make_number (point - inslen), make_number (point));
1201 return Qnil;
1202}
1203\f
1204static Lisp_Object
1205match_limit (num, beginningp)
1206 Lisp_Object num;
1207 int beginningp;
1208{
1209 register int n;
1210
1211 CHECK_NUMBER (num, 0);
1212 n = XINT (num);
4746118a
JB
1213 if (n < 0 || n >= search_regs.num_regs)
1214 args_out_of_range (num, make_number (search_regs.num_regs));
1215 if (search_regs.num_regs <= 0
1216 || search_regs.start[n] < 0)
ca1d1d23
JB
1217 return Qnil;
1218 return (make_number ((beginningp) ? search_regs.start[n]
1219 : search_regs.end[n]));
1220}
1221
1222DEFUN ("match-beginning", Fmatch_beginning, Smatch_beginning, 1, 1, 0,
1223 "Return position of start of text matched by last search.\n\
1224ARG, a number, specifies which parenthesized expression in the last regexp.\n\
1225 Value is nil if ARGth pair didn't match, or there were less than ARG pairs.\n\
1226Zero means the entire text matched by the whole regexp or whole string.")
1227 (num)
1228 Lisp_Object num;
1229{
1230 return match_limit (num, 1);
1231}
1232
1233DEFUN ("match-end", Fmatch_end, Smatch_end, 1, 1, 0,
1234 "Return position of end of text matched by last search.\n\
1235ARG, a number, specifies which parenthesized expression in the last regexp.\n\
1236 Value is nil if ARGth pair didn't match, or there were less than ARG pairs.\n\
1237Zero means the entire text matched by the whole regexp or whole string.")
1238 (num)
1239 Lisp_Object num;
1240{
1241 return match_limit (num, 0);
1242}
1243
1244DEFUN ("match-data", Fmatch_data, Smatch_data, 0, 0, 0,
1245 "Return a list containing all info on what the last search matched.\n\
1246Element 2N is `(match-beginning N)'; element 2N + 1 is `(match-end N)'.\n\
1247All the elements are markers or nil (nil if the Nth pair didn't match)\n\
1248if the last match was on a buffer; integers or nil if a string was matched.\n\
1249Use `store-match-data' to reinstate the data in this list.")
1250 ()
1251{
4746118a 1252 Lisp_Object *data;
ca1d1d23
JB
1253 int i, len;
1254
daa37602
JB
1255 if (NILP (last_thing_searched))
1256 error ("match-data called before any match found");
1257
4746118a
JB
1258 data = (Lisp_Object *) alloca ((2 * search_regs.num_regs)
1259 * sizeof (Lisp_Object));
1260
ca1d1d23 1261 len = -1;
4746118a 1262 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
1263 {
1264 int start = search_regs.start[i];
1265 if (start >= 0)
1266 {
daa37602 1267 if (EQ (last_thing_searched, Qt))
ca1d1d23
JB
1268 {
1269 XFASTINT (data[2 * i]) = start;
1270 XFASTINT (data[2 * i + 1]) = search_regs.end[i];
1271 }
daa37602 1272 else if (XTYPE (last_thing_searched) == Lisp_Buffer)
ca1d1d23
JB
1273 {
1274 data[2 * i] = Fmake_marker ();
daa37602
JB
1275 Fset_marker (data[2 * i],
1276 make_number (start),
1277 last_thing_searched);
ca1d1d23
JB
1278 data[2 * i + 1] = Fmake_marker ();
1279 Fset_marker (data[2 * i + 1],
daa37602
JB
1280 make_number (search_regs.end[i]),
1281 last_thing_searched);
ca1d1d23 1282 }
daa37602
JB
1283 else
1284 /* last_thing_searched must always be Qt, a buffer, or Qnil. */
1285 abort ();
1286
ca1d1d23
JB
1287 len = i;
1288 }
1289 else
1290 data[2 * i] = data [2 * i + 1] = Qnil;
1291 }
1292 return Flist (2 * len + 2, data);
1293}
1294
1295
1296DEFUN ("store-match-data", Fstore_match_data, Sstore_match_data, 1, 1, 0,
1297 "Set internal data on last search match from elements of LIST.\n\
1298LIST should have been created by calling `match-data' previously.")
1299 (list)
1300 register Lisp_Object list;
1301{
1302 register int i;
1303 register Lisp_Object marker;
1304
1305 if (!CONSP (list) && !NILP (list))
1306 list = wrong_type_argument (Qconsp, list, 0);
1307
daa37602
JB
1308 /* Unless we find a marker with a buffer in LIST, assume that this
1309 match data came from a string. */
1310 last_thing_searched = Qt;
1311
4746118a
JB
1312 /* Allocate registers if they don't already exist. */
1313 {
d084e942 1314 int length = XFASTINT (Flength (list)) / 2;
4746118a
JB
1315
1316 if (length > search_regs.num_regs)
1317 {
1113d9db
JB
1318 if (search_regs.num_regs == 0)
1319 {
1320 search_regs.start
1321 = (regoff_t *) xmalloc (length * sizeof (regoff_t));
1322 search_regs.end
1323 = (regoff_t *) xmalloc (length * sizeof (regoff_t));
1324 }
4746118a 1325 else
1113d9db
JB
1326 {
1327 search_regs.start
1328 = (regoff_t *) xrealloc (search_regs.start,
1329 length * sizeof (regoff_t));
1330 search_regs.end
1331 = (regoff_t *) xrealloc (search_regs.end,
1332 length * sizeof (regoff_t));
1333 }
4746118a 1334
1113d9db
JB
1335 re_set_registers (&searchbuf, &search_regs, length,
1336 search_regs.start, search_regs.end);
4746118a
JB
1337 }
1338 }
1339
1340 for (i = 0; i < search_regs.num_regs; i++)
ca1d1d23
JB
1341 {
1342 marker = Fcar (list);
1343 if (NILP (marker))
1344 {
1345 search_regs.start[i] = -1;
1346 list = Fcdr (list);
1347 }
1348 else
1349 {
daa37602
JB
1350 if (XTYPE (marker) == Lisp_Marker)
1351 {
1352 if (XMARKER (marker)->buffer == 0)
1353 XFASTINT (marker) = 0;
1354 else
1355 XSET (last_thing_searched, Lisp_Buffer,
1356 XMARKER (marker)->buffer);
1357 }
ca1d1d23
JB
1358
1359 CHECK_NUMBER_COERCE_MARKER (marker, 0);
1360 search_regs.start[i] = XINT (marker);
1361 list = Fcdr (list);
1362
1363 marker = Fcar (list);
1364 if (XTYPE (marker) == Lisp_Marker
1365 && XMARKER (marker)->buffer == 0)
1366 XFASTINT (marker) = 0;
1367
1368 CHECK_NUMBER_COERCE_MARKER (marker, 0);
1369 search_regs.end[i] = XINT (marker);
1370 }
1371 list = Fcdr (list);
1372 }
1373
1374 return Qnil;
1375}
1376
1377/* Quote a string to inactivate reg-expr chars */
1378
1379DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
1380 "Return a regexp string which matches exactly STRING and nothing else.")
1381 (str)
1382 Lisp_Object str;
1383{
1384 register unsigned char *in, *out, *end;
1385 register unsigned char *temp;
1386
1387 CHECK_STRING (str, 0);
1388
1389 temp = (unsigned char *) alloca (XSTRING (str)->size * 2);
1390
1391 /* Now copy the data into the new string, inserting escapes. */
1392
1393 in = XSTRING (str)->data;
1394 end = in + XSTRING (str)->size;
1395 out = temp;
1396
1397 for (; in != end; in++)
1398 {
1399 if (*in == '[' || *in == ']'
1400 || *in == '*' || *in == '.' || *in == '\\'
1401 || *in == '?' || *in == '+'
1402 || *in == '^' || *in == '$')
1403 *out++ = '\\';
1404 *out++ = *in;
1405 }
1406
1407 return make_string (temp, out - temp);
1408}
1409\f
1410syms_of_search ()
1411{
1412 register int i;
1413
1414 searchbuf.allocated = 100;
8c0e7b73 1415 searchbuf.buffer = (unsigned char *) malloc (searchbuf.allocated);
ca1d1d23
JB
1416 searchbuf.fastmap = search_fastmap;
1417
1418 Qsearch_failed = intern ("search-failed");
1419 staticpro (&Qsearch_failed);
1420 Qinvalid_regexp = intern ("invalid-regexp");
1421 staticpro (&Qinvalid_regexp);
1422
1423 Fput (Qsearch_failed, Qerror_conditions,
1424 Fcons (Qsearch_failed, Fcons (Qerror, Qnil)));
1425 Fput (Qsearch_failed, Qerror_message,
1426 build_string ("Search failed"));
1427
1428 Fput (Qinvalid_regexp, Qerror_conditions,
1429 Fcons (Qinvalid_regexp, Fcons (Qerror, Qnil)));
1430 Fput (Qinvalid_regexp, Qerror_message,
1431 build_string ("Invalid regexp"));
1432
1433 last_regexp = Qnil;
1434 staticpro (&last_regexp);
1435
daa37602
JB
1436 last_thing_searched = Qnil;
1437 staticpro (&last_thing_searched);
1438
ca1d1d23
JB
1439 defsubr (&Sstring_match);
1440 defsubr (&Slooking_at);
1441 defsubr (&Sskip_chars_forward);
1442 defsubr (&Sskip_chars_backward);
1443 defsubr (&Ssearch_forward);
1444 defsubr (&Ssearch_backward);
1445 defsubr (&Sword_search_forward);
1446 defsubr (&Sword_search_backward);
1447 defsubr (&Sre_search_forward);
1448 defsubr (&Sre_search_backward);
1449 defsubr (&Sreplace_match);
1450 defsubr (&Smatch_beginning);
1451 defsubr (&Smatch_end);
1452 defsubr (&Smatch_data);
1453 defsubr (&Sstore_match_data);
1454 defsubr (&Sregexp_quote);
1455}