summaryrefslogtreecommitdiff
path: root/src/intervals.c
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2022-09-25 16:15:16 -0400
committerStefan Monnier <monnier@iro.umontreal.ca>2022-09-25 16:15:16 -0400
commit650c20f1ca4e07591a727e1cfcc74b3363d15985 (patch)
tree85d11f6437cde22f410c25e0e5f71a3131ebd07d /src/intervals.c
parent8869332684c2302b5ba1ead4568bbc7ba1c0183e (diff)
parent4b85ae6a24380fb67a3315eaec9233f17a872473 (diff)
downloademacs-650c20f1ca4e07591a727e1cfcc74b3363d15985.tar.gz
Merge 'master' into noverlay
Diffstat (limited to 'src/intervals.c')
-rw-r--r--src/intervals.c167
1 files changed, 83 insertions, 84 deletions
diff --git a/src/intervals.c b/src/intervals.c
index 3db80ebed4a..78f4f6b6174 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -1,5 +1,5 @@
/* Code for doing intervals.
- Copyright (C) 1993-1995, 1997-1998, 2001-2017 Free Software
+ Copyright (C) 1993-1995, 1997-1998, 2001-2022 Free Software
Foundation, Inc.
This file is part of GNU Emacs.
@@ -117,7 +117,7 @@ create_root_interval (Lisp_Object parent)
/* Make the interval TARGET have exactly the properties of SOURCE. */
void
-copy_properties (register INTERVAL source, register INTERVAL target)
+copy_properties (INTERVAL source, INTERVAL target)
{
if (DEFAULT_INTERVAL_P (source) && DEFAULT_INTERVAL_P (target))
return;
@@ -165,10 +165,11 @@ merge_properties (register INTERVAL source, register INTERVAL target)
}
}
-/* Return true if the two intervals have the same properties. */
+/* Return true if the two intervals have the same properties.
+ If use_equal is true, use Fequal for comparisons instead of EQ. */
-bool
-intervals_equal (INTERVAL i0, INTERVAL i1)
+static bool
+intervals_equal_1 (INTERVAL i0, INTERVAL i1, bool use_equal)
{
Lisp_Object i0_cdr, i0_sym;
Lisp_Object i1_cdr, i1_val;
@@ -197,13 +198,14 @@ intervals_equal (INTERVAL i0, INTERVAL i1)
}
/* i0 has something i1 doesn't. */
- if (EQ (i1_val, Qnil))
+ if (NILP (i1_val))
return false;
/* i0 and i1 both have sym, but it has different values in each. */
if (!CONSP (i1_val)
|| (i1_val = XCDR (i1_val), !CONSP (i1_val))
- || !EQ (XCAR (i1_val), XCAR (i0_cdr)))
+ || use_equal ? NILP (Fequal (XCAR (i1_val), XCAR (i0_cdr)))
+ : !EQ (XCAR (i1_val), XCAR (i0_cdr)))
return false;
i0_cdr = XCDR (i0_cdr);
@@ -217,6 +219,14 @@ intervals_equal (INTERVAL i0, INTERVAL i1)
/* Lengths of the two plists were equal. */
return (NILP (i0_cdr) && NILP (i1_cdr));
}
+
+/* Return true if the two intervals have the same properties. */
+
+bool
+intervals_equal (INTERVAL i0, INTERVAL i1)
+{
+ return intervals_equal_1 (i0, i1, false);
+}
/* Traverse an interval tree TREE, performing FUNCTION on each node.
@@ -298,7 +308,7 @@ rotate_right (INTERVAL A)
set_interval_parent (c, A);
/* A's total length is decreased by the length of B and its left child. */
- A->total_length -= B->total_length - TOTAL_LENGTH (c);
+ A->total_length -= TOTAL_LENGTH (B) - TOTAL_LENGTH0 (c);
eassert (TOTAL_LENGTH (A) > 0);
eassert (LENGTH (A) > 0);
@@ -349,7 +359,7 @@ rotate_left (INTERVAL A)
set_interval_parent (c, A);
/* A's total length is decreased by the length of B and its right child. */
- A->total_length -= B->total_length - TOTAL_LENGTH (c);
+ A->total_length -= TOTAL_LENGTH (B) - TOTAL_LENGTH0 (c);
eassert (TOTAL_LENGTH (A) > 0);
eassert (LENGTH (A) > 0);
@@ -713,13 +723,23 @@ previous_interval (register INTERVAL interval)
return NULL;
}
-/* Find the interval containing POS given some non-NULL INTERVAL
- in the same tree. Note that we need to update interval->position
- if we go down the tree.
- To speed up the process, we assume that the ->position of
- I and all its parents is already uptodate. */
+/* Set the ->position field of I's parent, based on I->position. */
+#define SET_PARENT_POSITION(i) \
+ if (AM_LEFT_CHILD (i)) \
+ INTERVAL_PARENT (i)->position = \
+ i->position + TOTAL_LENGTH (i) - LEFT_TOTAL_LENGTH (i); \
+ else \
+ INTERVAL_PARENT (i)->position = \
+ i->position - LEFT_TOTAL_LENGTH (i) \
+ - LENGTH (INTERVAL_PARENT (i))
+
+/* Find the interval containing POS, given some interval I in
+ the same tree. Note that we update interval->position in each
+ interval we traverse, assuming it is already correctly set for the
+ argument I. We don't assume that any other interval already has a
+ correctly set ->position. */
INTERVAL
-update_interval (register INTERVAL i, ptrdiff_t pos)
+update_interval (INTERVAL i, ptrdiff_t pos)
{
if (!i)
return NULL;
@@ -729,7 +749,7 @@ update_interval (register INTERVAL i, ptrdiff_t pos)
if (pos < i->position)
{
/* Move left. */
- if (pos >= i->position - TOTAL_LENGTH (i->left))
+ if (pos >= i->position - LEFT_TOTAL_LENGTH (i))
{
i->left->position = i->position - TOTAL_LENGTH (i->left)
+ LEFT_TOTAL_LENGTH (i->left);
@@ -738,13 +758,16 @@ update_interval (register INTERVAL i, ptrdiff_t pos)
else if (NULL_PARENT (i))
error ("Point before start of properties");
else
- i = INTERVAL_PARENT (i);
+ {
+ SET_PARENT_POSITION (i);
+ i = INTERVAL_PARENT (i);
+ }
continue;
}
else if (pos >= INTERVAL_LAST_POS (i))
{
/* Move right. */
- if (pos < INTERVAL_LAST_POS (i) + TOTAL_LENGTH (i->right))
+ if (pos < INTERVAL_LAST_POS (i) + RIGHT_TOTAL_LENGTH (i))
{
i->right->position = INTERVAL_LAST_POS (i)
+ LEFT_TOTAL_LENGTH (i->right);
@@ -753,7 +776,10 @@ update_interval (register INTERVAL i, ptrdiff_t pos)
else if (NULL_PARENT (i))
error ("Point %"pD"d after end of properties", pos);
else
- i = INTERVAL_PARENT (i);
+ {
+ SET_PARENT_POSITION (i);
+ i = INTERVAL_PARENT (i);
+ }
continue;
}
else
@@ -1171,7 +1197,7 @@ delete_interval (register INTERVAL i)
register INTERVAL parent;
ptrdiff_t amt = LENGTH (i);
- eassert (amt == 0); /* Only used on zero-length intervals now. */
+ eassert (amt <= 0); /* Only used on zero total-length intervals now. */
if (ROOT_INTERVAL_P (i))
{
@@ -1557,8 +1583,8 @@ graft_intervals_into_buffer (INTERVAL source, ptrdiff_t position,
if (!inherit && tree && length > 0)
{
XSETBUFFER (buf, buffer);
- set_text_properties_1 (make_number (position),
- make_number (position + length),
+ set_text_properties_1 (make_fixnum (position),
+ make_fixnum (position + length),
Qnil, buf,
find_interval (tree, position));
}
@@ -1711,11 +1737,11 @@ lookup_char_property (Lisp_Object plist, Lisp_Object prop, bool textprop)
{
tail = XCDR (tail);
for (; NILP (fallback) && CONSP (tail); tail = XCDR (tail))
- fallback = Fplist_get (plist, XCAR (tail));
+ fallback = plist_get (plist, XCAR (tail));
}
if (textprop && NILP (fallback) && CONSP (Vdefault_text_properties))
- fallback = Fplist_get (Vdefault_text_properties, prop);
+ fallback = plist_get (Vdefault_text_properties, prop);
return fallback;
}
@@ -1793,7 +1819,7 @@ adjust_for_invis_intang (ptrdiff_t pos, ptrdiff_t test_offs, ptrdiff_t adj,
/* POS + ADJ would be beyond the buffer bounds, so do no adjustment. */
return pos;
- test_pos = make_number (pos + test_offs);
+ test_pos = make_fixnum (pos + test_offs);
invis_propval
= get_char_property_and_overlay (test_pos, Qinvisible, Qnil,
@@ -1806,7 +1832,7 @@ adjust_for_invis_intang (ptrdiff_t pos, ptrdiff_t test_offs, ptrdiff_t adj,
such that an insertion at POS would inherit it. */
&& (NILP (invis_overlay)
/* Invisible property is from a text-property. */
- ? (text_property_stickiness (Qinvisible, make_number (pos), Qnil)
+ ? (text_property_stickiness (Qinvisible, make_fixnum (pos), Qnil)
== (test_offs == 0 ? 1 : -1))
/* Invisible property is from an overlay. */
: (test_offs == 0
@@ -1926,8 +1952,8 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
if (! NILP (intangible_propval))
{
- while (XINT (pos) > BEGV
- && EQ (Fget_char_property (make_number (XINT (pos) - 1),
+ while (XFIXNUM (pos) > BEGV
+ && EQ (Fget_char_property (make_fixnum (XFIXNUM (pos) - 1),
Qintangible, Qnil),
intangible_propval))
pos = Fprevious_char_property_change (pos, Qnil);
@@ -1937,7 +1963,7 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
property is `front-sticky', perturb it to be one character
earlier -- this ensures that point can never move to the
beginning of an invisible/intangible/front-sticky region. */
- charpos = adjust_for_invis_intang (XINT (pos), 0, -1, 0);
+ charpos = adjust_for_invis_intang (XFIXNUM (pos), 0, -1, 0);
}
}
else
@@ -1954,12 +1980,12 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
/* If preceding char is intangible,
skip forward over all chars with matching intangible property. */
- intangible_propval = Fget_char_property (make_number (charpos - 1),
+ intangible_propval = Fget_char_property (make_fixnum (charpos - 1),
Qintangible, Qnil);
if (! NILP (intangible_propval))
{
- while (XINT (pos) < ZV
+ while (XFIXNUM (pos) < ZV
&& EQ (Fget_char_property (pos, Qintangible, Qnil),
intangible_propval))
pos = Fnext_char_property_change (pos, Qnil);
@@ -1969,7 +1995,7 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
property is `rear-sticky', perturb it to be one character
later -- this ensures that point can never move to the
end of an invisible/intangible/rear-sticky region. */
- charpos = adjust_for_invis_intang (XINT (pos), -1, 1, 0);
+ charpos = adjust_for_invis_intang (XFIXNUM (pos), -1, 1, 0);
}
}
@@ -2026,18 +2052,18 @@ set_point_both (ptrdiff_t charpos, ptrdiff_t bytepos)
enter_after = Qnil;
if (! EQ (leave_before, enter_before) && !NILP (leave_before))
- call2 (leave_before, make_number (old_position),
- make_number (charpos));
+ call2 (leave_before, make_fixnum (old_position),
+ make_fixnum (charpos));
if (! EQ (leave_after, enter_after) && !NILP (leave_after))
- call2 (leave_after, make_number (old_position),
- make_number (charpos));
+ call2 (leave_after, make_fixnum (old_position),
+ make_fixnum (charpos));
if (! EQ (enter_before, leave_before) && !NILP (enter_before))
- call2 (enter_before, make_number (old_position),
- make_number (charpos));
+ call2 (enter_before, make_fixnum (old_position),
+ make_fixnum (charpos));
if (! EQ (enter_after, leave_after) && !NILP (enter_after))
- call2 (enter_after, make_number (old_position),
- make_number (charpos));
+ call2 (enter_after, make_fixnum (old_position),
+ make_fixnum (charpos));
}
}
@@ -2055,7 +2081,7 @@ move_if_not_intangible (ptrdiff_t position)
if (! NILP (Vinhibit_point_motion_hooks))
/* If intangible is inhibited, always move point to POSITION. */
;
- else if (PT < position && XINT (pos) < ZV)
+ else if (PT < position && XFIXNUM (pos) < ZV)
{
/* We want to move forward, so check the text before POSITION. */
@@ -2065,23 +2091,23 @@ move_if_not_intangible (ptrdiff_t position)
/* If following char is intangible,
skip back over all chars with matching intangible property. */
if (! NILP (intangible_propval))
- while (XINT (pos) > BEGV
- && EQ (Fget_char_property (make_number (XINT (pos) - 1),
+ while (XFIXNUM (pos) > BEGV
+ && EQ (Fget_char_property (make_fixnum (XFIXNUM (pos) - 1),
Qintangible, Qnil),
intangible_propval))
pos = Fprevious_char_property_change (pos, Qnil);
}
- else if (XINT (pos) > BEGV)
+ else if (XFIXNUM (pos) > BEGV)
{
/* We want to move backward, so check the text after POSITION. */
- intangible_propval = Fget_char_property (make_number (XINT (pos) - 1),
+ intangible_propval = Fget_char_property (make_fixnum (XFIXNUM (pos) - 1),
Qintangible, Qnil);
/* If following char is intangible,
skip forward over all chars with matching intangible property. */
if (! NILP (intangible_propval))
- while (XINT (pos) < ZV
+ while (XFIXNUM (pos) < ZV
&& EQ (Fget_char_property (pos, Qintangible, Qnil),
intangible_propval))
pos = Fnext_char_property_change (pos, Qnil);
@@ -2096,7 +2122,7 @@ move_if_not_intangible (ptrdiff_t position)
try moving to POSITION (which means we actually move farther
if POSITION is inside of intangible text). */
- if (XINT (pos) != PT)
+ if (XFIXNUM (pos) != PT)
SET_PT (position);
}
@@ -2145,15 +2171,15 @@ get_property_and_range (ptrdiff_t pos, Lisp_Object prop, Lisp_Object *val,
/* Return the proper local keymap TYPE for position POSITION in
BUFFER; TYPE should be one of `keymap' or `local-map'. Use the map
- specified by the PROP property, if any. Otherwise, if TYPE is
- `local-map' use BUFFER's local map. */
+ specified by the TYPE property, if any. Otherwise, if TYPE is
+ `local-map', use BUFFER's local map. */
Lisp_Object
get_local_map (ptrdiff_t position, struct buffer *buffer, Lisp_Object type)
{
Lisp_Object prop, lispy_position, lispy_buffer;
ptrdiff_t old_begv, old_zv, old_begv_byte, old_zv_byte;
- ptrdiff_t count = SPECPDL_INDEX ();
+ specpdl_ref count = SPECPDL_INDEX ();
position = clip_to_bounds (BUF_BEGV (buffer), position, BUF_ZV (buffer));
@@ -2274,7 +2300,7 @@ compare_string_intervals (Lisp_Object s1, Lisp_Object s2)
/* If we ever find a mismatch between the strings,
they differ. */
- if (! intervals_equal (i1, i2))
+ if (! intervals_equal_1 (i1, i2, true))
return 0;
/* Advance POS till the end of the shorter interval,
@@ -2318,23 +2344,10 @@ set_intervals_multibyte_1 (INTERVAL i, bool multi_flag,
if (multi_flag)
{
- ptrdiff_t temp;
- left_end_byte = start_byte + LEFT_TOTAL_LENGTH (i);
+ left_end_byte
+ = advance_to_char_boundary (start_byte + LEFT_TOTAL_LENGTH (i));
left_end = BYTE_TO_CHAR (left_end_byte);
-
- temp = CHAR_TO_BYTE (left_end);
-
- /* If LEFT_END_BYTE is in the middle of a character,
- adjust it and LEFT_END to a char boundary. */
- if (left_end_byte > temp)
- {
- left_end_byte = temp;
- }
- if (left_end_byte < temp)
- {
- left_end--;
- left_end_byte = CHAR_TO_BYTE (left_end);
- }
+ eassert (CHAR_TO_BYTE (left_end) == left_end_byte);
}
else
{
@@ -2351,24 +2364,10 @@ set_intervals_multibyte_1 (INTERVAL i, bool multi_flag,
if (multi_flag)
{
- ptrdiff_t temp;
-
- right_start_byte = end_byte - RIGHT_TOTAL_LENGTH (i);
+ right_start_byte
+ = advance_to_char_boundary (end_byte - RIGHT_TOTAL_LENGTH (i));
right_start = BYTE_TO_CHAR (right_start_byte);
-
- /* If RIGHT_START_BYTE is in the middle of a character,
- adjust it and RIGHT_START to a char boundary. */
- temp = CHAR_TO_BYTE (right_start);
-
- if (right_start_byte < temp)
- {
- right_start_byte = temp;
- }
- if (right_start_byte > temp)
- {
- right_start++;
- right_start_byte = CHAR_TO_BYTE (right_start);
- }
+ eassert (CHAR_TO_BYTE (right_start) == right_start_byte);
}
else
{