aboutsummaryrefslogtreecommitdiffstats
path: root/src/search.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/search.c')
-rw-r--r--src/search.c86
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
862EMACS_INT 862ptrdiff_t
863scan_newline (ptrdiff_t start, ptrdiff_t start_byte, 863scan_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