(all_older_lcrecords): Deleted.
[chise/xemacs-chise.git-] / src / search.c
1 /* String search routines for XEmacs.
2    Copyright (C) 1985, 1986, 1987, 1992-1995 Free Software Foundation, Inc.
3    Copyright (C) 1995 Sun Microsystems, Inc.
4    Copyright (C) 1999,2000,2001 MORIOKA Tomohiko
5
6 This file is part of XEmacs.
7
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING.  If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23 /* Synched up with: FSF 19.29, except for region-cache stuff. */
24
25 /* Hacked on for Mule by Ben Wing, December 1994 and August 1995. */
26
27 /* This file has been Mule-ized except for the TRT stuff. */
28
29 #include <config.h>
30 #include "lisp.h"
31
32 #include "buffer.h"
33 #include "insdel.h"
34 #include "opaque.h"
35 #ifdef REGION_CACHE_NEEDS_WORK
36 #include "region-cache.h"
37 #endif
38 #include "syntax.h"
39
40 #include <sys/types.h>
41 #include "regex.h"
42 #include "casetab.h"
43 #include "chartab.h"
44
45 #define TRANSLATE(table, pos)   \
46  (!NILP (table) ? TRT_TABLE_OF (table, (Emchar) pos) : pos)
47 \f
48 #define REGEXP_CACHE_SIZE 20
49
50 /* If the regexp is non-nil, then the buffer contains the compiled form
51    of that regexp, suitable for searching.  */
52 struct regexp_cache
53 {
54   struct regexp_cache *next;
55   Lisp_Object regexp;
56   struct re_pattern_buffer buf;
57   char fastmap[0400];
58   /* Nonzero means regexp was compiled to do full POSIX backtracking.  */
59   char posix;
60 };
61
62 /* The instances of that struct.  */
63 static struct regexp_cache searchbufs[REGEXP_CACHE_SIZE];
64
65 /* The head of the linked list; points to the most recently used buffer.  */
66 static struct regexp_cache *searchbuf_head;
67
68
69 /* Every call to re_match, etc., must pass &search_regs as the regs
70    argument unless you can show it is unnecessary (i.e., if re_match
71    is certainly going to be called again before region-around-match
72    can be called).
73
74    Since the registers are now dynamically allocated, we need to make
75    sure not to refer to the Nth register before checking that it has
76    been allocated by checking search_regs.num_regs.
77
78    The regex code keeps track of whether it has allocated the search
79    buffer using bits in the re_pattern_buffer.  This means that whenever
80    you compile a new pattern, it completely forgets whether it has
81    allocated any registers, and will allocate new registers the next
82    time you call a searching or matching function.  Therefore, we need
83    to call re_set_registers after compiling a new pattern or after
84    setting the match registers, so that the regex functions will be
85    able to free or re-allocate it properly.  */
86
87 /* Note: things get trickier under Mule because the values returned from
88    the regexp routines are in Bytinds but we need them to be in Bufpos's.
89    We take the easy way out for the moment and just convert them immediately.
90    We could be more clever by not converting them until necessary, but
91    that gets real ugly real fast since the buffer might have changed and
92    the positions might be out of sync or out of range.
93    */
94 static struct re_registers search_regs;
95
96 /* The buffer in which the last search was performed, or
97    Qt if the last search was done in a string;
98    Qnil if no searching has been done yet.  */
99 static Lisp_Object last_thing_searched;
100
101 /* error condition signalled when regexp compile_pattern fails */
102
103 Lisp_Object Qinvalid_regexp;
104
105 /* Regular expressions used in forward/backward-word */
106 Lisp_Object Vforward_word_regexp, Vbackward_word_regexp;
107
108 /* range table for use with skip_chars.  Only needed for Mule. */
109 Lisp_Object Vskip_chars_range_table;
110
111 static void set_search_regs (struct buffer *buf, Bufpos beg, Charcount len);
112 static void save_search_regs (void);
113 static Bufpos simple_search (struct buffer *buf, Bufbyte *base_pat,
114                              Bytecount len, Bytind pos, Bytind lim,
115                              EMACS_INT n, Lisp_Object trt);
116 static Bufpos boyer_moore (struct buffer *buf, Bufbyte *base_pat,
117                            Bytecount len, Bytind pos, Bytind lim,
118                            EMACS_INT n, Lisp_Object trt,
119                            Lisp_Object inverse_trt, int charset_base);
120 static Bufpos search_buffer (struct buffer *buf, Lisp_Object str,
121                              Bufpos bufpos, Bufpos buflim, EMACS_INT n, int RE,
122                              Lisp_Object trt, Lisp_Object inverse_trt,
123                              int posix);
124
125 static void
126 matcher_overflow (void)
127 {
128   error ("Stack overflow in regexp matcher");
129 }
130
131 /* Compile a regexp and signal a Lisp error if anything goes wrong.
132    PATTERN is the pattern to compile.
133    CP is the place to put the result.
134    TRANSLATE is a translation table for ignoring case, or NULL for none.
135    REGP is the structure that says where to store the "register"
136    values that will result from matching this pattern.
137    If it is 0, we should compile the pattern not to record any
138    subexpression bounds.
139    POSIX is nonzero if we want full backtracking (POSIX style)
140    for this pattern.  0 means backtrack only enough to get a valid match.  */
141
142 static int
143 compile_pattern_1 (struct regexp_cache *cp, Lisp_Object pattern,
144                    Lisp_Object translate, struct re_registers *regp, int posix,
145                    Error_behavior errb)
146 {
147   const char *val;
148   reg_syntax_t old;
149
150   cp->regexp = Qnil;
151   cp->buf.translate = translate;
152   cp->posix = posix;
153   old = re_set_syntax (RE_SYNTAX_EMACS
154                        | (posix ? 0 : RE_NO_POSIX_BACKTRACKING));
155   val = (const char *)
156     re_compile_pattern ((char *) XSTRING_DATA (pattern),
157                         XSTRING_LENGTH (pattern), &cp->buf);
158   re_set_syntax (old);
159   if (val)
160     {
161       maybe_signal_error (Qinvalid_regexp, list1 (build_string (val)),
162                           Qsearch, errb);
163       return 0;
164     }
165
166   cp->regexp = Fcopy_sequence (pattern);
167   return 1;
168 }
169
170 /* Compile a regexp if necessary, but first check to see if there's one in
171    the cache.
172    PATTERN is the pattern to compile.
173    TRANSLATE is a translation table for ignoring case, or NULL for none.
174    REGP is the structure that says where to store the "register"
175    values that will result from matching this pattern.
176    If it is 0, we should compile the pattern not to record any
177    subexpression bounds.
178    POSIX is nonzero if we want full backtracking (POSIX style)
179    for this pattern.  0 means backtrack only enough to get a valid match.  */
180
181 struct re_pattern_buffer *
182 compile_pattern (Lisp_Object pattern, struct re_registers *regp,
183                  Lisp_Object translate, int posix, Error_behavior errb)
184 {
185   struct regexp_cache *cp, **cpp;
186
187   for (cpp = &searchbuf_head; ; cpp = &cp->next)
188     {
189       cp = *cpp;
190       if (!NILP (Fstring_equal (cp->regexp, pattern))
191           && EQ (cp->buf.translate, translate)
192           && cp->posix == posix)
193         break;
194
195       /* If we're at the end of the cache, compile into the last cell.  */
196       if (cp->next == 0)
197         {
198           if (!compile_pattern_1 (cp, pattern, translate, regp, posix,
199                                   errb))
200             return 0;
201           break;
202         }
203     }
204
205   /* When we get here, cp (aka *cpp) contains the compiled pattern,
206      either because we found it in the cache or because we just compiled it.
207      Move it to the front of the queue to mark it as most recently used.  */
208   *cpp = cp->next;
209   cp->next = searchbuf_head;
210   searchbuf_head = cp;
211
212   /* Advise the searching functions about the space we have allocated
213      for register data.  */
214   if (regp)
215     re_set_registers (&cp->buf, regp, regp->num_regs, regp->start, regp->end);
216
217   return &cp->buf;
218 }
219
220 /* Error condition used for failing searches */
221 Lisp_Object Qsearch_failed;
222
223 static Lisp_Object
224 signal_failure (Lisp_Object arg)
225 {
226   for (;;)
227     Fsignal (Qsearch_failed, list1 (arg));
228   return Qnil; /* Not reached. */
229 }
230
231 /* Convert the search registers from Bytinds to Bufpos's.  Needs to be
232    done after each regexp match that uses the search regs.
233
234    We could get a potential speedup by not converting the search registers
235    until it's really necessary, e.g. when match-data or replace-match is
236    called.  However, this complexifies the code a lot (e.g. the buffer
237    could have changed and the Bytinds stored might be invalid) and is
238    probably not a great time-saver. */
239
240 static void
241 fixup_search_regs_for_buffer (struct buffer *buf)
242 {
243   int i;
244   int num_regs = search_regs.num_regs;
245
246   for (i = 0; i < num_regs; i++)
247     {
248       if (search_regs.start[i] >= 0)
249         search_regs.start[i] = bytind_to_bufpos (buf, search_regs.start[i]);
250       if (search_regs.end[i] >= 0)
251         search_regs.end[i] = bytind_to_bufpos (buf, search_regs.end[i]);
252     }
253 }
254
255 /* Similar but for strings. */
256 static void
257 fixup_search_regs_for_string (Lisp_Object string)
258 {
259   int i;
260   int num_regs = search_regs.num_regs;
261
262   /* #### bytecount_to_charcount() is not that efficient.  This function
263      could be faster if it did its own conversion (using INC_CHARPTR()
264      and such), because the register ends are likely to be somewhat ordered.
265      (Even if not, you could sort them.)
266
267      Think about this if this function is a time hog, which it's probably
268      not. */
269   for (i = 0; i < num_regs; i++)
270     {
271       if (search_regs.start[i] > 0)
272         {
273           search_regs.start[i] =
274             bytecount_to_charcount (XSTRING_DATA (string),
275                                     search_regs.start[i]);
276         }
277       if (search_regs.end[i] > 0)
278         {
279           search_regs.end[i] =
280             bytecount_to_charcount (XSTRING_DATA (string),
281                                     search_regs.end[i]);
282         }
283     }
284 }
285
286 \f
287 static Lisp_Object
288 looking_at_1 (Lisp_Object string, struct buffer *buf, int posix)
289 {
290   /* This function has been Mule-ized, except for the trt table handling. */
291   Lisp_Object val;
292   Bytind p1, p2;
293   Bytecount s1, s2;
294   REGISTER int i;
295   struct re_pattern_buffer *bufp;
296
297   if (running_asynch_code)
298     save_search_regs ();
299
300   CHECK_STRING (string);
301   bufp = compile_pattern (string, &search_regs,
302                           (!NILP (buf->case_fold_search)
303                            ? XCASE_TABLE_DOWNCASE (buf->case_table) : Qnil),
304                           posix, ERROR_ME);
305
306   QUIT;
307
308   /* Get pointers and sizes of the two strings
309      that make up the visible portion of the buffer. */
310
311   p1 = BI_BUF_BEGV (buf);
312   p2 = BI_BUF_CEILING_OF (buf, p1);
313   s1 = p2 - p1;
314   s2 = BI_BUF_ZV (buf) - p2;
315
316   regex_emacs_buffer = buf;
317   regex_emacs_buffer_p = 1;
318   i = re_match_2 (bufp, (char *) BI_BUF_BYTE_ADDRESS (buf, p1),
319                   s1, (char *) BI_BUF_BYTE_ADDRESS (buf, p2), s2,
320                   BI_BUF_PT (buf) - BI_BUF_BEGV (buf), &search_regs,
321                   BI_BUF_ZV (buf) - BI_BUF_BEGV (buf));
322
323   if (i == -2)
324     matcher_overflow ();
325
326   val = (0 <= i ? Qt : Qnil);
327   if (NILP (val))
328     return Qnil;
329   {
330     int num_regs = search_regs.num_regs;
331     for (i = 0; i < num_regs; i++)
332       if (search_regs.start[i] >= 0)
333         {
334           search_regs.start[i] += BI_BUF_BEGV (buf);
335           search_regs.end[i] += BI_BUF_BEGV (buf);
336         }
337   }
338   XSETBUFFER (last_thing_searched, buf);
339   fixup_search_regs_for_buffer (buf);
340   return val;
341 }
342
343 DEFUN ("looking-at", Flooking_at, 1, 2, 0, /*
344 Return t if text after point matches regular expression REGEXP.
345 This function modifies the match data that `match-beginning',
346 `match-end' and `match-data' access; save and restore the match
347 data if you want to preserve them.
348
349 Optional argument BUFFER defaults to the current buffer.
350 */
351        (regexp, buffer))
352 {
353   return looking_at_1 (regexp, decode_buffer (buffer, 0), 0);
354 }
355
356 DEFUN ("posix-looking-at", Fposix_looking_at, 1, 2, 0, /*
357 Return t if text after point matches regular expression REGEXP.
358 Find the longest match, in accord with Posix regular expression rules.
359 This function modifies the match data that `match-beginning',
360 `match-end' and `match-data' access; save and restore the match
361 data if you want to preserve them.
362
363 Optional argument BUFFER defaults to the current buffer.
364 */
365        (regexp, buffer))
366 {
367   return looking_at_1 (regexp,  decode_buffer (buffer, 0), 1);
368 }
369 \f
370 static Lisp_Object
371 string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
372                 struct buffer *buf, int posix)
373 {
374   /* This function has been Mule-ized, except for the trt table handling. */
375   Bytecount val;
376   Charcount s;
377   struct re_pattern_buffer *bufp;
378
379   if (running_asynch_code)
380     save_search_regs ();
381
382   CHECK_STRING (regexp);
383   CHECK_STRING (string);
384
385   if (NILP (start))
386     s = 0;
387   else
388     {
389       Charcount len = XSTRING_CHAR_LENGTH (string);
390
391       CHECK_INT (start);
392       s = XINT (start);
393       if (s < 0 && -s <= len)
394         s = len + s;
395       else if (0 > s || s > len)
396         args_out_of_range (string, start);
397     }
398
399
400   bufp = compile_pattern (regexp, &search_regs,
401                           (!NILP (buf->case_fold_search)
402                            ? XCASE_TABLE_DOWNCASE (buf->case_table) : Qnil),
403                           0, ERROR_ME);
404   QUIT;
405   {
406     Bytecount bis = charcount_to_bytecount (XSTRING_DATA (string), s);
407     regex_emacs_buffer = buf;
408     regex_emacs_buffer_p = 0;
409     val = re_search (bufp, (char *) XSTRING_DATA (string),
410                      XSTRING_LENGTH (string), bis,
411                      XSTRING_LENGTH (string) - bis,
412                      &search_regs);
413   }
414   if (val == -2)
415     matcher_overflow ();
416   if (val < 0) return Qnil;
417   last_thing_searched = Qt;
418   fixup_search_regs_for_string (string);
419   return make_int (bytecount_to_charcount (XSTRING_DATA (string), val));
420 }
421
422 DEFUN ("string-match", Fstring_match, 2, 4, 0, /*
423 Return index of start of first match for REGEXP in STRING, or nil.
424 If third arg START is non-nil, start search at that index in STRING.
425 For index of first char beyond the match, do (match-end 0).
426 `match-end' and `match-beginning' also give indices of substrings
427 matched by parenthesis constructs in the pattern.
428
429 Optional arg BUFFER controls how case folding is done (according to
430 the value of `case-fold-search' in that buffer and that buffer's case
431 tables) and defaults to the current buffer.
432 */
433        (regexp, string, start, buffer))
434 {
435   return string_match_1 (regexp, string, start, decode_buffer (buffer, 0), 0);
436 }
437
438 DEFUN ("posix-string-match", Fposix_string_match, 2, 4, 0, /*
439 Return index of start of first match for REGEXP in STRING, or nil.
440 Find the longest match, in accord with Posix regular expression rules.
441 If third arg START is non-nil, start search at that index in STRING.
442 For index of first char beyond the match, do (match-end 0).
443 `match-end' and `match-beginning' also give indices of substrings
444 matched by parenthesis constructs in the pattern.
445
446 Optional arg BUFFER controls how case folding is done (according to
447 the value of `case-fold-search' in that buffer and that buffer's case
448 tables) and defaults to the current buffer.
449 */
450        (regexp, string, start, buffer))
451 {
452   return string_match_1 (regexp, string, start, decode_buffer (buffer, 0), 1);
453 }
454
455 /* Match REGEXP against STRING, searching all of STRING,
456    and return the index of the match, or negative on failure.
457    This does not clobber the match data. */
458
459 Bytecount
460 fast_string_match (Lisp_Object regexp,  const Bufbyte *nonreloc,
461                    Lisp_Object reloc, Bytecount offset,
462                    Bytecount length, int case_fold_search,
463                    Error_behavior errb, int no_quit)
464 {
465   /* This function has been Mule-ized, except for the trt table handling. */
466   Bytecount val;
467   Bufbyte *newnonreloc = (Bufbyte *) nonreloc;
468   struct re_pattern_buffer *bufp;
469
470   bufp = compile_pattern (regexp, 0,
471                           (case_fold_search
472                            ? XCASE_TABLE_DOWNCASE (current_buffer->case_table)
473                            : Qnil),
474                           0, errb);
475   if (!bufp)
476     return -1; /* will only do this when errb != ERROR_ME */
477   if (!no_quit)
478     QUIT;
479   else
480     no_quit_in_re_search = 1;
481
482   fixup_internal_substring (nonreloc, reloc, offset, &length);
483
484   if (!NILP (reloc))
485     {
486       if (no_quit)
487         newnonreloc = XSTRING_DATA (reloc);
488       else
489         {
490           /* QUIT could relocate RELOC.  Therefore we must alloca()
491              and copy.  No way around this except some serious
492              rewriting of re_search(). */
493           newnonreloc = (Bufbyte *) alloca (length);
494           memcpy (newnonreloc, XSTRING_DATA (reloc), length);
495         }
496     }
497
498   /* #### evil current-buffer dependency */
499   regex_emacs_buffer = current_buffer;
500   regex_emacs_buffer_p = 0;
501   val = re_search (bufp, (char *) newnonreloc + offset, length, 0,
502                    length, 0);
503
504   no_quit_in_re_search = 0;
505   return val;
506 }
507
508 Bytecount
509 fast_lisp_string_match (Lisp_Object regex, Lisp_Object string)
510 {
511   return fast_string_match (regex, 0, string, 0, -1, 0, ERROR_ME, 0);
512 }
513
514 \f
515 #ifdef REGION_CACHE_NEEDS_WORK
516 /* The newline cache: remembering which sections of text have no newlines.  */
517
518 /* If the user has requested newline caching, make sure it's on.
519    Otherwise, make sure it's off.
520    This is our cheezy way of associating an action with the change of
521    state of a buffer-local variable.  */
522 static void
523 newline_cache_on_off (struct buffer *buf)
524 {
525   if (NILP (buf->cache_long_line_scans))
526     {
527       /* It should be off.  */
528       if (buf->newline_cache)
529         {
530           free_region_cache (buf->newline_cache);
531           buf->newline_cache = 0;
532         }
533     }
534   else
535     {
536       /* It should be on.  */
537       if (buf->newline_cache == 0)
538         buf->newline_cache = new_region_cache ();
539     }
540 }
541 #endif
542 \f
543 /* Search in BUF for COUNT instances of the character TARGET between
544    START and END.
545
546    If COUNT is positive, search forwards; END must be >= START.
547    If COUNT is negative, search backwards for the -COUNTth instance;
548       END must be <= START.
549    If COUNT is zero, do anything you please; run rogue, for all I care.
550
551    If END is zero, use BEGV or ZV instead, as appropriate for the
552    direction indicated by COUNT.
553
554    If we find COUNT instances, set *SHORTAGE to zero, and return the
555    position after the COUNTth match.  Note that for reverse motion
556    this is not the same as the usual convention for Emacs motion commands.
557
558    If we don't find COUNT instances before reaching END, set *SHORTAGE
559    to the number of TARGETs left unfound, and return END.
560
561    If ALLOW_QUIT is non-zero, call QUIT periodically. */
562
563 static Bytind
564 bi_scan_buffer (struct buffer *buf, Emchar target, Bytind st, Bytind en,
565                 EMACS_INT count, EMACS_INT *shortage, int allow_quit)
566 {
567   /* This function has been Mule-ized. */
568   Bytind lim = en > 0 ? en :
569     ((count > 0) ? BI_BUF_ZV (buf) : BI_BUF_BEGV (buf));
570
571   /* #### newline cache stuff in this function not yet ported */
572
573   assert (count != 0);
574
575   if (shortage)
576     *shortage = 0;
577
578   if (count > 0)
579     {
580 #ifdef MULE
581       /* Due to the Mule representation of characters in a buffer,
582          we can simply search for characters in the range 0 - 127
583          directly.  For other characters, we do it the "hard" way.
584          Note that this way works for all characters but the other
585          way is faster. */
586       if (target >= 0200)
587         {
588           while (st < lim && count > 0)
589             {
590               if (BI_BUF_FETCH_CHAR (buf, st) == target)
591                 count--;
592               INC_BYTIND (buf, st);
593             }
594         }
595       else
596 #endif
597         {
598           while (st < lim && count > 0)
599             {
600               Bytind ceil;
601               Bufbyte *bufptr;
602
603               ceil = BI_BUF_CEILING_OF (buf, st);
604               ceil = min (lim, ceil);
605               bufptr = (Bufbyte *) memchr (BI_BUF_BYTE_ADDRESS (buf, st),
606                                            (int) target, ceil - st);
607               if (bufptr)
608                 {
609                   count--;
610                   st = BI_BUF_PTR_BYTE_POS (buf, bufptr) + 1;
611                 }
612               else
613                 st = ceil;
614             }
615         }
616
617       if (shortage)
618         *shortage = count;
619       if (allow_quit)
620         QUIT;
621       return st;
622     }
623   else
624     {
625 #ifdef MULE
626       if (target >= 0200)
627         {
628           while (st > lim && count < 0)
629             {
630               DEC_BYTIND (buf, st);
631               if (BI_BUF_FETCH_CHAR (buf, st) == target)
632                 count++;
633             }
634         }
635       else
636 #endif
637         {
638           while (st > lim && count < 0)
639             {
640               Bytind floor;
641               Bufbyte *bufptr;
642               Bufbyte *floorptr;
643
644               floor = BI_BUF_FLOOR_OF (buf, st);
645               floor = max (lim, floor);
646               /* No memrchr() ... */
647               bufptr = BI_BUF_BYTE_ADDRESS_BEFORE (buf, st);
648               floorptr = BI_BUF_BYTE_ADDRESS (buf, floor);
649               while (bufptr >= floorptr)
650                 {
651                   st--;
652                   /* At this point, both ST and BUFPTR refer to the same
653                      character.  When the loop terminates, ST will
654                      always point to the last character we tried. */
655                   if (* (unsigned char *) bufptr == (unsigned char) target)
656                     {
657                       count++;
658                       break;
659                     }
660                   bufptr--;
661                 }
662             }
663         }
664
665       if (shortage)
666         *shortage = -count;
667       if (allow_quit)
668         QUIT;
669       if (count)
670         return st;
671       else
672         {
673         /* We found the character we were looking for; we have to return
674            the position *after* it due to the strange way that the return
675            value is defined. */
676           INC_BYTIND (buf, st);
677           return st;
678         }
679     }
680 }
681
682 Bufpos
683 scan_buffer (struct buffer *buf, Emchar target, Bufpos start, Bufpos end,
684              EMACS_INT count, EMACS_INT *shortage, int allow_quit)
685 {
686   Bytind bi_retval;
687   Bytind bi_start, bi_end;
688
689   bi_start = bufpos_to_bytind (buf, start);
690   if (end)
691     bi_end = bufpos_to_bytind (buf, end);
692   else
693     bi_end = 0;
694   bi_retval = bi_scan_buffer (buf, target, bi_start, bi_end, count,
695                               shortage, allow_quit);
696   return bytind_to_bufpos (buf, bi_retval);
697 }
698
699 Bytind
700 bi_find_next_newline_no_quit (struct buffer *buf, Bytind from, int count)
701 {
702   return bi_scan_buffer (buf, '\n', from, 0, count, 0, 0);
703 }
704
705 Bufpos
706 find_next_newline_no_quit (struct buffer *buf, Bufpos from, int count)
707 {
708   return scan_buffer (buf, '\n', from, 0, count, 0, 0);
709 }
710
711 Bufpos
712 find_next_newline (struct buffer *buf, Bufpos from, int count)
713 {
714   return scan_buffer (buf, '\n', from, 0, count, 0, 1);
715 }
716
717 Bytind
718 bi_find_next_emchar_in_string (Lisp_String* str, Emchar target, Bytind st,
719                                EMACS_INT count)
720 {
721   /* This function has been Mule-ized. */
722   Bytind lim = string_length (str) -1;
723   Bufbyte* s = string_data (str);
724
725   assert (count >= 0);
726
727 #ifdef MULE
728   /* Due to the Mule representation of characters in a buffer,
729      we can simply search for characters in the range 0 - 127
730      directly.  For other characters, we do it the "hard" way.
731      Note that this way works for all characters but the other
732      way is faster. */
733   if (target >= 0200)
734     {
735       while (st < lim && count > 0)
736         {
737           if (string_char (str, st) == target)
738             count--;
739           INC_CHARBYTIND (s, st);
740         }
741     }
742   else
743 #endif
744     {
745       while (st < lim && count > 0)
746         {
747           Bufbyte *bufptr = (Bufbyte *) memchr (charptr_n_addr (s, st),
748                                                 (int) target, lim - st);
749           if (bufptr)
750             {
751               count--;
752               st =  (Bytind)(bufptr - s) + 1;
753             }
754           else
755             st = lim;
756         }
757     }
758   return st;
759 }
760
761 /* Like find_next_newline, but returns position before the newline,
762    not after, and only search up to TO.  This isn't just
763    find_next_newline (...)-1, because you might hit TO.  */
764 Bufpos
765 find_before_next_newline (struct buffer *buf, Bufpos from, Bufpos to, int count)
766 {
767   EMACS_INT shortage;
768   Bufpos pos = scan_buffer (buf, '\n', from, to, count, &shortage, 1);
769
770   if (shortage == 0)
771     pos--;
772
773   return pos;
774 }
775 \f
776 static Lisp_Object
777 skip_chars (struct buffer *buf, int forwardp, int syntaxp,
778             Lisp_Object string, Lisp_Object lim)
779 {
780   /* This function has been Mule-ized. */
781   REGISTER Bufbyte *p, *pend;
782   REGISTER Emchar c;
783   /* We store the first 256 chars in an array here and the rest in
784      a range table. */
785   unsigned char fastmap[0400];
786   int negate = 0;
787   REGISTER int i;
788 #ifdef UTF2000
789   Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->syntax_table);
790 #else
791   Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
792 #endif
793   Bufpos limit;
794
795   if (NILP (lim))
796     limit = forwardp ? BUF_ZV (buf) : BUF_BEGV (buf);
797   else
798     {
799       CHECK_INT_COERCE_MARKER (lim);
800       limit = XINT (lim);
801
802       /* In any case, don't allow scan outside bounds of buffer.  */
803       if (limit > BUF_ZV   (buf)) limit = BUF_ZV   (buf);
804       if (limit < BUF_BEGV (buf)) limit = BUF_BEGV (buf);
805     }
806
807   CHECK_STRING (string);
808   p = XSTRING_DATA (string);
809   pend = p + XSTRING_LENGTH (string);
810   memset (fastmap, 0, sizeof (fastmap));
811
812   Fclear_range_table (Vskip_chars_range_table);
813
814   if (p != pend && *p == '^')
815     {
816       negate = 1;
817       p++;
818     }
819
820   /* Find the characters specified and set their elements of fastmap.
821      If syntaxp, each character counts as itself.
822      Otherwise, handle backslashes and ranges specially  */
823
824   while (p != pend)
825     {
826       c = charptr_emchar (p);
827       INC_CHARPTR (p);
828       if (syntaxp)
829         {
830           if (c < 0400 && syntax_spec_code[c] < (unsigned char) Smax)
831             fastmap[c] = 1;
832           else
833             signal_simple_error ("Invalid syntax designator",
834                                  make_char (c));
835         }
836       else
837         {
838           if (c == '\\')
839             {
840               if (p == pend) break;
841               c = charptr_emchar (p);
842               INC_CHARPTR (p);
843             }
844           if (p != pend && *p == '-')
845             {
846               Emchar cend;
847
848               p++;
849               if (p == pend) break;
850               cend = charptr_emchar (p);
851               while (c <= cend && c < 0400)
852                 {
853                   fastmap[c] = 1;
854                   c++;
855                 }
856               if (c <= cend)
857                 Fput_range_table (make_int (c), make_int (cend), Qt,
858                                   Vskip_chars_range_table);
859               INC_CHARPTR (p);
860             }
861           else
862             {
863               if (c < 0400)
864                 fastmap[c] = 1;
865               else
866                 Fput_range_table (make_int (c), make_int (c), Qt,
867                                   Vskip_chars_range_table);
868             }
869         }
870     }
871
872   if (syntaxp && fastmap['-'] != 0)
873     fastmap[' '] = 1;
874
875   /* If ^ was the first character, complement the fastmap.
876      We don't complement the range table, however; we just use negate
877      in the comparisons below. */
878
879   if (negate)
880     for (i = 0; i < (int) (sizeof fastmap); i++)
881       fastmap[i] ^= 1;
882
883   {
884     Bufpos start_point = BUF_PT (buf);
885
886     if (syntaxp)
887       {
888         /* All syntax designators are normal chars so nothing strange
889            to worry about */
890         if (forwardp)
891           {
892             while (BUF_PT (buf) < limit
893                    && fastmap[(unsigned char)
894                               syntax_code_spec
895                               [(int) SYNTAX (syntax_table,
896                                              BUF_FETCH_CHAR
897                                              (buf, BUF_PT (buf)))]])
898               BUF_SET_PT (buf, BUF_PT (buf) + 1);
899           }
900         else
901           {
902             while (BUF_PT (buf) > limit
903                    && fastmap[(unsigned char)
904                               syntax_code_spec
905                               [(int) SYNTAX (syntax_table,
906                                              BUF_FETCH_CHAR
907                                              (buf, BUF_PT (buf) - 1))]])
908               BUF_SET_PT (buf, BUF_PT (buf) - 1);
909           }
910       }
911     else
912       {
913         if (forwardp)
914           {
915             while (BUF_PT (buf) < limit)
916               {
917                 Emchar ch = BUF_FETCH_CHAR (buf, BUF_PT (buf));
918                 if ((ch < 0400) ? fastmap[ch] :
919                     (NILP (Fget_range_table (make_int (ch),
920                                              Vskip_chars_range_table,
921                                              Qnil))
922                      == negate))
923                   BUF_SET_PT (buf, BUF_PT (buf) + 1);
924                 else
925                   break;
926               }
927           }
928         else
929           {
930             while (BUF_PT (buf) > limit)
931               {
932                 Emchar ch = BUF_FETCH_CHAR (buf, BUF_PT (buf) - 1);
933                 if ((ch < 0400) ? fastmap[ch] :
934                     (NILP (Fget_range_table (make_int (ch),
935                                              Vskip_chars_range_table,
936                                              Qnil))
937                      == negate))
938                   BUF_SET_PT (buf, BUF_PT (buf) - 1);
939                 else
940                   break;
941               }
942           }
943       }
944     QUIT;
945     return make_int (BUF_PT (buf) - start_point);
946   }
947 }
948
949 DEFUN ("skip-chars-forward", Fskip_chars_forward, 1, 3, 0, /*
950 Move point forward, stopping before a char not in STRING, or at pos LIMIT.
951 STRING is like the inside of a `[...]' in a regular expression
952 except that `]' is never special and `\\' quotes `^', `-' or `\\'.
953 Thus, with arg "a-zA-Z", this skips letters stopping before first nonletter.
954 With arg "^a-zA-Z", skips nonletters stopping before first letter.
955 Returns the distance traveled, either zero or positive.
956
957 Optional argument BUFFER defaults to the current buffer.
958 */
959        (string, limit, buffer))
960 {
961   return skip_chars (decode_buffer (buffer, 0), 1, 0, string, limit);
962 }
963
964 DEFUN ("skip-chars-backward", Fskip_chars_backward, 1, 3, 0, /*
965 Move point backward, stopping after a char not in STRING, or at pos LIMIT.
966 See `skip-chars-forward' for details.
967 Returns the distance traveled, either zero or negative.
968
969 Optional argument BUFFER defaults to the current buffer.
970 */
971        (string, limit, buffer))
972 {
973   return skip_chars (decode_buffer (buffer, 0), 0, 0, string, limit);
974 }
975
976
977 DEFUN ("skip-syntax-forward", Fskip_syntax_forward, 1, 3, 0, /*
978 Move point forward across chars in specified syntax classes.
979 SYNTAX is a string of syntax code characters.
980 Stop before a char whose syntax is not in SYNTAX, or at position LIMIT.
981 If SYNTAX starts with ^, skip characters whose syntax is NOT in SYNTAX.
982 This function returns the distance traveled, either zero or positive.
983
984 Optional argument BUFFER defaults to the current buffer.
985 */
986        (syntax, limit, buffer))
987 {
988   return skip_chars (decode_buffer (buffer, 0), 1, 1, syntax, limit);
989 }
990
991 DEFUN ("skip-syntax-backward", Fskip_syntax_backward, 1, 3, 0, /*
992 Move point backward across chars in specified syntax classes.
993 SYNTAX is a string of syntax code characters.
994 Stop on reaching a char whose syntax is not in SYNTAX, or at position LIMIT.
995 If SYNTAX starts with ^, skip characters whose syntax is NOT in SYNTAX.
996 This function returns the distance traveled, either zero or negative.
997
998 Optional argument BUFFER defaults to the current buffer.
999 */
1000        (syntax, limit, buffer))
1001 {
1002   return skip_chars (decode_buffer (buffer, 0), 0, 1, syntax, limit);
1003 }
1004
1005 \f
1006 /* Subroutines of Lisp buffer search functions. */
1007
1008 static Lisp_Object
1009 search_command (Lisp_Object string, Lisp_Object limit, Lisp_Object noerror,
1010                 Lisp_Object count, Lisp_Object buffer, int direction,
1011                 int RE, int posix)
1012 {
1013   /* This function has been Mule-ized, except for the trt table handling. */
1014   REGISTER Bufpos np;
1015   Bufpos lim;
1016   EMACS_INT n = direction;
1017   struct buffer *buf;
1018
1019   if (!NILP (count))
1020     {
1021       CHECK_INT (count);
1022       n *= XINT (count);
1023     }
1024
1025   buf = decode_buffer (buffer, 0);
1026   CHECK_STRING (string);
1027   if (NILP (limit))
1028     lim = n > 0 ? BUF_ZV (buf) : BUF_BEGV (buf);
1029   else
1030     {
1031       CHECK_INT_COERCE_MARKER (limit);
1032       lim = XINT (limit);
1033       if (n > 0 ? lim < BUF_PT (buf) : lim > BUF_PT (buf))
1034         error ("Invalid search limit (wrong side of point)");
1035       if (lim > BUF_ZV (buf))
1036         lim = BUF_ZV (buf);
1037       if (lim < BUF_BEGV (buf))
1038         lim = BUF_BEGV (buf);
1039     }
1040
1041   np = search_buffer (buf, string, BUF_PT (buf), lim, n, RE,
1042                       (!NILP (buf->case_fold_search)
1043                        ? XCASE_TABLE_CANON (buf->case_table)
1044                        : Qnil),
1045                       (!NILP (buf->case_fold_search)
1046                        ? XCASE_TABLE_EQV (buf->case_table)
1047                        : Qnil), posix);
1048
1049   if (np <= 0)
1050     {
1051       if (NILP (noerror))
1052         return signal_failure (string);
1053       if (!EQ (noerror, Qt))
1054         {
1055           if (lim < BUF_BEGV (buf) || lim > BUF_ZV (buf))
1056             abort ();
1057           BUF_SET_PT (buf, lim);
1058           return Qnil;
1059 #if 0 /* This would be clean, but maybe programs depend on
1060          a value of nil here.  */
1061           np = lim;
1062 #endif
1063         }
1064       else
1065         return Qnil;
1066     }
1067
1068   if (np < BUF_BEGV (buf) || np > BUF_ZV (buf))
1069     abort ();
1070
1071   BUF_SET_PT (buf, np);
1072
1073   return make_int (np);
1074 }
1075 \f
1076 static int
1077 trivial_regexp_p (Lisp_Object regexp)
1078 {
1079   /* This function has been Mule-ized. */
1080   Bytecount len = XSTRING_LENGTH (regexp);
1081   Bufbyte *s = XSTRING_DATA (regexp);
1082   while (--len >= 0)
1083     {
1084       switch (*s++)
1085         {
1086         case '.': case '*': case '+': case '?': case '[': case '^': case '$':
1087           return 0;
1088         case '\\':
1089           if (--len < 0)
1090             return 0;
1091           switch (*s++)
1092             {
1093             case '|': case '(': case ')': case '`': case '\'': case 'b':
1094             case 'B': case '<': case '>': case 'w': case 'W': case 's':
1095             case 'S': case '=':
1096 #ifdef MULE
1097             /* 97/2/25 jhod Added for category matches */
1098             case 'c': case 'C':
1099 #endif /* MULE */
1100             case '1': case '2': case '3': case '4': case '5':
1101             case '6': case '7': case '8': case '9':
1102               return 0;
1103             }
1104         }
1105     }
1106   return 1;
1107 }
1108
1109 /* Search for the n'th occurrence of STRING in BUF,
1110    starting at position BUFPOS and stopping at position BUFLIM,
1111    treating PAT as a literal string if RE is false or as
1112    a regular expression if RE is true.
1113
1114    If N is positive, searching is forward and BUFLIM must be greater
1115    than BUFPOS.
1116    If N is negative, searching is backward and BUFLIM must be less
1117    than BUFPOS.
1118
1119    Returns -x if only N-x occurrences found (x > 0),
1120    or else the position at the beginning of the Nth occurrence
1121    (if searching backward) or the end (if searching forward).
1122
1123    POSIX is nonzero if we want full backtracking (POSIX style)
1124    for this pattern.  0 means backtrack only enough to get a valid match.  */
1125 static Bufpos
1126 search_buffer (struct buffer *buf, Lisp_Object string, Bufpos bufpos,
1127                Bufpos buflim, EMACS_INT n, int RE, Lisp_Object trt,
1128                Lisp_Object inverse_trt, int posix)
1129 {
1130   /* This function has been Mule-ized, except for the trt table handling. */
1131   Bytecount len = XSTRING_LENGTH (string);
1132   Bufbyte *base_pat = XSTRING_DATA (string);
1133   REGISTER EMACS_INT i, j;
1134   Bytind p1, p2;
1135   Bytecount s1, s2;
1136   Bytind pos, lim;
1137
1138   if (running_asynch_code)
1139     save_search_regs ();
1140
1141   /* Null string is found at starting position.  */
1142   if (len == 0)
1143     {
1144       set_search_regs (buf, bufpos, 0);
1145       return bufpos;
1146     }
1147
1148   /* Searching 0 times means don't move.  */
1149   if (n == 0)
1150     return bufpos;
1151
1152   pos = bufpos_to_bytind (buf, bufpos);
1153   lim = bufpos_to_bytind (buf, buflim);
1154   if (RE && !trivial_regexp_p (string))
1155     {
1156       struct re_pattern_buffer *bufp;
1157
1158       bufp = compile_pattern (string, &search_regs, trt, posix,
1159                               ERROR_ME);
1160
1161       /* Get pointers and sizes of the two strings
1162          that make up the visible portion of the buffer. */
1163
1164       p1 = BI_BUF_BEGV (buf);
1165       p2 = BI_BUF_CEILING_OF (buf, p1);
1166       s1 = p2 - p1;
1167       s2 = BI_BUF_ZV (buf) - p2;
1168
1169       while (n < 0)
1170         {
1171           Bytecount val;
1172           QUIT;
1173           regex_emacs_buffer = buf;
1174           regex_emacs_buffer_p = 1;
1175           val = re_search_2 (bufp,
1176                              (char *) BI_BUF_BYTE_ADDRESS (buf, p1), s1,
1177                              (char *) BI_BUF_BYTE_ADDRESS (buf, p2), s2,
1178                              pos - BI_BUF_BEGV (buf), lim - pos, &search_regs,
1179                              pos - BI_BUF_BEGV (buf));
1180
1181           if (val == -2)
1182             {
1183               matcher_overflow ();
1184             }
1185           if (val >= 0)
1186             {
1187               int num_regs = search_regs.num_regs;
1188               j = BI_BUF_BEGV (buf);
1189               for (i = 0; i < num_regs; i++)
1190                 if (search_regs.start[i] >= 0)
1191                   {
1192                     search_regs.start[i] += j;
1193                     search_regs.end[i] += j;
1194                   }
1195               XSETBUFFER (last_thing_searched, buf);
1196               /* Set pos to the new position. */
1197               pos = search_regs.start[0];
1198               fixup_search_regs_for_buffer (buf);
1199               /* And bufpos too. */
1200               bufpos = search_regs.start[0];
1201             }
1202           else
1203             {
1204               return n;
1205             }
1206           n++;
1207         }
1208       while (n > 0)
1209         {
1210           Bytecount val;
1211           QUIT;
1212           regex_emacs_buffer = buf;
1213           regex_emacs_buffer_p = 1;
1214           val = re_search_2 (bufp,
1215                              (char *) BI_BUF_BYTE_ADDRESS (buf, p1), s1,
1216                              (char *) BI_BUF_BYTE_ADDRESS (buf, p2), s2,
1217                              pos - BI_BUF_BEGV (buf), lim - pos, &search_regs,
1218                              lim - BI_BUF_BEGV (buf));
1219           if (val == -2)
1220             {
1221               matcher_overflow ();
1222             }
1223           if (val >= 0)
1224             {
1225               int num_regs = search_regs.num_regs;
1226               j = BI_BUF_BEGV (buf);
1227               for (i = 0; i < num_regs; i++)
1228                 if (search_regs.start[i] >= 0)
1229                   {
1230                     search_regs.start[i] += j;
1231                     search_regs.end[i] += j;
1232                   }
1233               XSETBUFFER (last_thing_searched, buf);
1234               /* Set pos to the new position. */
1235               pos = search_regs.end[0];
1236               fixup_search_regs_for_buffer (buf);
1237               /* And bufpos too. */
1238               bufpos = search_regs.end[0];
1239             }
1240           else
1241             {
1242               return 0 - n;
1243             }
1244           n--;
1245         }
1246       return bufpos;
1247     }
1248   else                          /* non-RE case */
1249     {
1250       int charset_base = -1;
1251       int boyer_moore_ok = 1;
1252       Bufbyte *pat = 0;
1253       Bufbyte *patbuf = alloca_array (Bufbyte, len * MAX_EMCHAR_LEN);
1254       pat = patbuf;
1255 #ifdef MULE
1256       while (len > 0)
1257         {
1258           Bufbyte tmp_str[MAX_EMCHAR_LEN];
1259           Emchar c, translated, inverse;
1260           Bytecount orig_bytelen, new_bytelen, inv_bytelen;
1261
1262           /* If we got here and the RE flag is set, it's because
1263              we're dealing with a regexp known to be trivial, so the
1264              backslash just quotes the next character.  */
1265           if (RE && *base_pat == '\\')
1266             {
1267               len--;
1268               base_pat++;
1269             }
1270           c = charptr_emchar (base_pat);
1271           translated = TRANSLATE (trt, c);
1272           inverse = TRANSLATE (inverse_trt, c);
1273
1274           orig_bytelen = charcount_to_bytecount (base_pat, 1);
1275           inv_bytelen = set_charptr_emchar (tmp_str, inverse);
1276           new_bytelen = set_charptr_emchar (tmp_str, translated);
1277
1278
1279           if (new_bytelen != orig_bytelen || inv_bytelen != orig_bytelen)
1280             boyer_moore_ok = 0;
1281           if (translated != c || inverse != c)
1282             {
1283               /* Keep track of which character set row
1284                  contains the characters that need translation.  */
1285 #ifdef UTF2000
1286               int charset_base_code = c >> 6;
1287 #else
1288               int charset_base_code = c & ~CHAR_FIELD3_MASK;
1289 #endif
1290               if (charset_base == -1)
1291                 charset_base = charset_base_code;
1292               else if (charset_base != charset_base_code)
1293                 /* If two different rows appear, needing translation,
1294                    then we cannot use boyer_moore search.  */
1295                 boyer_moore_ok = 0;
1296             }
1297           memcpy (pat, tmp_str, new_bytelen);
1298           pat += new_bytelen;
1299           base_pat += orig_bytelen;
1300           len -= orig_bytelen;
1301         }
1302 #else /* not MULE */
1303       while (--len >= 0)
1304         {
1305           /* If we got here and the RE flag is set, it's because
1306              we're dealing with a regexp known to be trivial, so the
1307              backslash just quotes the next character.  */
1308           if (RE && *base_pat == '\\')
1309             {
1310               len--;
1311               base_pat++;
1312             }
1313           *pat++ = TRANSLATE (trt, *base_pat++);
1314         }
1315 #endif /* MULE */
1316       len = pat - patbuf;
1317       pat = base_pat = patbuf;
1318       if (boyer_moore_ok)
1319         return boyer_moore (buf, base_pat, len, pos, lim, n,
1320                             trt, inverse_trt, charset_base);
1321       else
1322         return simple_search (buf, base_pat, len, pos, lim, n, trt);
1323     }
1324 }
1325
1326 /* Do a simple string search N times for the string PAT,
1327    whose length is LEN/LEN_BYTE,
1328    from buffer position POS/POS_BYTE until LIM/LIM_BYTE.
1329    TRT is the translation table.
1330
1331    Return the character position where the match is found.
1332    Otherwise, if M matches remained to be found, return -M.
1333
1334    This kind of search works regardless of what is in PAT and
1335    regardless of what is in TRT.  It is used in cases where
1336    boyer_moore cannot work.  */
1337
1338 static Bufpos
1339 simple_search (struct buffer *buf, Bufbyte *base_pat, Bytecount len_byte,
1340                Bytind idx, Bytind lim, EMACS_INT n, Lisp_Object trt)
1341 {
1342   int forward = n > 0;
1343   Bytecount buf_len = 0; /* Shut up compiler. */
1344
1345   if (lim > idx)
1346     while (n > 0)
1347       {
1348         while (1)
1349           {
1350             Bytecount this_len = len_byte;
1351             Bytind this_idx = idx;
1352             Bufbyte *p = base_pat;
1353             if (idx >= lim)
1354               goto stop;
1355
1356             while (this_len > 0)
1357               {
1358                 Emchar pat_ch, buf_ch;
1359                 Bytecount pat_len;
1360
1361                 pat_ch = charptr_emchar (p);
1362                 buf_ch = BI_BUF_FETCH_CHAR (buf, this_idx);
1363
1364                 buf_ch = TRANSLATE (trt, buf_ch);
1365
1366                 if (buf_ch != pat_ch)
1367                   break;
1368
1369                 pat_len = charcount_to_bytecount (p, 1);
1370                 p += pat_len;
1371                 this_len -= pat_len;
1372                 INC_BYTIND (buf, this_idx);
1373               }
1374             if (this_len == 0)
1375               {
1376                 buf_len = this_idx - idx;
1377                 idx = this_idx;
1378                 break;
1379               }
1380             INC_BYTIND (buf, idx);
1381           }
1382         n--;
1383       }
1384   else
1385     while (n < 0)
1386       {
1387         while (1)
1388           {
1389             Bytecount this_len = len_byte;
1390             Bytind this_idx = idx;
1391             Bufbyte *p;
1392             if (idx <= lim)
1393               goto stop;
1394             p = base_pat + len_byte;
1395
1396             while (this_len > 0)
1397               {
1398                 Emchar pat_ch, buf_ch;
1399
1400                 DEC_CHARPTR (p);
1401                 DEC_BYTIND (buf, this_idx);
1402                 pat_ch = charptr_emchar (p);
1403                 buf_ch = BI_BUF_FETCH_CHAR (buf, this_idx);
1404
1405                 buf_ch = TRANSLATE (trt, buf_ch);
1406
1407                 if (buf_ch != pat_ch)
1408                   break;
1409
1410                 this_len -= charcount_to_bytecount (p, 1);
1411               }
1412             if (this_len == 0)
1413               {
1414                 buf_len = idx - this_idx;
1415                 idx = this_idx;
1416                 break;
1417               }
1418             DEC_BYTIND (buf, idx);
1419           }
1420         n++;
1421       }
1422  stop:
1423   if (n == 0)
1424     {
1425       Bufpos beg, end, retval;
1426       if (forward)
1427         {
1428           beg = bytind_to_bufpos (buf, idx - buf_len);
1429           retval = end = bytind_to_bufpos (buf, idx);
1430         }
1431       else
1432         {
1433           retval = beg = bytind_to_bufpos (buf, idx);
1434           end = bytind_to_bufpos (buf, idx + buf_len);
1435         }
1436       set_search_regs (buf, beg, end - beg);
1437
1438       return retval;
1439     }
1440   else if (n > 0)
1441     return -n;
1442   else
1443     return n;
1444 }
1445
1446 /* Do Boyer-Moore search N times for the string PAT,
1447    whose length is LEN/LEN_BYTE,
1448    from buffer position POS/POS_BYTE until LIM/LIM_BYTE.
1449    DIRECTION says which direction we search in.
1450    TRT and INVERSE_TRT are translation tables.
1451
1452    This kind of search works if all the characters in PAT that have
1453    nontrivial translation are the same aside from the last byte.  This
1454    makes it possible to translate just the last byte of a character,
1455    and do so after just a simple test of the context.
1456
1457    If that criterion is not satisfied, do not call this function.  */
1458             
1459 static Bufpos
1460 boyer_moore (struct buffer *buf, Bufbyte *base_pat, Bytecount len,
1461              Bytind pos, Bytind lim, EMACS_INT n, Lisp_Object trt,
1462              Lisp_Object inverse_trt, int charset_base)
1463 {
1464   /* #### Someone really really really needs to comment the workings
1465      of this junk somewhat better.
1466
1467      BTW "BM" stands for Boyer-Moore, which is one of the standard
1468      string-searching algorithms.  It's the best string-searching
1469      algorithm out there, provided that:
1470
1471      a) You're not fazed by algorithm complexity. (Rabin-Karp, which
1472      uses hashing, is much much easier to code but not as fast.)
1473      b) You can freely move backwards in the string that you're
1474      searching through.
1475
1476      As the comment below tries to explain (but garbles in typical
1477      programmer-ese), the idea is that you don't have to do a
1478      string match at every successive position in the text.  For
1479      example, let's say the pattern is "a very long string".  We
1480      compare the last character in the string (`g') with the
1481      corresponding character in the text.  If it mismatches, and
1482      it is, say, `z', then we can skip forward by the entire
1483      length of the pattern because `z' does not occur anywhere
1484      in the pattern.  If the mismatching character does occur
1485      in the pattern, we can usually still skip forward by more
1486      than one: e.g. if it is `l', then we can skip forward
1487      by the length of the substring "ong string" -- i.e. the
1488      largest end section of the pattern that does not contain
1489      the mismatched character.  So what we do is compute, for
1490      each possible character, the distance we can skip forward
1491      (the "stride") and use it in the string matching.  This
1492      is what the BM_tab holds. */
1493   REGISTER EMACS_INT *BM_tab;
1494   EMACS_INT *BM_tab_base;
1495   REGISTER Bytecount dirlen;
1496   EMACS_INT infinity;
1497   Bytind limit;
1498   Bytecount stride_for_teases = 0;
1499   REGISTER EMACS_INT i, j;
1500   Bufbyte *pat, *pat_end;
1501   REGISTER Bufbyte *cursor, *p_limit, *ptr2;
1502   Bufbyte simple_translate[0400];
1503   REGISTER int direction = ((n > 0) ? 1 : -1);
1504 #ifdef MULE
1505   Bufbyte translate_prev_byte = 0;
1506   Bufbyte translate_anteprev_byte = 0;
1507 #endif
1508 #ifdef C_ALLOCA
1509   EMACS_INT BM_tab_space[0400];
1510   BM_tab = &BM_tab_space[0];
1511 #else
1512   BM_tab = alloca_array (EMACS_INT, 256);
1513 #endif
1514   
1515   /* The general approach is that we are going to maintain that we
1516      know the first (closest to the present position, in whatever
1517      direction we're searching) character that could possibly be
1518      the last (furthest from present position) character of a
1519      valid match.  We advance the state of our knowledge by
1520      looking at that character and seeing whether it indeed
1521      matches the last character of the pattern.  If it does, we
1522      take a closer look.  If it does not, we move our pointer (to
1523      putative last characters) as far as is logically possible.
1524      This amount of movement, which I call a stride, will be the
1525      length of the pattern if the actual character appears nowhere
1526      in the pattern, otherwise it will be the distance from the
1527      last occurrence of that character to the end of the pattern.
1528      As a coding trick, an enormous stride is coded into the table
1529      for characters that match the last character.  This allows
1530      use of only a single test, a test for having gone past the
1531      end of the permissible match region, to test for both
1532      possible matches (when the stride goes past the end
1533      immediately) and failure to match (where you get nudged past
1534      the end one stride at a time).
1535
1536      Here we make a "mickey mouse" BM table.  The stride of the
1537      search is determined only by the last character of the
1538      putative match.  If that character does not match, we will
1539      stride the proper distance to propose a match that
1540      superimposes it on the last instance of a character that
1541      matches it (per trt), or misses it entirely if there is
1542      none. */
1543
1544   dirlen = len * direction;
1545   infinity = dirlen - (lim + pos + len + len) * direction;
1546   /* Record position after the end of the pattern.  */
1547   pat_end = base_pat + len;
1548   if (direction < 0)
1549     base_pat = pat_end - 1;
1550   BM_tab_base = BM_tab;
1551   BM_tab += 0400;
1552   j = dirlen;           /* to get it in a register */
1553   /* A character that does not appear in the pattern induces a
1554      stride equal to the pattern length. */
1555   while (BM_tab_base != BM_tab)
1556     {
1557       *--BM_tab = j;
1558       *--BM_tab = j;
1559       *--BM_tab = j;
1560       *--BM_tab = j;
1561     }
1562   /* We use this for translation, instead of TRT itself.  We
1563      fill this in to handle the characters that actually occur
1564      in the pattern.  Others don't matter anyway!  */
1565   xzero (simple_translate);
1566   for (i = 0; i < 0400; i++)
1567     simple_translate[i] = i;
1568   i = 0;
1569   while (i != infinity)
1570     {
1571       Bufbyte *ptr = base_pat + i;
1572       i += direction;
1573       if (i == dirlen)
1574         i = infinity;
1575       if (!NILP (trt))
1576         {
1577 #ifdef MULE
1578           Emchar ch, untranslated;
1579           int this_translated = 1;
1580
1581           /* Is *PTR the last byte of a character?  */
1582           if (pat_end - ptr == 1 || BUFBYTE_FIRST_BYTE_P (ptr[1]))
1583             {
1584               Bufbyte *charstart = ptr;
1585               while (!BUFBYTE_FIRST_BYTE_P (*charstart))
1586                 charstart--;
1587               untranslated = charptr_emchar (charstart);
1588 #ifdef UTF2000
1589               if (charset_base == (untranslated >> 6))
1590 #else
1591               if (charset_base == (untranslated & ~CHAR_FIELD3_MASK))
1592 #endif
1593                 {
1594                   ch = TRANSLATE (trt, untranslated);
1595                   if (!BUFBYTE_FIRST_BYTE_P (*ptr))
1596                     {
1597                       translate_prev_byte = ptr[-1];
1598                       if (!BUFBYTE_FIRST_BYTE_P (translate_prev_byte))
1599                         translate_anteprev_byte = ptr[-2];
1600                     }
1601                 }
1602               else
1603                 {
1604                   this_translated = 0;
1605                   ch = *ptr;
1606                 }
1607             }
1608           else
1609             {
1610               ch = *ptr;
1611               this_translated = 0;
1612             }
1613           if (ch > 0400)
1614             j = ((unsigned char) ch | 0200);
1615           else
1616             j = (unsigned char) ch;
1617               
1618           if (i == infinity)
1619             stride_for_teases = BM_tab[j];
1620           BM_tab[j] = dirlen - i;
1621           /* A translation table is accompanied by its inverse --
1622              see comment following downcase_table for details */
1623           if (this_translated)
1624             {
1625               Emchar starting_ch = ch;
1626               EMACS_INT starting_j = j;
1627               while (1)
1628                 {
1629                   ch = TRANSLATE (inverse_trt, ch);
1630                   if (ch > 0400)
1631                     j = ((unsigned char) ch | 0200);
1632                   else
1633                     j = (unsigned char) ch;
1634
1635                   /* For all the characters that map into CH,
1636                      set up simple_translate to map the last byte
1637                      into STARTING_J.  */
1638                   simple_translate[j] = starting_j;
1639                   if (ch == starting_ch)
1640                     break;
1641                   BM_tab[j] = dirlen - i;
1642                 }
1643             }
1644 #else
1645           EMACS_INT k;
1646           j = *ptr;
1647           k = (j = TRANSLATE (trt, j));
1648           if (i == infinity)
1649             stride_for_teases = BM_tab[j];
1650           BM_tab[j] = dirlen - i;
1651           /* A translation table is accompanied by its inverse --
1652              see comment following downcase_table for details */
1653
1654           while ((j = TRANSLATE (inverse_trt, j)) != k)
1655             {
1656               simple_translate[j] = k;
1657               BM_tab[j] = dirlen - i;
1658             }
1659 #endif
1660         }
1661       else
1662         {
1663           j = *ptr;
1664
1665           if (i == infinity)
1666             stride_for_teases = BM_tab[j];
1667           BM_tab[j] = dirlen - i;
1668         }
1669       /* stride_for_teases tells how much to stride if we get a
1670          match on the far character but are subsequently
1671          disappointed, by recording what the stride would have been
1672          for that character if the last character had been
1673          different. */
1674     }
1675   infinity = dirlen - infinity;
1676   pos += dirlen - ((direction > 0) ? direction : 0);
1677   /* loop invariant - pos points at where last char (first char if
1678      reverse) of pattern would align in a possible match.  */
1679   while (n != 0)
1680     {
1681       Bytind tail_end;
1682       Bufbyte *tail_end_ptr;
1683       /* It's been reported that some (broken) compiler thinks
1684          that Boolean expressions in an arithmetic context are
1685          unsigned.  Using an explicit ?1:0 prevents this.  */
1686       if ((lim - pos - ((direction > 0) ? 1 : 0)) * direction < 0)
1687         return n * (0 - direction);
1688       /* First we do the part we can by pointers (maybe
1689          nothing) */
1690       QUIT;
1691       pat = base_pat;
1692       limit = pos - dirlen + direction;
1693       /* XEmacs change: definitions of CEILING_OF and FLOOR_OF
1694          have changed.  See buffer.h. */
1695       limit = ((direction > 0)
1696                ? BI_BUF_CEILING_OF (buf, limit) - 1
1697                : BI_BUF_FLOOR_OF (buf, limit + 1));
1698       /* LIMIT is now the last (not beyond-last!) value POS can
1699          take on without hitting edge of buffer or the gap.  */
1700       limit = ((direction > 0)
1701                ? min (lim - 1, min (limit, pos + 20000))
1702                : max (lim, max (limit, pos - 20000)));
1703       tail_end = BI_BUF_CEILING_OF (buf, pos);
1704       tail_end_ptr = BI_BUF_BYTE_ADDRESS (buf, tail_end);
1705
1706       if ((limit - pos) * direction > 20)
1707         {
1708           p_limit = BI_BUF_BYTE_ADDRESS (buf, limit);
1709           ptr2 = (cursor = BI_BUF_BYTE_ADDRESS (buf, pos));
1710           /* In this loop, pos + cursor - ptr2 is the surrogate
1711              for pos */
1712           while (1)     /* use one cursor setting as long as i can */
1713             {
1714               if (direction > 0) /* worth duplicating */
1715                 {
1716                   /* Use signed comparison if appropriate to make
1717                      cursor+infinity sure to be > p_limit.
1718                      Assuming that the buffer lies in a range of
1719                      addresses that are all "positive" (as ints)
1720                      or all "negative", either kind of comparison
1721                      will work as long as we don't step by
1722                      infinity.  So pick the kind that works when
1723                      we do step by infinity.  */
1724                   if ((EMACS_INT) (p_limit + infinity) >
1725                       (EMACS_INT) p_limit)
1726                     while ((EMACS_INT) cursor <=
1727                            (EMACS_INT) p_limit)
1728                       cursor += BM_tab[*cursor];
1729                   else
1730                     while ((EMACS_UINT) cursor <=
1731                            (EMACS_UINT) p_limit)
1732                       cursor += BM_tab[*cursor];
1733                 }
1734               else
1735                 {
1736                   if ((EMACS_INT) (p_limit + infinity) <
1737                       (EMACS_INT) p_limit)
1738                     while ((EMACS_INT) cursor >=
1739                            (EMACS_INT) p_limit)
1740                       cursor += BM_tab[*cursor];
1741                   else
1742                     while ((EMACS_UINT) cursor >=
1743                            (EMACS_UINT) p_limit)
1744                       cursor += BM_tab[*cursor];
1745                 }
1746               /* If you are here, cursor is beyond the end of the
1747                  searched region.  This can happen if you match on
1748                  the far character of the pattern, because the
1749                  "stride" of that character is infinity, a number
1750                  able to throw you well beyond the end of the
1751                  search.  It can also happen if you fail to match
1752                  within the permitted region and would otherwise
1753                  try a character beyond that region */
1754               if ((cursor - p_limit) * direction <= len)
1755                 break;  /* a small overrun is genuine */
1756               cursor -= infinity; /* large overrun = hit */
1757               i = dirlen - direction;
1758               if (!NILP (trt))
1759                 {
1760                   while ((i -= direction) + direction != 0)
1761                     {
1762 #ifdef MULE
1763                       Emchar ch;
1764                       cursor -= direction;
1765                       /* Translate only the last byte of a character.  */
1766                       if ((cursor == tail_end_ptr
1767                            || BUFBYTE_FIRST_BYTE_P (cursor[1]))
1768                           && (BUFBYTE_FIRST_BYTE_P (cursor[0])
1769                               || (translate_prev_byte == cursor[-1]
1770                                   && (BUFBYTE_FIRST_BYTE_P (translate_prev_byte)
1771                                       || translate_anteprev_byte == cursor[-2]))))
1772                         ch = simple_translate[*cursor];
1773                       else
1774                         ch = *cursor;
1775                       if (pat[i] != ch)
1776                         break;
1777 #else
1778                       if (pat[i] != TRANSLATE (trt, *(cursor -= direction)))
1779                         break;
1780 #endif
1781                     }
1782                 }
1783               else
1784                 {
1785                   while ((i -= direction) + direction != 0)
1786                     if (pat[i] != *(cursor -= direction))
1787                       break;
1788                 }
1789               cursor += dirlen - i - direction; /* fix cursor */
1790               if (i + direction == 0)
1791                 {
1792                   cursor -= direction;
1793
1794                   {
1795                     Bytind bytstart = (pos + cursor - ptr2 +
1796                                        ((direction > 0)
1797                                         ? 1 - len : 0));
1798                     Bufpos bufstart = bytind_to_bufpos (buf, bytstart);
1799                     Bufpos bufend = bytind_to_bufpos (buf, bytstart + len);
1800
1801                     set_search_regs (buf, bufstart, bufend - bufstart);
1802                   }
1803
1804                   if ((n -= direction) != 0)
1805                     cursor += dirlen; /* to resume search */
1806                   else
1807                     return ((direction > 0)
1808                             ? search_regs.end[0] : search_regs.start[0]);
1809                 }
1810               else
1811                 cursor += stride_for_teases; /* <sigh> we lose -  */
1812             }
1813           pos += cursor - ptr2;
1814         }
1815       else
1816         /* Now we'll pick up a clump that has to be done the hard
1817            way because it covers a discontinuity */
1818         {
1819           /* XEmacs change: definitions of CEILING_OF and FLOOR_OF
1820              have changed.  See buffer.h. */
1821           limit = ((direction > 0)
1822                    ? BI_BUF_CEILING_OF (buf, pos - dirlen + 1) - 1
1823                    : BI_BUF_FLOOR_OF (buf, pos - dirlen));
1824           limit = ((direction > 0)
1825                    ? min (limit + len, lim - 1)
1826                    : max (limit - len, lim));
1827           /* LIMIT is now the last value POS can have
1828              and still be valid for a possible match.  */
1829           while (1)
1830             {
1831               /* This loop can be coded for space rather than
1832                  speed because it will usually run only once.
1833                  (the reach is at most len + 21, and typically
1834                  does not exceed len) */
1835               while ((limit - pos) * direction >= 0)
1836                 /* *not* BI_BUF_FETCH_CHAR.  We are working here
1837                    with bytes, not characters. */
1838                 pos += BM_tab[*BI_BUF_BYTE_ADDRESS (buf, pos)];
1839               /* now run the same tests to distinguish going off
1840                  the end, a match or a phony match. */
1841               if ((pos - limit) * direction <= len)
1842                 break;  /* ran off the end */
1843               /* Found what might be a match.
1844                  Set POS back to last (first if reverse) char pos.  */
1845               pos -= infinity;
1846               i = dirlen - direction;
1847               while ((i -= direction) + direction != 0)
1848                 {
1849 #ifdef MULE
1850                   Emchar ch;
1851                   Bufbyte *ptr;
1852 #endif
1853                   pos -= direction;
1854 #ifdef MULE
1855                   ptr = BI_BUF_BYTE_ADDRESS (buf, pos);
1856                   if ((ptr == tail_end_ptr
1857                        || BUFBYTE_FIRST_BYTE_P (ptr[1]))
1858                       && (BUFBYTE_FIRST_BYTE_P (ptr[0])
1859                           || (translate_prev_byte == ptr[-1]
1860                               && (BUFBYTE_FIRST_BYTE_P (translate_prev_byte)
1861                                   || translate_anteprev_byte == ptr[-2]))))
1862                     ch = simple_translate[*ptr];
1863                   else
1864                     ch = *ptr;
1865                   if (pat[i] != ch)
1866                     break;
1867                       
1868 #else
1869                   if (pat[i] != TRANSLATE (trt,
1870                                            *BI_BUF_BYTE_ADDRESS (buf, pos)))
1871                     break;
1872 #endif
1873                 }
1874               /* Above loop has moved POS part or all the way back
1875                  to the first char pos (last char pos if reverse).
1876                  Set it once again at the last (first if reverse)
1877                  char.  */
1878               pos += dirlen - i- direction;
1879               if (i + direction == 0)
1880                 {
1881                   pos -= direction;
1882
1883                   {
1884                     Bytind bytstart = (pos +
1885                                        ((direction > 0)
1886                                         ? 1 - len : 0));
1887                     Bufpos bufstart = bytind_to_bufpos (buf, bytstart);
1888                     Bufpos bufend = bytind_to_bufpos (buf, bytstart + len);
1889
1890                     set_search_regs (buf, bufstart, bufend - bufstart);
1891                   }
1892
1893                   if ((n -= direction) != 0)
1894                     pos += dirlen; /* to resume search */
1895                   else
1896                     return ((direction > 0)
1897                             ? search_regs.end[0] : search_regs.start[0]);
1898                 }
1899               else
1900                 pos += stride_for_teases;
1901             }
1902         }
1903       /* We have done one clump.  Can we continue? */
1904       if ((lim - pos) * direction < 0)
1905         return (0 - n) * direction;
1906     }
1907   return bytind_to_bufpos (buf, pos);
1908 }
1909
1910 /* Record beginning BEG and end BEG + LEN
1911    for a match just found in the current buffer.  */
1912
1913 static void
1914 set_search_regs (struct buffer *buf, Bufpos beg, Charcount len)
1915 {
1916   /* This function has been Mule-ized. */
1917   /* Make sure we have registers in which to store
1918      the match position.  */
1919   if (search_regs.num_regs == 0)
1920     {
1921       search_regs.start = xnew (regoff_t);
1922       search_regs.end   = xnew (regoff_t);
1923       search_regs.num_regs = 1;
1924     }
1925
1926   search_regs.start[0] = beg;
1927   search_regs.end[0] = beg + len;
1928   XSETBUFFER (last_thing_searched, buf);
1929 }
1930
1931 \f
1932 /* Given a string of words separated by word delimiters,
1933    compute a regexp that matches those exact words
1934    separated by arbitrary punctuation.  */
1935
1936 static Lisp_Object
1937 wordify (Lisp_Object buffer, Lisp_Object string)
1938 {
1939   Charcount i, len;
1940   EMACS_INT punct_count = 0, word_count = 0;
1941   struct buffer *buf = decode_buffer (buffer, 0);
1942 #ifdef UTF2000
1943   Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->syntax_table);
1944 #else
1945   Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
1946 #endif
1947
1948   CHECK_STRING (string);
1949   len = XSTRING_CHAR_LENGTH (string);
1950
1951   for (i = 0; i < len; i++)
1952     if (!WORD_SYNTAX_P (syntax_table, string_char (XSTRING (string), i)))
1953       {
1954         punct_count++;
1955         if (i > 0 && WORD_SYNTAX_P (syntax_table,
1956                                     string_char (XSTRING (string), i - 1)))
1957           word_count++;
1958       }
1959   if (WORD_SYNTAX_P (syntax_table, string_char (XSTRING (string), len - 1)))
1960     word_count++;
1961   if (!word_count) return build_string ("");
1962
1963   {
1964     /* The following value is an upper bound on the amount of storage we
1965        need.  In non-Mule, it is exact. */
1966     Bufbyte *storage =
1967       (Bufbyte *) alloca (XSTRING_LENGTH (string) - punct_count +
1968                           5 * (word_count - 1) + 4);
1969     Bufbyte *o = storage;
1970
1971     *o++ = '\\';
1972     *o++ = 'b';
1973
1974     for (i = 0; i < len; i++)
1975       {
1976         Emchar ch = string_char (XSTRING (string), i);
1977
1978         if (WORD_SYNTAX_P (syntax_table, ch))
1979           o += set_charptr_emchar (o, ch);
1980         else if (i > 0
1981                  && WORD_SYNTAX_P (syntax_table,
1982                                    string_char (XSTRING (string), i - 1))
1983                  && --word_count)
1984           {
1985             *o++ = '\\';
1986             *o++ = 'W';
1987             *o++ = '\\';
1988             *o++ = 'W';
1989             *o++ = '*';
1990           }
1991       }
1992
1993     *o++ = '\\';
1994     *o++ = 'b';
1995
1996     return make_string (storage, o - storage);
1997   }
1998 }
1999 \f
2000 DEFUN ("search-backward", Fsearch_backward, 1, 5, "sSearch backward: ", /*
2001 Search backward from point for STRING.
2002 Set point to the beginning of the occurrence found, and return point.
2003
2004 Optional second argument LIMIT bounds the search; it is a buffer
2005 position.  The match found must not extend before that position.
2006 The value nil is equivalent to (point-min).
2007
2008 Optional third argument NOERROR, if t, means just return nil (no
2009 error) if the search fails.  If neither nil nor t, set point to LIMIT
2010 and return nil.
2011
2012 Optional fourth argument COUNT is a repeat count--search for
2013 successive occurrences.
2014
2015 Optional fifth argument BUFFER specifies the buffer to search in and
2016 defaults to the current buffer.
2017
2018 See also the functions `match-beginning', `match-end' and `replace-match'.
2019 */
2020        (string, limit, noerror, count, buffer))
2021 {
2022   return search_command (string, limit, noerror, count, buffer, -1, 0, 0);
2023 }
2024
2025 DEFUN ("search-forward", Fsearch_forward, 1, 5, "sSearch: ", /*
2026 Search forward from point for STRING.
2027 Set point to the end of the occurrence found, and return point.
2028
2029 Optional second argument LIMIT bounds the search; it is a buffer
2030 position.  The match found must not extend after that position.  The
2031 value nil is equivalent to (point-max).
2032
2033 Optional third argument NOERROR, if t, means just return nil (no
2034 error) if the search fails.  If neither nil nor t, set point to LIMIT
2035 and return nil.
2036
2037 Optional fourth argument COUNT is a repeat count--search for
2038 successive occurrences.
2039
2040 Optional fifth argument BUFFER specifies the buffer to search in and
2041 defaults to the current buffer.
2042
2043 See also the functions `match-beginning', `match-end' and `replace-match'.
2044 */
2045        (string, limit, noerror, count, buffer))
2046 {
2047   return search_command (string, limit, noerror, count, buffer, 1, 0, 0);
2048 }
2049
2050 DEFUN ("word-search-backward", Fword_search_backward, 1, 5,
2051        "sWord search backward: ", /*
2052 Search backward from point for STRING, ignoring differences in punctuation.
2053 Set point to the beginning of the occurrence found, and return point.
2054
2055 Optional second argument LIMIT bounds the search; it is a buffer
2056 position.  The match found must not extend before that position.
2057 The value nil is equivalent to (point-min).
2058
2059 Optional third argument NOERROR, if t, means just return nil (no
2060 error) if the search fails.  If neither nil nor t, set point to LIMIT
2061 and return nil.
2062
2063 Optional fourth argument COUNT is a repeat count--search for
2064 successive occurrences.
2065
2066 Optional fifth argument BUFFER specifies the buffer to search in and
2067 defaults to the current buffer.
2068
2069 See also the functions `match-beginning', `match-end' and `replace-match'.
2070 */
2071        (string, limit, noerror, count, buffer))
2072 {
2073   return search_command (wordify (buffer, string), limit, noerror, count,
2074                          buffer, -1, 1, 0);
2075 }
2076
2077 DEFUN ("word-search-forward", Fword_search_forward, 1, 5, "sWord search: ", /*
2078 Search forward from point for STRING, ignoring differences in punctuation.
2079 Set point to the end of the occurrence found, and return point.
2080
2081 Optional second argument LIMIT bounds the search; it is a buffer
2082 position.  The match found must not extend after that position.  The
2083 value nil is equivalent to (point-max).
2084
2085 Optional third argument NOERROR, if t, means just return nil (no
2086 error) if the search fails.  If neither nil nor t, set point to LIMIT
2087 and return nil.
2088
2089 Optional fourth argument COUNT is a repeat count--search for
2090 successive occurrences.
2091
2092 Optional fifth argument BUFFER specifies the buffer to search in and
2093 defaults to the current buffer.
2094
2095 See also the functions `match-beginning', `match-end' and `replace-match'.
2096 */
2097        (string, limit, noerror, count, buffer))
2098 {
2099   return search_command (wordify (buffer, string), limit, noerror, count,
2100                          buffer, 1, 1, 0);
2101 }
2102
2103 DEFUN ("re-search-backward", Fre_search_backward, 1, 5,
2104        "sRE search backward: ", /*
2105 Search backward from point for match for regular expression REGEXP.
2106 Set point to the beginning of the match, and return point.
2107 The match found is the one starting last in the buffer
2108 and yet ending before the origin of the search.
2109
2110 Optional second argument LIMIT bounds the search; it is a buffer
2111 position.  The match found must not extend before that position.
2112 The value nil is equivalent to (point-min).
2113
2114 Optional third argument NOERROR, if t, means just return nil (no
2115 error) if the search fails.  If neither nil nor t, set point to LIMIT
2116 and return nil.
2117
2118 Optional fourth argument COUNT is a repeat count--search for
2119 successive occurrences.
2120
2121 Optional fifth argument BUFFER specifies the buffer to search in and
2122 defaults to the current buffer.
2123
2124 See also the functions `match-beginning', `match-end' and `replace-match'.
2125 */
2126        (regexp, limit, noerror, count, buffer))
2127 {
2128   return search_command (regexp, limit, noerror, count, buffer, -1, 1, 0);
2129 }
2130
2131 DEFUN ("re-search-forward", Fre_search_forward, 1, 5, "sRE search: ", /*
2132 Search forward from point for regular expression REGEXP.
2133 Set point to the end of the occurrence found, and return point.
2134
2135 Optional second argument LIMIT bounds the search; it is a buffer
2136 position.  The match found must not extend after that position.  The
2137 value nil is equivalent to (point-max).
2138
2139 Optional third argument NOERROR, if t, means just return nil (no
2140 error) if the search fails.  If neither nil nor t, set point to LIMIT
2141 and return nil.
2142
2143 Optional fourth argument COUNT is a repeat count--search for
2144 successive occurrences.
2145
2146 Optional fifth argument BUFFER specifies the buffer to search in and
2147 defaults to the current buffer.
2148
2149 See also the functions `match-beginning', `match-end' and `replace-match'.
2150 */
2151        (regexp, limit, noerror, count, buffer))
2152 {
2153   return search_command (regexp, limit, noerror, count, buffer, 1, 1, 0);
2154 }
2155
2156 DEFUN ("posix-search-backward", Fposix_search_backward, 1, 5,
2157        "sPosix search backward: ", /*
2158 Search backward from point for match for regular expression REGEXP.
2159 Find the longest match in accord with Posix regular expression rules.
2160 Set point to the beginning of the match, and return point.
2161 The match found is the one starting last in the buffer
2162 and yet ending before the origin of the search.
2163
2164 Optional second argument LIMIT bounds the search; it is a buffer
2165 position.  The match found must not extend before that position.
2166 The value nil is equivalent to (point-min).
2167
2168 Optional third argument NOERROR, if t, means just return nil (no
2169 error) if the search fails.  If neither nil nor t, set point to LIMIT
2170 and return nil.
2171
2172 Optional fourth argument COUNT is a repeat count--search for
2173 successive occurrences.
2174
2175 Optional fifth argument BUFFER specifies the buffer to search in and
2176 defaults to the current buffer.
2177
2178 See also the functions `match-beginning', `match-end' and `replace-match'.
2179 */
2180        (regexp, limit, noerror, count, buffer))
2181 {
2182   return search_command (regexp, limit, noerror, count, buffer, -1, 1, 1);
2183 }
2184
2185 DEFUN ("posix-search-forward", Fposix_search_forward, 1, 5, "sPosix search: ", /*
2186 Search forward from point for regular expression REGEXP.
2187 Find the longest match in accord with Posix regular expression rules.
2188 Set point to the end of the occurrence found, and return point.
2189
2190 Optional second argument LIMIT bounds the search; it is a buffer
2191 position.  The match found must not extend after that position.  The
2192 value nil is equivalent to (point-max).
2193
2194 Optional third argument NOERROR, if t, means just return nil (no
2195 error) if the search fails.  If neither nil nor t, set point to LIMIT
2196 and return nil.
2197
2198 Optional fourth argument COUNT is a repeat count--search for
2199 successive occurrences.
2200
2201 Optional fifth argument BUFFER specifies the buffer to search in and
2202 defaults to the current buffer.
2203
2204 See also the functions `match-beginning', `match-end' and `replace-match'.
2205 */
2206        (regexp, limit, noerror, count, buffer))
2207 {
2208   return search_command (regexp, limit, noerror, count, buffer, 1, 1, 1);
2209 }
2210
2211 \f
2212 static Lisp_Object
2213 free_created_dynarrs (Lisp_Object cons)
2214 {
2215   Dynarr_free (get_opaque_ptr (XCAR (cons)));
2216   Dynarr_free (get_opaque_ptr (XCDR (cons)));
2217   free_opaque_ptr (XCAR (cons));
2218   free_opaque_ptr (XCDR (cons));
2219   free_cons (XCONS (cons));
2220   return Qnil;
2221 }
2222
2223 DEFUN ("replace-match", Freplace_match, 1, 5, 0, /*
2224 Replace text matched by last search with REPLACEMENT.
2225 If second arg FIXEDCASE is non-nil, do not alter case of replacement text.
2226 Otherwise maybe capitalize the whole text, or maybe just word initials,
2227 based on the replaced text.
2228 If the replaced text has only capital letters
2229 and has at least one multiletter word, convert REPLACEMENT to all caps.
2230 If the replaced text has at least one word starting with a capital letter,
2231 then capitalize each word in REPLACEMENT.
2232
2233 If third arg LITERAL is non-nil, insert REPLACEMENT literally.
2234 Otherwise treat `\\' as special:
2235   `\\&' in REPLACEMENT means substitute original matched text.
2236   `\\N' means substitute what matched the Nth `\\(...\\)'.
2237        If Nth parens didn't match, substitute nothing.
2238   `\\\\' means insert one `\\'.
2239   `\\u' means upcase the next character.
2240   `\\l' means downcase the next character.
2241   `\\U' means begin upcasing all following characters.
2242   `\\L' means begin downcasing all following characters.
2243   `\\E' means terminate the effect of any `\\U' or `\\L'.
2244   Case changes made with `\\u', `\\l', `\\U', and `\\L' override
2245   all other case changes that may be made in the replaced text.
2246 FIXEDCASE and LITERAL are optional arguments.
2247 Leaves point at end of replacement text.
2248
2249 The optional fourth argument STRING can be a string to modify.
2250 In that case, this function creates and returns a new string
2251 which is made by replacing the part of STRING that was matched.
2252 When fourth argument is a string, fifth argument STRBUFFER specifies
2253 the buffer to be used for syntax-table and case-table lookup and
2254 defaults to the current buffer.  When fourth argument is not a string,
2255 the buffer that the match occurred in has automatically been remembered
2256 and you do not need to specify it.
2257 */
2258        (replacement, fixedcase, literal, string, strbuffer))
2259 {
2260   /* This function has been Mule-ized. */
2261   /* This function can GC */
2262   enum { nochange, all_caps, cap_initial } case_action;
2263   Bufpos pos, last;
2264   int some_multiletter_word;
2265   int some_lowercase;
2266   int some_uppercase;
2267   int some_nonuppercase_initial;
2268   Emchar c, prevc;
2269   Charcount inslen;
2270   struct buffer *buf;
2271   Lisp_Char_Table *syntax_table;
2272   int mc_count;
2273   Lisp_Object buffer;
2274   int_dynarr *ul_action_dynarr = 0;
2275   int_dynarr *ul_pos_dynarr = 0;
2276   int speccount;
2277
2278   CHECK_STRING (replacement);
2279
2280   if (! NILP (string))
2281     {
2282       CHECK_STRING (string);
2283       if (!EQ (last_thing_searched, Qt))
2284         error ("last thing matched was not a string");
2285       /* If the match data
2286          were abstracted into a special "match data" type instead
2287          of the typical half-assed "let the implementation be
2288          visible" form it's in, we could extend it to include
2289          the last string matched and the buffer used for that
2290          matching.  But of course we can't change it as it is. */
2291       buf = decode_buffer (strbuffer, 0);
2292       XSETBUFFER (buffer, buf);
2293     }
2294   else
2295     {
2296       if (!BUFFERP (last_thing_searched))
2297         error ("last thing matched was not a buffer");
2298       buffer = last_thing_searched;
2299       buf = XBUFFER (buffer);
2300     }
2301
2302 #ifdef UTF2000
2303   syntax_table = XCHAR_TABLE (buf->syntax_table);
2304 #else
2305   syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
2306 #endif
2307
2308   case_action = nochange;       /* We tried an initialization */
2309                                 /* but some C compilers blew it */
2310
2311   if (search_regs.num_regs == 0)
2312     error ("replace-match called before any match found");
2313
2314   if (NILP (string))
2315     {
2316       if (search_regs.start[0] < BUF_BEGV (buf)
2317           || search_regs.start[0] > search_regs.end[0]
2318           || search_regs.end[0] > BUF_ZV (buf))
2319         args_out_of_range (make_int (search_regs.start[0]),
2320                            make_int (search_regs.end[0]));
2321     }
2322   else
2323     {
2324       if (search_regs.start[0] < 0
2325           || search_regs.start[0] > search_regs.end[0]
2326           || search_regs.end[0] > XSTRING_CHAR_LENGTH (string))
2327         args_out_of_range (make_int (search_regs.start[0]),
2328                            make_int (search_regs.end[0]));
2329     }
2330
2331   if (NILP (fixedcase))
2332     {
2333       /* Decide how to casify by examining the matched text. */
2334
2335       last = search_regs.end[0];
2336       prevc = '\n';
2337       case_action = all_caps;
2338
2339       /* some_multiletter_word is set nonzero if any original word
2340          is more than one letter long. */
2341       some_multiletter_word = 0;
2342       some_lowercase = 0;
2343       some_nonuppercase_initial = 0;
2344       some_uppercase = 0;
2345
2346       for (pos = search_regs.start[0]; pos < last; pos++)
2347         {
2348           if (NILP (string))
2349             c = BUF_FETCH_CHAR (buf, pos);
2350           else
2351             c = string_char (XSTRING (string), pos);
2352
2353           if (LOWERCASEP (buf, c))
2354             {
2355               /* Cannot be all caps if any original char is lower case */
2356
2357               some_lowercase = 1;
2358               if (!WORD_SYNTAX_P (syntax_table, prevc))
2359                 some_nonuppercase_initial = 1;
2360               else
2361                 some_multiletter_word = 1;
2362             }
2363           else if (!NOCASEP (buf, c))
2364             {
2365               some_uppercase = 1;
2366               if (!WORD_SYNTAX_P (syntax_table, prevc))
2367                 ;
2368               else
2369                 some_multiletter_word = 1;
2370             }
2371           else
2372             {
2373               /* If the initial is a caseless word constituent,
2374                  treat that like a lowercase initial.  */
2375               if (!WORD_SYNTAX_P (syntax_table, prevc))
2376                 some_nonuppercase_initial = 1;
2377             }
2378
2379           prevc = c;
2380         }
2381
2382       /* Convert to all caps if the old text is all caps
2383          and has at least one multiletter word.  */
2384       if (! some_lowercase && some_multiletter_word)
2385         case_action = all_caps;
2386       /* Capitalize each word, if the old text has all capitalized words.  */
2387       else if (!some_nonuppercase_initial && some_multiletter_word)
2388         case_action = cap_initial;
2389       else if (!some_nonuppercase_initial && some_uppercase)
2390         /* Should x -> yz, operating on X, give Yz or YZ?
2391            We'll assume the latter.  */
2392         case_action = all_caps;
2393       else
2394         case_action = nochange;
2395     }
2396
2397   /* Do replacement in a string.  */
2398   if (!NILP (string))
2399     {
2400       Lisp_Object before, after;
2401
2402       speccount = specpdl_depth ();
2403       before = Fsubstring (string, Qzero, make_int (search_regs.start[0]));
2404       after = Fsubstring (string, make_int (search_regs.end[0]), Qnil);
2405
2406       /* Do case substitution into REPLACEMENT if desired.  */
2407       if (NILP (literal))
2408         {
2409           Charcount stlen = XSTRING_CHAR_LENGTH (replacement);
2410           Charcount strpos;
2411           /* XEmacs change: rewrote this loop somewhat to make it
2412              cleaner.  Also added \U, \E, etc. */
2413           Charcount literal_start = 0;
2414           /* We build up the substituted string in ACCUM.  */
2415           Lisp_Object accum;
2416
2417           accum = Qnil;
2418
2419           /* OK, the basic idea here is that we scan through the
2420              replacement string until we find a backslash, which
2421              represents a substring of the original string to be
2422              substituted.  We then append onto ACCUM the literal
2423              text before the backslash (LASTPOS marks the
2424              beginning of this) followed by the substring of the
2425              original string that needs to be inserted. */
2426           for (strpos = 0; strpos < stlen; strpos++)
2427             {
2428               /* If LITERAL_END is set, we've encountered a backslash
2429                  (the end of literal text to be inserted). */
2430               Charcount literal_end = -1;
2431               /* If SUBSTART is set, we need to also insert the
2432                  text from SUBSTART to SUBEND in the original string. */
2433               Charcount substart = -1;
2434               Charcount subend   = -1;
2435
2436               c = string_char (XSTRING (replacement), strpos);
2437               if (c == '\\' && strpos < stlen - 1)
2438                 {
2439                   c = string_char (XSTRING (replacement), ++strpos);
2440                   if (c == '&')
2441                     {
2442                       literal_end = strpos - 1;
2443                       substart = search_regs.start[0];
2444                       subend = search_regs.end[0];
2445                     }
2446                   else if (c >= '1' && c <= '9' &&
2447                            c <= search_regs.num_regs + '0')
2448                     {
2449                       if (search_regs.start[c - '0'] >= 0)
2450                         {
2451                           literal_end = strpos - 1;
2452                           substart = search_regs.start[c - '0'];
2453                           subend = search_regs.end[c - '0'];
2454                         }
2455                     }
2456                   else if (c == 'U' || c == 'u' || c == 'L' || c == 'l' ||
2457                            c == 'E')
2458                     {
2459                       /* Keep track of all case changes requested, but don't
2460                          make them now.  Do them later so we override
2461                          everything else. */
2462                       if (!ul_pos_dynarr)
2463                         {
2464                           ul_pos_dynarr = Dynarr_new (int);
2465                           ul_action_dynarr = Dynarr_new (int);
2466                           record_unwind_protect
2467                             (free_created_dynarrs,
2468                              noseeum_cons
2469                              (make_opaque_ptr (ul_pos_dynarr),
2470                               make_opaque_ptr (ul_action_dynarr)));
2471                         }
2472                       literal_end = strpos - 1;
2473                       Dynarr_add (ul_pos_dynarr,
2474                                   (!NILP (accum)
2475                                   ? XSTRING_CHAR_LENGTH (accum)
2476                                   : 0) + (literal_end - literal_start));
2477                       Dynarr_add (ul_action_dynarr, c);
2478                     }
2479                   else if (c == '\\')
2480                     /* So we get just one backslash. */
2481                     literal_end = strpos;
2482                 }
2483               if (literal_end >= 0)
2484                 {
2485                   Lisp_Object literal_text = Qnil;
2486                   Lisp_Object substring = Qnil;
2487                   if (literal_end != literal_start)
2488                     literal_text = Fsubstring (replacement,
2489                                                make_int (literal_start),
2490                                                make_int (literal_end));
2491                   if (substart >= 0 && subend != substart)
2492                     substring = Fsubstring (string,
2493                                             make_int (substart),
2494                                             make_int (subend));
2495                   if (!NILP (literal_text) || !NILP (substring))
2496                     accum = concat3 (accum, literal_text, substring);
2497                   literal_start = strpos + 1;
2498                 }
2499             }
2500
2501           if (strpos != literal_start)
2502             /* some literal text at end to be inserted */
2503             replacement = concat2 (accum, Fsubstring (replacement,
2504                                                       make_int (literal_start),
2505                                                       make_int (strpos)));
2506           else
2507             replacement = accum;
2508         }
2509
2510       /* replacement can be nil. */
2511       if (NILP (replacement))
2512         replacement = build_string ("");
2513
2514       if (case_action == all_caps)
2515         replacement = Fupcase (replacement, buffer);
2516       else if (case_action == cap_initial)
2517         replacement = Fupcase_initials (replacement, buffer);
2518
2519       /* Now finally, we need to process the \U's, \E's, etc. */
2520       if (ul_pos_dynarr)
2521         {
2522           int i = 0;
2523           int cur_action = 'E';
2524           Charcount stlen = XSTRING_CHAR_LENGTH (replacement);
2525           Charcount strpos;
2526
2527           for (strpos = 0; strpos < stlen; strpos++)
2528             {
2529               Emchar curchar = string_char (XSTRING (replacement), strpos);
2530               Emchar newchar = -1;
2531               if (i < Dynarr_length (ul_pos_dynarr) &&
2532                   strpos == Dynarr_at (ul_pos_dynarr, i))
2533                 {
2534                   int new_action = Dynarr_at (ul_action_dynarr, i);
2535                   i++;
2536                   if (new_action == 'u')
2537                     newchar = UPCASE (buf, curchar);
2538                   else if (new_action == 'l')
2539                     newchar = DOWNCASE (buf, curchar);
2540                   else
2541                     cur_action = new_action;
2542                 }
2543               if (newchar == -1)
2544                 {
2545                   if (cur_action == 'U')
2546                     newchar = UPCASE (buf, curchar);
2547                   else if (cur_action == 'L')
2548                     newchar = DOWNCASE (buf, curchar);
2549                   else
2550                     newchar = curchar;
2551                 }
2552               if (newchar != curchar)
2553                 set_string_char (XSTRING (replacement), strpos, newchar);
2554             }
2555         }
2556
2557       /* frees the Dynarrs if necessary. */
2558       unbind_to (speccount, Qnil);
2559       return concat3 (before, replacement, after);
2560     }
2561
2562   mc_count = begin_multiple_change (buf, search_regs.start[0],
2563                                     search_regs.end[0]);
2564
2565   /* begin_multiple_change() records an unwind-protect, so we need to
2566      record this value now. */
2567   speccount = specpdl_depth ();
2568
2569   /* We insert the replacement text before the old text, and then
2570      delete the original text.  This means that markers at the
2571      beginning or end of the original will float to the corresponding
2572      position in the replacement.  */
2573   BUF_SET_PT (buf, search_regs.start[0]);
2574   if (!NILP (literal))
2575     Finsert (1, &replacement);
2576   else
2577     {
2578       Charcount stlen = XSTRING_CHAR_LENGTH (replacement);
2579       Charcount strpos;
2580       struct gcpro gcpro1;
2581       GCPRO1 (replacement);
2582       for (strpos = 0; strpos < stlen; strpos++)
2583         {
2584           Charcount offset = BUF_PT (buf) - search_regs.start[0];
2585
2586           c = string_char (XSTRING (replacement), strpos);
2587           if (c == '\\' && strpos < stlen - 1)
2588             {
2589               c = string_char (XSTRING (replacement), ++strpos);
2590               if (c == '&')
2591                 Finsert_buffer_substring
2592                   (buffer,
2593                    make_int (search_regs.start[0] + offset),
2594                    make_int (search_regs.end[0] + offset));
2595               else if (c >= '1' && c <= '9' &&
2596                        c <= search_regs.num_regs + '0')
2597                 {
2598                   if (search_regs.start[c - '0'] >= 1)
2599                     Finsert_buffer_substring
2600                       (buffer,
2601                        make_int (search_regs.start[c - '0'] + offset),
2602                        make_int (search_regs.end[c - '0'] + offset));
2603                 }
2604               else if (c == 'U' || c == 'u' || c == 'L' || c == 'l' ||
2605                        c == 'E')
2606                 {
2607                   /* Keep track of all case changes requested, but don't
2608                      make them now.  Do them later so we override
2609                      everything else. */
2610                   if (!ul_pos_dynarr)
2611                     {
2612                       ul_pos_dynarr = Dynarr_new (int);
2613                       ul_action_dynarr = Dynarr_new (int);
2614                       record_unwind_protect
2615                         (free_created_dynarrs,
2616                          Fcons (make_opaque_ptr (ul_pos_dynarr),
2617                                 make_opaque_ptr (ul_action_dynarr)));
2618                     }
2619                   Dynarr_add (ul_pos_dynarr, BUF_PT (buf));
2620                   Dynarr_add (ul_action_dynarr, c);
2621                 }
2622               else
2623                 buffer_insert_emacs_char (buf, c);
2624             }
2625           else
2626             buffer_insert_emacs_char (buf, c);
2627         }
2628       UNGCPRO;
2629     }
2630
2631   inslen = BUF_PT (buf) - (search_regs.start[0]);
2632   buffer_delete_range (buf, search_regs.start[0] + inslen, search_regs.end[0] +
2633                        inslen, 0);
2634
2635   if (case_action == all_caps)
2636     Fupcase_region (make_int (BUF_PT (buf) - inslen),
2637                     make_int (BUF_PT (buf)),  buffer);
2638   else if (case_action == cap_initial)
2639     Fupcase_initials_region (make_int (BUF_PT (buf) - inslen),
2640                              make_int (BUF_PT (buf)), buffer);
2641
2642   /* Now go through and make all the case changes that were requested
2643      in the replacement string. */
2644   if (ul_pos_dynarr)
2645     {
2646       Bufpos eend = BUF_PT (buf);
2647       int i = 0;
2648       int cur_action = 'E';
2649
2650       for (pos = BUF_PT (buf) - inslen; pos < eend; pos++)
2651         {
2652           Emchar curchar = BUF_FETCH_CHAR (buf, pos);
2653           Emchar newchar = -1;
2654           if (i < Dynarr_length (ul_pos_dynarr) &&
2655               pos == Dynarr_at (ul_pos_dynarr, i))
2656             {
2657               int new_action = Dynarr_at (ul_action_dynarr, i);
2658               i++;
2659               if (new_action == 'u')
2660                 newchar = UPCASE (buf, curchar);
2661               else if (new_action == 'l')
2662                 newchar = DOWNCASE (buf, curchar);
2663               else
2664                 cur_action = new_action;
2665             }
2666           if (newchar == -1)
2667             {
2668               if (cur_action == 'U')
2669                 newchar = UPCASE (buf, curchar);
2670               else if (cur_action == 'L')
2671                 newchar = DOWNCASE (buf, curchar);
2672               else
2673                 newchar = curchar;
2674             }
2675           if (newchar != curchar)
2676             buffer_replace_char (buf, pos, newchar, 0, 0);
2677         }
2678     }
2679
2680   /* frees the Dynarrs if necessary. */
2681   unbind_to (speccount, Qnil);
2682   end_multiple_change (buf, mc_count);
2683
2684   return Qnil;
2685 }
2686 \f
2687 static Lisp_Object
2688 match_limit (Lisp_Object num, int beginningp)
2689 {
2690   /* This function has been Mule-ized. */
2691   int n;
2692
2693   CHECK_INT (num);
2694   n = XINT (num);
2695   if (n < 0 || n >= search_regs.num_regs)
2696     args_out_of_range (num, make_int (search_regs.num_regs));
2697   if (search_regs.num_regs == 0 ||
2698       search_regs.start[n] < 0)
2699     return Qnil;
2700   return make_int (beginningp ? search_regs.start[n] : search_regs.end[n]);
2701 }
2702
2703 DEFUN ("match-beginning", Fmatch_beginning, 1, 1, 0, /*
2704 Return position of start of text matched by last regexp search.
2705 NUM, specifies which parenthesized expression in the last regexp.
2706  Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
2707 Zero means the entire text matched by the whole regexp or whole string.
2708 */
2709        (num))
2710 {
2711   return match_limit (num, 1);
2712 }
2713
2714 DEFUN ("match-end", Fmatch_end, 1, 1, 0, /*
2715 Return position of end of text matched by last regexp search.
2716 NUM specifies which parenthesized expression in the last regexp.
2717  Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
2718 Zero means the entire text matched by the whole regexp or whole string.
2719 */
2720        (num))
2721 {
2722   return match_limit (num, 0);
2723 }
2724
2725 DEFUN ("match-data", Fmatch_data, 0, 2, 0, /*
2726 Return a list containing all info on what the last regexp search matched.
2727 Element 2N is `(match-beginning N)'; element 2N + 1 is `(match-end N)'.
2728 All the elements are markers or nil (nil if the Nth pair didn't match)
2729 if the last match was on a buffer; integers or nil if a string was matched.
2730 Use `store-match-data' to reinstate the data in this list.
2731
2732 If INTEGERS (the optional first argument) is non-nil, always use integers
2733 \(rather than markers) to represent buffer positions.
2734 If REUSE is a list, reuse it as part of the value.  If REUSE is long enough
2735 to hold all the values, and if INTEGERS is non-nil, no consing is done.
2736 */
2737        (integers, reuse))
2738 {
2739   /* This function has been Mule-ized. */
2740   Lisp_Object tail, prev;
2741   Lisp_Object *data;
2742   int i;
2743   Charcount len;
2744
2745   if (NILP (last_thing_searched))
2746     /*error ("match-data called before any match found");*/
2747     return Qnil;
2748
2749   data = alloca_array (Lisp_Object, 2 * search_regs.num_regs);
2750
2751   len = -1;
2752   for (i = 0; i < search_regs.num_regs; i++)
2753     {
2754       Bufpos start = search_regs.start[i];
2755       if (start >= 0)
2756         {
2757           if (EQ (last_thing_searched, Qt)
2758               || !NILP (integers))
2759             {
2760               data[2 * i] = make_int (start);
2761               data[2 * i + 1] = make_int (search_regs.end[i]);
2762             }
2763           else if (BUFFERP (last_thing_searched))
2764             {
2765               data[2 * i] = Fmake_marker ();
2766               Fset_marker (data[2 * i],
2767                            make_int (start),
2768                            last_thing_searched);
2769               data[2 * i + 1] = Fmake_marker ();
2770               Fset_marker (data[2 * i + 1],
2771                            make_int (search_regs.end[i]),
2772                            last_thing_searched);
2773             }
2774           else
2775             /* last_thing_searched must always be Qt, a buffer, or Qnil.  */
2776             abort ();
2777
2778           len = i;
2779         }
2780       else
2781         data[2 * i] = data [2 * i + 1] = Qnil;
2782     }
2783   if (!CONSP (reuse))
2784     return Flist (2 * len + 2, data);
2785
2786   /* If REUSE is a list, store as many value elements as will fit
2787      into the elements of REUSE.  */
2788   for (prev = Qnil, i = 0, tail = reuse; CONSP (tail); i++, tail = XCDR (tail))
2789     {
2790       if (i < 2 * len + 2)
2791         XCAR (tail) = data[i];
2792       else
2793         XCAR (tail) = Qnil;
2794       prev = tail;
2795     }
2796
2797   /* If we couldn't fit all value elements into REUSE,
2798      cons up the rest of them and add them to the end of REUSE.  */
2799   if (i < 2 * len + 2)
2800     XCDR (prev) = Flist (2 * len + 2 - i, data + i);
2801
2802   return reuse;
2803 }
2804
2805
2806 DEFUN ("store-match-data", Fstore_match_data, 1, 1, 0, /*
2807 Set internal data on last search match from elements of LIST.
2808 LIST should have been created by calling `match-data' previously.
2809 */
2810        (list))
2811 {
2812   /* This function has been Mule-ized. */
2813   REGISTER int i;
2814   REGISTER Lisp_Object marker;
2815   int num_regs;
2816   int length;
2817
2818   if (running_asynch_code)
2819     save_search_regs ();
2820
2821   CONCHECK_LIST (list);
2822
2823   /* Unless we find a marker with a buffer in LIST, assume that this
2824      match data came from a string.  */
2825   last_thing_searched = Qt;
2826
2827   /* Allocate registers if they don't already exist.  */
2828   length = XINT (Flength (list)) / 2;
2829   num_regs = search_regs.num_regs;
2830
2831   if (length > num_regs)
2832     {
2833       if (search_regs.num_regs == 0)
2834         {
2835           search_regs.start = xnew_array (regoff_t, length);
2836           search_regs.end   = xnew_array (regoff_t, length);
2837         }
2838       else
2839         {
2840           XREALLOC_ARRAY (search_regs.start, regoff_t, length);
2841           XREALLOC_ARRAY (search_regs.end,   regoff_t, length);
2842         }
2843
2844       search_regs.num_regs = length;
2845     }
2846
2847   for (i = 0; i < num_regs; i++)
2848     {
2849       marker = Fcar (list);
2850       if (NILP (marker))
2851         {
2852           search_regs.start[i] = -1;
2853           list = Fcdr (list);
2854         }
2855       else
2856         {
2857           if (MARKERP (marker))
2858             {
2859               if (XMARKER (marker)->buffer == 0)
2860                 marker = Qzero;
2861               else
2862                 XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer);
2863             }
2864
2865           CHECK_INT_COERCE_MARKER (marker);
2866           search_regs.start[i] = XINT (marker);
2867           list = Fcdr (list);
2868
2869           marker = Fcar (list);
2870           if (MARKERP (marker) && XMARKER (marker)->buffer == 0)
2871             marker = Qzero;
2872
2873           CHECK_INT_COERCE_MARKER (marker);
2874           search_regs.end[i] = XINT (marker);
2875         }
2876       list = Fcdr (list);
2877     }
2878
2879   return Qnil;
2880 }
2881
2882 /* If non-zero the match data have been saved in saved_search_regs
2883    during the execution of a sentinel or filter. */
2884 static int search_regs_saved;
2885 static struct re_registers saved_search_regs;
2886
2887 /* Called from Flooking_at, Fstring_match, search_buffer, Fstore_match_data
2888    if asynchronous code (filter or sentinel) is running. */
2889 static void
2890 save_search_regs (void)
2891 {
2892   if (!search_regs_saved)
2893     {
2894       saved_search_regs.num_regs = search_regs.num_regs;
2895       saved_search_regs.start = search_regs.start;
2896       saved_search_regs.end = search_regs.end;
2897       search_regs.num_regs = 0;
2898       search_regs.start = 0;
2899       search_regs.end = 0;
2900
2901       search_regs_saved = 1;
2902     }
2903 }
2904
2905 /* Called upon exit from filters and sentinels. */
2906 void
2907 restore_match_data (void)
2908 {
2909   if (search_regs_saved)
2910     {
2911       if (search_regs.num_regs > 0)
2912         {
2913           xfree (search_regs.start);
2914           xfree (search_regs.end);
2915         }
2916       search_regs.num_regs = saved_search_regs.num_regs;
2917       search_regs.start = saved_search_regs.start;
2918       search_regs.end = saved_search_regs.end;
2919
2920       search_regs_saved = 0;
2921     }
2922 }
2923
2924 /* Quote a string to inactivate reg-expr chars */
2925
2926 DEFUN ("regexp-quote", Fregexp_quote, 1, 1, 0, /*
2927 Return a regexp string which matches exactly STRING and nothing else.
2928 */
2929        (string))
2930 {
2931   REGISTER Bufbyte *in, *out, *end;
2932   REGISTER Bufbyte *temp;
2933
2934   CHECK_STRING (string);
2935
2936   temp = (Bufbyte *) alloca (XSTRING_LENGTH (string) * 2);
2937
2938   /* Now copy the data into the new string, inserting escapes. */
2939
2940   in = XSTRING_DATA (string);
2941   end = in + XSTRING_LENGTH (string);
2942   out = temp;
2943
2944   while (in < end)
2945     {
2946       Emchar c = charptr_emchar (in);
2947
2948       if (c == '[' || c == ']'
2949           || c == '*' || c == '.' || c == '\\'
2950           || c == '?' || c == '+'
2951           || c == '^' || c == '$')
2952         *out++ = '\\';
2953       out += set_charptr_emchar (out, c);
2954       INC_CHARPTR (in);
2955     }
2956
2957   return make_string (temp, out - temp);
2958 }
2959
2960 DEFUN ("set-word-regexp", Fset_word_regexp, 1, 1, 0, /*
2961 Set the regexp to be used to match a word in regular-expression searching.
2962 #### Not yet implemented.  Currently does nothing.
2963 #### Do not use this yet.  Its calling interface is likely to change.
2964 */
2965        (regexp))
2966 {
2967   return Qnil;
2968 }
2969
2970 \f
2971 /************************************************************************/
2972 /*                            initialization                            */
2973 /************************************************************************/
2974
2975 void
2976 syms_of_search (void)
2977 {
2978
2979   DEFERROR_STANDARD (Qsearch_failed, Qinvalid_operation);
2980   DEFERROR_STANDARD (Qinvalid_regexp, Qsyntax_error);
2981
2982   DEFSUBR (Flooking_at);
2983   DEFSUBR (Fposix_looking_at);
2984   DEFSUBR (Fstring_match);
2985   DEFSUBR (Fposix_string_match);
2986   DEFSUBR (Fskip_chars_forward);
2987   DEFSUBR (Fskip_chars_backward);
2988   DEFSUBR (Fskip_syntax_forward);
2989   DEFSUBR (Fskip_syntax_backward);
2990   DEFSUBR (Fsearch_forward);
2991   DEFSUBR (Fsearch_backward);
2992   DEFSUBR (Fword_search_forward);
2993   DEFSUBR (Fword_search_backward);
2994   DEFSUBR (Fre_search_forward);
2995   DEFSUBR (Fre_search_backward);
2996   DEFSUBR (Fposix_search_forward);
2997   DEFSUBR (Fposix_search_backward);
2998   DEFSUBR (Freplace_match);
2999   DEFSUBR (Fmatch_beginning);
3000   DEFSUBR (Fmatch_end);
3001   DEFSUBR (Fmatch_data);
3002   DEFSUBR (Fstore_match_data);
3003   DEFSUBR (Fregexp_quote);
3004   DEFSUBR (Fset_word_regexp);
3005 }
3006
3007 void
3008 reinit_vars_of_search (void)
3009 {
3010   int i;
3011
3012   last_thing_searched = Qnil;
3013   staticpro_nodump (&last_thing_searched);
3014
3015   for (i = 0; i < REGEXP_CACHE_SIZE; ++i)
3016     {
3017       searchbufs[i].buf.allocated = 100;
3018       searchbufs[i].buf.buffer = (unsigned char *) xmalloc (100);
3019       searchbufs[i].buf.fastmap = searchbufs[i].fastmap;
3020       searchbufs[i].regexp = Qnil;
3021       staticpro_nodump (&searchbufs[i].regexp);
3022       searchbufs[i].next = (i == REGEXP_CACHE_SIZE-1 ? 0 : &searchbufs[i+1]);
3023     }
3024   searchbuf_head = &searchbufs[0];
3025 }
3026
3027 void
3028 vars_of_search (void)
3029 {
3030   reinit_vars_of_search ();
3031
3032   DEFVAR_LISP ("forward-word-regexp", &Vforward_word_regexp /*
3033 *Regular expression to be used in `forward-word'.
3034 #### Not yet implemented.
3035 */ );
3036   Vforward_word_regexp = Qnil;
3037
3038   DEFVAR_LISP ("backward-word-regexp", &Vbackward_word_regexp /*
3039 *Regular expression to be used in `backward-word'.
3040 #### Not yet implemented.
3041 */ );
3042   Vbackward_word_regexp = Qnil;
3043 }
3044
3045 void
3046 complex_vars_of_search (void)
3047 {
3048   Vskip_chars_range_table = Fmake_range_table ();
3049   staticpro (&Vskip_chars_range_table);
3050 }