X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fcontext-property.cc;h=6e22b2f808211b28aaa7acedad6afba52f9829f6;hb=b5de1ca579bc679f69b5df30803fda31a74075d5;hp=5904254d7d9e263520f5f025a385bb8137820257;hpb=0c14539bc83d6bb405141b6f21430b33d1e8fcf0;p=lilypond.git diff --git a/lily/context-property.cc b/lily/context-property.cc index 5904254d7d..6e22b2f808 100644 --- a/lily/context-property.cc +++ b/lily/context-property.cc @@ -24,7 +24,6 @@ #include "international.hh" #include "item.hh" #include "main.hh" -#include "simple-closure.hh" #include "smobs.hh" #include "spanner.hh" #include "unpure-pure-container.hh" @@ -40,10 +39,11 @@ general_pushpop_property (Context *context, SCM grob_property_path, SCM new_value) { + // Numbers may appear, but not in first place if (!scm_is_symbol (context_property) || !scm_is_symbol (scm_car (grob_property_path))) { - warning (_ ("need symbol arguments for \\override and \\revert")); + warning (_ ("need symbol argument for \\override and \\revert")); if (do_internal_type_checking_global) assert (false); } @@ -59,15 +59,14 @@ typecheck_grob (SCM symbol, SCM value) return typecheck_grob (symbol, upc->unpure_part ()) && typecheck_grob (symbol, upc->pure_part ()); return ly_is_procedure (value) - || unsmob (value) || type_check_assignment (symbol, value, ly_symbol2scm ("backend-type?")); } class Grob_properties : public Simple_smob { public: - SCM mark_smob (); - static const char type_p_name_[]; + SCM mark_smob () const; + static const char * const type_p_name_; private: friend class Grob_property_info; friend SCM ly_make_grob_properties (SCM); @@ -82,7 +81,11 @@ private: // cooked_from_ is the value of alist_ from which the expansion has // been done SCM cooked_from_; - // nested_ is a count of nested overrides in alist_ + // nested_ is a count of nested overrides in alist_ Or rather: of + // entries that must not appear in the cooked list and are + // identified by having a "key" that is not a symbol. Temporary + // overrides and reverts also meet that description and have a + // nominal key of #t/#f and a value of the original cons cell. int nested_; Grob_properties (SCM alist, SCM based_on) : @@ -94,10 +97,10 @@ private: cooked_ (alist), cooked_from_ (alist), nested_ (0) { } }; -const char Grob_properties::type_p_name_[] = "ly:grob-properties?"; +const char * const Grob_properties::type_p_name_ = "ly:grob-properties?"; SCM -Grob_properties::mark_smob () +Grob_properties::mark_smob () const { scm_gc_mark (alist_); scm_gc_mark (based_on_); @@ -234,6 +237,59 @@ Grob_property_info::push (SCM grob_property_path, SCM new_value) return SCM_EOL; } +// Used for \once \override, returns a token for matched_pop +SCM +Grob_property_info::temporary_override (SCM grob_property_path, SCM new_value) +{ + SCM cell = push (grob_property_path, new_value); + if (!scm_is_pair (cell)) + return cell; + if (scm_is_symbol (scm_car (cell))) + props_->nested_++; + cell = scm_cons (SCM_BOOL_T, cell); + props_->alist_ = scm_cons (cell, scm_cdr (props_->alist_)); + return cell; +} + +// Used for \once \revert, returns a token for matched_pop +SCM +Grob_property_info::temporary_revert (SCM grob_property_path) +{ + if (!check ()) + return SCM_EOL; + + SCM current_alist = props_->alist_; + SCM daddy = props_->based_on_; + SCM tail = SCM_EOL; + + if (!scm_is_pair (grob_property_path) + || !scm_is_symbol (scm_car (grob_property_path))) + { + programming_error ("Grob property path should be list of symbols."); + return SCM_EOL; + } + + if (scm_is_pair (scm_cdr (grob_property_path))) + { + tail = assoc_tail (grob_property_path, current_alist, daddy); + if (scm_is_false (tail)) + return SCM_EOL; + } + else + { + tail = assq_tail (scm_car (grob_property_path), current_alist, daddy); + if (scm_is_false (tail)) + return SCM_EOL; + ++props_->nested_; + } + + SCM cell = scm_cons (SCM_BOOL_F, scm_car (tail)); + props_->alist_ = partial_list_copy (current_alist, tail, + scm_cons (cell, scm_cdr (tail))); + return cell; +} + + void Grob_property_info::matched_pop (SCM cell) { @@ -247,7 +303,18 @@ Grob_property_info::matched_pop (SCM cell) { if (scm_is_eq (scm_car (p), cell)) { - if (scm_is_pair (scm_car (cell))) + SCM key = scm_car (cell); + if (scm_is_false (key)) + { + // temporary revert, reactivate + cell = scm_cdr (cell); + if (scm_is_symbol (scm_car (cell))) + props_->nested_--; + props_->alist_ = partial_list_copy (current_alist, p, + scm_cons (cell, scm_cdr (p))); + return; + } + if (!scm_is_symbol (key)) props_->nested_--; props_->alist_ = partial_list_copy (current_alist, p, scm_cdr (p)); return; @@ -337,7 +404,7 @@ apply_property_operations (Context *tg, SCM pre_init_ops) else if (scm_is_eq (type, ly_symbol2scm ("assign"))) tg->set_property (scm_car (entry), scm_cadr (entry)); else if (scm_is_eq (type, ly_symbol2scm ("apply"))) - scm_apply_1 (scm_car (entry), tg->self_scm (), scm_cdr (entry)); + scm_apply_1 (scm_car (entry), tg->self_scm (), scm_cdr (entry)); else if (scm_is_eq (type, ly_symbol2scm ("unset"))) tg->unset_property (scm_car (entry)); }