]> git.donarmstrong.com Git - lilypond.git/commitdiff
Fix 1063: Nested property revert
authorRodolfo Zitellini <xhero.gm@gmail.com>
Thu, 27 May 2010 03:30:00 +0000 (21:30 -0600)
committerCarl Sorensen <c_sorensen@byu.edu>
Fri, 13 Aug 2010 00:02:08 +0000 (18:02 -0600)
input/regression/nested-property-revert.ly [new file with mode: 0644]
lily/nested-property.cc

diff --git a/input/regression/nested-property-revert.ly b/input/regression/nested-property-revert.ly
new file mode 100644 (file)
index 0000000..aee39dc
--- /dev/null
@@ -0,0 +1,18 @@
+\version "2.13.30"
+
+\header {
+  texidoc = "
+If a nested property revert follows an override in the same grob for
+a different property, the nested property's default setting should not
+be evicted from the property alist.
+"
+}
+
+\relative c' {
+  c1\startTrillSpan
+  c1\stopTrillSpan
+  \override TrillSpanner #'color =  #red
+  \revert TrillSpanner #'(bound-details left text)
+  c1\startTrillSpan
+  c1\stopTrillSpan
+}
index fb62c7d80ad08196313ad8c2a4d6509369037524..db897d3fd847d60cce195e926889eced04c9ec23 100644 (file)
@@ -31,7 +31,7 @@ evict_from_alist (SCM symbol, SCM alist, SCM alist_end)
 /*
   PROP_PATH should be big-to-small ordering
  */
-SCM 
+SCM
 nested_property_alist (SCM alist, SCM prop_path, SCM value)
 {
   SCM new_value = SCM_BOOL_F;
@@ -52,17 +52,19 @@ nested_property_alist (SCM alist, SCM prop_path, SCM value)
   Recursively purge alist of prop_path:
 
   revert ((sym, val) : L, [sym]) = L
-  revert ((sym, val) : L, sym : props) = 
+  revert ((sym, val) : L, sym : props) =
     (sym, revert (val, rest-props)) ++ L
   revert ((sym, val) : L, p ++ rest-props) =
     (sym, val) : revert (L, p ++ rest-props)
 
  */
-SCM 
+SCM
 nested_property_revert_alist (SCM alist, SCM prop_path)
 {
+  int copy_count = 0;
+  bool drop = false;
   assert(scm_is_pair (prop_path));
-  
+
   SCM wanted_sym = scm_car (prop_path);
 
   SCM new_list = SCM_EOL;
@@ -71,6 +73,7 @@ nested_property_revert_alist (SCM alist, SCM prop_path)
     {
       SCM sub_sym = scm_caar (s);
       SCM old_val = scm_cdar (s);
+      drop = false;
 
       if (sub_sym == wanted_sym)
        {
@@ -81,25 +84,48 @@ nested_property_revert_alist (SCM alist, SCM prop_path)
              /* nothing changed: drop newly constructed list. */
              if (old_val == new_val)
                return alist;
-             
+
              *tail = scm_acons (sub_sym, new_val, SCM_EOL);
              tail = SCM_CDRLOC(*tail);
+              *tail = scm_cdr (s);
+              return new_list;
            }
          else
            {
-             /* old value is dropped. */
+              /* old value should be dropped only if we have another copy of it in the alist */
+              copy_count++;
+              /*
+                Only drop the first instance found.
+                the overridden value is always the first
+                if this was the only copy, we will return
+                the original list anyways so it is not relevant
+                if we drop this pair
+              */
+              if (copy_count == 1)
+                drop = true;
            }
-         
-         *tail = scm_cdr (s);
-         return new_list;
+         /* we now iterate over every item */
        }
-
-      *tail = scm_acons (sub_sym, old_val, SCM_EOL);
-      tail = SCM_CDRLOC (*tail);
+      /*
+        Make a new list with every item
+        except for the eventual dropped one
+      */
+      if (!drop)
+        {
+          *tail = scm_acons (sub_sym, old_val, SCM_EOL);
+          tail = SCM_CDRLOC (*tail);
+        }
     }
 
-  /* Wanted symbol not found: drop newly constructed list. */
-  return alist;
+  /*
+    If we find more than one copy of the property
+    push the new list, else it means we are trying to
+    revert the original value
+  */
+  if (copy_count > 1)
+    return new_list;
+  else
+    return alist;
 }
 
 
@@ -109,7 +135,7 @@ set_nested_property (Grob *me, SCM big_to_small, SCM value)
   SCM alist = me->get_property (scm_car (big_to_small));
 
   alist = nested_property_alist (alist, scm_cdr (big_to_small), value);
-  
+
   me->set_property (scm_car (big_to_small), alist);
 }