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)
This commit is contained in:
Eli Zaretskii 2023-04-22 19:27:16 +03:00
parent 4e0f4292aa
commit 9a0f10b5f8

View file

@ -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. */) from the absolute start of the buffer, disregarding the narrowing. */)
(register Lisp_Object position, Lisp_Object absolute) (register Lisp_Object position, Lisp_Object absolute)
{ {
ptrdiff_t pos, start = BEGV_BYTE; ptrdiff_t pos_byte, start_byte = BEGV_BYTE;
if (MARKERP (position)) 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)) else if (NILP (position))
pos = PT; pos_byte = PT_BYTE;
else else
{ {
CHECK_FIXNUM (position); 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)) 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, /* Check that POSITION is valid. */
if we're reporting absolute positions, in the buffer. */ if (pos_byte < BEG_BYTE || pos_byte > Z_BYTE)
if (NILP (absolute) && (pos < BEGV || pos > ZV)) args_out_of_range_3 (make_int (BYTE_TO_CHAR (pos_byte)),
args_out_of_range_3 (make_int (pos), make_int (BEGV), make_int (ZV)); make_int (BEG), make_int (Z));
else if (!NILP (absolute) && (pos < 1 || pos > Z))
args_out_of_range_3 (make_int (pos), make_int (1), make_int (Z));
return make_int (count_lines (start, CHAR_TO_BYTE (pos)) + 1); return make_int (count_lines (start_byte, pos_byte) + 1);
} }