aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2013-02-11 15:37:18 -0800
committerPaul Eggert2013-02-11 15:37:18 -0800
commita84b7c5334e232913111b840f2283d0138a6f5fb (patch)
tree8ee4e55f7059d1eb918fb5966cd81ee3f84153bc /src
parent71d4202f204ea5fad93eb34406f0ef671630f271 (diff)
downloademacs-a84b7c5334e232913111b840f2283d0138a6f5fb.tar.gz
emacs-a84b7c5334e232913111b840f2283d0138a6f5fb.zip
Tune by using memchr and memrchr.
* .bzrignore: Add string.h. * admin/merge-gnulib (GNULIB_MODULES): Add memrchr. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * lib/memrchr.c, lib/string.in.h, m4/memrchr.m4, m4/string_h.m4: New files, from gnulib. * src/doc.c (Fsnarf_documentation): * src/fileio.c (Fsubstitute_in_file_name): * src/search.c (find_newline, scan_newline): * src/xdisp.c (pos_visible_p, display_count_lines): Use memchr and memrchr rather than scanning byte-by-byte. * src/search.c (find_newline): Rename from scan_buffer. Omit first arg TARGET, as it's always '\n'. All callers changed.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/doc.c5
-rw-r--r--src/editfns.c5
-rw-r--r--src/fileio.c10
-rw-r--r--src/lisp.h4
-rw-r--r--src/region-cache.h2
-rw-r--r--src/search.c172
-rw-r--r--src/xdisp.c101
8 files changed, 150 insertions, 158 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index b3d3958853b..30470f5730a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,14 @@
12013-02-11 Paul Eggert <eggert@cs.ucla.edu> 12013-02-11 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Tune by using memchr and memrchr.
4 * doc.c (Fsnarf_documentation):
5 * fileio.c (Fsubstitute_in_file_name):
6 * search.c (find_newline, scan_newline):
7 * xdisp.c (pos_visible_p, display_count_lines):
8 Use memchr and memrchr rather than scanning byte-by-byte.
9 * search.c (find_newline): Rename from scan_buffer.
10 Omit first arg TARGET, as it's always '\n'. All callers changed.
11
3 Clean up read_key_sequence a tiny bit more. 12 Clean up read_key_sequence a tiny bit more.
4 * keyboard.c (read_char_x_menu_prompt) [HAVE_MENUS]: 13 * keyboard.c (read_char_x_menu_prompt) [HAVE_MENUS]:
5 (read_key_sequence): Remove unused locals. 14 (read_key_sequence): Remove unused locals.
diff --git a/src/doc.c b/src/doc.c
index fa2eca66a1d..7234fb38bf9 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -630,11 +630,10 @@ the same file name is found in the `doc-directory'. */)
630 break; 630 break;
631 631
632 buf[filled] = 0; 632 buf[filled] = 0;
633 p = buf;
634 end = buf + (filled < 512 ? filled : filled - 128); 633 end = buf + (filled < 512 ? filled : filled - 128);
635 while (p != end && *p != '\037') p++; 634 p = memchr (buf, '\037', end - buf);
636 /* p points to ^_Ffunctionname\n or ^_Vvarname\n or ^_Sfilename\n. */ 635 /* p points to ^_Ffunctionname\n or ^_Vvarname\n or ^_Sfilename\n. */
637 if (p != end) 636 if (p)
638 { 637 {
639 end = strchr (p, '\n'); 638 end = strchr (p, '\n');
640 639
diff --git a/src/editfns.c b/src/editfns.c
index 0f88a781b88..c5cd8b0b725 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -735,9 +735,8 @@ Field boundaries are not noticed if `inhibit-field-text-motion' is non-nil. */)
735 /* This is the ONLY_IN_LINE case, check that NEW_POS and 735 /* This is the ONLY_IN_LINE case, check that NEW_POS and
736 FIELD_BOUND are on the same line by seeing whether 736 FIELD_BOUND are on the same line by seeing whether
737 there's an intervening newline or not. */ 737 there's an intervening newline or not. */
738 || (scan_buffer ('\n', 738 || (find_newline (XFASTINT (new_pos), XFASTINT (field_bound),
739 XFASTINT (new_pos), XFASTINT (field_bound), 739 fwd ? -1 : 1, &shortage, 1),
740 fwd ? -1 : 1, &shortage, 1),
741 shortage != 0))) 740 shortage != 0)))
742 /* Constrain NEW_POS to FIELD_BOUND. */ 741 /* Constrain NEW_POS to FIELD_BOUND. */
743 new_pos = field_bound; 742 new_pos = field_bound;
diff --git a/src/fileio.c b/src/fileio.c
index 98a9b32ea91..89ad3396464 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -1710,8 +1710,9 @@ those `/' is discarded. */)
1710 else if (*p == '{') 1710 else if (*p == '{')
1711 { 1711 {
1712 o = ++p; 1712 o = ++p;
1713 while (p != endp && *p != '}') p++; 1713 p = memchr (p, '}', endp - p);
1714 if (*p != '}') goto missingclose; 1714 if (! p)
1715 goto missingclose;
1715 s = p; 1716 s = p;
1716 } 1717 }
1717 else 1718 else
@@ -1779,8 +1780,9 @@ those `/' is discarded. */)
1779 else if (*p == '{') 1780 else if (*p == '{')
1780 { 1781 {
1781 o = ++p; 1782 o = ++p;
1782 while (p != endp && *p != '}') p++; 1783 p = memchr (p, '}', endp - p);
1783 if (*p != '}') goto missingclose; 1784 if (! p)
1785 goto missingclose;
1784 s = p++; 1786 s = p++;
1785 } 1787 }
1786 else 1788 else
diff --git a/src/lisp.h b/src/lisp.h
index 14db66c6793..37d2b45e85b 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3346,8 +3346,8 @@ extern ptrdiff_t fast_c_string_match_ignore_case (Lisp_Object, const char *,
3346extern ptrdiff_t fast_string_match_ignore_case (Lisp_Object, Lisp_Object); 3346extern ptrdiff_t fast_string_match_ignore_case (Lisp_Object, Lisp_Object);
3347extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t, 3347extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t,
3348 ptrdiff_t, ptrdiff_t, Lisp_Object); 3348 ptrdiff_t, ptrdiff_t, Lisp_Object);
3349extern ptrdiff_t scan_buffer (int, ptrdiff_t, ptrdiff_t, ptrdiff_t, 3349extern ptrdiff_t find_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t,
3350 ptrdiff_t *, bool); 3350 ptrdiff_t *, bool);
3351extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, 3351extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t,
3352 EMACS_INT, bool); 3352 EMACS_INT, bool);
3353extern ptrdiff_t find_next_newline (ptrdiff_t, int); 3353extern ptrdiff_t find_next_newline (ptrdiff_t, int);
diff --git a/src/region-cache.h b/src/region-cache.h
index 697ae1c791f..e4c6b59ee95 100644
--- a/src/region-cache.h
+++ b/src/region-cache.h
@@ -40,7 +40,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
40 existing data structure, and disturb as little of the existing code 40 existing data structure, and disturb as little of the existing code
41 as possible. 41 as possible.
42 42
43 So here's the tack. We add some caching to the scan_buffer 43 So here's the tack. We add some caching to the find_newline
44 function, so that when it searches for a newline, it notes that the 44 function, so that when it searches for a newline, it notes that the
45 region between the start and end of the search contained no 45 region between the start and end of the search contained no
46 newlines; then, the next time around, it consults this cache to see 46 newlines; then, the next time around, it consults this cache to see
diff --git a/src/search.c b/src/search.c
index c4ccf6c257b..c25d2441018 100644
--- a/src/search.c
+++ b/src/search.c
@@ -619,7 +619,7 @@ newline_cache_on_off (struct buffer *buf)
619} 619}
620 620
621 621
622/* Search for COUNT instances of the character TARGET between START and END. 622/* Search for COUNT newlines between START and END.
623 623
624 If COUNT is positive, search forwards; END must be >= START. 624 If COUNT is positive, search forwards; END must be >= START.
625 If COUNT is negative, search backwards for the -COUNTth instance; 625 If COUNT is negative, search backwards for the -COUNTth instance;
@@ -634,14 +634,14 @@ newline_cache_on_off (struct buffer *buf)
634 this is not the same as the usual convention for Emacs motion commands. 634 this is not the same as the usual convention for Emacs motion commands.
635 635
636 If we don't find COUNT instances before reaching END, set *SHORTAGE 636 If we don't find COUNT instances before reaching END, set *SHORTAGE
637 to the number of TARGETs left unfound, and return END. 637 to the number of newlines left unfound, and return END.
638 638
639 If ALLOW_QUIT, set immediate_quit. That's good to do 639 If ALLOW_QUIT, set immediate_quit. That's good to do
640 except when inside redisplay. */ 640 except when inside redisplay. */
641 641
642ptrdiff_t 642ptrdiff_t
643scan_buffer (int target, ptrdiff_t start, ptrdiff_t end, 643find_newline (ptrdiff_t start, ptrdiff_t end,
644 ptrdiff_t count, ptrdiff_t *shortage, bool allow_quit) 644 ptrdiff_t count, ptrdiff_t *shortage, bool allow_quit)
645{ 645{
646 struct region_cache *newline_cache; 646 struct region_cache *newline_cache;
647 ptrdiff_t end_byte = -1; 647 ptrdiff_t end_byte = -1;
@@ -656,7 +656,7 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end,
656 else 656 else
657 { 657 {
658 direction = -1; 658 direction = -1;
659 if (!end) 659 if (!end)
660 end = BEGV, end_byte = BEGV_BYTE; 660 end = BEGV, end_byte = BEGV_BYTE;
661 } 661 }
662 if (end_byte == -1) 662 if (end_byte == -1)
@@ -684,7 +684,7 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end,
684 684
685 /* If we're looking for a newline, consult the newline cache 685 /* If we're looking for a newline, consult the newline cache
686 to see where we can avoid some scanning. */ 686 to see where we can avoid some scanning. */
687 if (target == '\n' && newline_cache) 687 if (newline_cache)
688 { 688 {
689 ptrdiff_t next_change; 689 ptrdiff_t next_change;
690 immediate_quit = 0; 690 immediate_quit = 0;
@@ -723,32 +723,32 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end,
723 723
724 while (cursor < ceiling_addr) 724 while (cursor < ceiling_addr)
725 { 725 {
726 unsigned char *scan_start = cursor;
727
728 /* The dumb loop. */ 726 /* The dumb loop. */
729 while (*cursor != target && ++cursor < ceiling_addr) 727 unsigned char *nl = memchr (cursor, '\n', ceiling_addr - cursor);
730 ;
731 728
732 /* If we're looking for newlines, cache the fact that 729 /* If we're looking for newlines, cache the fact that
733 the region from start to cursor is free of them. */ 730 the region from start to cursor is free of them. */
734 if (target == '\n' && newline_cache) 731 if (newline_cache)
735 know_region_cache (current_buffer, newline_cache, 732 {
736 BYTE_TO_CHAR (start_byte + scan_start - base), 733 unsigned char *low = cursor;
737 BYTE_TO_CHAR (start_byte + cursor - base)); 734 unsigned char *lim = nl ? nl : ceiling_addr;
738 735 know_region_cache (current_buffer, newline_cache,
739 /* Did we find the target character? */ 736 BYTE_TO_CHAR (low - base + start_byte),
740 if (cursor < ceiling_addr) 737 BYTE_TO_CHAR (lim - base + start_byte));
741 { 738 }
742 if (--count == 0) 739
743 { 740 if (! nl)
744 immediate_quit = 0; 741 break;
745 return BYTE_TO_CHAR (start_byte + cursor - base + 1); 742
746 } 743 if (--count == 0)
747 cursor++; 744 {
748 } 745 immediate_quit = 0;
746 return BYTE_TO_CHAR (nl + 1 - base + start_byte);
747 }
748 cursor = nl + 1;
749 } 749 }
750 750
751 start = BYTE_TO_CHAR (start_byte + cursor - base); 751 start = BYTE_TO_CHAR (ceiling_addr - base + start_byte);
752 } 752 }
753 } 753 }
754 else 754 else
@@ -760,7 +760,7 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end,
760 ptrdiff_t tem; 760 ptrdiff_t tem;
761 761
762 /* Consult the newline cache, if appropriate. */ 762 /* Consult the newline cache, if appropriate. */
763 if (target == '\n' && newline_cache) 763 if (newline_cache)
764 { 764 {
765 ptrdiff_t next_change; 765 ptrdiff_t next_change;
766 immediate_quit = 0; 766 immediate_quit = 0;
@@ -794,31 +794,32 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end,
794 794
795 while (cursor >= ceiling_addr) 795 while (cursor >= ceiling_addr)
796 { 796 {
797 unsigned char *scan_start = cursor; 797 unsigned char *nl = memrchr (ceiling_addr, '\n',
798 798 cursor + 1 - ceiling_addr);
799 while (*cursor != target && --cursor >= ceiling_addr)
800 ;
801 799
802 /* If we're looking for newlines, cache the fact that 800 /* If we're looking for newlines, cache the fact that
803 the region from after the cursor to start is free of them. */ 801 the region from after the cursor to start is free of them. */
804 if (target == '\n' && newline_cache) 802 if (newline_cache)
805 know_region_cache (current_buffer, newline_cache, 803 {
806 BYTE_TO_CHAR (start_byte + cursor - base), 804 unsigned char *low = nl ? nl : ceiling_addr - 1;
807 BYTE_TO_CHAR (start_byte + scan_start - base)); 805 unsigned char *lim = cursor;
808 806 know_region_cache (current_buffer, newline_cache,
809 /* Did we find the target character? */ 807 BYTE_TO_CHAR (low - base + start_byte),
810 if (cursor >= ceiling_addr) 808 BYTE_TO_CHAR (lim - base + start_byte));
811 { 809 }
812 if (++count >= 0) 810
813 { 811 if (! nl)
814 immediate_quit = 0; 812 break;
815 return BYTE_TO_CHAR (start_byte + cursor - base); 813
816 } 814 if (++count >= 0)
817 cursor--; 815 {
818 } 816 immediate_quit = 0;
817 return BYTE_TO_CHAR (nl - base + start_byte);
818 }
819 cursor = nl - 1;
819 } 820 }
820 821
821 start = BYTE_TO_CHAR (start_byte + cursor - base); 822 start = BYTE_TO_CHAR (ceiling_addr - 1 - base + start_byte);
822 } 823 }
823 } 824 }
824 825
@@ -828,8 +829,7 @@ scan_buffer (int target, ptrdiff_t start, ptrdiff_t end,
828 return start; 829 return start;
829} 830}
830 831
831/* Search for COUNT instances of a line boundary, which means either a 832/* Search for COUNT instances of a line boundary.
832 newline or (if selective display enabled) a carriage return.
833 Start at START. If COUNT is negative, search backwards. 833 Start at START. If COUNT is negative, search backwards.
834 834
835 We report the resulting position by calling TEMP_SET_PT_BOTH. 835 We report the resulting position by calling TEMP_SET_PT_BOTH.
@@ -860,9 +860,6 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte,
860 860
861 bool old_immediate_quit = immediate_quit; 861 bool old_immediate_quit = immediate_quit;
862 862
863 /* The code that follows is like scan_buffer
864 but checks for either newline or carriage return. */
865
866 if (allow_quit) 863 if (allow_quit)
867 immediate_quit++; 864 immediate_quit++;
868 865
@@ -874,29 +871,25 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte,
874 ceiling = min (limit_byte - 1, ceiling); 871 ceiling = min (limit_byte - 1, ceiling);
875 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; 872 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
876 base = (cursor = BYTE_POS_ADDR (start_byte)); 873 base = (cursor = BYTE_POS_ADDR (start_byte));
877 while (1)
878 {
879 while (*cursor != '\n' && ++cursor != ceiling_addr)
880 ;
881 874
882 if (cursor != ceiling_addr) 875 do
876 {
877 unsigned char *nl = memchr (cursor, '\n', ceiling_addr - cursor);
878 if (! nl)
879 break;
880 if (--count == 0)
883 { 881 {
884 if (--count == 0) 882 immediate_quit = old_immediate_quit;
885 { 883 start_byte += nl - base + 1;
886 immediate_quit = old_immediate_quit; 884 start = BYTE_TO_CHAR (start_byte);
887 start_byte = start_byte + cursor - base + 1; 885 TEMP_SET_PT_BOTH (start, start_byte);
888 start = BYTE_TO_CHAR (start_byte); 886 return 0;
889 TEMP_SET_PT_BOTH (start, start_byte);
890 return 0;
891 }
892 else
893 if (++cursor == ceiling_addr)
894 break;
895 } 887 }
896 else 888 cursor = nl + 1;
897 break;
898 } 889 }
899 start_byte += cursor - base; 890 while (cursor < ceiling_addr);
891
892 start_byte += ceiling_addr - base;
900 } 893 }
901 } 894 }
902 else 895 else
@@ -905,31 +898,28 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte,
905 { 898 {
906 ceiling = BUFFER_FLOOR_OF (start_byte - 1); 899 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
907 ceiling = max (limit_byte, ceiling); 900 ceiling = max (limit_byte, ceiling);
908 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1; 901 ceiling_addr = BYTE_POS_ADDR (ceiling);
909 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); 902 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
910 while (1) 903 while (1)
911 { 904 {
912 while (--cursor != ceiling_addr && *cursor != '\n') 905 unsigned char *nl = memrchr (ceiling_addr, '\n',
913 ; 906 cursor - ceiling_addr);
907 if (! nl)
908 break;
914 909
915 if (cursor != ceiling_addr) 910 if (++count == 0)
916 { 911 {
917 if (++count == 0) 912 immediate_quit = old_immediate_quit;
918 { 913 /* Return the position AFTER the match we found. */
919 immediate_quit = old_immediate_quit; 914 start_byte += nl - base + 1;
920 /* Return the position AFTER the match we found. */ 915 start = BYTE_TO_CHAR (start_byte);
921 start_byte = start_byte + cursor - base + 1; 916 TEMP_SET_PT_BOTH (start, start_byte);
922 start = BYTE_TO_CHAR (start_byte); 917 return 0;
923 TEMP_SET_PT_BOTH (start, start_byte);
924 return 0;
925 }
926 } 918 }
927 else 919
928 break; 920 cursor = nl;
929 } 921 }
930 /* Here we add 1 to compensate for the last decrement 922 start_byte += ceiling_addr - base;
931 of CURSOR, which took it past the valid range. */
932 start_byte += cursor - base + 1;
933 } 923 }
934 } 924 }
935 925
@@ -942,7 +932,7 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte,
942ptrdiff_t 932ptrdiff_t
943find_next_newline_no_quit (ptrdiff_t from, ptrdiff_t cnt) 933find_next_newline_no_quit (ptrdiff_t from, ptrdiff_t cnt)
944{ 934{
945 return scan_buffer ('\n', from, 0, cnt, (ptrdiff_t *) 0, 0); 935 return find_newline (from, 0, cnt, (ptrdiff_t *) 0, 0);
946} 936}
947 937
948/* Like find_next_newline, but returns position before the newline, 938/* Like find_next_newline, but returns position before the newline,
@@ -953,7 +943,7 @@ ptrdiff_t
953find_before_next_newline (ptrdiff_t from, ptrdiff_t to, ptrdiff_t cnt) 943find_before_next_newline (ptrdiff_t from, ptrdiff_t to, ptrdiff_t cnt)
954{ 944{
955 ptrdiff_t shortage; 945 ptrdiff_t shortage;
956 ptrdiff_t pos = scan_buffer ('\n', from, to, cnt, &shortage, 1); 946 ptrdiff_t pos = find_newline (from, to, cnt, &shortage, 1);
957 947
958 if (shortage == 0) 948 if (shortage == 0)
959 pos--; 949 pos--;
diff --git a/src/xdisp.c b/src/xdisp.c
index 3b82de9432d..463f4f9ef05 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1392,21 +1392,9 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1392 Lisp_Object cpos = make_number (charpos); 1392 Lisp_Object cpos = make_number (charpos);
1393 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil); 1393 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1394 Lisp_Object string = string_from_display_spec (spec); 1394 Lisp_Object string = string_from_display_spec (spec);
1395 int newline_in_string = 0; 1395 bool newline_in_string
1396 1396 = (STRINGP (string)
1397 if (STRINGP (string)) 1397 && memchr (SDATA (string), '\n', SBYTES (string)));
1398 {
1399 const char *s = SSDATA (string);
1400 const char *e = s + SBYTES (string);
1401 while (s < e)
1402 {
1403 if (*s++ == '\n')
1404 {
1405 newline_in_string = 1;
1406 break;
1407 }
1408 }
1409 }
1410 /* The tricky code below is needed because there's a 1398 /* The tricky code below is needed because there's a
1411 discrepancy between move_it_to and how we set cursor 1399 discrepancy between move_it_to and how we set cursor
1412 when the display line ends in a newline from a 1400 when the display line ends in a newline from a
@@ -14759,7 +14747,7 @@ compute_window_start_on_continuation_line (struct window *w)
14759 SET_TEXT_POS (start_pos, ZV, ZV_BYTE); 14747 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14760 14748
14761 /* Find the start of the continued line. This should be fast 14749 /* Find the start of the continued line. This should be fast
14762 because scan_buffer is fast (newline cache). */ 14750 because find_newline is fast (newline cache). */
14763 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0); 14751 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14764 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos), 14752 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14765 row, DEFAULT_FACE_ID); 14753 row, DEFAULT_FACE_ID);
@@ -21626,31 +21614,36 @@ display_count_lines (ptrdiff_t start_byte,
21626 ceiling = min (limit_byte - 1, ceiling); 21614 ceiling = min (limit_byte - 1, ceiling);
21627 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1; 21615 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
21628 base = (cursor = BYTE_POS_ADDR (start_byte)); 21616 base = (cursor = BYTE_POS_ADDR (start_byte));
21629 while (1) 21617
21618 do
21630 { 21619 {
21631 if (selective_display) 21620 if (selective_display)
21632 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr) 21621 {
21633 ; 21622 while (*cursor != '\n' && *cursor != 015
21623 && ++cursor != ceiling_addr)
21624 continue;
21625 if (cursor == ceiling_addr)
21626 break;
21627 }
21634 else 21628 else
21635 while (*cursor != '\n' && ++cursor != ceiling_addr) 21629 {
21636 ; 21630 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
21631 if (! cursor)
21632 break;
21633 }
21634
21635 cursor++;
21637 21636
21638 if (cursor != ceiling_addr) 21637 if (--count == 0)
21639 { 21638 {
21640 if (--count == 0) 21639 start_byte += cursor - base;
21641 { 21640 *byte_pos_ptr = start_byte;
21642 start_byte += cursor - base + 1; 21641 return orig_count;
21643 *byte_pos_ptr = start_byte;
21644 return orig_count;
21645 }
21646 else
21647 if (++cursor == ceiling_addr)
21648 break;
21649 } 21642 }
21650 else
21651 break;
21652 } 21643 }
21653 start_byte += cursor - base; 21644 while (cursor < ceiling_addr);
21645
21646 start_byte += ceiling_addr - base;
21654 } 21647 }
21655 } 21648 }
21656 else 21649 else
@@ -21659,35 +21652,35 @@ display_count_lines (ptrdiff_t start_byte,
21659 { 21652 {
21660 ceiling = BUFFER_FLOOR_OF (start_byte - 1); 21653 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
21661 ceiling = max (limit_byte, ceiling); 21654 ceiling = max (limit_byte, ceiling);
21662 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1; 21655 ceiling_addr = BYTE_POS_ADDR (ceiling);
21663 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1); 21656 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
21664 while (1) 21657 while (1)
21665 { 21658 {
21666 if (selective_display) 21659 if (selective_display)
21667 while (--cursor != ceiling_addr 21660 {
21668 && *cursor != '\n' && *cursor != 015) 21661 while (--cursor >= ceiling_addr
21669 ; 21662 && *cursor != '\n' && *cursor != 015)
21663 continue;
21664 if (cursor < ceiling_addr)
21665 break;
21666 }
21670 else 21667 else
21671 while (--cursor != ceiling_addr && *cursor != '\n') 21668 {
21672 ; 21669 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
21670 if (! cursor)
21671 break;
21672 }
21673 21673
21674 if (cursor != ceiling_addr) 21674 if (++count == 0)
21675 { 21675 {
21676 if (++count == 0) 21676 start_byte += cursor - base + 1;
21677 { 21677 *byte_pos_ptr = start_byte;
21678 start_byte += cursor - base + 1; 21678 /* When scanning backwards, we should
21679 *byte_pos_ptr = start_byte; 21679 not count the newline posterior to which we stop. */
21680 /* When scanning backwards, we should 21680 return - orig_count - 1;
21681 not count the newline posterior to which we stop. */
21682 return - orig_count - 1;
21683 }
21684 } 21681 }
21685 else
21686 break;
21687 } 21682 }
21688 /* Here we add 1 to compensate for the last decrement 21683 start_byte += ceiling_addr - base;
21689 of CURSOR, which took it past the valid range. */
21690 start_byte += cursor - base + 1;
21691 } 21684 }
21692 } 21685 }
21693 21686