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