This commit was manufactured by cvs2svn to create branch 'utf-2000'.
[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_match_object = Qnil;
317   regex_emacs_buffer = buf;
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_match_object = string;
408     regex_emacs_buffer = buf;
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_match_object = reloc;
500   regex_emacs_buffer = current_buffer;
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 #ifndef emacs
789 #ifdef UTF2000
790   Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->syntax_table);
791 #else
792   Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
793 #endif
794 #endif
795   Bufpos limit;
796
797   if (NILP (lim))
798     limit = forwardp ? BUF_ZV (buf) : BUF_BEGV (buf);
799   else
800     {
801       CHECK_INT_COERCE_MARKER (lim);
802       limit = XINT (lim);
803
804       /* In any case, don't allow scan outside bounds of buffer.  */
805       if (limit > BUF_ZV   (buf)) limit = BUF_ZV   (buf);
806       if (limit < BUF_BEGV (buf)) limit = BUF_BEGV (buf);
807     }
808
809   CHECK_STRING (string);
810   p = XSTRING_DATA (string);
811   pend = p + XSTRING_LENGTH (string);
812   memset (fastmap, 0, sizeof (fastmap));
813
814   Fclear_range_table (Vskip_chars_range_table);
815
816   if (p != pend && *p == '^')
817     {
818       negate = 1;
819       p++;
820     }
821
822   /* Find the characters specified and set their elements of fastmap.
823      If syntaxp, each character counts as itself.
824      Otherwise, handle backslashes and ranges specially  */
825
826   while (p != pend)
827     {
828       c = charptr_emchar (p);
829       INC_CHARPTR (p);
830       if (syntaxp)
831         {
832           if (c < 0400 && syntax_spec_code[c] < (unsigned char) Smax)
833             fastmap[c] = 1;
834           else
835             signal_simple_error ("Invalid syntax designator",
836                                  make_char (c));
837         }
838       else
839         {
840           if (c == '\\')
841             {
842               if (p == pend) break;
843               c = charptr_emchar (p);
844               INC_CHARPTR (p);
845             }
846           if (p != pend && *p == '-')
847             {
848               Emchar cend;
849
850               p++;
851               if (p == pend) break;
852               cend = charptr_emchar (p);
853               while (c <= cend && c < 0400)
854                 {
855                   fastmap[c] = 1;
856                   c++;
857                 }
858               if (c <= cend)
859                 Fput_range_table (make_int (c), make_int (cend), Qt,
860                                   Vskip_chars_range_table);
861               INC_CHARPTR (p);
862             }
863           else
864             {
865               if (c < 0400)
866                 fastmap[c] = 1;
867               else
868                 Fput_range_table (make_int (c), make_int (c), Qt,
869                                   Vskip_chars_range_table);
870             }
871         }
872     }
873
874   if (syntaxp && fastmap['-'] != 0)
875     fastmap[' '] = 1;
876
877   /* If ^ was the first character, complement the fastmap.
878      We don't complement the range table, however; we just use negate
879      in the comparisons below. */
880
881   if (negate)
882     for (i = 0; i < (int) (sizeof fastmap); i++)
883       fastmap[i] ^= 1;
884
885   {
886     Bufpos start_point = BUF_PT (buf);
887
888     if (syntaxp)
889       {
890         SETUP_SYNTAX_CACHE_FOR_BUFFER (buf, BUF_PT (buf), forwardp ? 1 : -1);
891         /* All syntax designators are normal chars so nothing strange
892            to worry about */
893         if (forwardp)
894           {
895             while (BUF_PT (buf) < limit
896                    && fastmap[(unsigned char)
897                               syntax_code_spec
898                               [(int) SYNTAX_FROM_CACHE (syntax_table,
899                                                         BUF_FETCH_CHAR
900                                                         (buf, BUF_PT (buf)))]])
901               {
902                 BUF_SET_PT (buf, BUF_PT (buf) + 1);
903                 UPDATE_SYNTAX_CACHE_FORWARD (BUF_PT (buf));
904               }
905           }
906         else
907           {
908             while (BUF_PT (buf) > limit
909                    && fastmap[(unsigned char)
910                               syntax_code_spec
911                               [(int) SYNTAX_FROM_CACHE (syntax_table,
912                                                         BUF_FETCH_CHAR
913                                                         (buf, BUF_PT (buf) - 1))]])
914               {
915                 BUF_SET_PT (buf, BUF_PT (buf) - 1);
916                 UPDATE_SYNTAX_CACHE_BACKWARD (BUF_PT (buf) - 1);
917               }
918           }
919       }
920     else
921       {
922         if (forwardp)
923           {
924             while (BUF_PT (buf) < limit)
925               {
926                 Emchar ch = BUF_FETCH_CHAR (buf, BUF_PT (buf));
927                 if ((ch < 0400) ? fastmap[ch] :
928                     (NILP (Fget_range_table (make_int (ch),
929                                              Vskip_chars_range_table,
930                                              Qnil))
931                      == negate))
932                   BUF_SET_PT (buf, BUF_PT (buf) + 1);
933                 else
934                   break;
935               }
936           }
937         else
938           {
939             while (BUF_PT (buf) > limit)
940               {
941                 Emchar ch = BUF_FETCH_CHAR (buf, BUF_PT (buf) - 1);
942                 if ((ch < 0400) ? fastmap[ch] :
943                     (NILP (Fget_range_table (make_int (ch),
944                                              Vskip_chars_range_table,
945                                              Qnil))
946                      == negate))
947                   BUF_SET_PT (buf, BUF_PT (buf) - 1);
948                 else
949                   break;
950               }
951           }
952       }
953     QUIT;
954     return make_int (BUF_PT (buf) - start_point);
955   }
956 }
957
958 DEFUN ("skip-chars-forward", Fskip_chars_forward, 1, 3, 0, /*
959 Move point forward, stopping before a char not in STRING, or at pos LIMIT.
960 STRING is like the inside of a `[...]' in a regular expression
961 except that `]' is never special and `\\' quotes `^', `-' or `\\'.
962 Thus, with arg "a-zA-Z", this skips letters stopping before first nonletter.
963 With arg "^a-zA-Z", skips nonletters stopping before first letter.
964 Returns the distance traveled, either zero or positive.
965
966 Optional argument BUFFER defaults to the current buffer.
967 */
968        (string, limit, buffer))
969 {
970   return skip_chars (decode_buffer (buffer, 0), 1, 0, string, limit);
971 }
972
973 DEFUN ("skip-chars-backward", Fskip_chars_backward, 1, 3, 0, /*
974 Move point backward, stopping after a char not in STRING, or at pos LIMIT.
975 See `skip-chars-forward' for details.
976 Returns the distance traveled, either zero or negative.
977
978 Optional argument BUFFER defaults to the current buffer.
979 */
980        (string, limit, buffer))
981 {
982   return skip_chars (decode_buffer (buffer, 0), 0, 0, string, limit);
983 }
984
985
986 DEFUN ("skip-syntax-forward", Fskip_syntax_forward, 1, 3, 0, /*
987 Move point forward across chars in specified syntax classes.
988 SYNTAX is a string of syntax code characters.
989 Stop before a char whose syntax is not in SYNTAX, or at position LIMIT.
990 If SYNTAX starts with ^, skip characters whose syntax is NOT in SYNTAX.
991 This function returns the distance traveled, either zero or positive.
992
993 Optional argument BUFFER defaults to the current buffer.
994 */
995        (syntax, limit, buffer))
996 {
997   return skip_chars (decode_buffer (buffer, 0), 1, 1, syntax, limit);
998 }
999
1000 DEFUN ("skip-syntax-backward", Fskip_syntax_backward, 1, 3, 0, /*
1001 Move point backward across chars in specified syntax classes.
1002 SYNTAX is a string of syntax code characters.
1003 Stop on reaching a char whose syntax is not in SYNTAX, or at position LIMIT.
1004 If SYNTAX starts with ^, skip characters whose syntax is NOT in SYNTAX.
1005 This function returns the distance traveled, either zero or negative.
1006
1007 Optional argument BUFFER defaults to the current buffer.
1008 */
1009        (syntax, limit, buffer))
1010 {
1011   return skip_chars (decode_buffer (buffer, 0), 0, 1, syntax, limit);
1012 }
1013
1014 \f
1015 /* Subroutines of Lisp buffer search functions. */
1016
1017 static Lisp_Object
1018 search_command (Lisp_Object string, Lisp_Object limit, Lisp_Object noerror,
1019                 Lisp_Object count, Lisp_Object buffer, int direction,
1020                 int RE, int posix)
1021 {
1022   /* This function has been Mule-ized, except for the trt table handling. */
1023   REGISTER Bufpos np;
1024   Bufpos lim;
1025   EMACS_INT n = direction;
1026   struct buffer *buf;
1027
1028   if (!NILP (count))
1029     {
1030       CHECK_INT (count);
1031       n *= XINT (count);
1032     }
1033
1034   buf = decode_buffer (buffer, 0);
1035   CHECK_STRING (string);
1036   if (NILP (limit))
1037     lim = n > 0 ? BUF_ZV (buf) : BUF_BEGV (buf);
1038   else
1039     {
1040       CHECK_INT_COERCE_MARKER (limit);
1041       lim = XINT (limit);
1042       if (n > 0 ? lim < BUF_PT (buf) : lim > BUF_PT (buf))
1043         error ("Invalid search limit (wrong side of point)");
1044       if (lim > BUF_ZV (buf))
1045         lim = BUF_ZV (buf);
1046       if (lim < BUF_BEGV (buf))
1047         lim = BUF_BEGV (buf);
1048     }
1049
1050   np = search_buffer (buf, string, BUF_PT (buf), lim, n, RE,
1051                       (!NILP (buf->case_fold_search)
1052                        ? XCASE_TABLE_CANON (buf->case_table)
1053                        : Qnil),
1054                       (!NILP (buf->case_fold_search)
1055                        ? XCASE_TABLE_EQV (buf->case_table)
1056                        : Qnil), posix);
1057
1058   if (np <= 0)
1059     {
1060       if (NILP (noerror))
1061         return signal_failure (string);
1062       if (!EQ (noerror, Qt))
1063         {
1064           if (lim < BUF_BEGV (buf) || lim > BUF_ZV (buf))
1065             abort ();
1066           BUF_SET_PT (buf, lim);
1067           return Qnil;
1068 #if 0 /* This would be clean, but maybe programs depend on
1069          a value of nil here.  */
1070           np = lim;
1071 #endif
1072         }
1073       else
1074         return Qnil;
1075     }
1076
1077   if (np < BUF_BEGV (buf) || np > BUF_ZV (buf))
1078     abort ();
1079
1080   BUF_SET_PT (buf, np);
1081
1082   return make_int (np);
1083 }
1084 \f
1085 static int
1086 trivial_regexp_p (Lisp_Object regexp)
1087 {
1088   /* This function has been Mule-ized. */
1089   Bytecount len = XSTRING_LENGTH (regexp);
1090   Bufbyte *s = XSTRING_DATA (regexp);
1091   while (--len >= 0)
1092     {
1093       switch (*s++)
1094         {
1095         case '.': case '*': case '+': case '?': case '[': case '^': case '$':
1096           return 0;
1097         case '\\':
1098           if (--len < 0)
1099             return 0;
1100           switch (*s++)
1101             {
1102             case '|': case '(': case ')': case '`': case '\'': case 'b':
1103             case 'B': case '<': case '>': case 'w': case 'W': case 's':
1104             case 'S': case '=':
1105 #ifdef MULE
1106             /* 97/2/25 jhod Added for category matches */
1107             case 'c': case 'C':
1108 #endif /* MULE */
1109             case '1': case '2': case '3': case '4': case '5':
1110             case '6': case '7': case '8': case '9':
1111               return 0;
1112             }
1113         }
1114     }
1115   return 1;
1116 }
1117
1118 /* Search for the n'th occurrence of STRING in BUF,
1119    starting at position BUFPOS and stopping at position BUFLIM,
1120    treating PAT as a literal string if RE is false or as
1121    a regular expression if RE is true.
1122
1123    If N is positive, searching is forward and BUFLIM must be greater
1124    than BUFPOS.
1125    If N is negative, searching is backward and BUFLIM must be less
1126    than BUFPOS.
1127
1128    Returns -x if only N-x occurrences found (x > 0),
1129    or else the position at the beginning of the Nth occurrence
1130    (if searching backward) or the end (if searching forward).
1131
1132    POSIX is nonzero if we want full backtracking (POSIX style)
1133    for this pattern.  0 means backtrack only enough to get a valid match.  */
1134 static Bufpos
1135 search_buffer (struct buffer *buf, Lisp_Object string, Bufpos bufpos,
1136                Bufpos buflim, EMACS_INT n, int RE, Lisp_Object trt,
1137                Lisp_Object inverse_trt, int posix)
1138 {
1139   /* This function has been Mule-ized, except for the trt table handling. */
1140   Bytecount len = XSTRING_LENGTH (string);
1141   Bufbyte *base_pat = XSTRING_DATA (string);
1142   REGISTER EMACS_INT i, j;
1143   Bytind p1, p2;
1144   Bytecount s1, s2;
1145   Bytind pos, lim;
1146
1147   if (running_asynch_code)
1148     save_search_regs ();
1149
1150   /* Null string is found at starting position.  */
1151   if (len == 0)
1152     {
1153       set_search_regs (buf, bufpos, 0);
1154       return bufpos;
1155     }
1156
1157   /* Searching 0 times means don't move.  */
1158   if (n == 0)
1159     return bufpos;
1160
1161   pos = bufpos_to_bytind (buf, bufpos);
1162   lim = bufpos_to_bytind (buf, buflim);
1163   if (RE && !trivial_regexp_p (string))
1164     {
1165       struct re_pattern_buffer *bufp;
1166
1167       bufp = compile_pattern (string, &search_regs, trt, posix,
1168                               ERROR_ME);
1169
1170       /* Get pointers and sizes of the two strings
1171          that make up the visible portion of the buffer. */
1172
1173       p1 = BI_BUF_BEGV (buf);
1174       p2 = BI_BUF_CEILING_OF (buf, p1);
1175       s1 = p2 - p1;
1176       s2 = BI_BUF_ZV (buf) - p2;
1177       regex_match_object = Qnil;
1178
1179       while (n < 0)
1180         {
1181           Bytecount val;
1182           QUIT;
1183           regex_emacs_buffer = buf;
1184           val = re_search_2 (bufp,
1185                              (char *) BI_BUF_BYTE_ADDRESS (buf, p1), s1,
1186                              (char *) BI_BUF_BYTE_ADDRESS (buf, p2), s2,
1187                              pos - BI_BUF_BEGV (buf), lim - pos, &search_regs,
1188                              pos - BI_BUF_BEGV (buf));
1189
1190           if (val == -2)
1191             {
1192               matcher_overflow ();
1193             }
1194           if (val >= 0)
1195             {
1196               int num_regs = search_regs.num_regs;
1197               j = BI_BUF_BEGV (buf);
1198               for (i = 0; i < num_regs; i++)
1199                 if (search_regs.start[i] >= 0)
1200                   {
1201                     search_regs.start[i] += j;
1202                     search_regs.end[i] += j;
1203                   }
1204               XSETBUFFER (last_thing_searched, buf);
1205               /* Set pos to the new position. */
1206               pos = search_regs.start[0];
1207               fixup_search_regs_for_buffer (buf);
1208               /* And bufpos too. */
1209               bufpos = search_regs.start[0];
1210             }
1211           else
1212             {
1213               return n;
1214             }
1215           n++;
1216         }
1217       while (n > 0)
1218         {
1219           Bytecount val;
1220           QUIT;
1221           regex_emacs_buffer = buf;
1222           val = re_search_2 (bufp,
1223                              (char *) BI_BUF_BYTE_ADDRESS (buf, p1), s1,
1224                              (char *) BI_BUF_BYTE_ADDRESS (buf, p2), s2,
1225                              pos - BI_BUF_BEGV (buf), lim - pos, &search_regs,
1226                              lim - BI_BUF_BEGV (buf));
1227           if (val == -2)
1228             {
1229               matcher_overflow ();
1230             }
1231           if (val >= 0)
1232             {
1233               int num_regs = search_regs.num_regs;
1234               j = BI_BUF_BEGV (buf);
1235               for (i = 0; i < num_regs; i++)
1236                 if (search_regs.start[i] >= 0)
1237                   {
1238                     search_regs.start[i] += j;
1239                     search_regs.end[i] += j;
1240                   }
1241               XSETBUFFER (last_thing_searched, buf);
1242               /* Set pos to the new position. */
1243               pos = search_regs.end[0];
1244               fixup_search_regs_for_buffer (buf);
1245               /* And bufpos too. */
1246               bufpos = search_regs.end[0];
1247             }
1248           else
1249             {
1250               return 0 - n;
1251             }
1252           n--;
1253         }
1254       return bufpos;
1255     }
1256   else                          /* non-RE case */
1257     {
1258       int charset_base = -1;
1259       int boyer_moore_ok = 1;
1260       Bufbyte *pat = 0;
1261       Bufbyte *patbuf = alloca_array (Bufbyte, len * MAX_EMCHAR_LEN);
1262       pat = patbuf;
1263 #ifdef MULE
1264       while (len > 0)
1265         {
1266           Bufbyte tmp_str[MAX_EMCHAR_LEN];
1267           Emchar c, translated, inverse;
1268           Bytecount orig_bytelen, new_bytelen, inv_bytelen;
1269
1270           /* If we got here and the RE flag is set, it's because
1271              we're dealing with a regexp known to be trivial, so the
1272              backslash just quotes the next character.  */
1273           if (RE && *base_pat == '\\')
1274             {
1275               len--;
1276               base_pat++;
1277             }
1278           c = charptr_emchar (base_pat);
1279           translated = TRANSLATE (trt, c);
1280           inverse = TRANSLATE (inverse_trt, c);
1281
1282           orig_bytelen = charcount_to_bytecount (base_pat, 1);
1283           inv_bytelen = set_charptr_emchar (tmp_str, inverse);
1284           new_bytelen = set_charptr_emchar (tmp_str, translated);
1285
1286
1287           if (new_bytelen != orig_bytelen || inv_bytelen != orig_bytelen)
1288             boyer_moore_ok = 0;
1289           if (translated != c || inverse != c)
1290             {
1291               /* Keep track of which character set row
1292                  contains the characters that need translation.  */
1293 #ifdef UTF2000
1294               int charset_base_code = c >> 6;
1295 #else
1296               int charset_base_code = c & ~CHAR_FIELD3_MASK;
1297 #endif
1298               if (charset_base == -1)
1299                 charset_base = charset_base_code;
1300               else if (charset_base != charset_base_code)
1301                 /* If two different rows appear, needing translation,
1302                    then we cannot use boyer_moore search.  */
1303                 boyer_moore_ok = 0;
1304             }
1305           memcpy (pat, tmp_str, new_bytelen);
1306           pat += new_bytelen;
1307           base_pat += orig_bytelen;
1308           len -= orig_bytelen;
1309         }
1310 #else /* not MULE */
1311       while (--len >= 0)
1312         {
1313           /* If we got here and the RE flag is set, it's because
1314              we're dealing with a regexp known to be trivial, so the
1315              backslash just quotes the next character.  */
1316           if (RE && *base_pat == '\\')
1317             {
1318               len--;
1319               base_pat++;
1320             }
1321           *pat++ = TRANSLATE (trt, *base_pat++);
1322         }
1323 #endif /* MULE */
1324       len = pat - patbuf;
1325       pat = base_pat = patbuf;
1326       if (boyer_moore_ok)
1327         return boyer_moore (buf, base_pat, len, pos, lim, n,
1328                             trt, inverse_trt, charset_base);
1329       else
1330         return simple_search (buf, base_pat, len, pos, lim, n, trt);
1331     }
1332 }
1333
1334 /* Do a simple string search N times for the string PAT,
1335    whose length is LEN/LEN_BYTE,
1336    from buffer position POS/POS_BYTE until LIM/LIM_BYTE.
1337    TRT is the translation table.
1338
1339    Return the character position where the match is found.
1340    Otherwise, if M matches remained to be found, return -M.
1341
1342    This kind of search works regardless of what is in PAT and
1343    regardless of what is in TRT.  It is used in cases where
1344    boyer_moore cannot work.  */
1345
1346 static Bufpos
1347 simple_search (struct buffer *buf, Bufbyte *base_pat, Bytecount len_byte,
1348                Bytind idx, Bytind lim, EMACS_INT n, Lisp_Object trt)
1349 {
1350   int forward = n > 0;
1351   Bytecount buf_len = 0; /* Shut up compiler. */
1352
1353   if (lim > idx)
1354     while (n > 0)
1355       {
1356         while (1)
1357           {
1358             Bytecount this_len = len_byte;
1359             Bytind this_idx = idx;
1360             Bufbyte *p = base_pat;
1361             if (idx >= lim)
1362               goto stop;
1363
1364             while (this_len > 0)
1365               {
1366                 Emchar pat_ch, buf_ch;
1367                 Bytecount pat_len;
1368
1369                 pat_ch = charptr_emchar (p);
1370                 buf_ch = BI_BUF_FETCH_CHAR (buf, this_idx);
1371
1372                 buf_ch = TRANSLATE (trt, buf_ch);
1373
1374                 if (buf_ch != pat_ch)
1375                   break;
1376
1377                 pat_len = charcount_to_bytecount (p, 1);
1378                 p += pat_len;
1379                 this_len -= pat_len;
1380                 INC_BYTIND (buf, this_idx);
1381               }
1382             if (this_len == 0)
1383               {
1384                 buf_len = this_idx - idx;
1385                 idx = this_idx;
1386                 break;
1387               }
1388             INC_BYTIND (buf, idx);
1389           }
1390         n--;
1391       }
1392   else
1393     while (n < 0)
1394       {
1395         while (1)
1396           {
1397             Bytecount this_len = len_byte;
1398             Bytind this_idx = idx;
1399             Bufbyte *p;
1400             if (idx <= lim)
1401               goto stop;
1402             p = base_pat + len_byte;
1403
1404             while (this_len > 0)
1405               {
1406                 Emchar pat_ch, buf_ch;
1407
1408                 DEC_CHARPTR (p);
1409                 DEC_BYTIND (buf, this_idx);
1410                 pat_ch = charptr_emchar (p);
1411                 buf_ch = BI_BUF_FETCH_CHAR (buf, this_idx);
1412
1413                 buf_ch = TRANSLATE (trt, buf_ch);
1414
1415                 if (buf_ch != pat_ch)
1416                   break;
1417
1418                 this_len -= charcount_to_bytecount (p, 1);
1419               }
1420             if (this_len == 0)
1421               {
1422                 buf_len = idx - this_idx;
1423                 idx = this_idx;
1424                 break;
1425               }
1426             DEC_BYTIND (buf, idx);
1427           }
1428         n++;
1429       }
1430  stop:
1431   if (n == 0)
1432     {
1433       Bufpos beg, end, retval;
1434       if (forward)
1435         {
1436           beg = bytind_to_bufpos (buf, idx - buf_len);
1437           retval = end = bytind_to_bufpos (buf, idx);
1438         }
1439       else
1440         {
1441           retval = beg = bytind_to_bufpos (buf, idx);
1442           end = bytind_to_bufpos (buf, idx + buf_len);
1443         }
1444       set_search_regs (buf, beg, end - beg);
1445
1446       return retval;
1447     }
1448   else if (n > 0)
1449     return -n;
1450   else
1451     return n;
1452 }
1453
1454 /* Do Boyer-Moore search N times for the string PAT,
1455    whose length is LEN/LEN_BYTE,
1456    from buffer position POS/POS_BYTE until LIM/LIM_BYTE.
1457    DIRECTION says which direction we search in.
1458    TRT and INVERSE_TRT are translation tables.
1459
1460    This kind of search works if all the characters in PAT that have
1461    nontrivial translation are the same aside from the last byte.  This
1462    makes it possible to translate just the last byte of a character,
1463    and do so after just a simple test of the context.
1464
1465    If that criterion is not satisfied, do not call this function.  */
1466             
1467 static Bufpos
1468 boyer_moore (struct buffer *buf, Bufbyte *base_pat, Bytecount len,
1469              Bytind pos, Bytind lim, EMACS_INT n, Lisp_Object trt,
1470              Lisp_Object inverse_trt, int charset_base)
1471 {
1472   /* #### Someone really really really needs to comment the workings
1473      of this junk somewhat better.
1474
1475      BTW "BM" stands for Boyer-Moore, which is one of the standard
1476      string-searching algorithms.  It's the best string-searching
1477      algorithm out there, provided that:
1478
1479      a) You're not fazed by algorithm complexity. (Rabin-Karp, which
1480      uses hashing, is much much easier to code but not as fast.)
1481      b) You can freely move backwards in the string that you're
1482      searching through.
1483
1484      As the comment below tries to explain (but garbles in typical
1485      programmer-ese), the idea is that you don't have to do a
1486      string match at every successive position in the text.  For
1487      example, let's say the pattern is "a very long string".  We
1488      compare the last character in the string (`g') with the
1489      corresponding character in the text.  If it mismatches, and
1490      it is, say, `z', then we can skip forward by the entire
1491      length of the pattern because `z' does not occur anywhere
1492      in the pattern.  If the mismatching character does occur
1493      in the pattern, we can usually still skip forward by more
1494      than one: e.g. if it is `l', then we can skip forward
1495      by the length of the substring "ong string" -- i.e. the
1496      largest end section of the pattern that does not contain
1497      the mismatched character.  So what we do is compute, for
1498      each possible character, the distance we can skip forward
1499      (the "stride") and use it in the string matching.  This
1500      is what the BM_tab holds. */
1501   REGISTER EMACS_INT *BM_tab;
1502   EMACS_INT *BM_tab_base;
1503   REGISTER Bytecount dirlen;
1504   EMACS_INT infinity;
1505   Bytind limit;
1506   Bytecount stride_for_teases = 0;
1507   REGISTER EMACS_INT i, j;
1508   Bufbyte *pat, *pat_end;
1509   REGISTER Bufbyte *cursor, *p_limit, *ptr2;
1510   Bufbyte simple_translate[0400];
1511   REGISTER int direction = ((n > 0) ? 1 : -1);
1512 #ifdef MULE
1513   Bufbyte translate_prev_byte = 0;
1514   Bufbyte translate_anteprev_byte = 0;
1515 #endif
1516 #ifdef C_ALLOCA
1517   EMACS_INT BM_tab_space[0400];
1518   BM_tab = &BM_tab_space[0];
1519 #else
1520   BM_tab = alloca_array (EMACS_INT, 256);
1521 #endif
1522   
1523   /* The general approach is that we are going to maintain that we
1524      know the first (closest to the present position, in whatever
1525      direction we're searching) character that could possibly be
1526      the last (furthest from present position) character of a
1527      valid match.  We advance the state of our knowledge by
1528      looking at that character and seeing whether it indeed
1529      matches the last character of the pattern.  If it does, we
1530      take a closer look.  If it does not, we move our pointer (to
1531      putative last characters) as far as is logically possible.
1532      This amount of movement, which I call a stride, will be the
1533      length of the pattern if the actual character appears nowhere
1534      in the pattern, otherwise it will be the distance from the
1535      last occurrence of that character to the end of the pattern.
1536      As a coding trick, an enormous stride is coded into the table
1537      for characters that match the last character.  This allows
1538      use of only a single test, a test for having gone past the
1539      end of the permissible match region, to test for both
1540      possible matches (when the stride goes past the end
1541      immediately) and failure to match (where you get nudged past
1542      the end one stride at a time).
1543
1544      Here we make a "mickey mouse" BM table.  The stride of the
1545      search is determined only by the last character of the
1546      putative match.  If that character does not match, we will
1547      stride the proper distance to propose a match that
1548      superimposes it on the last instance of a character that
1549      matches it (per trt), or misses it entirely if there is
1550      none. */
1551
1552   dirlen = len * direction;
1553   infinity = dirlen - (lim + pos + len + len) * direction;
1554   /* Record position after the end of the pattern.  */
1555   pat_end = base_pat + len;
1556   if (direction < 0)
1557     base_pat = pat_end - 1;
1558   BM_tab_base = BM_tab;
1559   BM_tab += 0400;
1560   j = dirlen;           /* to get it in a register */
1561   /* A character that does not appear in the pattern induces a
1562      stride equal to the pattern length. */
1563   while (BM_tab_base != BM_tab)
1564     {
1565       *--BM_tab = j;
1566       *--BM_tab = j;
1567       *--BM_tab = j;
1568       *--BM_tab = j;
1569     }
1570   /* We use this for translation, instead of TRT itself.  We
1571      fill this in to handle the characters that actually occur
1572      in the pattern.  Others don't matter anyway!  */
1573   xzero (simple_translate);
1574   for (i = 0; i < 0400; i++)
1575     simple_translate[i] = i;
1576   i = 0;
1577   while (i != infinity)
1578     {
1579       Bufbyte *ptr = base_pat + i;
1580       i += direction;
1581       if (i == dirlen)
1582         i = infinity;
1583       if (!NILP (trt))
1584         {
1585 #ifdef MULE
1586           Emchar ch, untranslated;
1587           int this_translated = 1;
1588
1589           /* Is *PTR the last byte of a character?  */
1590           if (pat_end - ptr == 1 || BUFBYTE_FIRST_BYTE_P (ptr[1]))
1591             {
1592               Bufbyte *charstart = ptr;
1593               while (!BUFBYTE_FIRST_BYTE_P (*charstart))
1594                 charstart--;
1595               untranslated = charptr_emchar (charstart);
1596 #ifdef UTF2000
1597               if (charset_base == (untranslated >> 6))
1598 #else
1599               if (charset_base == (untranslated & ~CHAR_FIELD3_MASK))
1600 #endif
1601                 {
1602                   ch = TRANSLATE (trt, untranslated);
1603                   if (!BUFBYTE_FIRST_BYTE_P (*ptr))
1604                     {
1605                       translate_prev_byte = ptr[-1];
1606                       if (!BUFBYTE_FIRST_BYTE_P (translate_prev_byte))
1607                         translate_anteprev_byte = ptr[-2];
1608                     }
1609                 }
1610               else
1611                 {
1612                   this_translated = 0;
1613                   ch = *ptr;
1614                 }
1615             }
1616           else
1617             {
1618               ch = *ptr;
1619               this_translated = 0;
1620             }
1621           if (ch > 0400)
1622             j = ((unsigned char) ch | 0200);
1623           else
1624             j = (unsigned char) ch;
1625               
1626           if (i == infinity)
1627             stride_for_teases = BM_tab[j];
1628           BM_tab[j] = dirlen - i;
1629           /* A translation table is accompanied by its inverse --
1630              see comment following downcase_table for details */
1631           if (this_translated)
1632             {
1633               Emchar starting_ch = ch;
1634               EMACS_INT starting_j = j;
1635               while (1)
1636                 {
1637                   ch = TRANSLATE (inverse_trt, ch);
1638                   if (ch > 0400)
1639                     j = ((unsigned char) ch | 0200);
1640                   else
1641                     j = (unsigned char) ch;
1642
1643                   /* For all the characters that map into CH,
1644                      set up simple_translate to map the last byte
1645                      into STARTING_J.  */
1646                   simple_translate[j] = starting_j;
1647                   if (ch == starting_ch)
1648                     break;
1649                   BM_tab[j] = dirlen - i;
1650                 }
1651             }
1652 #else
1653           EMACS_INT k;
1654           j = *ptr;
1655           k = (j = TRANSLATE (trt, j));
1656           if (i == infinity)
1657             stride_for_teases = BM_tab[j];
1658           BM_tab[j] = dirlen - i;
1659           /* A translation table is accompanied by its inverse --
1660              see comment following downcase_table for details */
1661
1662           while ((j = TRANSLATE (inverse_trt, j)) != k)
1663             {
1664               simple_translate[j] = k;
1665               BM_tab[j] = dirlen - i;
1666             }
1667 #endif
1668         }
1669       else
1670         {
1671           j = *ptr;
1672
1673           if (i == infinity)
1674             stride_for_teases = BM_tab[j];
1675           BM_tab[j] = dirlen - i;
1676         }
1677       /* stride_for_teases tells how much to stride if we get a
1678          match on the far character but are subsequently
1679          disappointed, by recording what the stride would have been
1680          for that character if the last character had been
1681          different. */
1682     }
1683   infinity = dirlen - infinity;
1684   pos += dirlen - ((direction > 0) ? direction : 0);
1685   /* loop invariant - pos points at where last char (first char if
1686      reverse) of pattern would align in a possible match.  */
1687   while (n != 0)
1688     {
1689       Bytind tail_end;
1690       Bufbyte *tail_end_ptr;
1691       /* It's been reported that some (broken) compiler thinks
1692          that Boolean expressions in an arithmetic context are
1693          unsigned.  Using an explicit ?1:0 prevents this.  */
1694       if ((lim - pos - ((direction > 0) ? 1 : 0)) * direction < 0)
1695         return n * (0 - direction);
1696       /* First we do the part we can by pointers (maybe
1697          nothing) */
1698       QUIT;
1699       pat = base_pat;
1700       limit = pos - dirlen + direction;
1701       /* XEmacs change: definitions of CEILING_OF and FLOOR_OF
1702          have changed.  See buffer.h. */
1703       limit = ((direction > 0)
1704                ? BI_BUF_CEILING_OF (buf, limit) - 1
1705                : BI_BUF_FLOOR_OF (buf, limit + 1));
1706       /* LIMIT is now the last (not beyond-last!) value POS can
1707          take on without hitting edge of buffer or the gap.  */
1708       limit = ((direction > 0)
1709                ? min (lim - 1, min (limit, pos + 20000))
1710                : max (lim, max (limit, pos - 20000)));
1711       tail_end = BI_BUF_CEILING_OF (buf, pos);
1712       tail_end_ptr = BI_BUF_BYTE_ADDRESS (buf, tail_end);
1713
1714       if ((limit - pos) * direction > 20)
1715         {
1716           p_limit = BI_BUF_BYTE_ADDRESS (buf, limit);
1717           ptr2 = (cursor = BI_BUF_BYTE_ADDRESS (buf, pos));
1718           /* In this loop, pos + cursor - ptr2 is the surrogate
1719              for pos */
1720           while (1)     /* use one cursor setting as long as i can */
1721             {
1722               if (direction > 0) /* worth duplicating */
1723                 {
1724                   /* Use signed comparison if appropriate to make
1725                      cursor+infinity sure to be > p_limit.
1726                      Assuming that the buffer lies in a range of
1727                      addresses that are all "positive" (as ints)
1728                      or all "negative", either kind of comparison
1729                      will work as long as we don't step by
1730                      infinity.  So pick the kind that works when
1731                      we do step by infinity.  */
1732                   if ((EMACS_INT) (p_limit + infinity) >
1733                       (EMACS_INT) p_limit)
1734                     while ((EMACS_INT) cursor <=
1735                            (EMACS_INT) p_limit)
1736                       cursor += BM_tab[*cursor];
1737                   else
1738                     while ((EMACS_UINT) cursor <=
1739                            (EMACS_UINT) p_limit)
1740                       cursor += BM_tab[*cursor];
1741                 }
1742               else
1743                 {
1744                   if ((EMACS_INT) (p_limit + infinity) <
1745                       (EMACS_INT) p_limit)
1746                     while ((EMACS_INT) cursor >=
1747                            (EMACS_INT) p_limit)
1748                       cursor += BM_tab[*cursor];
1749                   else
1750                     while ((EMACS_UINT) cursor >=
1751                            (EMACS_UINT) p_limit)
1752                       cursor += BM_tab[*cursor];
1753                 }
1754               /* If you are here, cursor is beyond the end of the
1755                  searched region.  This can happen if you match on
1756                  the far character of the pattern, because the
1757                  "stride" of that character is infinity, a number
1758                  able to throw you well beyond the end of the
1759                  search.  It can also happen if you fail to match
1760                  within the permitted region and would otherwise
1761                  try a character beyond that region */
1762               if ((cursor - p_limit) * direction <= len)
1763                 break;  /* a small overrun is genuine */
1764               cursor -= infinity; /* large overrun = hit */
1765               i = dirlen - direction;
1766               if (!NILP (trt))
1767                 {
1768                   while ((i -= direction) + direction != 0)
1769                     {
1770 #ifdef MULE
1771                       Emchar ch;
1772                       cursor -= direction;
1773                       /* Translate only the last byte of a character.  */
1774                       if ((cursor == tail_end_ptr
1775                            || BUFBYTE_FIRST_BYTE_P (cursor[1]))
1776                           && (BUFBYTE_FIRST_BYTE_P (cursor[0])
1777                               || (translate_prev_byte == cursor[-1]
1778                                   && (BUFBYTE_FIRST_BYTE_P (translate_prev_byte)
1779                                       || translate_anteprev_byte == cursor[-2]))))
1780                         ch = simple_translate[*cursor];
1781                       else
1782                         ch = *cursor;
1783                       if (pat[i] != ch)
1784                         break;
1785 #else
1786                       if (pat[i] != TRANSLATE (trt, *(cursor -= direction)))
1787                         break;
1788 #endif
1789                     }
1790                 }
1791               else
1792                 {
1793                   while ((i -= direction) + direction != 0)
1794                     if (pat[i] != *(cursor -= direction))
1795                       break;
1796                 }
1797               cursor += dirlen - i - direction; /* fix cursor */
1798               if (i + direction == 0)
1799                 {
1800                   cursor -= direction;
1801
1802                   {
1803                     Bytind bytstart = (pos + cursor - ptr2 +
1804                                        ((direction > 0)
1805                                         ? 1 - len : 0));
1806                     Bufpos bufstart = bytind_to_bufpos (buf, bytstart);
1807                     Bufpos bufend = bytind_to_bufpos (buf, bytstart + len);
1808
1809                     set_search_regs (buf, bufstart, bufend - bufstart);
1810                   }
1811
1812                   if ((n -= direction) != 0)
1813                     cursor += dirlen; /* to resume search */
1814                   else
1815                     return ((direction > 0)
1816                             ? search_regs.end[0] : search_regs.start[0]);
1817                 }
1818               else
1819                 cursor += stride_for_teases; /* <sigh> we lose -  */
1820             }
1821           pos += cursor - ptr2;
1822         }
1823       else
1824         /* Now we'll pick up a clump that has to be done the hard
1825            way because it covers a discontinuity */
1826         {
1827           /* XEmacs change: definitions of CEILING_OF and FLOOR_OF
1828              have changed.  See buffer.h. */
1829           limit = ((direction > 0)
1830                    ? BI_BUF_CEILING_OF (buf, pos - dirlen + 1) - 1
1831                    : BI_BUF_FLOOR_OF (buf, pos - dirlen));
1832           limit = ((direction > 0)
1833                    ? min (limit + len, lim - 1)
1834                    : max (limit - len, lim));
1835           /* LIMIT is now the last value POS can have
1836              and still be valid for a possible match.  */
1837           while (1)
1838             {
1839               /* This loop can be coded for space rather than
1840                  speed because it will usually run only once.
1841                  (the reach is at most len + 21, and typically
1842                  does not exceed len) */
1843               while ((limit - pos) * direction >= 0)
1844                 /* *not* BI_BUF_FETCH_CHAR.  We are working here
1845                    with bytes, not characters. */
1846                 pos += BM_tab[*BI_BUF_BYTE_ADDRESS (buf, pos)];
1847               /* now run the same tests to distinguish going off
1848                  the end, a match or a phony match. */
1849               if ((pos - limit) * direction <= len)
1850                 break;  /* ran off the end */
1851               /* Found what might be a match.
1852                  Set POS back to last (first if reverse) char pos.  */
1853               pos -= infinity;
1854               i = dirlen - direction;
1855               while ((i -= direction) + direction != 0)
1856                 {
1857 #ifdef MULE
1858                   Emchar ch;
1859                   Bufbyte *ptr;
1860 #endif
1861                   pos -= direction;
1862 #ifdef MULE
1863                   ptr = BI_BUF_BYTE_ADDRESS (buf, pos);
1864                   if ((ptr == tail_end_ptr
1865                        || BUFBYTE_FIRST_BYTE_P (ptr[1]))
1866                       && (BUFBYTE_FIRST_BYTE_P (ptr[0])
1867                           || (translate_prev_byte == ptr[-1]
1868                               && (BUFBYTE_FIRST_BYTE_P (translate_prev_byte)
1869                                   || translate_anteprev_byte == ptr[-2]))))
1870                     ch = simple_translate[*ptr];
1871                   else
1872                     ch = *ptr;
1873                   if (pat[i] != ch)
1874                     break;
1875                       
1876 #else
1877                   if (pat[i] != TRANSLATE (trt,
1878                                            *BI_BUF_BYTE_ADDRESS (buf, pos)))
1879                     break;
1880 #endif
1881                 }
1882               /* Above loop has moved POS part or all the way back
1883                  to the first char pos (last char pos if reverse).
1884                  Set it once again at the last (first if reverse)
1885                  char.  */
1886               pos += dirlen - i- direction;
1887               if (i + direction == 0)
1888                 {
1889                   pos -= direction;
1890
1891                   {
1892                     Bytind bytstart = (pos +
1893                                        ((direction > 0)
1894                                         ? 1 - len : 0));
1895                     Bufpos bufstart = bytind_to_bufpos (buf, bytstart);
1896                     Bufpos bufend = bytind_to_bufpos (buf, bytstart + len);
1897
1898                     set_search_regs (buf, bufstart, bufend - bufstart);
1899                   }
1900
1901                   if ((n -= direction) != 0)
1902                     pos += dirlen; /* to resume search */
1903                   else
1904                     return ((direction > 0)
1905                             ? search_regs.end[0] : search_regs.start[0]);
1906                 }
1907               else
1908                 pos += stride_for_teases;
1909             }
1910         }
1911       /* We have done one clump.  Can we continue? */
1912       if ((lim - pos) * direction < 0)
1913         return (0 - n) * direction;
1914     }
1915   return bytind_to_bufpos (buf, pos);
1916 }
1917
1918 /* Record beginning BEG and end BEG + LEN
1919    for a match just found in the current buffer.  */
1920
1921 static void
1922 set_search_regs (struct buffer *buf, Bufpos beg, Charcount len)
1923 {
1924   /* This function has been Mule-ized. */
1925   /* Make sure we have registers in which to store
1926      the match position.  */
1927   if (search_regs.num_regs == 0)
1928     {
1929       search_regs.start = xnew (regoff_t);
1930       search_regs.end   = xnew (regoff_t);
1931       search_regs.num_regs = 1;
1932     }
1933
1934   search_regs.start[0] = beg;
1935   search_regs.end[0] = beg + len;
1936   XSETBUFFER (last_thing_searched, buf);
1937 }
1938
1939 \f
1940 /* Given a string of words separated by word delimiters,
1941    compute a regexp that matches those exact words
1942    separated by arbitrary punctuation.  */
1943
1944 static Lisp_Object
1945 wordify (Lisp_Object buffer, Lisp_Object string)
1946 {
1947   Charcount i, len;
1948   EMACS_INT punct_count = 0, word_count = 0;
1949   struct buffer *buf = decode_buffer (buffer, 0);
1950 #ifdef UTF2000
1951   Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->syntax_table);
1952 #else
1953   Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
1954 #endif
1955
1956   CHECK_STRING (string);
1957   len = XSTRING_CHAR_LENGTH (string);
1958
1959   for (i = 0; i < len; i++)
1960     if (!WORD_SYNTAX_P (syntax_table, string_char (XSTRING (string), i)))
1961       {
1962         punct_count++;
1963         if (i > 0 && WORD_SYNTAX_P (syntax_table,
1964                                     string_char (XSTRING (string), i - 1)))
1965           word_count++;
1966       }
1967   if (WORD_SYNTAX_P (syntax_table, string_char (XSTRING (string), len - 1)))
1968     word_count++;
1969   if (!word_count) return build_string ("");
1970
1971   {
1972     /* The following value is an upper bound on the amount of storage we
1973        need.  In non-Mule, it is exact. */
1974     Bufbyte *storage =
1975       (Bufbyte *) alloca (XSTRING_LENGTH (string) - punct_count +
1976                           5 * (word_count - 1) + 4);
1977     Bufbyte *o = storage;
1978
1979     *o++ = '\\';
1980     *o++ = 'b';
1981
1982     for (i = 0; i < len; i++)
1983       {
1984         Emchar ch = string_char (XSTRING (string), i);
1985
1986         if (WORD_SYNTAX_P (syntax_table, ch))
1987           o += set_charptr_emchar (o, ch);
1988         else if (i > 0
1989                  && WORD_SYNTAX_P (syntax_table,
1990                                    string_char (XSTRING (string), i - 1))
1991                  && --word_count)
1992           {
1993             *o++ = '\\';
1994             *o++ = 'W';
1995             *o++ = '\\';
1996             *o++ = 'W';
1997             *o++ = '*';
1998           }
1999       }
2000
2001     *o++ = '\\';
2002     *o++ = 'b';
2003
2004     return make_string (storage, o - storage);
2005   }
2006 }
2007 \f
2008 DEFUN ("search-backward", Fsearch_backward, 1, 5, "sSearch backward: ", /*
2009 Search backward from point for STRING.
2010 Set point to the beginning of the occurrence found, and return point.
2011
2012 Optional second argument LIMIT bounds the search; it is a buffer
2013 position.  The match found must not extend before that position.
2014 The value nil is equivalent to (point-min).
2015
2016 Optional third argument NOERROR, if t, means just return nil (no
2017 error) if the search fails.  If neither nil nor t, set point to LIMIT
2018 and return nil.
2019
2020 Optional fourth argument COUNT is a repeat count--search for
2021 successive occurrences.
2022
2023 Optional fifth argument BUFFER specifies the buffer to search in and
2024 defaults to the current buffer.
2025
2026 See also the functions `match-beginning', `match-end' and `replace-match'.
2027 */
2028        (string, limit, noerror, count, buffer))
2029 {
2030   return search_command (string, limit, noerror, count, buffer, -1, 0, 0);
2031 }
2032
2033 DEFUN ("search-forward", Fsearch_forward, 1, 5, "sSearch: ", /*
2034 Search forward from point for STRING.
2035 Set point to the end of the occurrence found, and return point.
2036
2037 Optional second argument LIMIT bounds the search; it is a buffer
2038 position.  The match found must not extend after that position.  The
2039 value nil is equivalent to (point-max).
2040
2041 Optional third argument NOERROR, if t, means just return nil (no
2042 error) if the search fails.  If neither nil nor t, set point to LIMIT
2043 and return nil.
2044
2045 Optional fourth argument COUNT is a repeat count--search for
2046 successive occurrences.
2047
2048 Optional fifth argument BUFFER specifies the buffer to search in and
2049 defaults to the current buffer.
2050
2051 See also the functions `match-beginning', `match-end' and `replace-match'.
2052 */
2053        (string, limit, noerror, count, buffer))
2054 {
2055   return search_command (string, limit, noerror, count, buffer, 1, 0, 0);
2056 }
2057
2058 DEFUN ("word-search-backward", Fword_search_backward, 1, 5,
2059        "sWord search backward: ", /*
2060 Search backward from point for STRING, ignoring differences in punctuation.
2061 Set point to the beginning of the occurrence found, and return point.
2062
2063 Optional second argument LIMIT bounds the search; it is a buffer
2064 position.  The match found must not extend before that position.
2065 The value nil is equivalent to (point-min).
2066
2067 Optional third argument NOERROR, if t, means just return nil (no
2068 error) if the search fails.  If neither nil nor t, set point to LIMIT
2069 and return nil.
2070
2071 Optional fourth argument COUNT is a repeat count--search for
2072 successive occurrences.
2073
2074 Optional fifth argument BUFFER specifies the buffer to search in and
2075 defaults to the current buffer.
2076
2077 See also the functions `match-beginning', `match-end' and `replace-match'.
2078 */
2079        (string, limit, noerror, count, buffer))
2080 {
2081   return search_command (wordify (buffer, string), limit, noerror, count,
2082                          buffer, -1, 1, 0);
2083 }
2084
2085 DEFUN ("word-search-forward", Fword_search_forward, 1, 5, "sWord search: ", /*
2086 Search forward from point for STRING, ignoring differences in punctuation.
2087 Set point to the end of the occurrence found, and return point.
2088
2089 Optional second argument LIMIT bounds the search; it is a buffer
2090 position.  The match found must not extend after that position.  The
2091 value nil is equivalent to (point-max).
2092
2093 Optional third argument NOERROR, if t, means just return nil (no
2094 error) if the search fails.  If neither nil nor t, set point to LIMIT
2095 and return nil.
2096
2097 Optional fourth argument COUNT is a repeat count--search for
2098 successive occurrences.
2099
2100 Optional fifth argument BUFFER specifies the buffer to search in and
2101 defaults to the current buffer.
2102
2103 See also the functions `match-beginning', `match-end' and `replace-match'.
2104 */
2105        (string, limit, noerror, count, buffer))
2106 {
2107   return search_command (wordify (buffer, string), limit, noerror, count,
2108                          buffer, 1, 1, 0);
2109 }
2110
2111 DEFUN ("re-search-backward", Fre_search_backward, 1, 5,
2112        "sRE search backward: ", /*
2113 Search backward from point for match for regular expression REGEXP.
2114 Set point to the beginning of the match, and return point.
2115 The match found is the one starting last in the buffer
2116 and yet ending before the origin of the search.
2117
2118 Optional second argument LIMIT bounds the search; it is a buffer
2119 position.  The match found must not extend before that position.
2120 The value nil is equivalent to (point-min).
2121
2122 Optional third argument NOERROR, if t, means just return nil (no
2123 error) if the search fails.  If neither nil nor t, set point to LIMIT
2124 and return nil.
2125
2126 Optional fourth argument COUNT is a repeat count--search for
2127 successive occurrences.
2128
2129 Optional fifth argument BUFFER specifies the buffer to search in and
2130 defaults to the current buffer.
2131
2132 See also the functions `match-beginning', `match-end' and `replace-match'.
2133 */
2134        (regexp, limit, noerror, count, buffer))
2135 {
2136   return search_command (regexp, limit, noerror, count, buffer, -1, 1, 0);
2137 }
2138
2139 DEFUN ("re-search-forward", Fre_search_forward, 1, 5, "sRE search: ", /*
2140 Search forward from point for regular expression REGEXP.
2141 Set point to the end of the occurrence found, and return point.
2142
2143 Optional second argument LIMIT bounds the search; it is a buffer
2144 position.  The match found must not extend after that position.  The
2145 value nil is equivalent to (point-max).
2146
2147 Optional third argument NOERROR, if t, means just return nil (no
2148 error) if the search fails.  If neither nil nor t, set point to LIMIT
2149 and return nil.
2150
2151 Optional fourth argument COUNT is a repeat count--search for
2152 successive occurrences.
2153
2154 Optional fifth argument BUFFER specifies the buffer to search in and
2155 defaults to the current buffer.
2156
2157 See also the functions `match-beginning', `match-end' and `replace-match'.
2158 */
2159        (regexp, limit, noerror, count, buffer))
2160 {
2161   return search_command (regexp, limit, noerror, count, buffer, 1, 1, 0);
2162 }
2163
2164 DEFUN ("posix-search-backward", Fposix_search_backward, 1, 5,
2165        "sPosix search backward: ", /*
2166 Search backward from point for match for regular expression REGEXP.
2167 Find the longest match in accord with Posix regular expression rules.
2168 Set point to the beginning of the match, and return point.
2169 The match found is the one starting last in the buffer
2170 and yet ending before the origin of the search.
2171
2172 Optional second argument LIMIT bounds the search; it is a buffer
2173 position.  The match found must not extend before that position.
2174 The value nil is equivalent to (point-min).
2175
2176 Optional third argument NOERROR, if t, means just return nil (no
2177 error) if the search fails.  If neither nil nor t, set point to LIMIT
2178 and return nil.
2179
2180 Optional fourth argument COUNT is a repeat count--search for
2181 successive occurrences.
2182
2183 Optional fifth argument BUFFER specifies the buffer to search in and
2184 defaults to the current buffer.
2185
2186 See also the functions `match-beginning', `match-end' and `replace-match'.
2187 */
2188        (regexp, limit, noerror, count, buffer))
2189 {
2190   return search_command (regexp, limit, noerror, count, buffer, -1, 1, 1);
2191 }
2192
2193 DEFUN ("posix-search-forward", Fposix_search_forward, 1, 5, "sPosix search: ", /*
2194 Search forward from point for regular expression REGEXP.
2195 Find the longest match in accord with Posix regular expression rules.
2196 Set point to the end of the occurrence found, and return point.
2197
2198 Optional second argument LIMIT bounds the search; it is a buffer
2199 position.  The match found must not extend after that position.  The
2200 value nil is equivalent to (point-max).
2201
2202 Optional third argument NOERROR, if t, means just return nil (no
2203 error) if the search fails.  If neither nil nor t, set point to LIMIT
2204 and return nil.
2205
2206 Optional fourth argument COUNT is a repeat count--search for
2207 successive occurrences.
2208
2209 Optional fifth argument BUFFER specifies the buffer to search in and
2210 defaults to the current buffer.
2211
2212 See also the functions `match-beginning', `match-end' and `replace-match'.
2213 */
2214        (regexp, limit, noerror, count, buffer))
2215 {
2216   return search_command (regexp, limit, noerror, count, buffer, 1, 1, 1);
2217 }
2218
2219 \f
2220 static Lisp_Object
2221 free_created_dynarrs (Lisp_Object cons)
2222 {
2223   Dynarr_free (get_opaque_ptr (XCAR (cons)));
2224   Dynarr_free (get_opaque_ptr (XCDR (cons)));
2225   free_opaque_ptr (XCAR (cons));
2226   free_opaque_ptr (XCDR (cons));
2227   free_cons (XCONS (cons));
2228   return Qnil;
2229 }
2230
2231 DEFUN ("replace-match", Freplace_match, 1, 5, 0, /*
2232 Replace text matched by last search with REPLACEMENT.
2233 If second arg FIXEDCASE is non-nil, do not alter case of replacement text.
2234 Otherwise maybe capitalize the whole text, or maybe just word initials,
2235 based on the replaced text.
2236 If the replaced text has only capital letters
2237 and has at least one multiletter word, convert REPLACEMENT to all caps.
2238 If the replaced text has at least one word starting with a capital letter,
2239 then capitalize each word in REPLACEMENT.
2240
2241 If third arg LITERAL is non-nil, insert REPLACEMENT literally.
2242 Otherwise treat `\\' as special:
2243   `\\&' in REPLACEMENT means substitute original matched text.
2244   `\\N' means substitute what matched the Nth `\\(...\\)'.
2245        If Nth parens didn't match, substitute nothing.
2246   `\\\\' means insert one `\\'.
2247   `\\u' means upcase the next character.
2248   `\\l' means downcase the next character.
2249   `\\U' means begin upcasing all following characters.
2250   `\\L' means begin downcasing all following characters.
2251   `\\E' means terminate the effect of any `\\U' or `\\L'.
2252   Case changes made with `\\u', `\\l', `\\U', and `\\L' override
2253   all other case changes that may be made in the replaced text.
2254 FIXEDCASE and LITERAL are optional arguments.
2255 Leaves point at end of replacement text.
2256
2257 The optional fourth argument STRING can be a string to modify.
2258 In that case, this function creates and returns a new string
2259 which is made by replacing the part of STRING that was matched.
2260 When fourth argument is a string, fifth argument STRBUFFER specifies
2261 the buffer to be used for syntax-table and case-table lookup and
2262 defaults to the current buffer.  When fourth argument is not a string,
2263 the buffer that the match occurred in has automatically been remembered
2264 and you do not need to specify it.
2265 */
2266        (replacement, fixedcase, literal, string, strbuffer))
2267 {
2268   /* This function has been Mule-ized. */
2269   /* This function can GC */
2270   enum { nochange, all_caps, cap_initial } case_action;
2271   Bufpos pos, last;
2272   int some_multiletter_word;
2273   int some_lowercase;
2274   int some_uppercase;
2275   int some_nonuppercase_initial;
2276   Emchar c, prevc;
2277   Charcount inslen;
2278   struct buffer *buf;
2279   Lisp_Char_Table *syntax_table;
2280   int mc_count;
2281   Lisp_Object buffer;
2282   int_dynarr *ul_action_dynarr = 0;
2283   int_dynarr *ul_pos_dynarr = 0;
2284   int speccount;
2285
2286   CHECK_STRING (replacement);
2287
2288   if (! NILP (string))
2289     {
2290       CHECK_STRING (string);
2291       if (!EQ (last_thing_searched, Qt))
2292         error ("last thing matched was not a string");
2293       /* If the match data
2294          were abstracted into a special "match data" type instead
2295          of the typical half-assed "let the implementation be
2296          visible" form it's in, we could extend it to include
2297          the last string matched and the buffer used for that
2298          matching.  But of course we can't change it as it is. */
2299       buf = decode_buffer (strbuffer, 0);
2300       XSETBUFFER (buffer, buf);
2301     }
2302   else
2303     {
2304       if (!BUFFERP (last_thing_searched))
2305         error ("last thing matched was not a buffer");
2306       buffer = last_thing_searched;
2307       buf = XBUFFER (buffer);
2308     }
2309
2310 #ifdef UTF2000
2311   syntax_table = XCHAR_TABLE (buf->syntax_table);
2312 #else
2313   syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
2314 #endif
2315
2316   case_action = nochange;       /* We tried an initialization */
2317                                 /* but some C compilers blew it */
2318
2319   if (search_regs.num_regs == 0)
2320     error ("replace-match called before any match found");
2321
2322   if (NILP (string))
2323     {
2324       if (search_regs.start[0] < BUF_BEGV (buf)
2325           || search_regs.start[0] > search_regs.end[0]
2326           || search_regs.end[0] > BUF_ZV (buf))
2327         args_out_of_range (make_int (search_regs.start[0]),
2328                            make_int (search_regs.end[0]));
2329     }
2330   else
2331     {
2332       if (search_regs.start[0] < 0
2333           || search_regs.start[0] > search_regs.end[0]
2334           || search_regs.end[0] > XSTRING_CHAR_LENGTH (string))
2335         args_out_of_range (make_int (search_regs.start[0]),
2336                            make_int (search_regs.end[0]));
2337     }
2338
2339   if (NILP (fixedcase))
2340     {
2341       /* Decide how to casify by examining the matched text. */
2342
2343       last = search_regs.end[0];
2344       prevc = '\n';
2345       case_action = all_caps;
2346
2347       /* some_multiletter_word is set nonzero if any original word
2348          is more than one letter long. */
2349       some_multiletter_word = 0;
2350       some_lowercase = 0;
2351       some_nonuppercase_initial = 0;
2352       some_uppercase = 0;
2353
2354       for (pos = search_regs.start[0]; pos < last; pos++)
2355         {
2356           if (NILP (string))
2357             c = BUF_FETCH_CHAR (buf, pos);
2358           else
2359             c = string_char (XSTRING (string), pos);
2360
2361           if (LOWERCASEP (buf, c))
2362             {
2363               /* Cannot be all caps if any original char is lower case */
2364
2365               some_lowercase = 1;
2366               if (!WORD_SYNTAX_P (syntax_table, prevc))
2367                 some_nonuppercase_initial = 1;
2368               else
2369                 some_multiletter_word = 1;
2370             }
2371           else if (!NOCASEP (buf, c))
2372             {
2373               some_uppercase = 1;
2374               if (!WORD_SYNTAX_P (syntax_table, prevc))
2375                 ;
2376               else
2377                 some_multiletter_word = 1;
2378             }
2379           else
2380             {
2381               /* If the initial is a caseless word constituent,
2382                  treat that like a lowercase initial.  */
2383               if (!WORD_SYNTAX_P (syntax_table, prevc))
2384                 some_nonuppercase_initial = 1;
2385             }
2386
2387           prevc = c;
2388         }
2389
2390       /* Convert to all caps if the old text is all caps
2391          and has at least one multiletter word.  */
2392       if (! some_lowercase && some_multiletter_word)
2393         case_action = all_caps;
2394       /* Capitalize each word, if the old text has all capitalized words.  */
2395       else if (!some_nonuppercase_initial && some_multiletter_word)
2396         case_action = cap_initial;
2397       else if (!some_nonuppercase_initial && some_uppercase)
2398         /* Should x -> yz, operating on X, give Yz or YZ?
2399            We'll assume the latter.  */
2400         case_action = all_caps;
2401       else
2402         case_action = nochange;
2403     }
2404
2405   /* Do replacement in a string.  */
2406   if (!NILP (string))
2407     {
2408       Lisp_Object before, after;
2409
2410       speccount = specpdl_depth ();
2411       before = Fsubstring (string, Qzero, make_int (search_regs.start[0]));
2412       after = Fsubstring (string, make_int (search_regs.end[0]), Qnil);
2413
2414       /* Do case substitution into REPLACEMENT if desired.  */
2415       if (NILP (literal))
2416         {
2417           Charcount stlen = XSTRING_CHAR_LENGTH (replacement);
2418           Charcount strpos;
2419           /* XEmacs change: rewrote this loop somewhat to make it
2420              cleaner.  Also added \U, \E, etc. */
2421           Charcount literal_start = 0;
2422           /* We build up the substituted string in ACCUM.  */
2423           Lisp_Object accum;
2424
2425           accum = Qnil;
2426
2427           /* OK, the basic idea here is that we scan through the
2428              replacement string until we find a backslash, which
2429              represents a substring of the original string to be
2430              substituted.  We then append onto ACCUM the literal
2431              text before the backslash (LASTPOS marks the
2432              beginning of this) followed by the substring of the
2433              original string that needs to be inserted. */
2434           for (strpos = 0; strpos < stlen; strpos++)
2435             {
2436               /* If LITERAL_END is set, we've encountered a backslash
2437                  (the end of literal text to be inserted). */
2438               Charcount literal_end = -1;
2439               /* If SUBSTART is set, we need to also insert the
2440                  text from SUBSTART to SUBEND in the original string. */
2441               Charcount substart = -1;
2442               Charcount subend   = -1;
2443
2444               c = string_char (XSTRING (replacement), strpos);
2445               if (c == '\\' && strpos < stlen - 1)
2446                 {
2447                   c = string_char (XSTRING (replacement), ++strpos);
2448                   if (c == '&')
2449                     {
2450                       literal_end = strpos - 1;
2451                       substart = search_regs.start[0];
2452                       subend = search_regs.end[0];
2453                     }
2454                   else if (c >= '1' && c <= '9' &&
2455                            c <= search_regs.num_regs + '0')
2456                     {
2457                       if (search_regs.start[c - '0'] >= 0)
2458                         {
2459                           literal_end = strpos - 1;
2460                           substart = search_regs.start[c - '0'];
2461                           subend = search_regs.end[c - '0'];
2462                         }
2463                     }
2464                   else if (c == 'U' || c == 'u' || c == 'L' || c == 'l' ||
2465                            c == 'E')
2466                     {
2467                       /* Keep track of all case changes requested, but don't
2468                          make them now.  Do them later so we override
2469                          everything else. */
2470                       if (!ul_pos_dynarr)
2471                         {
2472                           ul_pos_dynarr = Dynarr_new (int);
2473                           ul_action_dynarr = Dynarr_new (int);
2474                           record_unwind_protect
2475                             (free_created_dynarrs,
2476                              noseeum_cons
2477                              (make_opaque_ptr (ul_pos_dynarr),
2478                               make_opaque_ptr (ul_action_dynarr)));
2479                         }
2480                       literal_end = strpos - 1;
2481                       Dynarr_add (ul_pos_dynarr,
2482                                   (!NILP (accum)
2483                                   ? XSTRING_CHAR_LENGTH (accum)
2484                                   : 0) + (literal_end - literal_start));
2485                       Dynarr_add (ul_action_dynarr, c);
2486                     }
2487                   else if (c == '\\')
2488                     /* So we get just one backslash. */
2489                     literal_end = strpos;
2490                 }
2491               if (literal_end >= 0)
2492                 {
2493                   Lisp_Object literal_text = Qnil;
2494                   Lisp_Object substring = Qnil;
2495                   if (literal_end != literal_start)
2496                     literal_text = Fsubstring (replacement,
2497                                                make_int (literal_start),
2498                                                make_int (literal_end));
2499                   if (substart >= 0 && subend != substart)
2500                     substring = Fsubstring (string,
2501                                             make_int (substart),
2502                                             make_int (subend));
2503                   if (!NILP (literal_text) || !NILP (substring))
2504                     accum = concat3 (accum, literal_text, substring);
2505                   literal_start = strpos + 1;
2506                 }
2507             }
2508
2509           if (strpos != literal_start)
2510             /* some literal text at end to be inserted */
2511             replacement = concat2 (accum, Fsubstring (replacement,
2512                                                       make_int (literal_start),
2513                                                       make_int (strpos)));
2514           else
2515             replacement = accum;
2516         }
2517
2518       /* replacement can be nil. */
2519       if (NILP (replacement))
2520         replacement = build_string ("");
2521
2522       if (case_action == all_caps)
2523         replacement = Fupcase (replacement, buffer);
2524       else if (case_action == cap_initial)
2525         replacement = Fupcase_initials (replacement, buffer);
2526
2527       /* Now finally, we need to process the \U's, \E's, etc. */
2528       if (ul_pos_dynarr)
2529         {
2530           int i = 0;
2531           int cur_action = 'E';
2532           Charcount stlen = XSTRING_CHAR_LENGTH (replacement);
2533           Charcount strpos;
2534
2535           for (strpos = 0; strpos < stlen; strpos++)
2536             {
2537               Emchar curchar = string_char (XSTRING (replacement), strpos);
2538               Emchar newchar = -1;
2539               if (i < Dynarr_length (ul_pos_dynarr) &&
2540                   strpos == Dynarr_at (ul_pos_dynarr, i))
2541                 {
2542                   int new_action = Dynarr_at (ul_action_dynarr, i);
2543                   i++;
2544                   if (new_action == 'u')
2545                     newchar = UPCASE (buf, curchar);
2546                   else if (new_action == 'l')
2547                     newchar = DOWNCASE (buf, curchar);
2548                   else
2549                     cur_action = new_action;
2550                 }
2551               if (newchar == -1)
2552                 {
2553                   if (cur_action == 'U')
2554                     newchar = UPCASE (buf, curchar);
2555                   else if (cur_action == 'L')
2556                     newchar = DOWNCASE (buf, curchar);
2557                   else
2558                     newchar = curchar;
2559                 }
2560               if (newchar != curchar)
2561                 set_string_char (XSTRING (replacement), strpos, newchar);
2562             }
2563         }
2564
2565       /* frees the Dynarrs if necessary. */
2566       unbind_to (speccount, Qnil);
2567       return concat3 (before, replacement, after);
2568     }
2569
2570   mc_count = begin_multiple_change (buf, search_regs.start[0],
2571                                     search_regs.end[0]);
2572
2573   /* begin_multiple_change() records an unwind-protect, so we need to
2574      record this value now. */
2575   speccount = specpdl_depth ();
2576
2577   /* We insert the replacement text before the old text, and then
2578      delete the original text.  This means that markers at the
2579      beginning or end of the original will float to the corresponding
2580      position in the replacement.  */
2581   BUF_SET_PT (buf, search_regs.start[0]);
2582   if (!NILP (literal))
2583     Finsert (1, &replacement);
2584   else
2585     {
2586       Charcount stlen = XSTRING_CHAR_LENGTH (replacement);
2587       Charcount strpos;
2588       struct gcpro gcpro1;
2589       GCPRO1 (replacement);
2590       for (strpos = 0; strpos < stlen; strpos++)
2591         {
2592           Charcount offset = BUF_PT (buf) - search_regs.start[0];
2593
2594           c = string_char (XSTRING (replacement), strpos);
2595           if (c == '\\' && strpos < stlen - 1)
2596             {
2597               c = string_char (XSTRING (replacement), ++strpos);
2598               if (c == '&')
2599                 Finsert_buffer_substring
2600                   (buffer,
2601                    make_int (search_regs.start[0] + offset),
2602                    make_int (search_regs.end[0] + offset));
2603               else if (c >= '1' && c <= '9' &&
2604                        c <= search_regs.num_regs + '0')
2605                 {
2606                   if (search_regs.start[c - '0'] >= 1)
2607                     Finsert_buffer_substring
2608                       (buffer,
2609                        make_int (search_regs.start[c - '0'] + offset),
2610                        make_int (search_regs.end[c - '0'] + offset));
2611                 }
2612               else if (c == 'U' || c == 'u' || c == 'L' || c == 'l' ||
2613                        c == 'E')
2614                 {
2615                   /* Keep track of all case changes requested, but don't
2616                      make them now.  Do them later so we override
2617                      everything else. */
2618                   if (!ul_pos_dynarr)
2619                     {
2620                       ul_pos_dynarr = Dynarr_new (int);
2621                       ul_action_dynarr = Dynarr_new (int);
2622                       record_unwind_protect
2623                         (free_created_dynarrs,
2624                          Fcons (make_opaque_ptr (ul_pos_dynarr),
2625                                 make_opaque_ptr (ul_action_dynarr)));
2626                     }
2627                   Dynarr_add (ul_pos_dynarr, BUF_PT (buf));
2628                   Dynarr_add (ul_action_dynarr, c);
2629                 }
2630               else
2631                 buffer_insert_emacs_char (buf, c);
2632             }
2633           else
2634             buffer_insert_emacs_char (buf, c);
2635         }
2636       UNGCPRO;
2637     }
2638
2639   inslen = BUF_PT (buf) - (search_regs.start[0]);
2640   buffer_delete_range (buf, search_regs.start[0] + inslen, search_regs.end[0] +
2641                        inslen, 0);
2642
2643   if (case_action == all_caps)
2644     Fupcase_region (make_int (BUF_PT (buf) - inslen),
2645                     make_int (BUF_PT (buf)),  buffer);
2646   else if (case_action == cap_initial)
2647     Fupcase_initials_region (make_int (BUF_PT (buf) - inslen),
2648                              make_int (BUF_PT (buf)), buffer);
2649
2650   /* Now go through and make all the case changes that were requested
2651      in the replacement string. */
2652   if (ul_pos_dynarr)
2653     {
2654       Bufpos eend = BUF_PT (buf);
2655       int i = 0;
2656       int cur_action = 'E';
2657
2658       for (pos = BUF_PT (buf) - inslen; pos < eend; pos++)
2659         {
2660           Emchar curchar = BUF_FETCH_CHAR (buf, pos);
2661           Emchar newchar = -1;
2662           if (i < Dynarr_length (ul_pos_dynarr) &&
2663               pos == Dynarr_at (ul_pos_dynarr, i))
2664             {
2665               int new_action = Dynarr_at (ul_action_dynarr, i);
2666               i++;
2667               if (new_action == 'u')
2668                 newchar = UPCASE (buf, curchar);
2669               else if (new_action == 'l')
2670                 newchar = DOWNCASE (buf, curchar);
2671               else
2672                 cur_action = new_action;
2673             }
2674           if (newchar == -1)
2675             {
2676               if (cur_action == 'U')
2677                 newchar = UPCASE (buf, curchar);
2678               else if (cur_action == 'L')
2679                 newchar = DOWNCASE (buf, curchar);
2680               else
2681                 newchar = curchar;
2682             }
2683           if (newchar != curchar)
2684             buffer_replace_char (buf, pos, newchar, 0, 0);
2685         }
2686     }
2687
2688   /* frees the Dynarrs if necessary. */
2689   unbind_to (speccount, Qnil);
2690   end_multiple_change (buf, mc_count);
2691
2692   return Qnil;
2693 }
2694 \f
2695 static Lisp_Object
2696 match_limit (Lisp_Object num, int beginningp)
2697 {
2698   /* This function has been Mule-ized. */
2699   int n;
2700
2701   CHECK_INT (num);
2702   n = XINT (num);
2703   if (n < 0 || n >= search_regs.num_regs)
2704     args_out_of_range (num, make_int (search_regs.num_regs));
2705   if (search_regs.num_regs == 0 ||
2706       search_regs.start[n] < 0)
2707     return Qnil;
2708   return make_int (beginningp ? search_regs.start[n] : search_regs.end[n]);
2709 }
2710
2711 DEFUN ("match-beginning", Fmatch_beginning, 1, 1, 0, /*
2712 Return position of start of text matched by last regexp search.
2713 NUM, specifies which parenthesized expression in the last regexp.
2714  Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
2715 Zero means the entire text matched by the whole regexp or whole string.
2716 */
2717        (num))
2718 {
2719   return match_limit (num, 1);
2720 }
2721
2722 DEFUN ("match-end", Fmatch_end, 1, 1, 0, /*
2723 Return position of end of text matched by last regexp search.
2724 NUM specifies which parenthesized expression in the last regexp.
2725  Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
2726 Zero means the entire text matched by the whole regexp or whole string.
2727 */
2728        (num))
2729 {
2730   return match_limit (num, 0);
2731 }
2732
2733 DEFUN ("match-data", Fmatch_data, 0, 2, 0, /*
2734 Return a list containing all info on what the last regexp search matched.
2735 Element 2N is `(match-beginning N)'; element 2N + 1 is `(match-end N)'.
2736 All the elements are markers or nil (nil if the Nth pair didn't match)
2737 if the last match was on a buffer; integers or nil if a string was matched.
2738 Use `store-match-data' to reinstate the data in this list.
2739
2740 If INTEGERS (the optional first argument) is non-nil, always use integers
2741 \(rather than markers) to represent buffer positions.
2742 If REUSE is a list, reuse it as part of the value.  If REUSE is long enough
2743 to hold all the values, and if INTEGERS is non-nil, no consing is done.
2744 */
2745        (integers, reuse))
2746 {
2747   /* This function has been Mule-ized. */
2748   Lisp_Object tail, prev;
2749   Lisp_Object *data;
2750   int i;
2751   Charcount len;
2752
2753   if (NILP (last_thing_searched))
2754     /*error ("match-data called before any match found");*/
2755     return Qnil;
2756
2757   data = alloca_array (Lisp_Object, 2 * search_regs.num_regs);
2758
2759   len = -1;
2760   for (i = 0; i < search_regs.num_regs; i++)
2761     {
2762       Bufpos start = search_regs.start[i];
2763       if (start >= 0)
2764         {
2765           if (EQ (last_thing_searched, Qt)
2766               || !NILP (integers))
2767             {
2768               data[2 * i] = make_int (start);
2769               data[2 * i + 1] = make_int (search_regs.end[i]);
2770             }
2771           else if (BUFFERP (last_thing_searched))
2772             {
2773               data[2 * i] = Fmake_marker ();
2774               Fset_marker (data[2 * i],
2775                            make_int (start),
2776                            last_thing_searched);
2777               data[2 * i + 1] = Fmake_marker ();
2778               Fset_marker (data[2 * i + 1],
2779                            make_int (search_regs.end[i]),
2780                            last_thing_searched);
2781             }
2782           else
2783             /* last_thing_searched must always be Qt, a buffer, or Qnil.  */
2784             abort ();
2785
2786           len = i;
2787         }
2788       else
2789         data[2 * i] = data [2 * i + 1] = Qnil;
2790     }
2791   if (!CONSP (reuse))
2792     return Flist (2 * len + 2, data);
2793
2794   /* If REUSE is a list, store as many value elements as will fit
2795      into the elements of REUSE.  */
2796   for (prev = Qnil, i = 0, tail = reuse; CONSP (tail); i++, tail = XCDR (tail))
2797     {
2798       if (i < 2 * len + 2)
2799         XCAR (tail) = data[i];
2800       else
2801         XCAR (tail) = Qnil;
2802       prev = tail;
2803     }
2804
2805   /* If we couldn't fit all value elements into REUSE,
2806      cons up the rest of them and add them to the end of REUSE.  */
2807   if (i < 2 * len + 2)
2808     XCDR (prev) = Flist (2 * len + 2 - i, data + i);
2809
2810   return reuse;
2811 }
2812
2813
2814 DEFUN ("store-match-data", Fstore_match_data, 1, 1, 0, /*
2815 Set internal data on last search match from elements of LIST.
2816 LIST should have been created by calling `match-data' previously.
2817 */
2818        (list))
2819 {
2820   /* This function has been Mule-ized. */
2821   REGISTER int i;
2822   REGISTER Lisp_Object marker;
2823   int num_regs;
2824   int length;
2825
2826   if (running_asynch_code)
2827     save_search_regs ();
2828
2829   CONCHECK_LIST (list);
2830
2831   /* Unless we find a marker with a buffer in LIST, assume that this
2832      match data came from a string.  */
2833   last_thing_searched = Qt;
2834
2835   /* Allocate registers if they don't already exist.  */
2836   length = XINT (Flength (list)) / 2;
2837   num_regs = search_regs.num_regs;
2838
2839   if (length > num_regs)
2840     {
2841       if (search_regs.num_regs == 0)
2842         {
2843           search_regs.start = xnew_array (regoff_t, length);
2844           search_regs.end   = xnew_array (regoff_t, length);
2845         }
2846       else
2847         {
2848           XREALLOC_ARRAY (search_regs.start, regoff_t, length);
2849           XREALLOC_ARRAY (search_regs.end,   regoff_t, length);
2850         }
2851
2852       search_regs.num_regs = length;
2853     }
2854
2855   for (i = 0; i < num_regs; i++)
2856     {
2857       marker = Fcar (list);
2858       if (NILP (marker))
2859         {
2860           search_regs.start[i] = -1;
2861           list = Fcdr (list);
2862         }
2863       else
2864         {
2865           if (MARKERP (marker))
2866             {
2867               if (XMARKER (marker)->buffer == 0)
2868                 marker = Qzero;
2869               else
2870                 XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer);
2871             }
2872
2873           CHECK_INT_COERCE_MARKER (marker);
2874           search_regs.start[i] = XINT (marker);
2875           list = Fcdr (list);
2876
2877           marker = Fcar (list);
2878           if (MARKERP (marker) && XMARKER (marker)->buffer == 0)
2879             marker = Qzero;
2880
2881           CHECK_INT_COERCE_MARKER (marker);
2882           search_regs.end[i] = XINT (marker);
2883         }
2884       list = Fcdr (list);
2885     }
2886
2887   return Qnil;
2888 }
2889
2890 /* If non-zero the match data have been saved in saved_search_regs
2891    during the execution of a sentinel or filter. */
2892 static int search_regs_saved;
2893 static struct re_registers saved_search_regs;
2894
2895 /* Called from Flooking_at, Fstring_match, search_buffer, Fstore_match_data
2896    if asynchronous code (filter or sentinel) is running. */
2897 static void
2898 save_search_regs (void)
2899 {
2900   if (!search_regs_saved)
2901     {
2902       saved_search_regs.num_regs = search_regs.num_regs;
2903       saved_search_regs.start = search_regs.start;
2904       saved_search_regs.end = search_regs.end;
2905       search_regs.num_regs = 0;
2906       search_regs.start = 0;
2907       search_regs.end = 0;
2908
2909       search_regs_saved = 1;
2910     }
2911 }
2912
2913 /* Called upon exit from filters and sentinels. */
2914 void
2915 restore_match_data (void)
2916 {
2917   if (search_regs_saved)
2918     {
2919       if (search_regs.num_regs > 0)
2920         {
2921           xfree (search_regs.start);
2922           xfree (search_regs.end);
2923         }
2924       search_regs.num_regs = saved_search_regs.num_regs;
2925       search_regs.start = saved_search_regs.start;
2926       search_regs.end = saved_search_regs.end;
2927
2928       search_regs_saved = 0;
2929     }
2930 }
2931
2932 /* Quote a string to inactivate reg-expr chars */
2933
2934 DEFUN ("regexp-quote", Fregexp_quote, 1, 1, 0, /*
2935 Return a regexp string which matches exactly STRING and nothing else.
2936 */
2937        (string))
2938 {
2939   REGISTER Bufbyte *in, *out, *end;
2940   REGISTER Bufbyte *temp;
2941
2942   CHECK_STRING (string);
2943
2944   temp = (Bufbyte *) alloca (XSTRING_LENGTH (string) * 2);
2945
2946   /* Now copy the data into the new string, inserting escapes. */
2947
2948   in = XSTRING_DATA (string);
2949   end = in + XSTRING_LENGTH (string);
2950   out = temp;
2951
2952   while (in < end)
2953     {
2954       Emchar c = charptr_emchar (in);
2955
2956       if (c == '[' || c == ']'
2957           || c == '*' || c == '.' || c == '\\'
2958           || c == '?' || c == '+'
2959           || c == '^' || c == '$')
2960         *out++ = '\\';
2961       out += set_charptr_emchar (out, c);
2962       INC_CHARPTR (in);
2963     }
2964
2965   return make_string (temp, out - temp);
2966 }
2967
2968 DEFUN ("set-word-regexp", Fset_word_regexp, 1, 1, 0, /*
2969 Set the regexp to be used to match a word in regular-expression searching.
2970 #### Not yet implemented.  Currently does nothing.
2971 #### Do not use this yet.  Its calling interface is likely to change.
2972 */
2973        (regexp))
2974 {
2975   return Qnil;
2976 }
2977
2978 \f
2979 /************************************************************************/
2980 /*                            initialization                            */
2981 /************************************************************************/
2982
2983 void
2984 syms_of_search (void)
2985 {
2986
2987   DEFERROR_STANDARD (Qsearch_failed, Qinvalid_operation);
2988   DEFERROR_STANDARD (Qinvalid_regexp, Qsyntax_error);
2989
2990   DEFSUBR (Flooking_at);
2991   DEFSUBR (Fposix_looking_at);
2992   DEFSUBR (Fstring_match);
2993   DEFSUBR (Fposix_string_match);
2994   DEFSUBR (Fskip_chars_forward);
2995   DEFSUBR (Fskip_chars_backward);
2996   DEFSUBR (Fskip_syntax_forward);
2997   DEFSUBR (Fskip_syntax_backward);
2998   DEFSUBR (Fsearch_forward);
2999   DEFSUBR (Fsearch_backward);
3000   DEFSUBR (Fword_search_forward);
3001   DEFSUBR (Fword_search_backward);
3002   DEFSUBR (Fre_search_forward);
3003   DEFSUBR (Fre_search_backward);
3004   DEFSUBR (Fposix_search_forward);
3005   DEFSUBR (Fposix_search_backward);
3006   DEFSUBR (Freplace_match);
3007   DEFSUBR (Fmatch_beginning);
3008   DEFSUBR (Fmatch_end);
3009   DEFSUBR (Fmatch_data);
3010   DEFSUBR (Fstore_match_data);
3011   DEFSUBR (Fregexp_quote);
3012   DEFSUBR (Fset_word_regexp);
3013 }
3014
3015 void
3016 reinit_vars_of_search (void)
3017 {
3018   int i;
3019
3020   last_thing_searched = Qnil;
3021   staticpro_nodump (&last_thing_searched);
3022
3023   for (i = 0; i < REGEXP_CACHE_SIZE; ++i)
3024     {
3025       searchbufs[i].buf.allocated = 100;
3026       searchbufs[i].buf.buffer = (unsigned char *) xmalloc (100);
3027       searchbufs[i].buf.fastmap = searchbufs[i].fastmap;
3028       searchbufs[i].regexp = Qnil;
3029       staticpro_nodump (&searchbufs[i].regexp);
3030       searchbufs[i].next = (i == REGEXP_CACHE_SIZE-1 ? 0 : &searchbufs[i+1]);
3031     }
3032   searchbuf_head = &searchbufs[0];
3033 }
3034
3035 void
3036 vars_of_search (void)
3037 {
3038   reinit_vars_of_search ();
3039
3040   DEFVAR_LISP ("forward-word-regexp", &Vforward_word_regexp /*
3041 *Regular expression to be used in `forward-word'.
3042 #### Not yet implemented.
3043 */ );
3044   Vforward_word_regexp = Qnil;
3045
3046   DEFVAR_LISP ("backward-word-regexp", &Vbackward_word_regexp /*
3047 *Regular expression to be used in `backward-word'.
3048 #### Not yet implemented.
3049 */ );
3050   Vbackward_word_regexp = Qnil;
3051 }
3052
3053 void
3054 complex_vars_of_search (void)
3055 {
3056   Vskip_chars_range_table = Fmake_range_table ();
3057   staticpro (&Vskip_chars_range_table);
3058 }