* bug#20153: 24.4.91; destructive add-face-text-property and string deep copying @ 2015-03-20 12:28 Oleh Krehel 2019-10-09 2:25 ` Lars Ingebrigtsen 2019-10-09 3:04 ` Lars Ingebrigtsen 0 siblings, 2 replies; 8+ messages in thread From: Oleh Krehel @ 2015-03-20 12:28 UTC (permalink / raw) To: 20153 Here's an example of what I'm trying to do: (setq test-str-1 #(";; This `is' a test" 0 3 (fontified nil face font-lock-comment-delimiter-face) 3 9 (fontified nil face font-lock-comment-face) 9 11 (fontified nil face (font-lock-constant-face font-lock-comment-face)) 11 19 (fontified nil face font-lock-comment-face))) (setq test-str-2 (concat test-str-1)) (add-face-text-property 0 (length test-str-2) 'foobar t test-str-2) I would like to modify `test-str-2' without touching `test-str-1'. For that, I either need `add-face-text-property' to be non-destructive, either w.r.t. the string or at least w.r.t. the properties of the string, or a way to deep-copy a string. Here's the result of evaling the code above: test-str-2 ;; => #(";; This `is' a test" 0 3 (fontified nil face (font-lock-comment-delimiter-face foobar)) 3 9 (fontified nil face (font-lock-comment-face foobar)) 9 11 (fontified nil face (font-lock-constant-face font-lock-comment-face foobar)) 11 19 (fontified nil face (font-lock-comment-face foobar))) test-str-1 ;; => #(";; This `is' a test" 0 3 (face font-lock-comment-delimiter-face fontified nil) 3 9 (face font-lock-comment-face fontified nil) 9 11 (face (font-lock-constant-face font-lock-comment-face foobar) ; <= foobar is here fontified nil) 11 19 (face font-lock-comment-face fontified nil)) As you see, `test-str-1' was modified. I'd like to know a straightforward solution to the problem itself, I'm fine with either way of implementation. Oleh ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#20153: 24.4.91; destructive add-face-text-property and string deep copying 2015-03-20 12:28 bug#20153: 24.4.91; destructive add-face-text-property and string deep copying Oleh Krehel @ 2019-10-09 2:25 ` Lars Ingebrigtsen 2019-10-09 3:04 ` Lars Ingebrigtsen 1 sibling, 0 replies; 8+ messages in thread From: Lars Ingebrigtsen @ 2019-10-09 2:25 UTC (permalink / raw) To: Oleh Krehel; +Cc: 20153 Oleh Krehel <ohwoeowho@gmail.com> writes: > Here's an example of what I'm trying to do: > > (setq test-str-1 > #(";; This `is' a test" > 0 3 (fontified nil face font-lock-comment-delimiter-face) > 3 9 (fontified nil face font-lock-comment-face) > 9 11 (fontified nil face (font-lock-constant-face font-lock-comment-face)) > 11 19 (fontified nil face font-lock-comment-face))) > (setq test-str-2 (concat test-str-1)) > (add-face-text-property 0 (length test-str-2) 'foobar t test-str-2) > > I would like to modify `test-str-2' without touching `test-str-1'. > For that, I either need `add-face-text-property' to be non-destructive, > either w.r.t. the string or at least w.r.t. the properties of the > string, or a way to deep-copy a string. It's this code (in add_properties): /* The previous value is a list, so prepend (or append) the new value to this list. */ if (set_type == TEXT_PROPERTY_PREPEND) Fsetcar (this_cdr, Fcons (val1, Fcar (this_cdr))); else nconc2 (Fcar (this_cdr), list1 (val1)); But changing that would have pretty far-reaching consequences. I wonder whether instead Fadd_face_text_property should just (when called with a string parameter) just copy the `face' property list first? That should avoid the problem and not lead to any general slowdown. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#20153: 24.4.91; destructive add-face-text-property and string deep copying 2015-03-20 12:28 bug#20153: 24.4.91; destructive add-face-text-property and string deep copying Oleh Krehel 2019-10-09 2:25 ` Lars Ingebrigtsen @ 2019-10-09 3:04 ` Lars Ingebrigtsen 2019-10-09 8:24 ` Oleh Krehel 2019-10-09 17:10 ` Eli Zaretskii 1 sibling, 2 replies; 8+ messages in thread From: Lars Ingebrigtsen @ 2019-10-09 3:04 UTC (permalink / raw) To: Oleh Krehel; +Cc: 20153 I've never really worked with the interval internals before, so I thought this was going to be easy to fix. :-/ But the problem is that copy_intervals doesn't do a "deep" copy of the text properties, so this has no effect, really. (Patch included for reference.) Instead I've now changed add_properties (and add_text_properties_1) to take a bool parameter to say whether they're allowed to be destructive or not, and make the add-face-text-property call that with false as the parameter if the object is a string. This fixes the test case for me and should hopefully have no measurable performance impact. diff --git a/src/textprop.c b/src/textprop.c index d36b9e14a6..dcd3284209 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -1334,6 +1334,18 @@ face(s) are retained. This is done by setting the `face' property to Lisp_Object append, Lisp_Object object) { AUTO_LIST2 (properties, Qface, face); + + /* If we're adding face properties to a string, and the face + property is already a list, then copy the list first to avoid + destructively altering it. */ + if (STRINGP (object)) + { + INTERVAL copy = copy_intervals (string_intervals (object), + 0, SCHARS (object)); + set_interval_object (copy, object); + set_string_intervals (object, copy); + } + add_text_properties_1 (start, end, properties, object, (NILP (append) ? TEXT_PROPERTY_PREPEND -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply related [flat|nested] 8+ messages in thread
* bug#20153: 24.4.91; destructive add-face-text-property and string deep copying 2019-10-09 3:04 ` Lars Ingebrigtsen @ 2019-10-09 8:24 ` Oleh Krehel 2019-10-09 17:10 ` Eli Zaretskii 1 sibling, 0 replies; 8+ messages in thread From: Oleh Krehel @ 2019-10-09 8:24 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: 20153 Thanks for your work, Lars. Oleh ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#20153: 24.4.91; destructive add-face-text-property and string deep copying 2019-10-09 3:04 ` Lars Ingebrigtsen 2019-10-09 8:24 ` Oleh Krehel @ 2019-10-09 17:10 ` Eli Zaretskii 2019-10-09 17:45 ` Lars Ingebrigtsen 1 sibling, 1 reply; 8+ messages in thread From: Eli Zaretskii @ 2019-10-09 17:10 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: 20153, ohwoeowho > From: Lars Ingebrigtsen <larsi@gnus.org> > Date: Wed, 09 Oct 2019 05:04:03 +0200 > Cc: 20153@debbugs.gnu.org > > Instead I've now changed add_properties (and add_text_properties_1) to > take a bool parameter to say whether they're allowed to be destructive > or not, and make the add-face-text-property call that with false as the > parameter if the object is a string. This fixes the test case for me > and should hopefully have no measurable performance impact. Isn't that a backward-incompatible change? ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#20153: 24.4.91; destructive add-face-text-property and string deep copying 2019-10-09 17:10 ` Eli Zaretskii @ 2019-10-09 17:45 ` Lars Ingebrigtsen 2019-10-09 18:06 ` Eli Zaretskii 0 siblings, 1 reply; 8+ messages in thread From: Lars Ingebrigtsen @ 2019-10-09 17:45 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 20153, ohwoeowho Eli Zaretskii <eliz@gnu.org> writes: >> Instead I've now changed add_properties (and add_text_properties_1) to >> take a bool parameter to say whether they're allowed to be destructive >> or not, and make the add-face-text-property call that with false as the >> parameter if the object is a string. This fixes the test case for me >> and should hopefully have no measurable performance impact. > > Isn't that a backward-incompatible change? It is, but the previous behaviour was a bug. If you have a copy of a string and modify the copy, the original string shouldn't change. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#20153: 24.4.91; destructive add-face-text-property and string deep copying 2019-10-09 17:45 ` Lars Ingebrigtsen @ 2019-10-09 18:06 ` Eli Zaretskii 2019-10-09 18:09 ` Lars Ingebrigtsen 0 siblings, 1 reply; 8+ messages in thread From: Eli Zaretskii @ 2019-10-09 18:06 UTC (permalink / raw) To: Lars Ingebrigtsen; +Cc: 20153, ohwoeowho > From: Lars Ingebrigtsen <larsi@gnus.org> > Cc: ohwoeowho@gmail.com, 20153@debbugs.gnu.org > Date: Wed, 09 Oct 2019 19:45:54 +0200 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> Instead I've now changed add_properties (and add_text_properties_1) to > >> take a bool parameter to say whether they're allowed to be destructive > >> or not, and make the add-face-text-property call that with false as the > >> parameter if the object is a string. This fixes the test case for me > >> and should hopefully have no measurable performance impact. > > > > Isn't that a backward-incompatible change? > > It is, but the previous behaviour was a bug. If you have a copy of a > string and modify the copy, the original string shouldn't change. AFAIU, the string didn't change, only its plist did. Right? Please bring this up on emacs-devel, and if no one objects to the change, we should at least mention it in NEWS. Thanks. ^ permalink raw reply [flat|nested] 8+ messages in thread
* bug#20153: 24.4.91; destructive add-face-text-property and string deep copying 2019-10-09 18:06 ` Eli Zaretskii @ 2019-10-09 18:09 ` Lars Ingebrigtsen 0 siblings, 0 replies; 8+ messages in thread From: Lars Ingebrigtsen @ 2019-10-09 18:09 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 20153, ohwoeowho Eli Zaretskii <eliz@gnu.org> writes: > AFAIU, the string didn't change, only its plist did. Right? Yes. > Please bring this up on emacs-devel, and if no one objects to the > change, we should at least mention it in NEWS. Will do. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2019-10-09 18:09 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-03-20 12:28 bug#20153: 24.4.91; destructive add-face-text-property and string deep copying Oleh Krehel 2019-10-09 2:25 ` Lars Ingebrigtsen 2019-10-09 3:04 ` Lars Ingebrigtsen 2019-10-09 8:24 ` Oleh Krehel 2019-10-09 17:10 ` Eli Zaretskii 2019-10-09 17:45 ` Lars Ingebrigtsen 2019-10-09 18:06 ` Eli Zaretskii 2019-10-09 18:09 ` Lars Ingebrigtsen
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).