Yet another fix for copying properties by 'format'

* src/textprop.c (extend_property_ranges): Accept an additional
argument OLD_END, and only extend the end of a property range if
its original end is at OLD_END; all the other ranges are left
intact.  (Bug#23897)
* src/editfns.c (styled_format): Pass the original length of the
string to 'extend_property_ranges'.
* src/intervals.h (extend_property_ranges): Adjust prototype.

* test/src/editfns-tests.el (format-properties): Add tests for
bug#23897.
This commit is contained in:
Eli Zaretskii 2016-07-08 22:34:34 +03:00
parent d0c0b71d88
commit d8a9c450cf
4 changed files with 21 additions and 8 deletions

View file

@ -4631,7 +4631,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
len = make_number (SCHARS (args[i]));
Lisp_Object new_len = make_number (info[i].end - info[i].start);
props = text_property_list (args[i], make_number (0), len, Qnil);
props = extend_property_ranges (props, new_len);
props = extend_property_ranges (props, len, new_len);
/* If successive arguments have properties, be sure that
the value of `composition' property be the copy. */
if (1 < i && info[i - 1].end)

View file

@ -285,7 +285,7 @@ extern void set_text_properties_1 (Lisp_Object, Lisp_Object,
Lisp_Object text_property_list (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object);
void add_text_properties_from_list (Lisp_Object, Lisp_Object, Lisp_Object);
Lisp_Object extend_property_ranges (Lisp_Object, Lisp_Object);
Lisp_Object extend_property_ranges (Lisp_Object, Lisp_Object, Lisp_Object);
Lisp_Object get_char_property_and_overlay (Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object*);
extern int text_property_stickiness (Lisp_Object prop, Lisp_Object pos,

View file

@ -2043,18 +2043,19 @@ add_text_properties_from_list (Lisp_Object object, Lisp_Object list, Lisp_Object
end-points to NEW_END. */
Lisp_Object
extend_property_ranges (Lisp_Object list, Lisp_Object new_end)
extend_property_ranges (Lisp_Object list, Lisp_Object old_end, Lisp_Object new_end)
{
Lisp_Object prev = Qnil, head = list;
ptrdiff_t max = XINT (new_end);
for (; CONSP (list); prev = list, list = XCDR (list))
{
Lisp_Object item, beg, end;
Lisp_Object item, beg;
ptrdiff_t end;
item = XCAR (list);
beg = XCAR (item);
end = XCAR (XCDR (item));
end = XINT (XCAR (XCDR (item)));
if (XINT (beg) >= max)
{
@ -2065,12 +2066,14 @@ extend_property_ranges (Lisp_Object list, Lisp_Object new_end)
else
XSETCDR (prev, XCDR (list));
}
else if (XINT (end) != max)
else if ((end == XINT (old_end) && end != max)
|| end > max)
{
/* Either the end-point is past the end of the new string,
and we need to discard the properties past the new end,
or the caller is extending the property range, and we
should update the end-point to reflect that. */
should update all end-points that are on the old end of
the range to reflect that. */
XSETCAR (XCDR (item), new_end);
}
}

View file

@ -54,4 +54,14 @@
;; Bug #23859
(should (ert-equal-including-properties
(format "%4s" (propertize "hi" 'face 'bold))
#(" hi" 0 4 (face bold)))))
#(" hi" 0 4 (face bold))))
;; Bug #23897
(should (ert-equal-including-properties
(format "%s" (concat (propertize "01234" 'face 'bold) "56789"))
#("0123456789" 0 5 (face bold))))
(should (ert-equal-including-properties
(format "%s" (concat (propertize "01" 'face 'bold)
(propertize "23" 'face 'underline)
"45"))
#("012345" 0 2 (face bold) 2 4 (face underline)))))