From f425229f3869b6cce39f8d61584e38109f4bdaa1 Mon Sep 17 00:00:00 2001
From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Thu, 15 Jan 2004 19:36:19 +0000
Subject: [PATCH] * lily/system.cc (uniquify_list): new function
 (output_lines): uniquify_list () on all-elements

* input/regression/rest-pitch.ly (texidoc): add rest under beam.

* lily/system.cc (typeset_grob): warn if adding twice.
---
 ChangeLog                      |  3 ++
 input/regression/rest-pitch.ly | 23 +++++++-------
 lily/include/paper-score.hh    |  4 +--
 lily/paper-score.cc            |  3 ++
 lily/system.cc                 | 57 ++++++++++++++++++++++++++++++++++
 5 files changed, 76 insertions(+), 14 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3262ef9298..b513e8dac2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2004-01-15  Han-Wen Nienhuys   <hanwen@xs4all.nl>
 
+	* lily/system.cc (uniquify_list): new function
+	(output_lines): uniquify_list () on all-elements
+
 	* lily/beam.cc (rest_collision_callback): don't move anything if
 	staff-position is set.
 
diff --git a/input/regression/rest-pitch.ly b/input/regression/rest-pitch.ly
index 61f38fffc4..3269b8996f 100644
--- a/input/regression/rest-pitch.ly
+++ b/input/regression/rest-pitch.ly
@@ -1,24 +1,23 @@
-#(ly:set-option 'old-relative)
 \version "2.1.7"
 \header {
 
 texidoc = "Rests can have pitches--these will be affected by
-transposition and relativization. If a rest has a pitch, rest
-collision will leave it alone."
+transposition and relativization. If a rest has a pitch, rest/rest and
+beam/rest collision resolving will leave it alone."
 
 }
 
     \paper { raggedright= ##t }
 
 \score { \notes\relative c'' 
-{
-   a4\rest b4\rest c4\rest
+	 {
+	     a4\rest b4\rest c4\rest
 
-<<d \\  d\rest^"rest pitch" >>
-<<d \\  r>>
-  c16 [ d r e] 
-  c16 [ d e\rest^"rest pitch" e] 
-  
-}
-}
+	     <<d \\  d\rest^"rest pitch" >>
+	     <<d \\  r>>
+	     c16 [ d r e] 
+	     c16 [ d e\rest^"rest pitch" e] 
+	     
+	 }
+     }
 
diff --git a/lily/include/paper-score.hh b/lily/include/paper-score.hh
index 831f913e3e..505a2fc571 100644
--- a/lily/include/paper-score.hh
+++ b/lily/include/paper-score.hh
@@ -15,7 +15,7 @@
 #include "lily-proto.hh"
 #include "music-output.hh"
 #include "lily-guile.hh"
-
+#include "protected-scm.hh"
 
 /** all stuff which goes onto paper. notes, signs, symbols in a score
      #Paper_score# contains the items, the columns.
@@ -23,7 +23,7 @@
     */
 class Paper_score : public Music_output
 {
-  SCM main_smob_;
+  Protected_scm main_smob_;
 public:
   Paper_def *paper_;
 
diff --git a/lily/paper-score.cc b/lily/paper-score.cc
index 0cc8169ede..5e31a512ec 100644
--- a/lily/paper-score.cc
+++ b/lily/paper-score.cc
@@ -42,10 +42,13 @@ Paper_score::typeset_line (System *l)
   main_smob_ = gh_cons (l->self_scm (), main_smob_);
   l->pscore_ = this;
 
+#if 0
   /*
     We don't unprotect l->self_scm (), we haven't got any place else to
     protect it from collection.  */
+#endif
 
+  scm_gc_unprotect_object (l->self_scm());
 }
 
 Paper_score::Paper_score (Paper_score const &s)
diff --git a/lily/system.cc b/lily/system.cc
index a776eeba9a..ff5239153c 100644
--- a/lily/system.cc
+++ b/lily/system.cc
@@ -60,6 +60,48 @@ System::spanner_count () const
 }
   
 
+int
+scm_default_compare (const void * a, const void *b)
+{
+  SCM pa = *(SCM *)a;
+  SCM pb = *(SCM *)b;
+
+  if (pa < pb) return -1 ;
+  else if (pa > pb) return 1;
+  else return 0;
+}
+
+/*
+  modify L in place: sort it 
+*/
+
+SCM
+uniquify_list (SCM l)
+{
+  int len = scm_ilength (l);
+  SCM  * arr = new SCM[len];
+  int k = 0;
+  for (SCM s =l ; SCM_NNULLP (s); s = SCM_CDR(s))
+    arr[k++] = SCM_CAR(s);
+
+  assert (k == len);
+  qsort (arr, len, sizeof (SCM), &scm_default_compare);
+
+  k = 0;
+  SCM s =l;
+  for (int i = 0; i < len ; i++)
+    {
+      if (i && arr[i] == arr[i-1])
+	continue;
+
+      SCM_SETCAR(s, arr[i]);      
+      s = SCM_CDR(s);
+    }
+
+  SCM_SETCDR(s, SCM_EOL);
+  
+  return l; 
+}
 
 void
 System::typeset_grob (Grob * elem)
@@ -124,6 +166,21 @@ System::output_lines ()
     }
   handle_broken_dependencies ();
 
+  /*
+    Because the this->get_grob_property (all-elements) contains items
+    in 3 versions, handle_broken_dependencies () will leave duplicated
+    items in all-elements. Strictly speaking this is harmless, but it
+    leads to duplicated symbols in the output. uniquify_list() makes
+    sure that no duplicates are in the list.
+   */
+  for (int i=0; i < broken_intos_.size (); i++)
+    {
+      SCM al = broken_intos_[i]->get_grob_property ("all-elements");
+      al  = uniquify_list (al); 
+    }
+  
+
+  
   if (verbose_global_b)
     progress_indication (_f ("Element count %d.",  count + element_count ()));
 
-- 
2.39.5