Commit ad077db0 authored by Karl Heuer's avatar Karl Heuer

Handle the new convention that `position' values

in a string's intervals start from zero.
(validate_interval_range, interval_of, Fnext_property_change)
(property_change_between_p, Fnext_single_property_change)
(Fprevious_property_change, Fprevious_single_property_change):
(Ftext_property_any, Ftext_property_not_all): Implement that.

Undo previous change.
parent 944d4e4b
...@@ -150,11 +150,9 @@ validate_interval_range (object, begin, end, force) ...@@ -150,11 +150,9 @@ validate_interval_range (object, begin, end, force)
if (! (0 <= XINT (*begin) && XINT (*begin) <= XINT (*end) if (! (0 <= XINT (*begin) && XINT (*begin) <= XINT (*end)
&& XINT (*end) <= s->size)) && XINT (*end) <= s->size))
args_out_of_range (*begin, *end); args_out_of_range (*begin, *end);
/* User-level Positions in strings start with 0, XSETFASTINT (*begin, XFASTINT (*begin));
but the interval code always wants positions starting with 1. */
XSETFASTINT (*begin, XFASTINT (*begin) + 1);
if (begin != end) if (begin != end)
XSETFASTINT (*end, XFASTINT (*end) + 1); XSETFASTINT (*end, XFASTINT (*end));
i = s->intervals; i = s->intervals;
if (s->size == 0) if (s->size == 0)
...@@ -479,7 +477,7 @@ erase_properties (i) ...@@ -479,7 +477,7 @@ erase_properties (i)
} }
#endif #endif
/* Returns the interval of the POSITION in OBJECT. /* Returns the interval of POSITION in OBJECT.
POSITION is BEG-based. */ POSITION is BEG-based. */
INTERVAL INTERVAL
...@@ -509,9 +507,8 @@ interval_of (position, object) ...@@ -509,9 +507,8 @@ interval_of (position, object)
{ {
register struct Lisp_String *s = XSTRING (object); register struct Lisp_String *s = XSTRING (object);
/* We expect position to be 1-based. */ beg = 0;
beg = BEG; end = s->size;
end = s->size + BEG;
i = s->intervals; i = s->intervals;
} }
...@@ -716,7 +713,7 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT.") ...@@ -716,7 +713,7 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT.")
? XSTRING (object)->size ? XSTRING (object)->size
: BUF_ZV (XBUFFER (object)))); : BUF_ZV (XBUFFER (object))));
else else
XSETFASTINT (position, next->position - (STRINGP (object))); XSETFASTINT (position, next->position);
return position; return position;
} }
...@@ -726,17 +723,15 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT.") ...@@ -726,17 +723,15 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT.")
next = next_interval (i); next = next_interval (i);
while (! NULL_INTERVAL_P (next) && intervals_equal (i, next) while (! NULL_INTERVAL_P (next) && intervals_equal (i, next)
&& (NILP (limit) && (NILP (limit) || next->position < XFASTINT (limit)))
|| next->position - (STRINGP (object)) < XFASTINT (limit)))
next = next_interval (next); next = next_interval (next);
if (NULL_INTERVAL_P (next)) if (NULL_INTERVAL_P (next))
return limit; return limit;
if (! NILP (limit) if (! NILP (limit) && !(next->position < XFASTINT (limit)))
&& !(next->position - (STRINGP (object)) < XFASTINT (limit)))
return limit; return limit;
XSETFASTINT (position, next->position - (STRINGP (object))); XSETFASTINT (position, next->position);
return position; return position;
} }
...@@ -762,7 +757,7 @@ property_change_between_p (beg, end) ...@@ -762,7 +757,7 @@ property_change_between_p (beg, end)
next = next_interval (next); next = next_interval (next);
if (NULL_INTERVAL_P (next)) if (NULL_INTERVAL_P (next))
return 0; return 0;
if (next->position - (STRINGP (object)) >= end) if (next->position >= end)
return 0; return 0;
} }
...@@ -803,17 +798,15 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT.") ...@@ -803,17 +798,15 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT.")
next = next_interval (i); next = next_interval (i);
while (! NULL_INTERVAL_P (next) while (! NULL_INTERVAL_P (next)
&& EQ (here_val, textget (next->plist, prop)) && EQ (here_val, textget (next->plist, prop))
&& (NILP (limit) || next->position - (STRINGP (object)) < XFASTINT (limit))) && (NILP (limit) || next->position < XFASTINT (limit)))
next = next_interval (next); next = next_interval (next);
if (NULL_INTERVAL_P (next)) if (NULL_INTERVAL_P (next))
return limit; return limit;
if (! NILP (limit) if (! NILP (limit) && !(next->position < XFASTINT (limit)))
&& !(next->position - (STRINGP (object)) < XFASTINT (limit)))
return limit; return limit;
XSETFASTINT (position, next->position - (STRINGP (object))); return make_number (next->position);
return position;
} }
DEFUN ("previous-property-change", Fprevious_property_change, DEFUN ("previous-property-change", Fprevious_property_change,
...@@ -848,19 +841,15 @@ back past position LIMIT; return LIMIT if nothing is found until LIMIT.") ...@@ -848,19 +841,15 @@ back past position LIMIT; return LIMIT if nothing is found until LIMIT.")
previous = previous_interval (i); previous = previous_interval (i);
while (! NULL_INTERVAL_P (previous) && intervals_equal (previous, i) while (! NULL_INTERVAL_P (previous) && intervals_equal (previous, i)
&& (NILP (limit) && (NILP (limit)
|| (previous->position + LENGTH (previous) - (STRINGP (object)) || (previous->position + LENGTH (previous) > XFASTINT (limit))))
> XFASTINT (limit))))
previous = previous_interval (previous); previous = previous_interval (previous);
if (NULL_INTERVAL_P (previous)) if (NULL_INTERVAL_P (previous))
return limit; return limit;
if (!NILP (limit) if (!NILP (limit)
&& !(previous->position + LENGTH (previous) - (STRINGP (object)) && !(previous->position + LENGTH (previous) > XFASTINT (limit)))
> XFASTINT (limit)))
return limit; return limit;
XSETFASTINT (position, (previous->position + LENGTH (previous) return make_number (previous->position + LENGTH (previous));
- (STRINGP (object))));
return position;
} }
DEFUN ("previous-single-property-change", Fprevious_single_property_change, DEFUN ("previous-single-property-change", Fprevious_single_property_change,
...@@ -900,19 +889,15 @@ back past position LIMIT; return LIMIT if nothing is found until LIMIT.") ...@@ -900,19 +889,15 @@ back past position LIMIT; return LIMIT if nothing is found until LIMIT.")
while (! NULL_INTERVAL_P (previous) while (! NULL_INTERVAL_P (previous)
&& EQ (here_val, textget (previous->plist, prop)) && EQ (here_val, textget (previous->plist, prop))
&& (NILP (limit) && (NILP (limit)
|| (previous->position + LENGTH (previous) - (STRINGP (object)) || (previous->position + LENGTH (previous) > XFASTINT (limit))))
> XFASTINT (limit))))
previous = previous_interval (previous); previous = previous_interval (previous);
if (NULL_INTERVAL_P (previous)) if (NULL_INTERVAL_P (previous))
return limit; return limit;
if (!NILP (limit) if (!NILP (limit)
&& !(previous->position + LENGTH (previous) - (STRINGP (object)) && !(previous->position + LENGTH (previous) > XFASTINT (limit)))
> XFASTINT (limit)))
return limit; return limit;
XSETFASTINT (position, (previous->position + LENGTH (previous) return make_number (previous->position + LENGTH (previous));
- (STRINGP (object))));
return position;
} }
/* Callers note, this can GC when OBJECT is a buffer (or nil). */ /* Callers note, this can GC when OBJECT is a buffer (or nil). */
...@@ -1294,7 +1279,7 @@ containing the text.") ...@@ -1294,7 +1279,7 @@ containing the text.")
pos = i->position; pos = i->position;
if (pos < XINT (start)) if (pos < XINT (start))
pos = XINT (start); pos = XINT (start);
return make_number (pos - (STRINGP (object))); return make_number (pos);
} }
i = next_interval (i); i = next_interval (i);
} }
...@@ -1330,121 +1315,13 @@ containing the text.") ...@@ -1330,121 +1315,13 @@ containing the text.")
{ {
if (i->position > s) if (i->position > s)
s = i->position; s = i->position;
return make_number (s - (STRINGP (object))); return make_number (s);
} }
i = next_interval (i); i = next_interval (i);
} }
return Qnil; return Qnil;
} }
#if 0 /* You can use set-text-properties for this. */
DEFUN ("erase-text-properties", Ferase_text_properties,
Serase_text_properties, 2, 3, 0,
"Remove all properties from the text from START to END.\n\
The optional third argument, OBJECT,\n\
is the string or buffer containing the text.")
(start, end, object)
Lisp_Object start, end, object;
{
register INTERVAL i;
register INTERVAL prev_changed = NULL_INTERVAL;
register int s, len, modified;
if (NILP (object))
XSETBUFFER (object, current_buffer);
i = validate_interval_range (object, &start, &end, soft);
if (NULL_INTERVAL_P (i))
return Qnil;
s = XINT (start);
len = XINT (end) - s;
if (i->position != s)
{
register int got;
register INTERVAL unchanged = i;
/* If there are properties here, then this text will be modified. */
if (! NILP (i->plist))
{
i = split_interval_right (unchanged, s - unchanged->position);
i->plist = Qnil;
modified++;
if (LENGTH (i) > len)
{
i = split_interval_right (i, len);
copy_properties (unchanged, i);
return Qt;
}
if (LENGTH (i) == len)
return Qt;
got = LENGTH (i);
}
/* If the text of I is without any properties, and contains
LEN or more characters, then we may return without changing
anything.*/
else if (LENGTH (i) - (s - i->position) <= len)
return Qnil;
/* The amount of text to change extends past I, so just note
how much we've gotten. */
else
got = LENGTH (i) - (s - i->position);
len -= got;
prev_changed = i;
i = next_interval (i);
}
/* We are starting at the beginning of an interval, I. */
while (len > 0)
{
if (LENGTH (i) >= len)
{
/* If I has no properties, simply merge it if possible. */
if (NILP (i->plist))
{
if (! NULL_INTERVAL_P (prev_changed))
merge_interval_left (i);
return modified ? Qt : Qnil;
}
if (LENGTH (i) > len)
i = split_interval_left (i, len);
if (! NULL_INTERVAL_P (prev_changed))
merge_interval_left (i);
else
i->plist = Qnil;
return Qt;
}
/* Here if we still need to erase past the end of I */
len -= LENGTH (i);
if (NULL_INTERVAL_P (prev_changed))
{
modified += erase_properties (i);
prev_changed = i;
}
else
{
modified += ! NILP (i->plist);
/* Merging I will give it the properties of PREV_CHANGED. */
prev_changed = i = merge_interval_left (i);
}
i = next_interval (i);
}
return modified ? Qt : Qnil;
}
#endif /* 0 */
/* I don't think this is the right interface to export; how often do you /* I don't think this is the right interface to export; how often do you
want to do something like this, other than when you're copying objects want to do something like this, other than when you're copying objects
around? around?
...@@ -1460,7 +1337,7 @@ is the string or buffer containing the text.") ...@@ -1460,7 +1337,7 @@ is the string or buffer containing the text.")
Return t if any property value actually changed, nil otherwise. */ Return t if any property value actually changed, nil otherwise. */
/* Note this can GC when DEST is a buffer. */ /* Note this can GC when DEST is a buffer. */
Lisp_Object Lisp_Object
copy_text_properties (start, end, src, pos, dest, prop) copy_text_properties (start, end, src, pos, dest, prop)
Lisp_Object start, end, src, pos, dest, prop; Lisp_Object start, end, src, pos, dest, prop;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment