This source file includes following definitions.
- matcher_overflow
- freeze_buffer_relocation
- compile_pattern_1
- shrink_regexp_cache
- clear_regexp_cache
- unfreeze_pattern
- freeze_pattern
- compile_pattern
- looking_at_1
- string_match_1
- fast_string_match_internal
- fast_c_string_match_internal
- fast_looking_at
- newline_cache_on_off
- find_newline
- scan_newline
- scan_newline_from_point
- find_newline_no_quit
- find_before_next_newline
- search_command
- trivial_regexp_p
- search_buffer_re
- search_buffer_non_re
- search_buffer
- simple_search
- boyer_moore
- set_search_regs
- match_limit
- DEFUN
- DEFUN
- DEFUN
- save_search_regs
- restore_search_regs
- update_search_regs
- unwind_set_match_data
- record_unwind_save_match_data
- DEFUN
- find_newline1
- DEFUN
- syms_of_search
- syms_of_search_for_pdumper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <config.h>
23
24 #include "lisp.h"
25 #include "character.h"
26 #include "buffer.h"
27 #include "syntax.h"
28 #include "charset.h"
29 #include "region-cache.h"
30 #include "blockinput.h"
31 #include "intervals.h"
32 #include "pdumper.h"
33 #include "composite.h"
34
35 #include "regex-emacs.h"
36
37 #define REGEXP_CACHE_SIZE 20
38
39
40
41 struct regexp_cache
42 {
43 struct regexp_cache *next;
44 Lisp_Object regexp, f_whitespace_regexp;
45
46
47
48 Lisp_Object syntax_table;
49 struct re_pattern_buffer buf;
50 char fastmap[0400];
51
52 bool posix;
53
54 bool busy;
55 };
56
57
58 static struct regexp_cache searchbufs[REGEXP_CACHE_SIZE];
59
60
61 static struct regexp_cache *searchbuf_head;
62
63 static void set_search_regs (ptrdiff_t, ptrdiff_t);
64 static void save_search_regs (void);
65 static EMACS_INT simple_search (EMACS_INT, unsigned char *, ptrdiff_t,
66 ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t,
67 ptrdiff_t, ptrdiff_t);
68 static EMACS_INT boyer_moore (EMACS_INT, unsigned char *, ptrdiff_t,
69 Lisp_Object, Lisp_Object, ptrdiff_t,
70 ptrdiff_t, int);
71
72 Lisp_Object re_match_object;
73
74 static AVOID
75 matcher_overflow (void)
76 {
77 error ("Stack overflow in regexp matcher");
78 }
79
80 static void
81 freeze_buffer_relocation (void)
82 {
83 #ifdef REL_ALLOC
84
85
86 r_alloc_inhibit_buffer_relocation (1);
87 record_unwind_protect_int (r_alloc_inhibit_buffer_relocation, 0);
88 #endif
89 }
90
91
92
93
94
95
96
97
98
99
100 static void
101 compile_pattern_1 (struct regexp_cache *cp, Lisp_Object pattern,
102 Lisp_Object translate, bool posix)
103 {
104 const char *whitespace_regexp;
105 char *val;
106
107 eassert (!cp->busy);
108 cp->regexp = Qnil;
109 cp->buf.translate = translate;
110 cp->posix = posix;
111 cp->buf.multibyte = STRING_MULTIBYTE (pattern);
112 cp->buf.charset_unibyte = charset_unibyte;
113 if (STRINGP (Vsearch_spaces_regexp))
114 cp->f_whitespace_regexp = Vsearch_spaces_regexp;
115 else
116 cp->f_whitespace_regexp = Qnil;
117
118 whitespace_regexp = STRINGP (Vsearch_spaces_regexp) ?
119 SSDATA (Vsearch_spaces_regexp) : NULL;
120
121 val = (char *) re_compile_pattern (SSDATA (pattern), SBYTES (pattern),
122 posix, whitespace_regexp, &cp->buf);
123
124
125
126 cp->syntax_table = cp->buf.used_syntax ? BVAR (current_buffer, syntax_table) : Qt;
127
128 if (val)
129 xsignal1 (Qinvalid_regexp, build_string (val));
130
131 cp->regexp = Fcopy_sequence (pattern);
132 }
133
134
135
136
137
138 void
139 shrink_regexp_cache (void)
140 {
141 struct regexp_cache *cp;
142
143 for (cp = searchbuf_head; cp != 0; cp = cp->next)
144 if (!cp->busy)
145 {
146 cp->buf.allocated = cp->buf.used;
147 cp->buf.buffer = xrealloc (cp->buf.buffer, cp->buf.used);
148 }
149 }
150
151
152
153
154
155
156 void
157 clear_regexp_cache (void)
158 {
159 int i;
160
161 for (i = 0; i < REGEXP_CACHE_SIZE; ++i)
162
163
164
165 if (!searchbufs[i].busy && !BASE_EQ (searchbufs[i].syntax_table, Qt))
166 searchbufs[i].regexp = Qnil;
167 }
168
169 static void
170 unfreeze_pattern (void *arg)
171 {
172 struct regexp_cache *searchbuf = arg;
173 searchbuf->busy = false;
174 }
175
176 static void
177 freeze_pattern (struct regexp_cache *searchbuf)
178 {
179 eassert (!searchbuf->busy);
180 record_unwind_protect_ptr (unfreeze_pattern, searchbuf);
181 searchbuf->busy = true;
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195 static struct regexp_cache *
196 compile_pattern (Lisp_Object pattern, struct re_registers *regp,
197 Lisp_Object translate, bool posix, bool multibyte)
198 {
199 struct regexp_cache *cp, **cpp, **lru_nonbusy;
200
201 for (cpp = &searchbuf_head, lru_nonbusy = NULL; ; cpp = &cp->next)
202 {
203 cp = *cpp;
204 if (!cp->busy)
205 lru_nonbusy = cpp;
206
207
208
209
210
211 if (NILP (cp->regexp))
212 goto compile_it;
213 if (SCHARS (cp->regexp) == SCHARS (pattern)
214 && !cp->busy
215 && STRING_MULTIBYTE (cp->regexp) == STRING_MULTIBYTE (pattern)
216 && !NILP (Fstring_equal (cp->regexp, pattern))
217 && BASE_EQ (cp->buf.translate, translate)
218 && cp->posix == posix
219 && (BASE_EQ (cp->syntax_table, Qt)
220 || BASE_EQ (cp->syntax_table,
221 BVAR (current_buffer, syntax_table)))
222 && !NILP (Fequal (cp->f_whitespace_regexp, Vsearch_spaces_regexp))
223 && cp->buf.charset_unibyte == charset_unibyte)
224 break;
225
226
227
228 if (cp->next == 0)
229 {
230 if (!lru_nonbusy)
231 error ("Too much matching reentrancy");
232 cpp = lru_nonbusy;
233 cp = *cpp;
234 compile_it:
235 eassert (!cp->busy);
236 compile_pattern_1 (cp, pattern, translate, posix);
237 break;
238 }
239 }
240
241
242
243
244 *cpp = cp->next;
245 cp->next = searchbuf_head;
246 searchbuf_head = cp;
247
248
249
250 if (regp)
251 re_set_registers (&cp->buf, regp, regp->num_regs, regp->start, regp->end);
252
253
254
255 cp->buf.target_multibyte = multibyte;
256 return cp;
257 }
258
259
260 static Lisp_Object
261 looking_at_1 (Lisp_Object string, bool posix, bool modify_data)
262 {
263 Lisp_Object val;
264 unsigned char *p1, *p2;
265 ptrdiff_t s1, s2;
266 register ptrdiff_t i;
267
268 if (running_asynch_code)
269 save_search_regs ();
270
271
272
273 set_char_table_extras (BVAR (current_buffer, case_canon_table), 2,
274 BVAR (current_buffer, case_eqv_table));
275
276 CHECK_STRING (string);
277
278
279 bool modify_match_data = NILP (Vinhibit_changing_match_data) && modify_data;
280
281 struct regexp_cache *cache_entry = compile_pattern (
282 string,
283 modify_match_data ? &search_regs : NULL,
284 (!NILP (BVAR (current_buffer, case_fold_search))
285 ? BVAR (current_buffer, case_canon_table) : Qnil),
286 posix,
287 !NILP (BVAR (current_buffer, enable_multibyte_characters)));
288
289
290 maybe_quit ();
291
292
293
294
295 p1 = BEGV_ADDR;
296 s1 = GPT_BYTE - BEGV_BYTE;
297 p2 = GAP_END_ADDR;
298 s2 = ZV_BYTE - GPT_BYTE;
299 if (s1 < 0)
300 {
301 p2 = p1;
302 s2 = ZV_BYTE - BEGV_BYTE;
303 s1 = 0;
304 }
305 if (s2 < 0)
306 {
307 s1 = ZV_BYTE - BEGV_BYTE;
308 s2 = 0;
309 }
310
311 specpdl_ref count = SPECPDL_INDEX ();
312 freeze_buffer_relocation ();
313 freeze_pattern (cache_entry);
314 re_match_object = Qnil;
315 i = re_match_2 (&cache_entry->buf, (char *) p1, s1, (char *) p2, s2,
316 PT_BYTE - BEGV_BYTE,
317 modify_match_data ? &search_regs : NULL,
318 ZV_BYTE - BEGV_BYTE);
319
320 if (i == -2)
321 {
322 unbind_to (count, Qnil);
323 matcher_overflow ();
324 }
325
326 val = (i >= 0 ? Qt : Qnil);
327 if (modify_match_data && i >= 0)
328 {
329 for (i = 0; i < search_regs.num_regs; i++)
330 if (search_regs.start[i] >= 0)
331 {
332 search_regs.start[i]
333 = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE);
334 search_regs.end[i]
335 = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
336 }
337
338 XSETBUFFER (last_thing_searched, current_buffer);
339 }
340
341 return unbind_to (count, val);
342 }
343
344 DEFUN ("looking-at", Flooking_at, Slooking_at, 1, 2, 0,
345 doc:
346
347
348 )
349 (Lisp_Object regexp, Lisp_Object inhibit_modify)
350 {
351 return looking_at_1 (regexp, 0, NILP (inhibit_modify));
352 }
353
354 DEFUN ("posix-looking-at", Fposix_looking_at, Sposix_looking_at, 1, 2, 0,
355 doc:
356
357
358
359
360 )
361 (Lisp_Object regexp, Lisp_Object inhibit_modify)
362 {
363 return looking_at_1 (regexp, 1, NILP (inhibit_modify));
364 }
365
366 static Lisp_Object
367 string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
368 bool posix, bool modify_data)
369 {
370 ptrdiff_t val;
371 EMACS_INT pos;
372 ptrdiff_t pos_byte, i;
373 bool modify_match_data = NILP (Vinhibit_changing_match_data) && modify_data;
374
375 if (running_asynch_code)
376 save_search_regs ();
377
378 CHECK_STRING (regexp);
379 CHECK_STRING (string);
380
381 if (NILP (start))
382 pos = 0, pos_byte = 0;
383 else
384 {
385 ptrdiff_t len = SCHARS (string);
386
387 CHECK_FIXNUM (start);
388 pos = XFIXNUM (start);
389 if (pos < 0 && -pos <= len)
390 pos = len + pos;
391 else if (0 > pos || pos > len)
392 args_out_of_range (string, start);
393 pos_byte = string_char_to_byte (string, pos);
394 }
395
396
397
398 set_char_table_extras (BVAR (current_buffer, case_canon_table), 2,
399 BVAR (current_buffer, case_eqv_table));
400
401 specpdl_ref count = SPECPDL_INDEX ();
402 struct regexp_cache *cache_entry
403 = compile_pattern (regexp,
404 modify_match_data ? &search_regs : NULL,
405 (!NILP (BVAR (current_buffer, case_fold_search))
406 ? BVAR (current_buffer, case_canon_table)
407 : Qnil),
408 posix,
409 STRING_MULTIBYTE (string));
410 freeze_pattern (cache_entry);
411 re_match_object = string;
412 val = re_search (&cache_entry->buf, SSDATA (string),
413 SBYTES (string), pos_byte,
414 SBYTES (string) - pos_byte,
415 (modify_match_data ? &search_regs : NULL));
416 unbind_to (count, Qnil);
417
418
419 if (modify_match_data)
420 last_thing_searched = Qt;
421
422 if (val == -2)
423 matcher_overflow ();
424 if (val < 0) return Qnil;
425
426 if (modify_match_data)
427 for (i = 0; i < search_regs.num_regs; i++)
428 if (search_regs.start[i] >= 0)
429 {
430 search_regs.start[i]
431 = string_byte_to_char (string, search_regs.start[i]);
432 search_regs.end[i]
433 = string_byte_to_char (string, search_regs.end[i]);
434 }
435
436 return make_fixnum (string_byte_to_char (string, val));
437 }
438
439 DEFUN ("string-match", Fstring_match, Sstring_match, 2, 4, 0,
440 doc:
441
442
443
444
445
446
447
448
449
450
451 )
452 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
453 Lisp_Object inhibit_modify)
454 {
455 return string_match_1 (regexp, string, start, 0, NILP (inhibit_modify));
456 }
457
458 DEFUN ("posix-string-match", Fposix_string_match, Sposix_string_match, 2, 4, 0,
459 doc:
460
461
462
463
464
465
466
467
468
469
470 )
471 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
472 Lisp_Object inhibit_modify)
473 {
474 return string_match_1 (regexp, string, start, 1, NILP (inhibit_modify));
475 }
476
477
478
479
480
481 ptrdiff_t
482 fast_string_match_internal (Lisp_Object regexp, Lisp_Object string,
483 Lisp_Object table)
484 {
485 re_match_object = string;
486 specpdl_ref count = SPECPDL_INDEX ();
487 struct regexp_cache *cache_entry
488 = compile_pattern (regexp, 0, table, 0, STRING_MULTIBYTE (string));
489 freeze_pattern (cache_entry);
490 ptrdiff_t val = re_search (&cache_entry->buf, SSDATA (string),
491 SBYTES (string), 0,
492 SBYTES (string), 0);
493 unbind_to (count, Qnil);
494 return val;
495 }
496
497
498
499
500
501
502
503
504 ptrdiff_t
505 fast_c_string_match_internal (Lisp_Object regexp,
506 const char *string, ptrdiff_t len,
507 Lisp_Object table)
508 {
509
510
511
512 regexp = string_make_unibyte (regexp);
513
514
515 specpdl_ref count = SPECPDL_INDEX ();
516 struct regexp_cache *cache_entry
517 = compile_pattern (regexp, 0, table, 0, 0);
518 freeze_pattern (cache_entry);
519 re_match_object = Qt;
520 ptrdiff_t val = re_search (&cache_entry->buf, string, len, 0, len, 0);
521 unbind_to (count, Qnil);
522 return val;
523 }
524
525
526
527
528
529
530
531 ptrdiff_t
532 fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte,
533 ptrdiff_t limit, ptrdiff_t limit_byte, Lisp_Object string)
534 {
535 bool multibyte;
536 unsigned char *p1, *p2;
537 ptrdiff_t s1, s2;
538 ptrdiff_t len;
539
540 if (STRINGP (string))
541 {
542 if (pos_byte < 0)
543 pos_byte = string_char_to_byte (string, pos);
544 if (limit_byte < 0)
545 limit_byte = string_char_to_byte (string, limit);
546 p1 = NULL;
547 s1 = 0;
548 p2 = SDATA (string);
549 s2 = SBYTES (string);
550 multibyte = STRING_MULTIBYTE (string);
551 }
552 else
553 {
554 if (pos_byte < 0)
555 pos_byte = CHAR_TO_BYTE (pos);
556 if (limit_byte < 0)
557 limit_byte = CHAR_TO_BYTE (limit);
558 pos_byte -= BEGV_BYTE;
559 limit_byte -= BEGV_BYTE;
560 p1 = BEGV_ADDR;
561 s1 = GPT_BYTE - BEGV_BYTE;
562 p2 = GAP_END_ADDR;
563 s2 = ZV_BYTE - GPT_BYTE;
564 if (s1 < 0)
565 {
566 p2 = p1;
567 s2 = ZV_BYTE - BEGV_BYTE;
568 s1 = 0;
569 }
570 if (s2 < 0)
571 {
572 s1 = ZV_BYTE - BEGV_BYTE;
573 s2 = 0;
574 }
575 multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
576 }
577
578 struct regexp_cache *cache_entry =
579 compile_pattern (regexp, 0, Qnil, 0, multibyte);
580 specpdl_ref count = SPECPDL_INDEX ();
581 freeze_buffer_relocation ();
582 freeze_pattern (cache_entry);
583 re_match_object = STRINGP (string) ? string : Qnil;
584 len = re_match_2 (&cache_entry->buf, (char *) p1, s1, (char *) p2, s2,
585 pos_byte, NULL, limit_byte);
586
587 unbind_to (count, Qnil);
588 return len;
589 }
590
591
592
593
594
595
596
597
598 static struct region_cache *
599 newline_cache_on_off (struct buffer *buf)
600 {
601 struct buffer *base_buf = buf;
602 bool indirect_p = false;
603
604 if (buf->base_buffer)
605 {
606 base_buf = buf->base_buffer;
607 indirect_p = true;
608 }
609
610
611
612
613
614
615 if (NILP (BVAR (buf, cache_long_scans)))
616 {
617 if (!indirect_p
618 || NILP (BVAR (base_buf, cache_long_scans)))
619 {
620
621 if (base_buf->newline_cache)
622 {
623 free_region_cache (base_buf->newline_cache);
624 base_buf->newline_cache = 0;
625 }
626 }
627 return NULL;
628 }
629 else
630 {
631 if (!indirect_p
632 || !NILP (BVAR (base_buf, cache_long_scans)))
633 {
634
635 if (base_buf->newline_cache == 0)
636 {
637 base_buf->newline_cache = new_region_cache ();
638 __lsan_ignore_object (base_buf->newline_cache);
639 }
640 }
641 return base_buf->newline_cache;
642 }
643 }
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671 ptrdiff_t
672 find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end,
673 ptrdiff_t end_byte, ptrdiff_t count, ptrdiff_t *counted,
674 ptrdiff_t *bytepos, bool allow_quit)
675 {
676 struct region_cache *newline_cache;
677 struct buffer *cache_buffer;
678
679 if (!end)
680 {
681 if (count > 0)
682 end = ZV, end_byte = ZV_BYTE;
683 else
684 end = BEGV, end_byte = BEGV_BYTE;
685 }
686 if (end_byte == -1)
687 end_byte = CHAR_TO_BYTE (end);
688
689 newline_cache = newline_cache_on_off (current_buffer);
690 if (current_buffer->base_buffer)
691 cache_buffer = current_buffer->base_buffer;
692 else
693 cache_buffer = current_buffer;
694
695 if (counted)
696 *counted = count;
697
698 if (count > 0)
699 while (start != end)
700 {
701
702
703
704
705
706 ptrdiff_t tem, ceiling_byte = end_byte - 1;
707
708
709
710 if (newline_cache)
711 {
712 ptrdiff_t next_change;
713 int result = 1;
714
715 while (start < end && result)
716 {
717 ptrdiff_t lim1;
718
719 result = region_cache_forward (cache_buffer, newline_cache,
720 start, &next_change);
721 if (result)
722 {
723
724
725
726
727 if (next_change > ZV)
728 next_change = ZV;
729 start = next_change;
730 lim1 = next_change = end;
731 }
732 else
733 lim1 = min (next_change, end);
734
735
736
737
738
739 start_byte = CHAR_TO_BYTE (start);
740 while (start < lim1
741 && FETCH_BYTE (start_byte) == '\n')
742 {
743 start_byte++;
744 start++;
745 if (--count == 0)
746 {
747 if (bytepos)
748 *bytepos = start_byte;
749 return start;
750 }
751 }
752
753
754
755
756
757 if (start < next_change && !result)
758 break;
759 result = 1;
760 }
761 if (start >= end)
762 {
763 start = end;
764 start_byte = end_byte;
765 break;
766 }
767
768
769 if (start_byte > ceiling_byte)
770 start_byte = ceiling_byte;
771
772
773
774 ceiling_byte = min (CHAR_TO_BYTE (next_change) - 1, ceiling_byte);
775 }
776 else if (start_byte == -1)
777 start_byte = CHAR_TO_BYTE (start);
778
779
780
781
782
783 tem = BUFFER_CEILING_OF (start_byte);
784 ceiling_byte = min (tem, ceiling_byte);
785
786 {
787
788 unsigned char *lim_addr = BYTE_POS_ADDR (ceiling_byte) + 1;
789 ptrdiff_t lim_byte = ceiling_byte + 1;
790
791
792
793 ptrdiff_t base = start_byte - lim_byte;
794 ptrdiff_t cursor, next;
795
796 for (cursor = base; cursor < 0; cursor = next)
797 {
798
799 unsigned char *nl = memchr (lim_addr + cursor, '\n', - cursor);
800 next = nl ? nl - lim_addr : 0;
801
802
803
804 if (newline_cache && cursor != next)
805 {
806 know_region_cache (cache_buffer, newline_cache,
807 BYTE_TO_CHAR (lim_byte + cursor),
808 BYTE_TO_CHAR (lim_byte + next));
809
810 lim_addr = BYTE_POS_ADDR (ceiling_byte) + 1;
811 }
812
813 if (! nl)
814 break;
815 next++;
816
817 if (--count == 0)
818 {
819 if (bytepos)
820 *bytepos = lim_byte + next;
821 return BYTE_TO_CHAR (lim_byte + next);
822 }
823 if (allow_quit)
824 maybe_quit ();
825 }
826
827 start_byte = lim_byte;
828 start = BYTE_TO_CHAR (start_byte);
829 }
830 }
831 else
832 while (start > end)
833 {
834
835 ptrdiff_t tem, ceiling_byte = end_byte;
836
837
838 if (newline_cache)
839 {
840 ptrdiff_t next_change;
841 int result = 1;
842
843 while (start > end && result)
844 {
845 ptrdiff_t lim1;
846
847 result = region_cache_backward (cache_buffer, newline_cache,
848 start, &next_change);
849 if (result)
850 {
851 start = next_change;
852 lim1 = next_change = end;
853 }
854 else
855 lim1 = max (next_change, end);
856 start_byte = CHAR_TO_BYTE (start);
857 while (start > lim1
858 && FETCH_BYTE (start_byte - 1) == '\n')
859 {
860 if (++count == 0)
861 {
862 if (bytepos)
863 *bytepos = start_byte;
864 return start;
865 }
866 start_byte--;
867 start--;
868 }
869 if (start > next_change && !result)
870 break;
871 result = 1;
872 }
873 if (start <= end)
874 {
875 start = end;
876 start_byte = end_byte;
877 break;
878 }
879
880
881 if (start_byte <= ceiling_byte)
882 start_byte = ceiling_byte + 1;
883
884
885
886 ceiling_byte = max (CHAR_TO_BYTE (next_change), ceiling_byte);
887 }
888 else if (start_byte == -1)
889 start_byte = CHAR_TO_BYTE (start);
890
891
892 tem = BUFFER_FLOOR_OF (start_byte - 1);
893 ceiling_byte = max (tem, ceiling_byte);
894
895 {
896
897 unsigned char *ceiling_addr = BYTE_POS_ADDR (ceiling_byte);
898
899
900
901
902 ptrdiff_t base = start_byte - ceiling_byte;
903 ptrdiff_t cursor, prev;
904
905 for (cursor = base; 0 < cursor; cursor = prev)
906 {
907 unsigned char *nl = memrchr (ceiling_addr, '\n', cursor);
908 prev = nl ? nl - ceiling_addr : -1;
909
910
911
912 if (newline_cache && cursor != prev + 1)
913 {
914 know_region_cache (cache_buffer, newline_cache,
915 BYTE_TO_CHAR (ceiling_byte + prev + 1),
916 BYTE_TO_CHAR (ceiling_byte + cursor));
917
918 ceiling_addr = BYTE_POS_ADDR (ceiling_byte);
919 }
920
921 if (! nl)
922 break;
923
924 if (++count >= 0)
925 {
926 if (bytepos)
927 *bytepos = ceiling_byte + prev + 1;
928 return BYTE_TO_CHAR (ceiling_byte + prev + 1);
929 }
930 if (allow_quit)
931 maybe_quit ();
932 }
933
934 start_byte = ceiling_byte;
935 start = BYTE_TO_CHAR (start_byte);
936 }
937 }
938
939 if (counted)
940 *counted -= count;
941 if (bytepos)
942 {
943 *bytepos = start_byte == -1 ? CHAR_TO_BYTE (start) : start_byte;
944 eassert (*bytepos == CHAR_TO_BYTE (start));
945 }
946 return start;
947 }
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964 void
965 scan_newline (ptrdiff_t start, ptrdiff_t start_byte,
966 ptrdiff_t limit, ptrdiff_t limit_byte,
967 ptrdiff_t count, bool allow_quit)
968 {
969 ptrdiff_t charpos, bytepos, counted;
970
971 charpos = find_newline (start, start_byte, limit, limit_byte,
972 count, &counted, &bytepos, allow_quit);
973 if (counted != count)
974 TEMP_SET_PT_BOTH (limit, limit_byte);
975 else
976 TEMP_SET_PT_BOTH (charpos, bytepos);
977 }
978
979
980
981
982 ptrdiff_t
983 scan_newline_from_point (ptrdiff_t count, ptrdiff_t *charpos,
984 ptrdiff_t *bytepos)
985 {
986 ptrdiff_t counted;
987
988 if (count <= 0)
989 *charpos = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, count - 1,
990 &counted, bytepos, 1);
991 else
992 *charpos = find_newline (PT, PT_BYTE, ZV, ZV_BYTE, count,
993 &counted, bytepos, 1);
994 return counted;
995 }
996
997
998
999 ptrdiff_t
1000 find_newline_no_quit (ptrdiff_t from, ptrdiff_t frombyte,
1001 ptrdiff_t cnt, ptrdiff_t *bytepos)
1002 {
1003 return find_newline (from, frombyte, 0, -1, cnt, NULL, bytepos, 0);
1004 }
1005
1006
1007
1008
1009
1010 ptrdiff_t
1011 find_before_next_newline (ptrdiff_t from, ptrdiff_t to,
1012 ptrdiff_t cnt, ptrdiff_t *bytepos)
1013 {
1014 ptrdiff_t counted;
1015 ptrdiff_t pos = find_newline (from, -1, to, -1, cnt, &counted, bytepos, 1);
1016
1017 if (counted == cnt)
1018 {
1019 if (bytepos)
1020 dec_both (&pos, &*bytepos);
1021 else
1022 pos--;
1023 }
1024 return pos;
1025 }
1026
1027
1028
1029 static Lisp_Object
1030 search_command (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror,
1031 Lisp_Object count, int direction, bool RE, bool posix)
1032 {
1033 EMACS_INT np;
1034 EMACS_INT lim;
1035 ptrdiff_t lim_byte;
1036 EMACS_INT n = direction;
1037
1038 if (!NILP (count))
1039 {
1040 CHECK_FIXNUM (count);
1041 n *= XFIXNUM (count);
1042 }
1043
1044 CHECK_STRING (string);
1045 if (NILP (bound))
1046 {
1047 if (n > 0)
1048 lim = ZV, lim_byte = ZV_BYTE;
1049 else
1050 lim = BEGV, lim_byte = BEGV_BYTE;
1051 }
1052 else
1053 {
1054 lim = fix_position (bound);
1055 if (n > 0 ? lim < PT : lim > PT)
1056 error ("Invalid search bound (wrong side of point)");
1057 if (lim > ZV)
1058 lim = ZV, lim_byte = ZV_BYTE;
1059 else if (lim < BEGV)
1060 lim = BEGV, lim_byte = BEGV_BYTE;
1061 else
1062 lim_byte = CHAR_TO_BYTE (lim);
1063 }
1064
1065
1066
1067 set_char_table_extras (BVAR (current_buffer, case_canon_table), 2,
1068 BVAR (current_buffer, case_eqv_table));
1069
1070 np = search_buffer (string, PT, PT_BYTE, lim, lim_byte, n, RE,
1071 (!NILP (BVAR (current_buffer, case_fold_search))
1072 ? BVAR (current_buffer, case_canon_table)
1073 : Qnil),
1074 (!NILP (BVAR (current_buffer, case_fold_search))
1075 ? BVAR (current_buffer, case_eqv_table)
1076 : Qnil),
1077 posix);
1078 if (np <= 0)
1079 {
1080 if (NILP (noerror))
1081 xsignal1 (Qsearch_failed, string);
1082
1083 if (!EQ (noerror, Qt))
1084 {
1085 eassert (BEGV <= lim && lim <= ZV);
1086 SET_PT_BOTH (lim, lim_byte);
1087 return Qnil;
1088 #if 0
1089
1090 np = lim;
1091 #endif
1092 }
1093 else
1094 return Qnil;
1095 }
1096
1097 eassert (BEGV <= np && np <= ZV);
1098 SET_PT (np);
1099
1100 return make_fixnum (np);
1101 }
1102
1103
1104
1105 static bool
1106 trivial_regexp_p (Lisp_Object regexp)
1107 {
1108 ptrdiff_t len = SBYTES (regexp);
1109 unsigned char *s = SDATA (regexp);
1110 while (--len >= 0)
1111 {
1112 switch (*s++)
1113 {
1114 case '.': case '*': case '+': case '?': case '[': case '^': case '$':
1115 return 0;
1116 case '\\':
1117 if (--len < 0)
1118 return 0;
1119 switch (*s++)
1120 {
1121 case '|': case '(': case ')': case '`': case '\'': case 'b':
1122 case 'B': case '<': case '>': case 'w': case 'W': case 's':
1123 case 'S': case '=': case '{': case '}': case '_':
1124 case 'c': case 'C':
1125 case '1': case '2': case '3': case '4': case '5':
1126 case '6': case '7': case '8': case '9':
1127 return 0;
1128 }
1129 }
1130 }
1131 return 1;
1132 }
1133
1134 #define TRANSLATE(out, trt, d) \
1135 do \
1136 { \
1137 if (! NILP (trt)) \
1138 { \
1139 Lisp_Object temp; \
1140 temp = Faref (trt, make_fixnum (d)); \
1141 if (FIXNUMP (temp)) \
1142 out = XFIXNUM (temp); \
1143 else \
1144 out = d; \
1145 } \
1146 else \
1147 out = d; \
1148 } \
1149 while (0)
1150
1151
1152
1153
1154 static struct re_registers search_regs_1;
1155
1156 static EMACS_INT
1157 search_buffer_re (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
1158 ptrdiff_t lim, ptrdiff_t lim_byte, EMACS_INT n,
1159 Lisp_Object trt, Lisp_Object inverse_trt, bool posix)
1160 {
1161 unsigned char *p1, *p2;
1162 ptrdiff_t s1, s2;
1163
1164
1165 bool preserve_match_data = NILP (Vinhibit_changing_match_data);
1166
1167 struct regexp_cache *cache_entry =
1168 compile_pattern (string,
1169 preserve_match_data ? &search_regs : &search_regs_1,
1170 trt, posix,
1171 !NILP (BVAR (current_buffer, enable_multibyte_characters)));
1172 struct re_pattern_buffer *bufp = &cache_entry->buf;
1173
1174 maybe_quit ();
1175
1176
1177
1178
1179 p1 = BEGV_ADDR;
1180 s1 = GPT_BYTE - BEGV_BYTE;
1181 p2 = GAP_END_ADDR;
1182 s2 = ZV_BYTE - GPT_BYTE;
1183 if (s1 < 0)
1184 {
1185 p2 = p1;
1186 s2 = ZV_BYTE - BEGV_BYTE;
1187 s1 = 0;
1188 }
1189 if (s2 < 0)
1190 {
1191 s1 = ZV_BYTE - BEGV_BYTE;
1192 s2 = 0;
1193 }
1194
1195 specpdl_ref count = SPECPDL_INDEX ();
1196 freeze_buffer_relocation ();
1197 freeze_pattern (cache_entry);
1198
1199 while (n < 0)
1200 {
1201 ptrdiff_t val;
1202
1203 re_match_object = Qnil;
1204 val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2,
1205 pos_byte - BEGV_BYTE, lim_byte - pos_byte,
1206 preserve_match_data ? &search_regs : &search_regs_1,
1207
1208 pos_byte - BEGV_BYTE);
1209 if (val == -2)
1210 {
1211 unbind_to (count, Qnil);
1212 matcher_overflow ();
1213 }
1214 if (val >= 0)
1215 {
1216 if (preserve_match_data)
1217 {
1218 pos_byte = search_regs.start[0] + BEGV_BYTE;
1219 for (ptrdiff_t i = 0; i < search_regs.num_regs; i++)
1220 if (search_regs.start[i] >= 0)
1221 {
1222 search_regs.start[i]
1223 = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE);
1224 search_regs.end[i]
1225 = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
1226 }
1227 XSETBUFFER (last_thing_searched, current_buffer);
1228
1229 pos = search_regs.start[0];
1230 }
1231 else
1232 {
1233 pos_byte = search_regs_1.start[0] + BEGV_BYTE;
1234
1235 pos = BYTE_TO_CHAR (search_regs_1.start[0] + BEGV_BYTE);
1236 }
1237 }
1238 else
1239 {
1240 unbind_to (count, Qnil);
1241 return (n);
1242 }
1243 n++;
1244 maybe_quit ();
1245 }
1246 while (n > 0)
1247 {
1248 ptrdiff_t val;
1249
1250 re_match_object = Qnil;
1251 val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2,
1252 pos_byte - BEGV_BYTE, lim_byte - pos_byte,
1253 preserve_match_data ? &search_regs : &search_regs_1,
1254 lim_byte - BEGV_BYTE);
1255 if (val == -2)
1256 {
1257 unbind_to (count, Qnil);
1258 matcher_overflow ();
1259 }
1260 if (val >= 0)
1261 {
1262 if (preserve_match_data)
1263 {
1264 pos_byte = search_regs.end[0] + BEGV_BYTE;
1265 for (ptrdiff_t i = 0; i < search_regs.num_regs; i++)
1266 if (search_regs.start[i] >= 0)
1267 {
1268 search_regs.start[i]
1269 = BYTE_TO_CHAR (search_regs.start[i] + BEGV_BYTE);
1270 search_regs.end[i]
1271 = BYTE_TO_CHAR (search_regs.end[i] + BEGV_BYTE);
1272 }
1273 XSETBUFFER (last_thing_searched, current_buffer);
1274 pos = search_regs.end[0];
1275 }
1276 else
1277 {
1278 pos_byte = search_regs_1.end[0] + BEGV_BYTE;
1279 pos = BYTE_TO_CHAR (search_regs_1.end[0] + BEGV_BYTE);
1280 }
1281 }
1282 else
1283 {
1284 unbind_to (count, Qnil);
1285 return (0 - n);
1286 }
1287 n--;
1288 maybe_quit ();
1289 }
1290 unbind_to (count, Qnil);
1291 return (pos);
1292 }
1293
1294 static EMACS_INT
1295 search_buffer_non_re (Lisp_Object string, ptrdiff_t pos,
1296 ptrdiff_t pos_byte, ptrdiff_t lim, ptrdiff_t lim_byte,
1297 EMACS_INT n, bool RE, Lisp_Object trt, Lisp_Object inverse_trt,
1298 bool posix)
1299 {
1300 unsigned char *raw_pattern, *pat;
1301 ptrdiff_t raw_pattern_size;
1302 ptrdiff_t raw_pattern_size_byte;
1303 unsigned char *patbuf;
1304 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
1305 unsigned char *base_pat;
1306
1307
1308 int char_base = -1;
1309 bool boyer_moore_ok = 1;
1310 USE_SAFE_ALLOCA;
1311
1312
1313
1314
1315
1316 if (multibyte == STRING_MULTIBYTE (string))
1317 {
1318 raw_pattern = SDATA (string);
1319 raw_pattern_size = SCHARS (string);
1320 raw_pattern_size_byte = SBYTES (string);
1321 }
1322 else if (multibyte)
1323 {
1324 raw_pattern_size = SCHARS (string);
1325 raw_pattern_size_byte
1326 = count_size_as_multibyte (SDATA (string),
1327 raw_pattern_size);
1328 raw_pattern = SAFE_ALLOCA (raw_pattern_size_byte + 1);
1329 copy_text (SDATA (string), raw_pattern,
1330 SCHARS (string), 0, 1);
1331 }
1332 else
1333 {
1334
1335 raw_pattern_size = SCHARS (string);
1336 raw_pattern_size_byte = SCHARS (string);
1337 raw_pattern = SAFE_ALLOCA (raw_pattern_size + 1);
1338 copy_text (SDATA (string), raw_pattern,
1339 SBYTES (string), 1, 0);
1340 }
1341
1342
1343 ptrdiff_t len = raw_pattern_size;
1344 ptrdiff_t len_byte = raw_pattern_size_byte;
1345 SAFE_NALLOCA (patbuf, MAX_MULTIBYTE_LENGTH, len);
1346 pat = patbuf;
1347 base_pat = raw_pattern;
1348 if (multibyte)
1349 {
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361 while (--len >= 0)
1362 {
1363 unsigned char str_base[MAX_MULTIBYTE_LENGTH], *str;
1364 int translated, inverse;
1365 int charlen;
1366
1367
1368
1369
1370 if (RE && *base_pat == '\\')
1371 {
1372 len--;
1373 raw_pattern_size--;
1374 len_byte--;
1375 base_pat++;
1376 }
1377
1378 int in_charlen, c = string_char_and_length (base_pat, &in_charlen);
1379
1380 if (NILP (trt))
1381 {
1382 str = base_pat;
1383 charlen = in_charlen;
1384 }
1385 else
1386 {
1387
1388 TRANSLATE (translated, trt, c);
1389 charlen = CHAR_STRING (translated, str_base);
1390 str = str_base;
1391
1392
1393 TRANSLATE (inverse, inverse_trt, c);
1394
1395 if (c != inverse && boyer_moore_ok)
1396 {
1397
1398
1399
1400 int this_char_base = -1;
1401
1402 while (boyer_moore_ok)
1403 {
1404 if (ASCII_CHAR_P (inverse))
1405 {
1406 if (this_char_base > 0)
1407 boyer_moore_ok = 0;
1408 else
1409 this_char_base = 0;
1410 }
1411 else if (CHAR_BYTE8_P (inverse))
1412
1413
1414
1415 boyer_moore_ok = 0;
1416 else if (this_char_base < 0)
1417 {
1418 this_char_base = inverse & ~0x3F;
1419 if (char_base < 0)
1420 char_base = this_char_base;
1421 else if (this_char_base != char_base)
1422 boyer_moore_ok = 0;
1423 }
1424 else if ((inverse & ~0x3F) != this_char_base)
1425 boyer_moore_ok = 0;
1426 if (c == inverse)
1427 break;
1428 TRANSLATE (inverse, inverse_trt, inverse);
1429 }
1430 }
1431 }
1432
1433
1434 memcpy (pat, str, charlen);
1435 pat += charlen;
1436 base_pat += in_charlen;
1437 len_byte -= in_charlen;
1438 }
1439
1440
1441
1442 if (char_base < 0)
1443 char_base = 0;
1444 }
1445 else
1446 {
1447
1448 char_base = 0;
1449 while (--len >= 0)
1450 {
1451 int c, translated, inverse;
1452
1453
1454
1455
1456 if (RE && *base_pat == '\\')
1457 {
1458 len--;
1459 raw_pattern_size--;
1460 base_pat++;
1461 }
1462 c = *base_pat++;
1463 TRANSLATE (translated, trt, c);
1464 *pat++ = translated;
1465
1466
1467 TRANSLATE (inverse, inverse_trt, c);
1468 while (1)
1469 {
1470 if (inverse >= 0200)
1471 {
1472 boyer_moore_ok = 0;
1473 break;
1474 }
1475 if (c == inverse)
1476 break;
1477 TRANSLATE (inverse, inverse_trt, inverse);
1478 }
1479 }
1480 }
1481
1482 len_byte = pat - patbuf;
1483 pat = base_pat = patbuf;
1484
1485 EMACS_INT result
1486 = (boyer_moore_ok
1487 ? boyer_moore (n, pat, len_byte, trt, inverse_trt,
1488 pos_byte, lim_byte,
1489 char_base)
1490 : simple_search (n, pat, raw_pattern_size, len_byte, trt,
1491 pos, pos_byte, lim, lim_byte));
1492 SAFE_FREE ();
1493 return result;
1494 }
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514 EMACS_INT
1515 search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
1516 ptrdiff_t lim, ptrdiff_t lim_byte, EMACS_INT n,
1517 bool RE, Lisp_Object trt, Lisp_Object inverse_trt, bool posix)
1518 {
1519 if (running_asynch_code)
1520 save_search_regs ();
1521
1522
1523
1524 if (n == 0 || SCHARS (string) == 0)
1525 {
1526 set_search_regs (pos_byte, 0);
1527 return pos;
1528 }
1529
1530 if (RE && !(trivial_regexp_p (string) && NILP (Vsearch_spaces_regexp)))
1531 pos = search_buffer_re (string, pos, pos_byte, lim, lim_byte,
1532 n, trt, inverse_trt, posix);
1533 else
1534 pos = search_buffer_non_re (string, pos, pos_byte, lim, lim_byte,
1535 n, RE, trt, inverse_trt, posix);
1536
1537 return pos;
1538 }
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552 static EMACS_INT
1553 simple_search (EMACS_INT n, unsigned char *pat,
1554 ptrdiff_t len, ptrdiff_t len_byte, Lisp_Object trt,
1555 ptrdiff_t pos, ptrdiff_t pos_byte,
1556 ptrdiff_t lim, ptrdiff_t lim_byte)
1557 {
1558 bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
1559 bool forward = n > 0;
1560
1561
1562 ptrdiff_t match_byte = PTRDIFF_MIN;
1563
1564 if (lim > pos && multibyte)
1565 while (n > 0)
1566 {
1567 while (1)
1568 {
1569
1570 ptrdiff_t this_pos_byte = pos_byte;
1571 ptrdiff_t this_len = len;
1572 unsigned char *p = pat;
1573 if (pos + len > lim || pos_byte + len_byte > lim_byte)
1574 goto stop;
1575
1576 while (this_len > 0)
1577 {
1578 int charlen, pat_ch = string_char_and_length (p, &charlen);
1579 int buf_charlen, buf_ch
1580 = string_char_and_length (BYTE_POS_ADDR (this_pos_byte),
1581 &buf_charlen);
1582 TRANSLATE (buf_ch, trt, buf_ch);
1583
1584 if (buf_ch != pat_ch)
1585 break;
1586
1587 this_len--;
1588 p += charlen;
1589
1590 this_pos_byte += buf_charlen;
1591 }
1592
1593 if (this_len == 0)
1594 {
1595 match_byte = this_pos_byte - pos_byte;
1596 pos += len;
1597 pos_byte += match_byte;
1598 break;
1599 }
1600
1601 inc_both (&pos, &pos_byte);
1602 }
1603
1604 n--;
1605 }
1606 else if (lim > pos)
1607 while (n > 0)
1608 {
1609 while (1)
1610 {
1611
1612 ptrdiff_t this_pos = pos;
1613 ptrdiff_t this_len = len;
1614 unsigned char *p = pat;
1615
1616 if (pos + len > lim)
1617 goto stop;
1618
1619 while (this_len > 0)
1620 {
1621 int pat_ch = *p++;
1622 int buf_ch = FETCH_BYTE (this_pos);
1623 TRANSLATE (buf_ch, trt, buf_ch);
1624
1625 if (buf_ch != pat_ch)
1626 break;
1627
1628 this_len--;
1629 this_pos++;
1630 }
1631
1632 if (this_len == 0)
1633 {
1634 match_byte = len;
1635 pos += len;
1636 break;
1637 }
1638
1639 pos++;
1640 }
1641
1642 n--;
1643 }
1644
1645 else if (lim < pos && multibyte)
1646 while (n < 0)
1647 {
1648 while (1)
1649 {
1650
1651 ptrdiff_t this_pos = pos;
1652 ptrdiff_t this_pos_byte = pos_byte;
1653 ptrdiff_t this_len = len;
1654 const unsigned char *p = pat + len_byte;
1655
1656 if (this_pos - len < lim || (pos_byte - len_byte) < lim_byte)
1657 goto stop;
1658
1659 while (this_len > 0)
1660 {
1661 int pat_ch, buf_ch;
1662
1663 dec_both (&this_pos, &this_pos_byte);
1664 p -= raw_prev_char_len (p);
1665 pat_ch = STRING_CHAR (p);
1666 buf_ch = STRING_CHAR (BYTE_POS_ADDR (this_pos_byte));
1667 TRANSLATE (buf_ch, trt, buf_ch);
1668
1669 if (buf_ch != pat_ch)
1670 break;
1671
1672 this_len--;
1673 }
1674
1675 if (this_len == 0)
1676 {
1677 match_byte = pos_byte - this_pos_byte;
1678 pos = this_pos;
1679 pos_byte = this_pos_byte;
1680 break;
1681 }
1682
1683 dec_both (&pos, &pos_byte);
1684 }
1685
1686 n++;
1687 }
1688 else if (lim < pos)
1689 while (n < 0)
1690 {
1691 while (1)
1692 {
1693
1694 ptrdiff_t this_pos = pos - len;
1695 ptrdiff_t this_len = len;
1696 unsigned char *p = pat;
1697
1698 if (this_pos < lim)
1699 goto stop;
1700
1701 while (this_len > 0)
1702 {
1703 int pat_ch = *p++;
1704 int buf_ch = FETCH_BYTE (this_pos);
1705 TRANSLATE (buf_ch, trt, buf_ch);
1706
1707 if (buf_ch != pat_ch)
1708 break;
1709 this_len--;
1710 this_pos++;
1711 }
1712
1713 if (this_len == 0)
1714 {
1715 match_byte = len;
1716 pos -= len;
1717 break;
1718 }
1719
1720 pos--;
1721 }
1722
1723 n++;
1724 }
1725
1726 stop:
1727 if (n == 0)
1728 {
1729 eassert (match_byte != PTRDIFF_MIN);
1730 if (forward)
1731 set_search_regs ((multibyte ? pos_byte : pos) - match_byte, match_byte);
1732 else
1733 set_search_regs (multibyte ? pos_byte : pos, match_byte);
1734
1735 return pos;
1736 }
1737 else if (n > 0)
1738 return -n;
1739 else
1740 return n;
1741 }
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758 static EMACS_INT
1759 boyer_moore (EMACS_INT n, unsigned char *base_pat,
1760 ptrdiff_t len_byte,
1761 Lisp_Object trt, Lisp_Object inverse_trt,
1762 ptrdiff_t pos_byte, ptrdiff_t lim_byte,
1763 int char_base)
1764 {
1765 int direction = ((n > 0) ? 1 : -1);
1766 register ptrdiff_t dirlen;
1767 ptrdiff_t limit;
1768 int stride_for_teases = 0;
1769 int BM_tab[0400];
1770 register unsigned char *cursor, *p_limit;
1771 register ptrdiff_t i;
1772 register int j;
1773 unsigned char *pat, *pat_end;
1774 bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
1775
1776 unsigned char simple_translate[0400];
1777
1778
1779
1780
1781 int translate_prev_byte1 = 0;
1782 int translate_prev_byte2 = 0;
1783 int translate_prev_byte3 = 0;
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806 dirlen = len_byte * direction;
1807
1808
1809 pat_end = base_pat + len_byte;
1810
1811
1812
1813 if (direction < 0)
1814 base_pat = pat_end - 1;
1815
1816
1817
1818 for (i = 0; i < 0400; i++)
1819 BM_tab[i] = dirlen;
1820
1821
1822
1823
1824 for (i = 0; i < 0400; i++)
1825 simple_translate[i] = i;
1826
1827 if (char_base)
1828 {
1829
1830
1831 eassume (0x80 <= char_base && char_base <= MAX_CHAR);
1832 unsigned char str[MAX_MULTIBYTE_LENGTH];
1833 int cblen = CHAR_STRING (char_base, str);
1834
1835 translate_prev_byte1 = str[cblen - 2];
1836 if (cblen > 2)
1837 {
1838 translate_prev_byte2 = str[cblen - 3];
1839 if (cblen > 3)
1840 translate_prev_byte3 = str[cblen - 4];
1841 }
1842 }
1843
1844 i = 0;
1845 while (i != dirlen)
1846 {
1847 unsigned char *ptr = base_pat + i;
1848 i += direction;
1849 if (! NILP (trt))
1850 {
1851
1852
1853
1854
1855 int ch = -1;
1856
1857 if (ASCII_CHAR_P (*ptr) || ! multibyte)
1858 ch = *ptr;
1859 else if (char_base
1860 && ((pat_end - ptr) == 1 || CHAR_HEAD_P (ptr[1])))
1861 {
1862 unsigned char *charstart = ptr - 1;
1863
1864 while (! (CHAR_HEAD_P (*charstart)))
1865 charstart--;
1866 ch = STRING_CHAR (charstart);
1867 if (char_base != (ch & ~0x3F))
1868 ch = -1;
1869 }
1870
1871 if (ch >= 0200 && multibyte)
1872 j = (ch & 0x3F) | 0200;
1873 else
1874 j = *ptr;
1875
1876 if (i == dirlen)
1877 stride_for_teases = BM_tab[j];
1878
1879 BM_tab[j] = dirlen - i;
1880
1881
1882 if (ch >= 0)
1883 {
1884 int starting_ch = ch;
1885 int starting_j = j;
1886
1887 while (1)
1888 {
1889 TRANSLATE (ch, inverse_trt, ch);
1890 if (ch >= 0200 && multibyte)
1891 j = (ch & 0x3F) | 0200;
1892 else
1893 j = ch;
1894
1895
1896
1897
1898 simple_translate[j] = starting_j;
1899 if (ch == starting_ch)
1900 break;
1901 BM_tab[j] = dirlen - i;
1902 }
1903 }
1904 }
1905 else
1906 {
1907 j = *ptr;
1908
1909 if (i == dirlen)
1910 stride_for_teases = BM_tab[j];
1911 BM_tab[j] = dirlen - i;
1912 }
1913
1914
1915
1916
1917
1918 }
1919 pos_byte += dirlen - ((direction > 0) ? direction : 0);
1920
1921
1922 while (n != 0)
1923 {
1924 ptrdiff_t tail_end;
1925 unsigned char *tail_end_ptr;
1926
1927
1928
1929
1930 if ((lim_byte - pos_byte - ((direction > 0) ? 1 : 0)) * direction
1931 < 0)
1932 return (n * (0 - direction));
1933
1934 maybe_quit ();
1935 pat = base_pat;
1936 limit = pos_byte - dirlen + direction;
1937 if (direction > 0)
1938 {
1939 limit = BUFFER_CEILING_OF (limit);
1940
1941
1942 limit = min (limit, pos_byte + 20000);
1943 limit = min (limit, lim_byte - 1);
1944 }
1945 else
1946 {
1947 limit = BUFFER_FLOOR_OF (limit);
1948
1949
1950 limit = max (limit, pos_byte - 20000);
1951 limit = max (limit, lim_byte);
1952 }
1953 tail_end = BUFFER_CEILING_OF (pos_byte) + 1;
1954 tail_end_ptr = BYTE_POS_ADDR (tail_end);
1955
1956 if ((limit - pos_byte) * direction > 20)
1957 {
1958 unsigned char *p2;
1959
1960 p_limit = BYTE_POS_ADDR (limit);
1961 p2 = (cursor = BYTE_POS_ADDR (pos_byte));
1962
1963 while (1)
1964 {
1965 if (direction > 0)
1966 {
1967 while (cursor <= p_limit)
1968 {
1969 if (BM_tab[*cursor] == 0)
1970 goto hit;
1971 cursor += BM_tab[*cursor];
1972 }
1973 }
1974 else
1975 {
1976 while (cursor >= p_limit)
1977 {
1978 if (BM_tab[*cursor] == 0)
1979 goto hit;
1980 cursor += BM_tab[*cursor];
1981 }
1982 }
1983
1984
1985
1986
1987 break;
1988
1989 hit:
1990 i = dirlen - direction;
1991 if (! NILP (trt))
1992 {
1993 while ((i -= direction) + direction != 0)
1994 {
1995 int ch;
1996 cursor -= direction;
1997
1998 if (! multibyte
1999 || ((cursor == tail_end_ptr
2000 || CHAR_HEAD_P (cursor[1]))
2001 && (CHAR_HEAD_P (cursor[0])
2002
2003
2004 || (translate_prev_byte1 == cursor[-1]
2005 && (CHAR_HEAD_P (translate_prev_byte1)
2006 || (translate_prev_byte2 == cursor[-2]
2007 && (CHAR_HEAD_P (translate_prev_byte2)
2008 || (translate_prev_byte3 == cursor[-3]))))))))
2009 ch = simple_translate[*cursor];
2010 else
2011 ch = *cursor;
2012 if (pat[i] != ch)
2013 break;
2014 }
2015 }
2016 else
2017 {
2018 while ((i -= direction) + direction != 0)
2019 {
2020 cursor -= direction;
2021 if (pat[i] != *cursor)
2022 break;
2023 }
2024 }
2025 cursor += dirlen - i - direction;
2026 if (i + direction == 0)
2027 {
2028 ptrdiff_t position, start, end;
2029 #ifdef REL_ALLOC
2030 ptrdiff_t cursor_off;
2031 #endif
2032
2033 cursor -= direction;
2034
2035 position = pos_byte + cursor - p2 + ((direction > 0)
2036 ? 1 - len_byte : 0);
2037 #ifdef REL_ALLOC
2038
2039
2040
2041 cursor_off = cursor - p2;
2042 #endif
2043 set_search_regs (position, len_byte);
2044 #ifdef REL_ALLOC
2045 p_limit = BYTE_POS_ADDR (limit);
2046 p2 = BYTE_POS_ADDR (pos_byte);
2047 cursor = p2 + cursor_off;
2048 #endif
2049
2050 if (NILP (Vinhibit_changing_match_data))
2051 {
2052 start = search_regs.start[0];
2053 end = search_regs.end[0];
2054 }
2055 else
2056
2057
2058
2059 {
2060 start = BYTE_TO_CHAR (position);
2061 end = BYTE_TO_CHAR (position + len_byte);
2062 }
2063
2064 if ((n -= direction) != 0)
2065 cursor += dirlen;
2066 else
2067 return direction > 0 ? end : start;
2068 }
2069 else
2070 cursor += stride_for_teases;
2071 }
2072 pos_byte += cursor - p2;
2073 }
2074 else
2075
2076
2077 {
2078 limit = ((direction > 0)
2079 ? BUFFER_CEILING_OF (pos_byte - dirlen + 1)
2080 : BUFFER_FLOOR_OF (pos_byte - dirlen - 1));
2081 limit = ((direction > 0)
2082 ? min (limit + len_byte, lim_byte - 1)
2083 : max (limit - len_byte, lim_byte));
2084
2085
2086 while (1)
2087 {
2088
2089
2090
2091
2092 while ((limit - pos_byte) * direction >= 0)
2093 {
2094 int ch = FETCH_BYTE (pos_byte);
2095 if (BM_tab[ch] == 0)
2096 goto hit2;
2097 pos_byte += BM_tab[ch];
2098 }
2099 break;
2100
2101 hit2:
2102
2103 i = dirlen - direction;
2104 while ((i -= direction) + direction != 0)
2105 {
2106 int ch;
2107 unsigned char *ptr;
2108 pos_byte -= direction;
2109 ptr = BYTE_POS_ADDR (pos_byte);
2110
2111 if (! multibyte
2112 || ((ptr == tail_end_ptr
2113 || CHAR_HEAD_P (ptr[1]))
2114 && (CHAR_HEAD_P (ptr[0])
2115
2116
2117 || (translate_prev_byte1 == ptr[-1]
2118 && (CHAR_HEAD_P (translate_prev_byte1)
2119 || (translate_prev_byte2 == ptr[-2]
2120 && (CHAR_HEAD_P (translate_prev_byte2)
2121 || translate_prev_byte3 == ptr[-3])))))))
2122 ch = simple_translate[*ptr];
2123 else
2124 ch = *ptr;
2125 if (pat[i] != ch)
2126 break;
2127 }
2128
2129
2130
2131 pos_byte += dirlen - i - direction;
2132 if (i + direction == 0)
2133 {
2134 ptrdiff_t position, start, end;
2135 pos_byte -= direction;
2136
2137 position = pos_byte + ((direction > 0) ? 1 - len_byte : 0);
2138 set_search_regs (position, len_byte);
2139
2140 if (NILP (Vinhibit_changing_match_data))
2141 {
2142 start = search_regs.start[0];
2143 end = search_regs.end[0];
2144 }
2145 else
2146
2147
2148
2149 {
2150 start = BYTE_TO_CHAR (position);
2151 end = BYTE_TO_CHAR (position + len_byte);
2152 }
2153
2154 if ((n -= direction) != 0)
2155 pos_byte += dirlen;
2156 else
2157 return direction > 0 ? end : start;
2158 }
2159 else
2160 pos_byte += stride_for_teases;
2161 }
2162 }
2163
2164 if ((lim_byte - pos_byte) * direction < 0)
2165 return ((0 - n) * direction);
2166 }
2167 return BYTE_TO_CHAR (pos_byte);
2168 }
2169
2170
2171
2172
2173
2174 static void
2175 set_search_regs (ptrdiff_t beg_byte, ptrdiff_t nbytes)
2176 {
2177 ptrdiff_t i;
2178
2179 if (!NILP (Vinhibit_changing_match_data))
2180 return;
2181
2182
2183
2184 if (search_regs.num_regs == 0)
2185 {
2186 search_regs.start = xmalloc (2 * sizeof *search_regs.start);
2187 search_regs.end = xmalloc (2 * sizeof *search_regs.end);
2188 search_regs.num_regs = 2;
2189 }
2190
2191
2192 for (i = 1; i < search_regs.num_regs; i++)
2193 {
2194 search_regs.start[i] = -1;
2195 search_regs.end[i] = -1;
2196 }
2197
2198 search_regs.start[0] = BYTE_TO_CHAR (beg_byte);
2199 search_regs.end[0] = BYTE_TO_CHAR (beg_byte + nbytes);
2200 XSETBUFFER (last_thing_searched, current_buffer);
2201 }
2202
2203 DEFUN ("search-backward", Fsearch_backward, Ssearch_backward, 1, 4,
2204 "MSearch backward: ",
2205 doc:
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223 )
2224 (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
2225 {
2226 return search_command (string, bound, noerror, count, -1, false, false);
2227 }
2228
2229 DEFUN ("search-forward", Fsearch_forward, Ssearch_forward, 1, 4, "MSearch: ",
2230 doc:
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248 )
2249 (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
2250 {
2251 return search_command (string, bound, noerror, count, 1, false, false);
2252 }
2253
2254 DEFUN ("re-search-backward", Fre_search_backward, Sre_search_backward, 1, 4,
2255 "sRE search backward: ",
2256 doc:
2257
2258
2259
2260
2261
2262
2263
2264 )
2265 (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
2266 {
2267 return search_command (regexp, bound, noerror, count, -1, true, false);
2268 }
2269
2270 DEFUN ("re-search-forward", Fre_search_forward, Sre_search_forward, 1, 4,
2271 "sRE search: ",
2272 doc:
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295 )
2296 (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
2297 {
2298 return search_command (regexp, bound, noerror, count, 1, true, false);
2299 }
2300
2301 DEFUN ("posix-search-backward", Fposix_search_backward, Sposix_search_backward, 1, 4,
2302 "sPosix search backward: ",
2303 doc:
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323 )
2324 (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
2325 {
2326 return search_command (regexp, bound, noerror, count, -1, true, true);
2327 }
2328
2329 DEFUN ("posix-search-forward", Fposix_search_forward, Sposix_search_forward, 1, 4,
2330 "sPosix search: ",
2331 doc:
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351 )
2352 (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
2353 {
2354 return search_command (regexp, bound, noerror, count, 1, true, true);
2355 }
2356
2357 DEFUN ("replace-match", Freplace_match, Sreplace_match, 1, 5, 0,
2358 doc:
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392 )
2393 (Lisp_Object newtext, Lisp_Object fixedcase, Lisp_Object literal, Lisp_Object string, Lisp_Object subexp)
2394 {
2395 enum { nochange, all_caps, cap_initial } case_action;
2396 ptrdiff_t pos, pos_byte;
2397 bool some_multiletter_word;
2398 bool some_lowercase;
2399 bool some_uppercase;
2400 bool some_nonuppercase_initial;
2401 int c, prevc;
2402 ptrdiff_t sub;
2403 ptrdiff_t opoint, newpoint;
2404
2405 CHECK_STRING (newtext);
2406
2407 if (! NILP (string))
2408 CHECK_STRING (string);
2409
2410
2411
2412
2413 if (NILP (literal)
2414 && !memchr (SSDATA (newtext), '\\', SBYTES (newtext)))
2415 literal = Qt;
2416
2417 case_action = nochange;
2418
2419
2420 ptrdiff_t num_regs = search_regs.num_regs;
2421 if (num_regs <= 0)
2422 error ("`replace-match' called before any match found");
2423
2424 sub = !NILP (subexp) ? check_integer_range (subexp, 0, num_regs - 1) : 0;
2425 ptrdiff_t sub_start = search_regs.start[sub];
2426 ptrdiff_t sub_end = search_regs.end[sub];
2427 eassert (sub_start <= sub_end);
2428
2429
2430 if (! (NILP (string)
2431 ? BEGV <= sub_start && sub_end <= ZV
2432 : 0 <= sub_start && sub_end <= SCHARS (string)))
2433 {
2434 if (sub_start < 0)
2435 xsignal2 (Qerror,
2436 build_string ("replace-match subexpression does not exist"),
2437 subexp);
2438 args_out_of_range (make_fixnum (sub_start), make_fixnum (sub_end));
2439 }
2440
2441 if (NILP (fixedcase))
2442 {
2443
2444 ptrdiff_t last;
2445
2446 pos = sub_start;
2447 last = sub_end;
2448
2449 if (NILP (string))
2450 pos_byte = CHAR_TO_BYTE (pos);
2451 else
2452 pos_byte = string_char_to_byte (string, pos);
2453
2454 prevc = '\n';
2455 case_action = all_caps;
2456
2457
2458
2459 some_multiletter_word = 0;
2460 some_lowercase = 0;
2461 some_nonuppercase_initial = 0;
2462 some_uppercase = 0;
2463
2464 while (pos < last)
2465 {
2466 if (NILP (string))
2467 {
2468 c = FETCH_CHAR_AS_MULTIBYTE (pos_byte);
2469 inc_both (&pos, &pos_byte);
2470 }
2471 else
2472 c = fetch_string_char_as_multibyte_advance (string,
2473 &pos, &pos_byte);
2474
2475 if (lowercasep (c))
2476 {
2477
2478
2479 some_lowercase = 1;
2480 if (SYNTAX (prevc) != Sword)
2481 some_nonuppercase_initial = 1;
2482 else
2483 some_multiletter_word = 1;
2484 }
2485 else if (uppercasep (c))
2486 {
2487 some_uppercase = 1;
2488 if (SYNTAX (prevc) != Sword)
2489 ;
2490 else
2491 some_multiletter_word = 1;
2492 }
2493 else
2494 {
2495
2496
2497 if (SYNTAX (prevc) != Sword)
2498 some_nonuppercase_initial = 1;
2499 }
2500
2501 prevc = c;
2502 }
2503
2504
2505
2506 if (! some_lowercase && some_multiletter_word)
2507 case_action = all_caps;
2508
2509 else if (!some_nonuppercase_initial && some_multiletter_word)
2510 case_action = cap_initial;
2511 else if (!some_nonuppercase_initial && some_uppercase)
2512
2513
2514 case_action = all_caps;
2515 else
2516 case_action = nochange;
2517 }
2518
2519
2520 if (!NILP (string))
2521 {
2522 Lisp_Object before, after;
2523
2524 before = Fsubstring (string, make_fixnum (0), make_fixnum (sub_start));
2525 after = Fsubstring (string, make_fixnum (sub_end), Qnil);
2526
2527
2528
2529 if (NILP (literal))
2530 {
2531 ptrdiff_t lastpos = 0;
2532 ptrdiff_t lastpos_byte = 0;
2533
2534 Lisp_Object accum;
2535 Lisp_Object middle;
2536 ptrdiff_t length = SBYTES (newtext);
2537
2538 accum = Qnil;
2539
2540 for (pos_byte = 0, pos = 0; pos_byte < length;)
2541 {
2542 ptrdiff_t substart = -1;
2543 ptrdiff_t subend = 0;
2544 bool delbackslash = 0;
2545
2546 c = fetch_string_char_advance (newtext, &pos, &pos_byte);
2547
2548 if (c == '\\')
2549 {
2550 c = fetch_string_char_advance (newtext, &pos, &pos_byte);
2551
2552 if (c == '&')
2553 {
2554 substart = sub_start;
2555 subend = sub_end;
2556 }
2557 else if (c >= '1' && c <= '9')
2558 {
2559 if (c - '0' < num_regs
2560 && search_regs.start[c - '0'] >= 0)
2561 {
2562 substart = search_regs.start[c - '0'];
2563 subend = search_regs.end[c - '0'];
2564 }
2565 else
2566 {
2567
2568
2569 substart = 0;
2570 subend = 0;
2571 }
2572 }
2573 else if (c == '\\')
2574 delbackslash = 1;
2575 else if (c != '?')
2576 error ("Invalid use of `\\' in replacement text");
2577 }
2578 if (substart >= 0)
2579 {
2580 if (pos - 2 != lastpos)
2581 middle = substring_both (newtext, lastpos,
2582 lastpos_byte,
2583 pos - 2, pos_byte - 2);
2584 else
2585 middle = Qnil;
2586 accum = concat3 (accum, middle,
2587 Fsubstring (string,
2588 make_fixnum (substart),
2589 make_fixnum (subend)));
2590 lastpos = pos;
2591 lastpos_byte = pos_byte;
2592 }
2593 else if (delbackslash)
2594 {
2595 middle = substring_both (newtext, lastpos,
2596 lastpos_byte,
2597 pos - 1, pos_byte - 1);
2598
2599 accum = concat2 (accum, middle);
2600 lastpos = pos;
2601 lastpos_byte = pos_byte;
2602 }
2603 }
2604
2605 if (pos != lastpos)
2606 middle = substring_both (newtext, lastpos,
2607 lastpos_byte,
2608 pos, pos_byte);
2609 else
2610 middle = Qnil;
2611
2612 newtext = concat2 (accum, middle);
2613 }
2614
2615
2616 if (case_action == all_caps)
2617 newtext = Fupcase (newtext);
2618 else if (case_action == cap_initial)
2619 newtext = Fupcase_initials (newtext);
2620
2621 return concat3 (before, newtext, after);
2622 }
2623
2624
2625 opoint = PT <= sub_start ? PT : max (PT, sub_end) - ZV;
2626
2627
2628
2629 if (NILP (literal))
2630 {
2631 ptrdiff_t length = SBYTES (newtext);
2632 unsigned char *substed;
2633 ptrdiff_t substed_alloc_size, substed_len;
2634 bool buf_multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2635 bool str_multibyte = STRING_MULTIBYTE (newtext);
2636 bool really_changed = 0;
2637
2638 substed_alloc_size = (length <= (STRING_BYTES_BOUND - 100) / 2
2639 ? length * 2 + 100
2640 : STRING_BYTES_BOUND);
2641 substed = xmalloc (substed_alloc_size);
2642 substed_len = 0;
2643
2644
2645
2646
2647
2648 for (pos_byte = 0, pos = 0; pos_byte < length;)
2649 {
2650 unsigned char str[MAX_MULTIBYTE_LENGTH];
2651 const unsigned char *add_stuff = NULL;
2652 ptrdiff_t add_len = 0;
2653 ptrdiff_t idx = -1;
2654 ptrdiff_t begbyte UNINIT;
2655
2656 if (str_multibyte)
2657 {
2658 c = fetch_string_char_advance_no_check (newtext,
2659 &pos, &pos_byte);
2660 if (!buf_multibyte)
2661 c = CHAR_TO_BYTE8 (c);
2662 }
2663 else
2664 {
2665
2666 c = SREF (newtext, pos_byte++);
2667 if (buf_multibyte)
2668 c = make_char_multibyte (c);
2669 }
2670
2671
2672
2673
2674
2675 if (c == '\\')
2676 {
2677 really_changed = 1;
2678
2679 if (str_multibyte)
2680 {
2681 c = fetch_string_char_advance_no_check (newtext,
2682 &pos, &pos_byte);
2683 if (!buf_multibyte && !ASCII_CHAR_P (c))
2684 c = CHAR_TO_BYTE8 (c);
2685 }
2686 else
2687 {
2688 c = SREF (newtext, pos_byte++);
2689 if (buf_multibyte)
2690 c = make_char_multibyte (c);
2691 }
2692
2693 if (c == '&')
2694 idx = sub;
2695 else if ('1' <= c && c <= '9' && c - '0' < num_regs)
2696 {
2697 if (search_regs.start[c - '0'] >= 1)
2698 idx = c - '0';
2699 }
2700 else if (c == '\\')
2701 add_len = 1, add_stuff = (unsigned char *) "\\";
2702 else
2703 {
2704 xfree (substed);
2705 error ("Invalid use of `\\' in replacement text");
2706 }
2707 }
2708 else
2709 {
2710 add_len = CHAR_STRING (c, str);
2711 add_stuff = str;
2712 }
2713
2714
2715
2716 if (idx >= 0)
2717 {
2718 begbyte = CHAR_TO_BYTE (search_regs.start[idx]);
2719 add_len = CHAR_TO_BYTE (search_regs.end[idx]) - begbyte;
2720 if (search_regs.start[idx] < GPT && GPT < search_regs.end[idx])
2721 move_gap_both (search_regs.start[idx], begbyte);
2722 }
2723
2724
2725
2726
2727
2728 if (substed_alloc_size - substed_len < add_len)
2729 substed =
2730 xpalloc (substed, &substed_alloc_size,
2731 add_len - (substed_alloc_size - substed_len),
2732 STRING_BYTES_BOUND, 1);
2733
2734
2735
2736 if (idx >= 0)
2737 add_stuff = BYTE_POS_ADDR (begbyte);
2738
2739
2740 if (add_stuff)
2741 {
2742 memcpy (substed + substed_len, add_stuff, add_len);
2743 substed_len += add_len;
2744 }
2745 }
2746
2747 if (really_changed)
2748 newtext = make_specified_string ((const char *) substed, -1,
2749 substed_len, buf_multibyte);
2750 xfree (substed);
2751 }
2752
2753 newpoint = sub_start + SCHARS (newtext);
2754
2755
2756 replace_range (sub_start, sub_end, newtext, 1, 0, 1, true, true);
2757
2758 if (case_action == all_caps)
2759 Fupcase_region (make_fixnum (search_regs.start[sub]),
2760 make_fixnum (newpoint),
2761 Qnil);
2762 else if (case_action == cap_initial)
2763 Fupcase_initials_region (make_fixnum (search_regs.start[sub]),
2764 make_fixnum (newpoint), Qnil);
2765
2766
2767
2768
2769
2770
2771
2772
2773 if (search_regs.num_regs != num_regs)
2774 error ("Match data clobbered by buffer modification hooks");
2775
2776
2777 TEMP_SET_PT (clip_to_bounds (BEGV, opoint + (opoint <= 0 ? ZV : 0), ZV));
2778
2779 move_if_not_intangible (newpoint);
2780
2781 signal_after_change (sub_start, sub_end - sub_start, SCHARS (newtext));
2782 update_compositions (sub_start, newpoint, CHECK_BORDER);
2783
2784 return Qnil;
2785 }
2786
2787 static Lisp_Object
2788 match_limit (Lisp_Object num, bool beginningp)
2789 {
2790 EMACS_INT n;
2791
2792 CHECK_FIXNUM (num);
2793 n = XFIXNUM (num);
2794 if (n < 0)
2795 args_out_of_range (num, make_fixnum (0));
2796 if (search_regs.num_regs <= 0)
2797 error ("No match data, because no search succeeded");
2798 if (n >= search_regs.num_regs
2799 || search_regs.start[n] < 0)
2800 return Qnil;
2801 return (make_fixnum ((beginningp) ? search_regs.start[n]
2802 : search_regs.end[n]));
2803 }
2804
2805 DEFUN ("match-beginning", Fmatch_beginning, Smatch_beginning, 1, 1, 0,
2806 doc:
2807
2808
2809
2810
2811
2812
2813 )
2814 (Lisp_Object subexp)
2815 {
2816 return match_limit (subexp, 1);
2817 }
2818
2819 DEFUN ("match-end", Fmatch_end, Smatch_end, 1, 1, 0,
2820 doc:
2821
2822
2823
2824
2825
2826
2827 )
2828 (Lisp_Object subexp)
2829 {
2830 return match_limit (subexp, 0);
2831 }
2832
2833 DEFUN ("match-data", Fmatch_data, Smatch_data, 0, 3, 0,
2834 doc:
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867 )
2868 (Lisp_Object integers, Lisp_Object reuse, Lisp_Object reseat)
2869 {
2870 Lisp_Object tail, prev;
2871 Lisp_Object *data;
2872 ptrdiff_t i, len;
2873
2874 if (!NILP (reseat))
2875 for (tail = reuse; CONSP (tail); tail = XCDR (tail))
2876 if (MARKERP (XCAR (tail)))
2877 {
2878 unchain_marker (XMARKER (XCAR (tail)));
2879 XSETCAR (tail, Qnil);
2880 }
2881
2882 if (NILP (last_thing_searched))
2883 return Qnil;
2884
2885 prev = Qnil;
2886
2887 USE_SAFE_ALLOCA;
2888 SAFE_NALLOCA (data, 1, 2 * search_regs.num_regs + 1);
2889
2890 len = 0;
2891 for (i = 0; i < search_regs.num_regs; i++)
2892 {
2893 ptrdiff_t start = search_regs.start[i];
2894 if (start >= 0)
2895 {
2896 if (BASE_EQ (last_thing_searched, Qt)
2897 || ! NILP (integers))
2898 {
2899 XSETFASTINT (data[2 * i], start);
2900 XSETFASTINT (data[2 * i + 1], search_regs.end[i]);
2901 }
2902 else if (BUFFERP (last_thing_searched))
2903 {
2904 data[2 * i] = Fmake_marker ();
2905 Fset_marker (data[2 * i],
2906 make_fixnum (start),
2907 last_thing_searched);
2908 data[2 * i + 1] = Fmake_marker ();
2909 Fset_marker (data[2 * i + 1],
2910 make_fixnum (search_regs.end[i]),
2911 last_thing_searched);
2912 }
2913 else
2914
2915 emacs_abort ();
2916
2917 len = 2 * i + 2;
2918 }
2919 else
2920 data[2 * i] = data[2 * i + 1] = Qnil;
2921 }
2922
2923 if (BUFFERP (last_thing_searched) && !NILP (integers))
2924 {
2925 data[len] = last_thing_searched;
2926 len++;
2927 }
2928
2929
2930 if (! CONSP (reuse))
2931 reuse = Flist (len, data);
2932 else
2933 {
2934
2935
2936 for (i = 0, tail = reuse; CONSP (tail);
2937 i++, tail = XCDR (tail))
2938 {
2939 if (i < len)
2940 XSETCAR (tail, data[i]);
2941 else
2942 XSETCAR (tail, Qnil);
2943 prev = tail;
2944 }
2945
2946
2947
2948 if (i < len)
2949 XSETCDR (prev, Flist (len - i, data + i));
2950 }
2951
2952 SAFE_FREE ();
2953 return reuse;
2954 }
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966 DEFUN ("set-match-data", Fset_match_data, Sset_match_data, 1, 2, 0,
2967 doc:
2968
2969
2970 )
2971 (register Lisp_Object list, Lisp_Object reseat)
2972 {
2973 ptrdiff_t i;
2974 register Lisp_Object marker;
2975
2976 if (running_asynch_code)
2977 save_search_regs ();
2978
2979 CHECK_LIST (list);
2980
2981
2982
2983 last_thing_searched = Qt;
2984
2985
2986 {
2987 ptrdiff_t length = list_length (list) / 2;
2988
2989 if (length > search_regs.num_regs)
2990 {
2991 ptrdiff_t num_regs = search_regs.num_regs;
2992 search_regs.start =
2993 xpalloc (search_regs.start, &num_regs, length - num_regs,
2994 min (PTRDIFF_MAX, UINT_MAX), sizeof *search_regs.start);
2995 search_regs.end =
2996 xrealloc (search_regs.end, num_regs * sizeof *search_regs.end);
2997
2998 for (i = search_regs.num_regs; i < num_regs; i++)
2999 search_regs.start[i] = -1;
3000
3001 search_regs.num_regs = num_regs;
3002 }
3003
3004 for (i = 0; CONSP (list); i++)
3005 {
3006 marker = XCAR (list);
3007 if (BUFFERP (marker))
3008 {
3009 last_thing_searched = marker;
3010 break;
3011 }
3012 if (i >= length)
3013 break;
3014 if (NILP (marker))
3015 {
3016 search_regs.start[i] = -1;
3017 list = XCDR (list);
3018 }
3019 else
3020 {
3021 Lisp_Object from;
3022 Lisp_Object m;
3023
3024 m = marker;
3025 if (MARKERP (marker))
3026 {
3027 if (XMARKER (marker)->buffer == 0)
3028 XSETFASTINT (marker, 0);
3029 else
3030 XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer);
3031 }
3032
3033 CHECK_FIXNUM_COERCE_MARKER (marker);
3034 from = marker;
3035
3036 if (!NILP (reseat) && MARKERP (m))
3037 {
3038 unchain_marker (XMARKER (m));
3039 XSETCAR (list, Qnil);
3040 }
3041
3042 if ((list = XCDR (list), !CONSP (list)))
3043 break;
3044
3045 m = marker = XCAR (list);
3046
3047 if (MARKERP (marker) && XMARKER (marker)->buffer == 0)
3048 XSETFASTINT (marker, 0);
3049
3050 CHECK_FIXNUM_COERCE_MARKER (marker);
3051 if (PTRDIFF_MIN <= XFIXNUM (from) && XFIXNUM (from) <= PTRDIFF_MAX
3052 && PTRDIFF_MIN <= XFIXNUM (marker)
3053 && XFIXNUM (marker) <= PTRDIFF_MAX)
3054 {
3055 search_regs.start[i] = XFIXNUM (from);
3056 search_regs.end[i] = XFIXNUM (marker);
3057 }
3058 else
3059 {
3060 search_regs.start[i] = -1;
3061 }
3062
3063 if (!NILP (reseat) && MARKERP (m))
3064 {
3065 unchain_marker (XMARKER (m));
3066 XSETCAR (list, Qnil);
3067 }
3068 }
3069 list = XCDR (list);
3070 }
3071
3072 for (; i < search_regs.num_regs; i++)
3073 search_regs.start[i] = -1;
3074 }
3075
3076 return Qnil;
3077 }
3078
3079 DEFUN ("match-data--translate", Fmatch_data__translate, Smatch_data__translate,
3080 1, 1, 0,
3081 doc: )
3082 (Lisp_Object n)
3083 {
3084 CHECK_FIXNUM (n);
3085 EMACS_INT delta = XFIXNUM (n);
3086 if (!NILP (last_thing_searched))
3087 for (ptrdiff_t i = 0; i < search_regs.num_regs; i++)
3088 if (search_regs.start[i] >= 0)
3089 {
3090 search_regs.start[i] = max (0, search_regs.start[i] + delta);
3091 search_regs.end[i] = max (0, search_regs.end[i] + delta);
3092 }
3093 return Qnil;
3094 }
3095
3096
3097
3098 static void
3099 save_search_regs (void)
3100 {
3101 if (saved_search_regs.num_regs == 0)
3102 {
3103 saved_search_regs = search_regs;
3104 saved_last_thing_searched = last_thing_searched;
3105 last_thing_searched = Qnil;
3106 search_regs.num_regs = 0;
3107 search_regs.start = 0;
3108 search_regs.end = 0;
3109 }
3110 }
3111
3112
3113 void
3114 restore_search_regs (void)
3115 {
3116 if (saved_search_regs.num_regs != 0)
3117 {
3118 if (search_regs.num_regs > 0)
3119 {
3120 xfree (search_regs.start);
3121 xfree (search_regs.end);
3122 }
3123 search_regs = saved_search_regs;
3124 last_thing_searched = saved_last_thing_searched;
3125 saved_last_thing_searched = Qnil;
3126 saved_search_regs.num_regs = 0;
3127 }
3128 }
3129
3130
3131 void
3132 update_search_regs (ptrdiff_t oldstart, ptrdiff_t oldend, ptrdiff_t newend)
3133 {
3134
3135 ptrdiff_t change = newend - oldend;
3136 ptrdiff_t i;
3137
3138 for (i = 0; i < search_regs.num_regs; i++)
3139 {
3140 if (search_regs.start[i] >= oldend)
3141 search_regs.start[i] += change;
3142 else if (search_regs.start[i] > oldstart)
3143 search_regs.start[i] = oldstart;
3144 if (search_regs.end[i] >= oldend)
3145 search_regs.end[i] += change;
3146 else if (search_regs.end[i] > oldstart)
3147 search_regs.end[i] = oldstart;
3148 }
3149 }
3150
3151 static void
3152 unwind_set_match_data (Lisp_Object list)
3153 {
3154
3155 Fset_match_data (list, Qt);
3156 }
3157
3158
3159 void
3160 record_unwind_save_match_data (void)
3161 {
3162 record_unwind_protect (unwind_set_match_data,
3163 Fmatch_data (Qnil, Qnil, Qnil));
3164 }
3165
3166
3167
3168 DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
3169 doc: )
3170 (Lisp_Object string)
3171 {
3172 char *in, *out, *end;
3173 char *temp;
3174 ptrdiff_t backslashes_added = 0;
3175
3176 CHECK_STRING (string);
3177
3178 USE_SAFE_ALLOCA;
3179 SAFE_NALLOCA (temp, 2, SBYTES (string));
3180
3181
3182
3183 in = SSDATA (string);
3184 end = in + SBYTES (string);
3185 out = temp;
3186
3187 for (; in != end; in++)
3188 {
3189 if (*in == '['
3190 || *in == '*' || *in == '.' || *in == '\\'
3191 || *in == '?' || *in == '+'
3192 || *in == '^' || *in == '$')
3193 *out++ = '\\', backslashes_added++;
3194 *out++ = *in;
3195 }
3196
3197 Lisp_Object result
3198 = (backslashes_added > 0
3199 ? make_specified_string (temp,
3200 SCHARS (string) + backslashes_added,
3201 out - temp,
3202 STRING_MULTIBYTE (string))
3203 : string);
3204 SAFE_FREE ();
3205 return result;
3206 }
3207
3208
3209 ptrdiff_t
3210 find_newline1 (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end,
3211 ptrdiff_t end_byte, ptrdiff_t count, ptrdiff_t *counted,
3212 ptrdiff_t *bytepos, bool allow_quit)
3213 {
3214 if (count > 0)
3215 {
3216 if (!end)
3217 end = ZV, end_byte = ZV_BYTE;
3218 }
3219 else
3220 {
3221 if (!end)
3222 end = BEGV, end_byte = BEGV_BYTE;
3223 }
3224 if (end_byte == -1)
3225 end_byte = CHAR_TO_BYTE (end);
3226
3227 if (counted)
3228 *counted = count;
3229
3230 if (count > 0)
3231 while (start != end)
3232 {
3233
3234
3235
3236
3237
3238 ptrdiff_t tem, ceiling_byte = end_byte - 1;
3239
3240 if (start_byte == -1)
3241 start_byte = CHAR_TO_BYTE (start);
3242
3243
3244
3245
3246
3247 tem = BUFFER_CEILING_OF (start_byte);
3248 ceiling_byte = min (tem, ceiling_byte);
3249
3250 {
3251
3252 unsigned char *lim_addr = BYTE_POS_ADDR (ceiling_byte) + 1;
3253 ptrdiff_t lim_byte = ceiling_byte + 1;
3254
3255
3256
3257 ptrdiff_t base = start_byte - lim_byte;
3258 ptrdiff_t cursor, next;
3259
3260 for (cursor = base; cursor < 0; cursor = next)
3261 {
3262
3263 unsigned char *nl = memchr (lim_addr + cursor, '\n', - cursor);
3264 next = nl ? nl - lim_addr : 0;
3265
3266 if (! nl)
3267 break;
3268 next++;
3269
3270 if (--count == 0)
3271 {
3272 if (bytepos)
3273 *bytepos = lim_byte + next;
3274 return BYTE_TO_CHAR (lim_byte + next);
3275 }
3276 if (allow_quit)
3277 maybe_quit ();
3278 }
3279
3280 start_byte = lim_byte;
3281 start = BYTE_TO_CHAR (start_byte);
3282 }
3283 }
3284
3285 if (counted)
3286 *counted -= count;
3287 if (bytepos)
3288 {
3289 *bytepos = start_byte == -1 ? CHAR_TO_BYTE (start) : start_byte;
3290 eassert (*bytepos == CHAR_TO_BYTE (start));
3291 }
3292 return start;
3293 }
3294
3295 DEFUN ("newline-cache-check", Fnewline_cache_check, Snewline_cache_check,
3296 0, 1, 0,
3297 doc:
3298
3299
3300
3301
3302
3303 )
3304 (Lisp_Object buffer)
3305 {
3306 struct buffer *buf, *old = NULL;
3307 ptrdiff_t nl_count_cache, nl_count_buf;
3308 Lisp_Object cache_newlines, buf_newlines, val;
3309 ptrdiff_t from, found, i;
3310
3311 if (NILP (buffer))
3312 buf = current_buffer;
3313 else
3314 {
3315 CHECK_BUFFER (buffer);
3316 buf = XBUFFER (buffer);
3317 old = current_buffer;
3318 }
3319 if (buf->base_buffer)
3320 buf = buf->base_buffer;
3321
3322
3323 if (NILP (BVAR (buf, cache_long_scans))
3324 || buf->newline_cache == NULL)
3325 return Qnil;
3326
3327
3328 if (old != NULL)
3329 set_buffer_internal_1 (buf);
3330
3331
3332 find_newline (BEGV, BEGV_BYTE, ZV, ZV_BYTE,
3333 TYPE_MAXIMUM (ptrdiff_t), &nl_count_cache, NULL, true);
3334
3335
3336 cache_newlines = make_vector (nl_count_cache, make_fixnum (-1));
3337
3338 if (nl_count_cache)
3339 {
3340 for (from = BEGV, found = from, i = 0; from < ZV; from = found, i++)
3341 {
3342 ptrdiff_t from_byte = CHAR_TO_BYTE (from), counted;
3343
3344 found = find_newline (from, from_byte, 0, -1, 1, &counted,
3345 NULL, true);
3346 if (counted == 0 || i >= nl_count_cache)
3347 break;
3348 ASET (cache_newlines, i, make_fixnum (found - 1));
3349 }
3350 }
3351
3352
3353 find_newline1 (BEGV, BEGV_BYTE, ZV, ZV_BYTE,
3354 TYPE_MAXIMUM (ptrdiff_t), &nl_count_buf, NULL, true);
3355 buf_newlines = make_vector (nl_count_buf, make_fixnum (-1));
3356 if (nl_count_buf)
3357 {
3358 for (from = BEGV, found = from, i = 0; from < ZV; from = found, i++)
3359 {
3360 ptrdiff_t from_byte = CHAR_TO_BYTE (from), counted;
3361
3362 found = find_newline1 (from, from_byte, 0, -1, 1, &counted,
3363 NULL, true);
3364 if (counted == 0 || i >= nl_count_buf)
3365 break;
3366 ASET (buf_newlines, i, make_fixnum (found - 1));
3367 }
3368 }
3369
3370
3371 val = CALLN (Fvector, cache_newlines, buf_newlines);
3372
3373 if (old != NULL)
3374 set_buffer_internal_1 (old);
3375 return val;
3376 }
3377
3378
3379 static void syms_of_search_for_pdumper (void);
3380
3381 void
3382 syms_of_search (void)
3383 {
3384 for (int i = 0; i < REGEXP_CACHE_SIZE; ++i)
3385 {
3386 staticpro (&searchbufs[i].regexp);
3387 staticpro (&searchbufs[i].f_whitespace_regexp);
3388 staticpro (&searchbufs[i].syntax_table);
3389 }
3390
3391
3392 DEFSYM (Qsearch_failed, "search-failed");
3393
3394
3395
3396 DEFSYM (Quser_search_failed, "user-search-failed");
3397
3398
3399 DEFSYM (Qinvalid_regexp, "invalid-regexp");
3400
3401 Fput (Qsearch_failed, Qerror_conditions,
3402 pure_list (Qsearch_failed, Qerror));
3403 Fput (Qsearch_failed, Qerror_message,
3404 build_pure_c_string ("Search failed"));
3405
3406 Fput (Quser_search_failed, Qerror_conditions,
3407 pure_list (Quser_search_failed, Quser_error, Qsearch_failed, Qerror));
3408 Fput (Quser_search_failed, Qerror_message,
3409 build_pure_c_string ("Search failed"));
3410
3411 Fput (Qinvalid_regexp, Qerror_conditions,
3412 pure_list (Qinvalid_regexp, Qerror));
3413 Fput (Qinvalid_regexp, Qerror_message,
3414 build_pure_c_string ("Invalid regexp"));
3415
3416 re_match_object = Qnil;
3417 staticpro (&re_match_object);
3418
3419 DEFVAR_LISP ("search-spaces-regexp", Vsearch_spaces_regexp,
3420 doc:
3421
3422
3423
3424
3425
3426 );
3427 Vsearch_spaces_regexp = Qnil;
3428
3429 DEFSYM (Qinhibit_changing_match_data, "inhibit-changing-match-data");
3430 DEFVAR_LISP ("inhibit-changing-match-data", Vinhibit_changing_match_data,
3431 doc:
3432
3433
3434
3435 );
3436 Vinhibit_changing_match_data = Qnil;
3437
3438 defsubr (&Slooking_at);
3439 defsubr (&Sposix_looking_at);
3440 defsubr (&Sstring_match);
3441 defsubr (&Sposix_string_match);
3442 defsubr (&Ssearch_forward);
3443 defsubr (&Ssearch_backward);
3444 defsubr (&Sre_search_forward);
3445 defsubr (&Sre_search_backward);
3446 defsubr (&Sposix_search_forward);
3447 defsubr (&Sposix_search_backward);
3448 defsubr (&Sreplace_match);
3449 defsubr (&Smatch_beginning);
3450 defsubr (&Smatch_end);
3451 defsubr (&Smatch_data);
3452 defsubr (&Sset_match_data);
3453 defsubr (&Smatch_data__translate);
3454 defsubr (&Sregexp_quote);
3455 defsubr (&Snewline_cache_check);
3456
3457 pdumper_do_now_and_after_load (syms_of_search_for_pdumper);
3458 }
3459
3460 static void
3461 syms_of_search_for_pdumper (void)
3462 {
3463 for (int i = 0; i < REGEXP_CACHE_SIZE; ++i)
3464 {
3465 searchbufs[i].buf.allocated = 100;
3466 searchbufs[i].buf.buffer = xmalloc (100);
3467 searchbufs[i].buf.fastmap = searchbufs[i].fastmap;
3468 searchbufs[i].regexp = Qnil;
3469 searchbufs[i].f_whitespace_regexp = Qnil;
3470 searchbufs[i].busy = false;
3471 searchbufs[i].syntax_table = Qnil;
3472 searchbufs[i].next = (i == REGEXP_CACHE_SIZE-1 ? 0 : &searchbufs[i+1]);
3473 }
3474 searchbuf_head = &searchbufs[0];
3475 }