aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2019-01-27 15:49:53 -0800
committerPaul Eggert2019-01-27 15:52:06 -0800
commitcc1c46e4122a08657a7c75495115d1c60efb1b31 (patch)
tree263f419e5f70ab9dceaa15093339623bf3513e64 /src
parent6c2ee11d8f27cc39f852b69a49056ba76ac6bee9 (diff)
downloademacs-cc1c46e4122a08657a7c75495115d1c60efb1b31.tar.gz
emacs-cc1c46e4122a08657a7c75495115d1c60efb1b31.zip
forward-line now works with bignums
* src/cmds.c (Fforward_line): Support bignum arg. (scan_newline): Return void since no caller was using the return value. * src/search.c (find_newline, scan_newline_from_point) (find_newline1): Return the number of newlines counted, not the count shortage, so that the return value always fits in ptrdiff_t even if the original count was a bignum. All callers changed. * test/src/cmds-tests.el (forward-line-with-bignum): New test.
Diffstat (limited to 'src')
-rw-r--r--src/cmds.c32
-rw-r--r--src/editfns.c6
-rw-r--r--src/lisp.h4
-rw-r--r--src/search.c92
4 files changed, 67 insertions, 67 deletions
diff --git a/src/cmds.c b/src/cmds.c
index 1f81b9986a7..239e3be5c07 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -121,28 +121,36 @@ it as a line moved across, even though there is no next line to
121go to its beginning. */) 121go to its beginning. */)
122 (Lisp_Object n) 122 (Lisp_Object n)
123{ 123{
124 ptrdiff_t opoint = PT, pos, pos_byte, shortage, count; 124 ptrdiff_t opoint = PT, pos, pos_byte, count;
125 bool excessive = false;
125 126
126 if (NILP (n)) 127 if (NILP (n))
127 count = 1; 128 count = 1;
128 else 129 else
129 { 130 {
130 CHECK_FIXNUM (n); 131 CHECK_INTEGER (n);
131 count = XFIXNUM (n); 132 if (FIXNUMP (n)
133 && -BUF_BYTES_MAX <= XFIXNUM (n) && XFIXNUM (n) <= BUF_BYTES_MAX)
134 count = XFIXNUM (n);
135 else
136 {
137 count = !NILP (Fnatnump (n)) ? BUF_BYTES_MAX : -BUF_BYTES_MAX;
138 excessive = true;
139 }
132 } 140 }
133 141
134 shortage = scan_newline_from_point (count, &pos, &pos_byte); 142 ptrdiff_t counted = scan_newline_from_point (count, &pos, &pos_byte);
135 143
136 SET_PT_BOTH (pos, pos_byte); 144 SET_PT_BOTH (pos, pos_byte);
137 145
138 if (shortage > 0 146 ptrdiff_t shortage = count - (count <= 0) - counted;
139 && (count <= 0 147 if (shortage != 0)
140 || (ZV > BEGV 148 shortage -= (count <= 0 ? -1
141 && PT != opoint 149 : (BEGV < ZV && PT != opoint
142 && (FETCH_BYTE (PT_BYTE - 1) != '\n')))) 150 && FETCH_BYTE (PT_BYTE - 1) != '\n'));
143 shortage--; 151 return (excessive
144 152 ? CALLN (Fplus, make_fixnum (shortage - count), n)
145 return make_fixnum (count <= 0 ? - shortage : shortage); 153 : make_fixnum (shortage));
146} 154}
147 155
148DEFUN ("beginning-of-line", Fbeginning_of_line, Sbeginning_of_line, 0, 1, "^p", 156DEFUN ("beginning-of-line", Fbeginning_of_line, Sbeginning_of_line, 0, 1, "^p",
diff --git a/src/editfns.c b/src/editfns.c
index 01376b06373..3edfd1dc201 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -668,7 +668,7 @@ Field boundaries are not noticed if `inhibit-field-text-motion' is non-nil. */)
668 /* It is possible that NEW_POS is not within the same field as 668 /* It is possible that NEW_POS is not within the same field as
669 OLD_POS; try to move NEW_POS so that it is. */ 669 OLD_POS; try to move NEW_POS so that it is. */
670 { 670 {
671 ptrdiff_t shortage; 671 ptrdiff_t counted;
672 Lisp_Object field_bound; 672 Lisp_Object field_bound;
673 673
674 if (fwd) 674 if (fwd)
@@ -691,8 +691,8 @@ Field boundaries are not noticed if `inhibit-field-text-motion' is non-nil. */)
691 there's an intervening newline or not. */ 691 there's an intervening newline or not. */
692 || (find_newline (XFIXNAT (new_pos), -1, 692 || (find_newline (XFIXNAT (new_pos), -1,
693 XFIXNAT (field_bound), -1, 693 XFIXNAT (field_bound), -1,
694 fwd ? -1 : 1, &shortage, NULL, 1), 694 fwd ? -1 : 1, &counted, NULL, 1),
695 shortage != 0))) 695 counted == 0)))
696 /* Constrain NEW_POS to FIELD_BOUND. */ 696 /* Constrain NEW_POS to FIELD_BOUND. */
697 new_pos = field_bound; 697 new_pos = field_bound;
698 698
diff --git a/src/lisp.h b/src/lisp.h
index 78bc423bed7..c5631e28453 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4271,8 +4271,8 @@ extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t,
4271 ptrdiff_t, ptrdiff_t, Lisp_Object); 4271 ptrdiff_t, ptrdiff_t, Lisp_Object);
4272extern ptrdiff_t find_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, 4272extern ptrdiff_t find_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t,
4273 ptrdiff_t, ptrdiff_t *, ptrdiff_t *, bool); 4273 ptrdiff_t, ptrdiff_t *, ptrdiff_t *, bool);
4274extern ptrdiff_t scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, 4274extern void scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t,
4275 ptrdiff_t, bool); 4275 ptrdiff_t, bool);
4276extern ptrdiff_t scan_newline_from_point (ptrdiff_t, ptrdiff_t *, ptrdiff_t *); 4276extern ptrdiff_t scan_newline_from_point (ptrdiff_t, ptrdiff_t *, ptrdiff_t *);
4277extern ptrdiff_t find_newline_no_quit (ptrdiff_t, ptrdiff_t, 4277extern ptrdiff_t find_newline_no_quit (ptrdiff_t, ptrdiff_t,
4278 ptrdiff_t, ptrdiff_t *); 4278 ptrdiff_t, ptrdiff_t *);
diff --git a/src/search.c b/src/search.c
index 059f8fc4d2e..17bc8d0c948 100644
--- a/src/search.c
+++ b/src/search.c
@@ -647,14 +647,16 @@ newline_cache_on_off (struct buffer *buf)
647 If COUNT is zero, do anything you please; run rogue, for all I care. 647 If COUNT is zero, do anything you please; run rogue, for all I care.
648 648
649 If END is zero, use BEGV or ZV instead, as appropriate for the 649 If END is zero, use BEGV or ZV instead, as appropriate for the
650 direction indicated by COUNT. 650 direction indicated by COUNT. If START_BYTE is -1 it is unknown,
651 and similarly for END_BYTE.
651 652
652 If we find COUNT instances, set *SHORTAGE to zero, and return the 653 If we find COUNT instances, set *COUNTED to COUNT, and return the
653 position past the COUNTth match. Note that for reverse motion 654 position past the COUNTth match. Note that for reverse motion
654 this is not the same as the usual convention for Emacs motion commands. 655 this is not the same as the usual convention for Emacs motion commands.
655 656
656 If we don't find COUNT instances before reaching END, set *SHORTAGE 657 If we don't find COUNT instances before reaching END, set *COUNTED
657 to the number of newlines left unfound, and return END. 658 to the number of newlines left found (negated if COUNT is negative),
659 and return END.
658 660
659 If BYTEPOS is not NULL, set *BYTEPOS to the byte position corresponding 661 If BYTEPOS is not NULL, set *BYTEPOS to the byte position corresponding
660 to the returned character position. 662 to the returned character position.
@@ -664,23 +666,17 @@ newline_cache_on_off (struct buffer *buf)
664 666
665ptrdiff_t 667ptrdiff_t
666find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, 668find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end,
667 ptrdiff_t end_byte, ptrdiff_t count, ptrdiff_t *shortage, 669 ptrdiff_t end_byte, ptrdiff_t count, ptrdiff_t *counted,
668 ptrdiff_t *bytepos, bool allow_quit) 670 ptrdiff_t *bytepos, bool allow_quit)
669{ 671{
670 struct region_cache *newline_cache; 672 struct region_cache *newline_cache;
671 int direction;
672 struct buffer *cache_buffer; 673 struct buffer *cache_buffer;
673 674
674 if (count > 0) 675 if (!end)
675 { 676 {
676 direction = 1; 677 if (count > 0)
677 if (!end)
678 end = ZV, end_byte = ZV_BYTE; 678 end = ZV, end_byte = ZV_BYTE;
679 } 679 else
680 else
681 {
682 direction = -1;
683 if (!end)
684 end = BEGV, end_byte = BEGV_BYTE; 680 end = BEGV, end_byte = BEGV_BYTE;
685 } 681 }
686 if (end_byte == -1) 682 if (end_byte == -1)
@@ -692,8 +688,8 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end,
692 else 688 else
693 cache_buffer = current_buffer; 689 cache_buffer = current_buffer;
694 690
695 if (shortage != 0) 691 if (counted)
696 *shortage = 0; 692 *counted = count;
697 693
698 if (count > 0) 694 if (count > 0)
699 while (start != end) 695 while (start != end)
@@ -936,8 +932,8 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end,
936 } 932 }
937 } 933 }
938 934
939 if (shortage) 935 if (counted)
940 *shortage = count * direction; 936 *counted -= count;
941 if (bytepos) 937 if (bytepos)
942 { 938 {
943 *bytepos = start_byte == -1 ? CHAR_TO_BYTE (start) : start_byte; 939 *bytepos = start_byte == -1 ? CHAR_TO_BYTE (start) : start_byte;
@@ -952,30 +948,28 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end,
952 We report the resulting position by calling TEMP_SET_PT_BOTH. 948 We report the resulting position by calling TEMP_SET_PT_BOTH.
953 949
954 If we find COUNT instances. we position after (always after, 950 If we find COUNT instances. we position after (always after,
955 even if scanning backwards) the COUNTth match, and return 0. 951 even if scanning backwards) the COUNTth match.
956 952
957 If we don't find COUNT instances before reaching the end of the 953 If we don't find COUNT instances before reaching the end of the
958 buffer (or the beginning, if scanning backwards), we return 954 buffer (or the beginning, if scanning backwards), we position at
959 the number of line boundaries left unfound, and position at
960 the limit we bumped up against. 955 the limit we bumped up against.
961 956
962 If ALLOW_QUIT, check for quitting. That's good to do 957 If ALLOW_QUIT, check for quitting. That's good to do
963 except in special cases. */ 958 except in special cases. */
964 959
965ptrdiff_t 960void
966scan_newline (ptrdiff_t start, ptrdiff_t start_byte, 961scan_newline (ptrdiff_t start, ptrdiff_t start_byte,
967 ptrdiff_t limit, ptrdiff_t limit_byte, 962 ptrdiff_t limit, ptrdiff_t limit_byte,
968 ptrdiff_t count, bool allow_quit) 963 ptrdiff_t count, bool allow_quit)
969{ 964{
970 ptrdiff_t charpos, bytepos, shortage; 965 ptrdiff_t charpos, bytepos, counted;
971 966
972 charpos = find_newline (start, start_byte, limit, limit_byte, 967 charpos = find_newline (start, start_byte, limit, limit_byte,
973 count, &shortage, &bytepos, allow_quit); 968 count, &counted, &bytepos, allow_quit);
974 if (shortage) 969 if (counted != count)
975 TEMP_SET_PT_BOTH (limit, limit_byte); 970 TEMP_SET_PT_BOTH (limit, limit_byte);
976 else 971 else
977 TEMP_SET_PT_BOTH (charpos, bytepos); 972 TEMP_SET_PT_BOTH (charpos, bytepos);
978 return shortage;
979} 973}
980 974
981/* Like above, but always scan from point and report the 975/* Like above, but always scan from point and report the
@@ -985,19 +979,19 @@ ptrdiff_t
985scan_newline_from_point (ptrdiff_t count, ptrdiff_t *charpos, 979scan_newline_from_point (ptrdiff_t count, ptrdiff_t *charpos,
986 ptrdiff_t *bytepos) 980 ptrdiff_t *bytepos)
987{ 981{
988 ptrdiff_t shortage; 982 ptrdiff_t counted;
989 983
990 if (count <= 0) 984 if (count <= 0)
991 *charpos = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, count - 1, 985 *charpos = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, count - 1,
992 &shortage, bytepos, 1); 986 &counted, bytepos, 1);
993 else 987 else
994 *charpos = find_newline (PT, PT_BYTE, ZV, ZV_BYTE, count, 988 *charpos = find_newline (PT, PT_BYTE, ZV, ZV_BYTE, count,
995 &shortage, bytepos, 1); 989 &counted, bytepos, 1);
996 return shortage; 990 return counted;
997} 991}
998 992
999/* Like find_newline, but doesn't allow QUITting and doesn't return 993/* Like find_newline, but doesn't allow QUITting and doesn't return
1000 SHORTAGE. */ 994 COUNTED. */
1001ptrdiff_t 995ptrdiff_t
1002find_newline_no_quit (ptrdiff_t from, ptrdiff_t frombyte, 996find_newline_no_quit (ptrdiff_t from, ptrdiff_t frombyte,
1003 ptrdiff_t cnt, ptrdiff_t *bytepos) 997 ptrdiff_t cnt, ptrdiff_t *bytepos)
@@ -1013,10 +1007,10 @@ ptrdiff_t
1013find_before_next_newline (ptrdiff_t from, ptrdiff_t to, 1007find_before_next_newline (ptrdiff_t from, ptrdiff_t to,
1014 ptrdiff_t cnt, ptrdiff_t *bytepos) 1008 ptrdiff_t cnt, ptrdiff_t *bytepos)
1015{ 1009{
1016 ptrdiff_t shortage; 1010 ptrdiff_t counted;
1017 ptrdiff_t pos = find_newline (from, -1, to, -1, cnt, &shortage, bytepos, 1); 1011 ptrdiff_t pos = find_newline (from, -1, to, -1, cnt, &counted, bytepos, 1);
1018 1012
1019 if (shortage == 0) 1013 if (counted == cnt)
1020 { 1014 {
1021 if (bytepos) 1015 if (bytepos)
1022 DEC_BOTH (pos, *bytepos); 1016 DEC_BOTH (pos, *bytepos);
@@ -3210,7 +3204,7 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
3210/* Like find_newline, but doesn't use the cache, and only searches forward. */ 3204/* Like find_newline, but doesn't use the cache, and only searches forward. */
3211static ptrdiff_t 3205static ptrdiff_t
3212find_newline1 (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, 3206find_newline1 (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end,
3213 ptrdiff_t end_byte, ptrdiff_t count, ptrdiff_t *shortage, 3207 ptrdiff_t end_byte, ptrdiff_t count, ptrdiff_t *counted,
3214 ptrdiff_t *bytepos, bool allow_quit) 3208 ptrdiff_t *bytepos, bool allow_quit)
3215{ 3209{
3216 if (count > 0) 3210 if (count > 0)
@@ -3226,8 +3220,8 @@ find_newline1 (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end,
3226 if (end_byte == -1) 3220 if (end_byte == -1)
3227 end_byte = CHAR_TO_BYTE (end); 3221 end_byte = CHAR_TO_BYTE (end);
3228 3222
3229 if (shortage != 0) 3223 if (counted)
3230 *shortage = 0; 3224 *counted = count;
3231 3225
3232 if (count > 0) 3226 if (count > 0)
3233 while (start != end) 3227 while (start != end)
@@ -3284,8 +3278,8 @@ find_newline1 (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end,
3284 } 3278 }
3285 } 3279 }
3286 3280
3287 if (shortage) 3281 if (counted)
3288 *shortage = count; 3282 *counted -= count;
3289 if (bytepos) 3283 if (bytepos)
3290 { 3284 {
3291 *bytepos = start_byte == -1 ? CHAR_TO_BYTE (start) : start_byte; 3285 *bytepos = start_byte == -1 ? CHAR_TO_BYTE (start) : start_byte;
@@ -3306,7 +3300,7 @@ the buffer. If the buffer doesn't have a cache, the value is nil. */)
3306 (Lisp_Object buffer) 3300 (Lisp_Object buffer)
3307{ 3301{
3308 struct buffer *buf, *old = NULL; 3302 struct buffer *buf, *old = NULL;
3309 ptrdiff_t shortage, nl_count_cache, nl_count_buf; 3303 ptrdiff_t nl_count_cache, nl_count_buf;
3310 Lisp_Object cache_newlines, buf_newlines, val; 3304 Lisp_Object cache_newlines, buf_newlines, val;
3311 ptrdiff_t from, found, i; 3305 ptrdiff_t from, found, i;
3312 3306
@@ -3332,8 +3326,7 @@ the buffer. If the buffer doesn't have a cache, the value is nil. */)
3332 3326
3333 /* How many newlines are there according to the cache? */ 3327 /* How many newlines are there according to the cache? */
3334 find_newline (BEGV, BEGV_BYTE, ZV, ZV_BYTE, 3328 find_newline (BEGV, BEGV_BYTE, ZV, ZV_BYTE,
3335 TYPE_MAXIMUM (ptrdiff_t), &shortage, NULL, true); 3329 TYPE_MAXIMUM (ptrdiff_t), &nl_count_cache, NULL, true);
3336 nl_count_cache = TYPE_MAXIMUM (ptrdiff_t) - shortage;
3337 3330
3338 /* Create vector and populate it. */ 3331 /* Create vector and populate it. */
3339 cache_newlines = make_uninit_vector (nl_count_cache); 3332 cache_newlines = make_uninit_vector (nl_count_cache);
@@ -3342,11 +3335,11 @@ the buffer. If the buffer doesn't have a cache, the value is nil. */)
3342 { 3335 {
3343 for (from = BEGV, found = from, i = 0; from < ZV; from = found, i++) 3336 for (from = BEGV, found = from, i = 0; from < ZV; from = found, i++)
3344 { 3337 {
3345 ptrdiff_t from_byte = CHAR_TO_BYTE (from); 3338 ptrdiff_t from_byte = CHAR_TO_BYTE (from), counted;
3346 3339
3347 found = find_newline (from, from_byte, 0, -1, 1, &shortage, 3340 found = find_newline (from, from_byte, 0, -1, 1, &counted,
3348 NULL, true); 3341 NULL, true);
3349 if (shortage != 0 || i >= nl_count_cache) 3342 if (counted == 0 || i >= nl_count_cache)
3350 break; 3343 break;
3351 ASET (cache_newlines, i, make_fixnum (found - 1)); 3344 ASET (cache_newlines, i, make_fixnum (found - 1));
3352 } 3345 }
@@ -3357,18 +3350,17 @@ the buffer. If the buffer doesn't have a cache, the value is nil. */)
3357 3350
3358 /* Now do the same, but without using the cache. */ 3351 /* Now do the same, but without using the cache. */
3359 find_newline1 (BEGV, BEGV_BYTE, ZV, ZV_BYTE, 3352 find_newline1 (BEGV, BEGV_BYTE, ZV, ZV_BYTE,
3360 TYPE_MAXIMUM (ptrdiff_t), &shortage, NULL, true); 3353 TYPE_MAXIMUM (ptrdiff_t), &nl_count_buf, NULL, true);
3361 nl_count_buf = TYPE_MAXIMUM (ptrdiff_t) - shortage;
3362 buf_newlines = make_uninit_vector (nl_count_buf); 3354 buf_newlines = make_uninit_vector (nl_count_buf);
3363 if (nl_count_buf) 3355 if (nl_count_buf)
3364 { 3356 {
3365 for (from = BEGV, found = from, i = 0; from < ZV; from = found, i++) 3357 for (from = BEGV, found = from, i = 0; from < ZV; from = found, i++)
3366 { 3358 {
3367 ptrdiff_t from_byte = CHAR_TO_BYTE (from); 3359 ptrdiff_t from_byte = CHAR_TO_BYTE (from), counted;
3368 3360
3369 found = find_newline1 (from, from_byte, 0, -1, 1, &shortage, 3361 found = find_newline1 (from, from_byte, 0, -1, 1, &counted,
3370 NULL, true); 3362 NULL, true);
3371 if (shortage != 0 || i >= nl_count_buf) 3363 if (counted == 0 || i >= nl_count_buf)
3372 break; 3364 break;
3373 ASET (buf_newlines, i, make_fixnum (found - 1)); 3365 ASET (buf_newlines, i, make_fixnum (found - 1));
3374 } 3366 }