Improve handling of nested overrides using list syntax.
[lilypond/mpolesky.git] / lily / nested-property.cc
blobfb62c7d80ad08196313ad8c2a4d6509369037524
1 #include "context.hh"
2 #include "grob.hh"
5 /*
6 Drop symbol from the list alist..alist_end.
7 */
8 SCM
9 evict_from_alist (SCM symbol, SCM alist, SCM alist_end)
11 SCM new_alist = SCM_EOL;
12 SCM *tail = &new_alist;
14 while (alist != alist_end)
16 if (ly_is_equal (scm_caar (alist), symbol))
18 alist = scm_cdr (alist);
19 break;
22 *tail = scm_cons (scm_car (alist), SCM_EOL);
23 tail = SCM_CDRLOC (*tail);
24 alist = scm_cdr (alist);
27 *tail = alist;
28 return new_alist;
32 PROP_PATH should be big-to-small ordering
34 SCM
35 nested_property_alist (SCM alist, SCM prop_path, SCM value)
37 SCM new_value = SCM_BOOL_F;
38 if (scm_is_pair (scm_cdr (prop_path)))
40 SCM sub_alist = ly_assoc_get (scm_car (prop_path), alist, SCM_EOL);
41 new_value = nested_property_alist (sub_alist, scm_cdr (prop_path), value);
43 else
45 new_value = value;
48 return scm_acons (scm_car (prop_path), new_value, alist);
52 Recursively purge alist of prop_path:
54 revert ((sym, val) : L, [sym]) = L
55 revert ((sym, val) : L, sym : props) =
56 (sym, revert (val, rest-props)) ++ L
57 revert ((sym, val) : L, p ++ rest-props) =
58 (sym, val) : revert (L, p ++ rest-props)
61 SCM
62 nested_property_revert_alist (SCM alist, SCM prop_path)
64 assert(scm_is_pair (prop_path));
66 SCM wanted_sym = scm_car (prop_path);
68 SCM new_list = SCM_EOL;
69 SCM *tail = &new_list;
70 for (SCM s = alist; scm_is_pair (s); s = scm_cdr (s))
72 SCM sub_sym = scm_caar (s);
73 SCM old_val = scm_cdar (s);
75 if (sub_sym == wanted_sym)
77 if (scm_is_pair (scm_cdr (prop_path)))
79 SCM new_val = nested_property_revert_alist (old_val, scm_cdr (prop_path));
81 /* nothing changed: drop newly constructed list. */
82 if (old_val == new_val)
83 return alist;
85 *tail = scm_acons (sub_sym, new_val, SCM_EOL);
86 tail = SCM_CDRLOC(*tail);
88 else
90 /* old value is dropped. */
93 *tail = scm_cdr (s);
94 return new_list;
97 *tail = scm_acons (sub_sym, old_val, SCM_EOL);
98 tail = SCM_CDRLOC (*tail);
101 /* Wanted symbol not found: drop newly constructed list. */
102 return alist;
106 void
107 set_nested_property (Grob *me, SCM big_to_small, SCM value)
109 SCM alist = me->get_property (scm_car (big_to_small));
111 alist = nested_property_alist (alist, scm_cdr (big_to_small), value);
113 me->set_property (scm_car (big_to_small), alist);