aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/search.c81
1 files changed, 55 insertions, 26 deletions
diff --git a/src/search.c b/src/search.c
index 7f006883270..f3835ff0743 100644
--- a/src/search.c
+++ b/src/search.c
@@ -592,6 +592,35 @@ search_command (string, bound, noerror, count, direction, RE)
592 return make_number (np); 592 return make_number (np);
593} 593}
594 594
595static int
596trivial_regexp_p (regexp)
597 Lisp_Object regexp;
598{
599 int len = XSTRING (regexp)->size;
600 unsigned char *s = XSTRING (regexp)->data;
601 unsigned char c;
602 while (--len >= 0)
603 {
604 switch (*s++)
605 {
606 case '.': case '*': case '+': case '?': case '[': case '^': case '$':
607 return 0;
608 case '\\':
609 if (--len < 0)
610 return 0;
611 switch (*s++)
612 {
613 case '|': case '(': case ')': case '`': case '\'': case 'b':
614 case 'B': case '<': case '>': case 'w': case 'W': case 's':
615 case 'S': case '1': case '2': case '3': case '4': case '5':
616 case '6': case '7': case '8': case '9':
617 return 0;
618 }
619 }
620 }
621 return 1;
622}
623
595/* Search for the n'th occurrence of STRING in the current buffer, 624/* Search for the n'th occurrence of STRING in the current buffer,
596 starting at position POS and stopping at position LIM, 625 starting at position POS and stopping at position LIM,
597 treating PAT as a literal string if RE is false or as 626 treating PAT as a literal string if RE is false or as
@@ -636,32 +665,10 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
636 if (n == 0) 665 if (n == 0)
637 return pos; 666 return pos;
638 667
639 if (RE) 668 if (RE && !trivial_regexp_p (string))
640 compile_pattern (string, &searchbuf, &search_regs, (char *) trt);
641
642 if (RE /* Here we detect whether the */
643 /* generality of an RE search is */
644 /* really needed. */
645 /* first item is "exact match" */
646 && *(searchbuf.buffer) == (char) RE_EXACTN_VALUE
647 && searchbuf.buffer[1] + 2 == searchbuf.used) /*first is ONLY item */
648 { 669 {
649 RE = 0; /* can do straight (non RE) search */ 670 compile_pattern (string, &searchbuf, &search_regs, (char *) trt);
650 pat = (base_pat = (unsigned char *) searchbuf.buffer + 2);
651 /* trt already applied */
652 len = searchbuf.used - 2;
653 }
654 else if (!RE)
655 {
656 pat = (unsigned char *) alloca (len);
657 671
658 for (i = len; i--;) /* Copy the pattern; apply trt */
659 *pat++ = (((int) trt) ? trt [*base_pat++] : *base_pat++);
660 pat -= len; base_pat = pat;
661 }
662
663 if (RE)
664 {
665 immediate_quit = 1; /* Quit immediately if user types ^G, 672 immediate_quit = 1; /* Quit immediately if user types ^G,
666 because letting this function finish 673 because letting this function finish
667 can take too long. */ 674 can take too long. */
@@ -693,7 +700,9 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
693 /* Don't allow match past current point */ 700 /* Don't allow match past current point */
694 pos - BEGV); 701 pos - BEGV);
695 if (val == -2) 702 if (val == -2)
696 matcher_overflow (); 703 {
704 matcher_overflow ();
705 }
697 if (val >= 0) 706 if (val >= 0)
698 { 707 {
699 j = BEGV; 708 j = BEGV;
@@ -721,7 +730,9 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
721 pos - BEGV, lim - pos, &search_regs, 730 pos - BEGV, lim - pos, &search_regs,
722 lim - BEGV); 731 lim - BEGV);
723 if (val == -2) 732 if (val == -2)
724 matcher_overflow (); 733 {
734 matcher_overflow ();
735 }
725 if (val >= 0) 736 if (val >= 0)
726 { 737 {
727 j = BEGV; 738 j = BEGV;
@@ -752,6 +763,24 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
752#else 763#else
753 BM_tab = (int *) alloca (0400 * sizeof (int)); 764 BM_tab = (int *) alloca (0400 * sizeof (int));
754#endif 765#endif
766 {
767 unsigned char *patbuf = (unsigned char *) alloca (len);
768 pat = patbuf;
769 while (--len >= 0)
770 {
771 /* If we got here and the RE flag is set, it's because we're
772 dealing with a regexp known to be trivial, so the backslash
773 just quotes the next character. */
774 if (RE && *base_pat == '\\')
775 {
776 len--;
777 base_pat++;
778 }
779 *pat++ = (trt ? trt[*base_pat++] : *base_pat++);
780 }
781 len = pat - patbuf;
782 pat = base_pat = patbuf;
783 }
755 /* The general approach is that we are going to maintain that we know */ 784 /* The general approach is that we are going to maintain that we know */
756 /* the first (closest to the present position, in whatever direction */ 785 /* the first (closest to the present position, in whatever direction */
757 /* we're searching) character that could possibly be the last */ 786 /* we're searching) character that could possibly be the last */