diff options
Diffstat (limited to 'src/search.c')
| -rw-r--r-- | src/search.c | 86 |
1 files changed, 9 insertions, 77 deletions
diff --git a/src/search.c b/src/search.c index 761c12a364a..99e8d2501fe 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -859,88 +859,20 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, | |||
| 859 | If ALLOW_QUIT, set immediate_quit. That's good to do | 859 | If ALLOW_QUIT, set immediate_quit. That's good to do |
| 860 | except in special cases. */ | 860 | except in special cases. */ |
| 861 | 861 | ||
| 862 | EMACS_INT | 862 | ptrdiff_t |
| 863 | scan_newline (ptrdiff_t start, ptrdiff_t start_byte, | 863 | scan_newline (ptrdiff_t start, ptrdiff_t start_byte, |
| 864 | ptrdiff_t limit, ptrdiff_t limit_byte, | 864 | ptrdiff_t limit, ptrdiff_t limit_byte, |
| 865 | EMACS_INT count, bool allow_quit) | 865 | ptrdiff_t count, bool allow_quit) |
| 866 | { | 866 | { |
| 867 | int direction = ((count > 0) ? 1 : -1); | 867 | ptrdiff_t charpos, bytepos, shortage; |
| 868 | |||
| 869 | unsigned char *cursor; | ||
| 870 | unsigned char *base; | ||
| 871 | |||
| 872 | ptrdiff_t ceiling; | ||
| 873 | unsigned char *ceiling_addr; | ||
| 874 | |||
| 875 | bool old_immediate_quit = immediate_quit; | ||
| 876 | |||
| 877 | if (allow_quit) | ||
| 878 | immediate_quit++; | ||
| 879 | 868 | ||
| 880 | if (count > 0) | 869 | charpos = find_newline (start, start_byte, limit, limit_byte, |
| 881 | { | 870 | count, &shortage, &bytepos, allow_quit); |
| 882 | while (start_byte < limit_byte) | 871 | if (shortage) |
| 883 | { | 872 | TEMP_SET_PT_BOTH (limit, limit_byte); |
| 884 | ceiling = BUFFER_CEILING_OF (start_byte); | ||
| 885 | ceiling = min (limit_byte - 1, ceiling); | ||
| 886 | ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; | ||
| 887 | base = (cursor = BYTE_POS_ADDR (start_byte)); | ||
| 888 | |||
| 889 | do | ||
| 890 | { | ||
| 891 | unsigned char *nl = memchr (cursor, '\n', ceiling_addr - cursor); | ||
| 892 | if (! nl) | ||
| 893 | break; | ||
| 894 | if (--count == 0) | ||
| 895 | { | ||
| 896 | immediate_quit = old_immediate_quit; | ||
| 897 | start_byte += nl - base + 1; | ||
| 898 | start = BYTE_TO_CHAR (start_byte); | ||
| 899 | TEMP_SET_PT_BOTH (start, start_byte); | ||
| 900 | return 0; | ||
| 901 | } | ||
| 902 | cursor = nl + 1; | ||
| 903 | } | ||
| 904 | while (cursor < ceiling_addr); | ||
| 905 | |||
| 906 | start_byte += ceiling_addr - base; | ||
| 907 | } | ||
| 908 | } | ||
| 909 | else | 873 | else |
| 910 | { | 874 | TEMP_SET_PT_BOTH (charpos, bytepos); |
| 911 | while (start_byte > limit_byte) | 875 | return shortage; |
| 912 | { | ||
| 913 | ceiling = BUFFER_FLOOR_OF (start_byte - 1); | ||
| 914 | ceiling = max (limit_byte, ceiling); | ||
| 915 | ceiling_addr = BYTE_POS_ADDR (ceiling); | ||
| 916 | base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); | ||
| 917 | while (1) | ||
| 918 | { | ||
| 919 | unsigned char *nl = memrchr (ceiling_addr, '\n', | ||
| 920 | cursor - ceiling_addr); | ||
| 921 | if (! nl) | ||
| 922 | break; | ||
| 923 | |||
| 924 | if (++count == 0) | ||
| 925 | { | ||
| 926 | immediate_quit = old_immediate_quit; | ||
| 927 | /* Return the position AFTER the match we found. */ | ||
| 928 | start_byte += nl - base + 1; | ||
| 929 | start = BYTE_TO_CHAR (start_byte); | ||
| 930 | TEMP_SET_PT_BOTH (start, start_byte); | ||
| 931 | return 0; | ||
| 932 | } | ||
| 933 | |||
| 934 | cursor = nl; | ||
| 935 | } | ||
| 936 | start_byte += ceiling_addr - base; | ||
| 937 | } | ||
| 938 | } | ||
| 939 | |||
| 940 | TEMP_SET_PT_BOTH (limit, limit_byte); | ||
| 941 | immediate_quit = old_immediate_quit; | ||
| 942 | |||
| 943 | return count * direction; | ||
| 944 | } | 876 | } |
| 945 | 877 | ||
| 946 | /* Like find_newline, but doesn't allow QUITting and doesn't return | 878 | /* Like find_newline, but doesn't allow QUITting and doesn't return |