From 73364778d21a8d1959eeb27f2bf127c4d9e8aba2 Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Wed, 1 Oct 2014 16:11:10 +0200 Subject: [PATCH] Issue 630/1: Implement Grob_property_info::matched_pop This can be passed a token returned from Grob_property_info::push and will then only revert the matching push or nothing at all. This is used to limit the fallout from internal property reversions that might not match the original override because of an intervening property push/pop. --- lily/context-property.cc | 44 ++++++++++++++++++++++++++++----- lily/include/grob-properties.hh | 3 ++- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/lily/context-property.cc b/lily/context-property.cc index 45b5d496c1..70370e3800 100644 --- a/lily/context-property.cc +++ b/lily/context-property.cc @@ -190,18 +190,21 @@ Grob_property_info::create () alist defined in a parent context. BASED-ON should always be a tail of ALIST. - Push or pop (depending on value of VAL) a single entry from a + Push a single entry from a translator property list by name of PROP. GROB_PROPERTY_PATH indicates nested alists, eg. '(beamed-stem-lengths details) + + Return value can be passed to matched_pop and will only cancel the + same override then. */ -void +SCM Grob_property_info::push (SCM grob_property_path, SCM new_value) { /* Don't mess with MIDI. */ if (!create ()) - return; + return SCM_EOL; SCM symbol = scm_car (grob_property_path); SCM rest = scm_cdr (grob_property_path); @@ -209,10 +212,12 @@ Grob_property_info::push (SCM grob_property_path, SCM new_value) { // poor man's typechecking if (typecheck_grob (symbol, nested_create_alist (rest, new_value))) { - props_->alist_ = scm_acons (grob_property_path, new_value, props_->alist_); + SCM cell = scm_cons (grob_property_path, new_value); + props_->alist_ = scm_cons (cell, props_->alist_); props_->nested_++; + return cell; } - return; + return SCM_EOL; } /* it's tempting to replace the head of the list if it's the same @@ -221,7 +226,34 @@ Grob_property_info::push (SCM grob_property_path, SCM new_value) */ if (typecheck_grob (symbol, new_value)) - props_->alist_ = scm_acons (symbol, new_value, props_->alist_); + { + SCM cell = scm_cons (symbol, new_value); + props_->alist_ = scm_cons (cell, props_->alist_); + return cell; + } + return SCM_EOL; +} + +void +Grob_property_info::matched_pop (SCM cell) +{ + if (!scm_is_pair (cell)) + return; + if (!check ()) + return; + SCM current_alist = props_->alist_; + SCM daddy = props_->based_on_; + for (SCM p = current_alist; !scm_is_eq (p, daddy); p = scm_cdr (p)) + { + if (scm_is_eq (scm_car (p), cell)) + { + if (scm_is_pair (scm_car (cell))) + props_->nested_--; + props_->alist_ = partial_list_copy (current_alist, p, scm_cdr (p)); + return; + } + } + return; } /* diff --git a/lily/include/grob-properties.hh b/lily/include/grob-properties.hh index 37569442c6..157613debb 100644 --- a/lily/include/grob-properties.hh +++ b/lily/include/grob-properties.hh @@ -47,7 +47,8 @@ public: bool check (); bool create (); SCM updated (); - void push (SCM path, SCM value); + SCM push (SCM path, SCM value); + void matched_pop (SCM); void pop (SCM path); void pushpop (SCM path, SCM value) { -- 2.39.5