diff options
Diffstat (limited to 'src/search.c')
| -rw-r--r-- | src/search.c | 51 |
1 files changed, 33 insertions, 18 deletions
diff --git a/src/search.c b/src/search.c index d4508004bf6..1c0f57487f9 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -638,15 +638,18 @@ newline_cache_on_off (struct buffer *buf) | |||
| 638 | If we don't find COUNT instances before reaching END, set *SHORTAGE | 638 | If we don't find COUNT instances before reaching END, set *SHORTAGE |
| 639 | to the number of newlines left unfound, and return END. | 639 | to the number of newlines left unfound, and return END. |
| 640 | 640 | ||
| 641 | If BYTEPOS is not NULL, set *BYTEPOS to the byte position corresponding | ||
| 642 | to the returned character position. | ||
| 643 | |||
| 641 | If ALLOW_QUIT, set immediate_quit. That's good to do | 644 | If ALLOW_QUIT, set immediate_quit. That's good to do |
| 642 | except when inside redisplay. */ | 645 | except when inside redisplay. */ |
| 643 | 646 | ||
| 644 | ptrdiff_t | 647 | ptrdiff_t |
| 645 | find_newline (ptrdiff_t start, ptrdiff_t end, | 648 | find_newline (ptrdiff_t start, ptrdiff_t end, ptrdiff_t count, |
| 646 | ptrdiff_t count, ptrdiff_t *shortage, bool allow_quit) | 649 | ptrdiff_t *shortage, ptrdiff_t *bytepos, bool allow_quit) |
| 647 | { | 650 | { |
| 648 | struct region_cache *newline_cache; | 651 | struct region_cache *newline_cache; |
| 649 | ptrdiff_t end_byte = -1; | 652 | ptrdiff_t start_byte = -1, end_byte = -1; |
| 650 | int direction; | 653 | int direction; |
| 651 | 654 | ||
| 652 | if (count > 0) | 655 | if (count > 0) |
| @@ -680,9 +683,7 @@ find_newline (ptrdiff_t start, ptrdiff_t end, | |||
| 680 | the position of the last character before the next such | 683 | the position of the last character before the next such |
| 681 | obstacle --- the last character the dumb search loop should | 684 | obstacle --- the last character the dumb search loop should |
| 682 | examine. */ | 685 | examine. */ |
| 683 | ptrdiff_t ceiling_byte = end_byte - 1; | 686 | ptrdiff_t tem, ceiling_byte = end_byte - 1; |
| 684 | ptrdiff_t start_byte; | ||
| 685 | ptrdiff_t tem; | ||
| 686 | 687 | ||
| 687 | /* If we're looking for a newline, consult the newline cache | 688 | /* If we're looking for a newline, consult the newline cache |
| 688 | to see where we can avoid some scanning. */ | 689 | to see where we can avoid some scanning. */ |
| @@ -745,21 +746,22 @@ find_newline (ptrdiff_t start, ptrdiff_t end, | |||
| 745 | if (--count == 0) | 746 | if (--count == 0) |
| 746 | { | 747 | { |
| 747 | immediate_quit = 0; | 748 | immediate_quit = 0; |
| 749 | if (bytepos) | ||
| 750 | *bytepos = nl + 1 - base + start_byte; | ||
| 748 | return BYTE_TO_CHAR (nl + 1 - base + start_byte); | 751 | return BYTE_TO_CHAR (nl + 1 - base + start_byte); |
| 749 | } | 752 | } |
| 750 | cursor = nl + 1; | 753 | cursor = nl + 1; |
| 751 | } | 754 | } |
| 752 | 755 | ||
| 753 | start = BYTE_TO_CHAR (ceiling_addr - base + start_byte); | 756 | start_byte += ceiling_addr - base; |
| 757 | start = BYTE_TO_CHAR (start_byte); | ||
| 754 | } | 758 | } |
| 755 | } | 759 | } |
| 756 | else | 760 | else |
| 757 | while (start > end) | 761 | while (start > end) |
| 758 | { | 762 | { |
| 759 | /* The last character to check before the next obstacle. */ | 763 | /* The last character to check before the next obstacle. */ |
| 760 | ptrdiff_t ceiling_byte = end_byte; | 764 | ptrdiff_t tem, ceiling_byte = end_byte; |
| 761 | ptrdiff_t start_byte; | ||
| 762 | ptrdiff_t tem; | ||
| 763 | 765 | ||
| 764 | /* Consult the newline cache, if appropriate. */ | 766 | /* Consult the newline cache, if appropriate. */ |
| 765 | if (newline_cache) | 767 | if (newline_cache) |
| @@ -816,18 +818,26 @@ find_newline (ptrdiff_t start, ptrdiff_t end, | |||
| 816 | if (++count >= 0) | 818 | if (++count >= 0) |
| 817 | { | 819 | { |
| 818 | immediate_quit = 0; | 820 | immediate_quit = 0; |
| 821 | if (bytepos) | ||
| 822 | *bytepos = nl - base + start_byte; | ||
| 819 | return BYTE_TO_CHAR (nl - base + start_byte); | 823 | return BYTE_TO_CHAR (nl - base + start_byte); |
| 820 | } | 824 | } |
| 821 | cursor = nl - 1; | 825 | cursor = nl - 1; |
| 822 | } | 826 | } |
| 823 | 827 | ||
| 824 | start = BYTE_TO_CHAR (ceiling_addr - 1 - base + start_byte); | 828 | start_byte += ceiling_addr - 1 - base; |
| 829 | start = BYTE_TO_CHAR (start_byte); | ||
| 825 | } | 830 | } |
| 826 | } | 831 | } |
| 827 | 832 | ||
| 828 | immediate_quit = 0; | 833 | immediate_quit = 0; |
| 829 | if (shortage != 0) | 834 | if (shortage) |
| 830 | *shortage = count * direction; | 835 | *shortage = count * direction; |
| 836 | if (bytepos) | ||
| 837 | { | ||
| 838 | *bytepos = start_byte == -1 ? CHAR_TO_BYTE (start) : start_byte; | ||
| 839 | eassert (*bytepos == CHAR_TO_BYTE (start)); | ||
| 840 | } | ||
| 831 | return start; | 841 | return start; |
| 832 | } | 842 | } |
| 833 | 843 | ||
| @@ -932,9 +942,9 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte, | |||
| 932 | } | 942 | } |
| 933 | 943 | ||
| 934 | ptrdiff_t | 944 | ptrdiff_t |
| 935 | find_next_newline_no_quit (ptrdiff_t from, ptrdiff_t cnt) | 945 | find_next_newline_no_quit (ptrdiff_t from, ptrdiff_t cnt, ptrdiff_t *bytepos) |
| 936 | { | 946 | { |
| 937 | return find_newline (from, 0, cnt, (ptrdiff_t *) 0, 0); | 947 | return find_newline (from, 0, cnt, NULL, bytepos, 0); |
| 938 | } | 948 | } |
| 939 | 949 | ||
| 940 | /* Like find_next_newline, but returns position before the newline, | 950 | /* Like find_next_newline, but returns position before the newline, |
| @@ -942,14 +952,19 @@ find_next_newline_no_quit (ptrdiff_t from, ptrdiff_t cnt) | |||
| 942 | find_next_newline (...)-1, because you might hit TO. */ | 952 | find_next_newline (...)-1, because you might hit TO. */ |
| 943 | 953 | ||
| 944 | ptrdiff_t | 954 | ptrdiff_t |
| 945 | find_before_next_newline (ptrdiff_t from, ptrdiff_t to, ptrdiff_t cnt) | 955 | find_before_next_newline (ptrdiff_t from, ptrdiff_t to, |
| 956 | ptrdiff_t cnt, ptrdiff_t *bytepos) | ||
| 946 | { | 957 | { |
| 947 | ptrdiff_t shortage; | 958 | ptrdiff_t shortage; |
| 948 | ptrdiff_t pos = find_newline (from, to, cnt, &shortage, 1); | 959 | ptrdiff_t pos = find_newline (from, to, cnt, &shortage, bytepos, 1); |
| 949 | 960 | ||
| 950 | if (shortage == 0) | 961 | if (shortage == 0) |
| 951 | pos--; | 962 | { |
| 952 | 963 | if (bytepos) | |
| 964 | DEC_BOTH (pos, *bytepos); | ||
| 965 | else | ||
| 966 | pos--; | ||
| 967 | } | ||
| 953 | return pos; | 968 | return pos; |
| 954 | } | 969 | } |
| 955 | 970 | ||