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