summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2023-04-22 19:27:16 +0300
committerEli Zaretskii <eliz@gnu.org>2023-04-22 19:27:16 +0300
commit9a0f10b5f88667261bafc65ccdd63bdd9ef80147 (patch)
treeed99dda5df927febb4ddf1a626eb50bb7af7526d
parent4e0f4292aaf1a9bf26ba2ee2983955cefc50beea (diff)
downloademacs-9a0f10b5f88667261bafc65ccdd63bdd9ef80147.tar.gz
Fix line-number-at-pos when POSITION is out of narrowing
* src/fns.c (Fline_number_at_pos): Don't signal an error when ABSOLUTE is nil and POSITION is outside of the narrowing, like the original Lisp implementation did. Minor speedup by using the byte position where it is available from the get-go. (Bug#62857)
-rw-r--r--src/fns.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/src/fns.c b/src/fns.c
index ff364c65e26..e8cd6211d6d 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -6116,29 +6116,40 @@ second optional argument ABSOLUTE is non-nil, the value counts the lines
from the absolute start of the buffer, disregarding the narrowing. */)
(register Lisp_Object position, Lisp_Object absolute)
{
- ptrdiff_t pos, start = BEGV_BYTE;
+ ptrdiff_t pos_byte, start_byte = BEGV_BYTE;
if (MARKERP (position))
- pos = marker_position (position);
+ {
+ /* We don't trust the byte position if the marker's buffer is
+ not the current buffer. */
+ if (XMARKER (position)->buffer != current_buffer)
+ pos_byte = CHAR_TO_BYTE (marker_position (position));
+ else
+ pos_byte = marker_byte_position (position);
+ }
else if (NILP (position))
- pos = PT;
+ pos_byte = PT_BYTE;
else
{
CHECK_FIXNUM (position);
- pos = XFIXNUM (position);
+ ptrdiff_t pos = XFIXNUM (position);
+ /* Check that POSITION is valid. */
+ if (pos < BEG || pos > Z)
+ args_out_of_range_3 (position, make_int (BEG), make_int (Z));
+ pos_byte = CHAR_TO_BYTE (pos);
}
if (!NILP (absolute))
- start = BEG_BYTE;
+ start_byte = BEG_BYTE;
+ else if (NILP (absolute))
+ pos_byte = clip_to_bounds (BEGV_BYTE, pos_byte, ZV_BYTE);
- /* Check that POSITION is in the accessible range of the buffer, or,
- if we're reporting absolute positions, in the buffer. */
- if (NILP (absolute) && (pos < BEGV || pos > ZV))
- args_out_of_range_3 (make_int (pos), make_int (BEGV), make_int (ZV));
- else if (!NILP (absolute) && (pos < 1 || pos > Z))
- args_out_of_range_3 (make_int (pos), make_int (1), make_int (Z));
+ /* Check that POSITION is valid. */
+ if (pos_byte < BEG_BYTE || pos_byte > Z_BYTE)
+ args_out_of_range_3 (make_int (BYTE_TO_CHAR (pos_byte)),
+ make_int (BEG), make_int (Z));
- return make_int (count_lines (start, CHAR_TO_BYTE (pos)) + 1);
+ return make_int (count_lines (start_byte, pos_byte) + 1);
}