]> git.donarmstrong.com Git - lilypond.git/commitdiff
patch::: 1.3.26.hwn3
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Thu, 24 Feb 2000 16:15:46 +0000 (17:15 +0100)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Thu, 24 Feb 2000 16:15:46 +0000 (17:15 +0100)
* Plug memory leak in Paper_outputter::output_{String,Real,int}_def()

* Plug memory leak in Score_engraver::set_columns ()

* Plug memory leak in Scheme_hash_table::set()

* Plug memory leak in Score_element::molecule_extent ()

---
Generated by hanwen@cs.uu.nl,
From = lilypond-1.3.26.hwn2, To = lilypond-1.3.26.hwn3

usage

    cd lilypond-source-dir; patch -E -p1 < lilypond-1.3.26.hwn3.diff

Patches do not contain automatically generated files
or (urg) empty directories,
i.e., you should rerun autoconf, configure

13 files changed:
CHANGES
VERSION
flower/include/hash-table.hh
lily/all-font-metrics.cc
lily/include/scm-hash.hh
lily/paper-def.cc
lily/paper-outputter.cc
lily/scm-hash.cc
lily/score-element.cc
lily/score-element.cc.orig [new file with mode: 0644]
lily/score-engraver.cc
lily/score.cc
lily/translator-group.cc

diff --git a/CHANGES b/CHANGES
index 5a4ec57e684302145c1983fecb02181a2d7754bd..eae8018ba12c2585a6e5cd45feffa548a937134a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,20 @@
-1.3.26.jcn2
+--- ../lilypond-1.3.26.hwn2/CHANGES    Thu Feb 24 13:52:54 2000
+++ b/CHANGES   Thu Feb 24 17:15:46 2000
+@@ -2,6 +2,14 @@
+ 1.3.26.hwn2
+ ===========
+* Plug memory leak in Paper_outputter::output_{String,Real,int}_def()
+
+* Plug memory leak in Score_engraver::set_columns ()
+
+* Plug memory leak in Scheme_hash_table::set()
+
+* Plug memory leak in Score_element::molecule_extent ()
+
+ * Bugfix: don't crash if a slur doesn't span anything.
+ * Bugfix: don't crash if doing beams without a staff symbol.1.3.26.jcn2
 ===========
 
 * Bugfix: font used in volta-spanner calculation.
diff --git a/VERSION b/VERSION
index 8fac086972764c56edcca1c174c3501a558a529c..6ea5f58835d12df6fb8a9323c076dd31849ad408 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=3
 PATCH_LEVEL=26
-MY_PATCH_LEVEL=jcn2
+MY_PATCH_LEVEL=hwn3
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
 # released version.
index 491feb3df7106fab4674d04c2421ad66bb383e10..aec7ae31afa721458f689bfd054702223d8590ab 100644 (file)
@@ -151,8 +151,8 @@ public:
     }
 
   /**
-     Find and return element.  If #s# is not in the table, create an entry in the table, and init
-   */
+     Find and return element.  If #s# is not in the table, create an
+     entry in the table, and init */
   V& elem (K s)
     {
       int l;
index 89936e5f0f72346f50514491f116b08f1cd88861..88f46c07a905895610a1999f9a648f85657e7d37 100644 (file)
@@ -39,11 +39,10 @@ All_font_metrics::find_afm (String name)
       afm_p->name_ = ly_symbol2scm (name.ch_C ());
       progress_indication ("]");
 
-      afm_p_dict_[sname] = afm_p->self_scm_;
-      scm_unprotect_object (afm_p->self_scm_);
+      afm_p_dict_.set (sname,afm_p->self_scm_);
     }
   
-  return dynamic_cast<Adobe_font_metric*> (unsmob_metrics (afm_p_dict_[sname]));
+  return dynamic_cast<Adobe_font_metric*> (unsmob_metrics (afm_p_dict_.get (sname)));
 }
 
 Scaled_font_metric * 
@@ -58,12 +57,11 @@ All_font_metrics::find_scaled (String nm, int m)
     {
       Font_metric *f = find_font (nm);
       s = new Scaled_font_metric (f, m);
-      scaled_p_dict_[sname] = s->self_scm_;
+      scaled_p_dict_.set (sname, s->self_scm_);
       fm =  s;
-      scm_unprotect_object (s->self_scm_);
     }
   else
-    fm = unsmob_metrics (scaled_p_dict_[sname]);
+    fm = unsmob_metrics (scaled_p_dict_.get (sname));
 
   return dynamic_cast<Scaled_font_metric*> (fm);
 }
@@ -83,12 +81,11 @@ All_font_metrics::find_tfm (String name)
       tfm_p->name_ = ly_symbol2scm (name.ch_C( ));
       progress_indication ("]");
 
-      tfm_p_dict_[sname] = tfm_p->self_scm_;
-      scm_unprotect_object (tfm_p->self_scm_);      
+      tfm_p_dict_.set (sname, tfm_p->self_scm_);
     }
     
   return
-    dynamic_cast<Tex_font_metric*> (unsmob_metrics (tfm_p_dict_[sname]));
+    dynamic_cast<Tex_font_metric*> (unsmob_metrics (tfm_p_dict_.get(sname)));
 }
 
 
index a0382d0446b918f0fd9ee16c2928e17ac4a9e394..3bc455f88a9c4ba8360467a993eec75438eecb1b 100644 (file)
 /**
    auto resizing hash table. This should come from GUILE.
  */
-class Scheme_hash_table : public Hash_table<SCM,SCM>
+class Scheme_hash_table : private Hash_table<SCM,SCM>
 {
-public:  
+public:
+  //  bool elem_b (SCM k) const;
+  Hash_table<SCM,SCM>::try_retrieve;
+  Hash_table<SCM,SCM>::elem_b;  
+  /**
+     WARNING: putting something in assumes responsibility for cleaning
+     up.  */
+  void set (SCM k, SCM v);
+  SCM get (SCM k);
+  
   Scheme_hash_table ();
   void operator = (Scheme_hash_table const &); 
   Scheme_hash_table (Scheme_hash_table const &);
index 233e2075d21c1f973c2a9e5f810794320ca47e98..2f60f9e14ce2f65295ed3210c2eedc141a736e2b 100644 (file)
@@ -81,7 +81,7 @@ Paper_def::get_realvar (SCM s) const
 Interval
 Paper_def::line_dimensions_int (int n) const
 {
-  SCM s = default_properties_ [ly_symbol2scm ("margin-shape")];
+  SCM s = default_properties_.get (ly_symbol2scm ("margin-shape"));
   if (!gh_pair_p (s))
     {
       Real lw =  get_var ("linewidth");
index 9e9a57d9b1575775a22e49fa8b0211ef1dfe6d8d..40a4b966fe2a1a605156cbc622485b8aaf966dac 100644 (file)
@@ -10,6 +10,7 @@
 #include <time.h>
 #include <fstream.h>
 #include <math.h>
+#include <iostream.h>
 
 #include "dimensions.hh"
 #include "dictionary-iter.hh"
@@ -132,6 +133,21 @@ Paper_outputter::output_scheme (SCM scm)
 }
 
 
+int
+count_cells (SCM s)
+{
+  if (Atom * a = unsmob_atom (s))
+    {
+      return 2 + count_cells (a->func_);
+    }
+  else if (gh_pair_p (s))
+    {
+      return 2 + count_cells (gh_car (s))+ count_cells (gh_cdr (s));
+    }
+  else
+    return 1;
+}
+
 void
 Paper_outputter::dump_onto (Paper_stream *ps)
 {
@@ -206,7 +222,10 @@ Paper_outputter::dump_onto (Paper_stream *ps)
          *ps << c;
          free (c);
        }
-    }
+      cout << "\nCells in use: " <<  scm_cells_allocated << endl;
+  cout <<    "protects "  << scm_ilength (scm_protects) << endl;
+
+  }
 }
 
 void
@@ -283,7 +302,7 @@ Paper_outputter::output_Real_def (String k, Real v)
                     SCM_UNDEFINED);
   output_scheme (scm);
 
-  gh_define (k.ch_l (), gh_double2scm (v));
+  //  gh_define (k.ch_l (), gh_double2scm (v));
 }
 
 void
@@ -296,7 +315,7 @@ Paper_outputter::output_String_def (String k, String v)
                     SCM_UNDEFINED);
   output_scheme (scm);
 
-  gh_define (k.ch_l (), ly_str02scm (v.ch_l ()));
+  // gh_define (k.ch_l (), ly_str02scm (v.ch_l ()));
 }
 
 void
@@ -308,7 +327,7 @@ Paper_outputter::output_int_def (String k, int v)
                     SCM_UNDEFINED);
   output_scheme (scm);
 
-  gh_define (k.ch_l (), gh_int2scm (v));
+  // gh_define (k.ch_l (), gh_int2scm (v));
 }
 
 
index 4d417416f15ca4226394d99bb8292a8e29dd23d4..ca0920fd42de2141a0c3edd6be15f970c9b61dee 100644 (file)
@@ -6,6 +6,7 @@
   (c) 1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
   
  */
+#include <stdio.h>
 
 #include "scm-hash.hh"
 #include "hash-table-iter.hh"
@@ -63,6 +64,9 @@ int
 Scheme_hash_table::print_smob (SCM s, SCM p, scm_print_state*)
 {
   assert (SMOB_IS_TYPE_B (Scheme_hash_table, s));
+  char str[1000];
+  sprintf (str, "#<Scheme_hash_table 0x%0ulx ", s);
+  scm_puts (str, p);      
   Scheme_hash_table *me = SMOB_TO_TYPE(Scheme_hash_table,s);
   for (Hash_table_iter<SCM,SCM> i (*me); i.ok(); i++)
     {
@@ -71,10 +75,23 @@ Scheme_hash_table::print_smob (SCM s, SCM p, scm_print_state*)
       scm_display (i.val (), p);
       scm_puts ("\n",p);            
     }
+  scm_puts ("> ",p);        
   return 1;
 }
 
 
+void
+Scheme_hash_table::set (SCM k, SCM v)
+{
+  elem (k ) = v; 
+  scm_unprotect_object (v);
+}
+
+SCM
+Scheme_hash_table::get (SCM k)
+{
+  return elem (k);
+}
 
 
 Scheme_hash_table::~Scheme_hash_table( )
index 42a7d083c25bce1e74ef6b378047ca9c13a0ae9e..5a46ce458ce35dd74b3f461f59a4921aea292987 100644 (file)
@@ -164,7 +164,11 @@ Score_element::molecule_extent(Dimension_cache const *c)
 {
   Score_element *s = dynamic_cast<Score_element*>(c->element_l());
   Molecule*m = s->do_brew_molecule_p();
-  return  m->extent()[c->axis ()];
+  
+  Interval iv =  m->extent()[c->axis ()];
+
+  delete m;
+  return iv;
 }
 
 
diff --git a/lily/score-element.cc.orig b/lily/score-element.cc.orig
new file mode 100644 (file)
index 0000000..42a7d08
--- /dev/null
@@ -0,0 +1,649 @@
+/*
+  score-elem.cc -- implement Score_element
+
+  source file of the GNU LilyPond music typesetter
+
+  (c)  1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+
+
+#include <string.h>
+
+#include "group-interface.hh"
+#include "misc.hh"
+#include "paper-score.hh"
+#include "paper-def.hh"
+#include "lookup.hh"
+#include "molecule.hh"
+#include "score-element.hh"
+#include "debug.hh"
+#include "spanner.hh"
+#include "line-of-score.hh"
+#include "item.hh"
+#include "paper-column.hh"
+#include "molecule.hh"
+#include "misc.hh"
+#include "paper-outputter.hh"
+#include "dimension-cache.hh"
+#include "side-position-interface.hh"
+#include "item.hh"
+
+Score_element::Score_element()
+{
+  output_p_ =0;
+  dim_cache_[X_AXIS] = new Dimension_cache;
+  dim_cache_[Y_AXIS] = new Dimension_cache;
+  dim_cache_[X_AXIS]->elt_l_ = dim_cache_[Y_AXIS]->elt_l_ = this;
+  
+  used_b_ = false;
+
+  dim_cache_[X_AXIS]->set_callback (molecule_extent);
+  dim_cache_[Y_AXIS]->set_callback (molecule_extent); 
+  used_b_ = false;
+  pscore_l_=0;
+  lookup_l_ =0;
+  status_i_ = 0;
+  self_scm_ = SCM_EOL;
+  original_l_ = 0;
+  element_property_alist_ = SCM_EOL;
+
+  smobify_self ();
+
+
+  set_elt_property ("dependencies", SCM_EOL);
+}
+
+SCM ly_deep_copy (SCM);
+
+SCM
+ly_deep_copy (SCM l)
+{
+  if (gh_pair_p (l))
+    {
+      return gh_cons (ly_deep_copy (gh_car (l)), ly_deep_copy (gh_cdr (l)));
+    }
+  else
+    return l;
+}
+
+
+Score_element::Score_element (Score_element const&s)
+{
+  dim_cache_[X_AXIS] = new Dimension_cache (*s.dim_cache_[X_AXIS]);
+  dim_cache_[Y_AXIS] = new Dimension_cache (*s.dim_cache_[Y_AXIS]);
+  dim_cache_[X_AXIS]->elt_l_ = dim_cache_[Y_AXIS]->elt_l_ = this;
+  
+  self_scm_ = SCM_EOL;
+  used_b_ = true;
+  original_l_ =(Score_element*) &s;
+
+  /*
+    should protect because smobify_self () might trigger GC.
+   */
+  SCM onstack = ly_deep_copy (s.element_property_alist_);
+  element_property_alist_ = onstack;
+
+  output_p_ =0;
+  status_i_ = s.status_i_;
+  lookup_l_ = s.lookup_l_;
+  pscore_l_ = s.pscore_l_;
+
+  smobify_self ();
+}
+
+Score_element::~Score_element()
+{
+  assert (!output_p_);
+  assert (status_i_ >=0);
+  status_i_  = -1;
+
+  delete dim_cache_[X_AXIS];
+  delete dim_cache_[Y_AXIS];  
+}
+
+
+Real
+Score_element::get_real (String s) const
+{
+  return gh_scm2double (get_elt_property (s));
+}
+
+void
+Score_element::set_real (String s, Real r)
+{
+  set_elt_property (s, gh_double2scm (r));
+}
+
+// should also have one that takes SCM arg. 
+SCM
+Score_element::get_elt_property (String nm) const
+{
+  SCM sym =  ly_symbol2scm (nm.ch_C());
+  SCM s = scm_assq(sym, element_property_alist_);
+
+  if (s != SCM_BOOL_F)
+    return gh_cdr (s); 
+  
+  if (pscore_l_)
+    {
+      SCM sym2 = ly_symbol2scm ((name () + ("::" + nm)).ch_C());
+      SCM val;
+      
+      // should probably check for Type::sym as well.
+      Paper_def * p= pscore_l_->paper_l_;
+      if (p->default_properties_.try_retrieve (sym2, &val))
+       return val;
+      else if (p->default_properties_.try_retrieve (sym, &val))
+       return val;
+    }
+  
+  return SCM_UNDEFINED;
+}
+
+SCM
+Score_element::remove_elt_property (String key)
+{
+  SCM s = get_elt_property (key); 
+  SCM sym = ly_symbol2scm (key.ch_C());
+  element_property_alist_ =  scm_assq_remove_x (element_property_alist_, sym);
+  return s;
+}
+
+/*
+  UGH. assoc vs. assq
+ */
+void
+Score_element::set_elt_property (String k, SCM v)
+{
+  SCM s = ly_symbol2scm (k.ch_C( ));
+  element_property_alist_ = scm_assoc_set_x (element_property_alist_, s, v);
+}
+
+Interval
+Score_element::molecule_extent(Dimension_cache const *c)
+{
+  Score_element *s = dynamic_cast<Score_element*>(c->element_l());
+  Molecule*m = s->do_brew_molecule_p();
+  return  m->extent()[c->axis ()];
+}
+
+
+void
+Score_element::print() const
+{
+#ifndef NPRINT
+  DEBUG_OUT << classname(this) << "{\n";
+    
+  if (flower_dstream && !flower_dstream->silent_b ("Score_element"))
+    ly_display_scm (element_property_alist_);
+
+  if (original_l_)
+    DEBUG_OUT << "Copy ";
+  do_print();
+  
+  DEBUG_OUT <<  "}\n";
+#endif
+}
+
+Paper_def*
+Score_element::paper_l ()  const
+{
+ return pscore_l_ ? pscore_l_->paper_l_ : 0;
+}
+
+Lookup const *
+Score_element::lookup_l () const
+{
+  if (!lookup_l_)
+    {
+      Score_element * urg = (Score_element*)this;
+      SCM sz = urg->remove_elt_property ("fontsize");
+      int i = (gh_number_p (sz))
+       ? gh_scm2int  (sz)
+       : 0;
+
+      urg->lookup_l_ =  (Lookup*)pscore_l_->paper_l_->lookup_l (i);
+    }
+  return lookup_l_;
+}
+
+void
+Score_element::add_processing()
+{
+  assert (status_i_ >=0);
+  if (status_i_)
+    return;
+  status_i_ ++;
+
+#if 0
+    /*
+    UGH. UGH. UGH.
+   */
+  if (get_elt_property ("self-alignment-X") != SCM_UNDEFINED
+      && !dim_cache_[X_AXIS]->off_callback_l_)
+    {
+      dim_cache_[X_AXIS]->off_callbacks_.push (Side_position_interface::aligned_on_self);
+    }
+  
+  if (get_elt_property ("self-alignment-Y") != SCM_UNDEFINED
+      && !dim_cache_[X_AXIS]->off_callback_l_)
+      
+    {
+      dim_cache_[Y_AXIS]->set_offset_callback (Side_position_interface::aligned_on_self);
+    }
+#endif
+  
+  do_add_processing();
+}
+
+void
+Score_element::calculate_dependencies (int final, int busy,
+                                      Score_element_method_pointer funcptr)
+{
+  assert (status_i_ >=0);
+
+  if (status_i_ >= final)
+    return;
+
+  assert (status_i_!= busy);
+  status_i_= busy;
+
+  Link_array<Score_element> dependency_arr =
+    Group_interface__extract_elements (this, (Score_element*)0, "dependencies");
+  
+  for (int i=0; i < dependency_arr.size(); i++)
+    dependency_arr[i]->calculate_dependencies (final, busy, funcptr);
+
+  Link_array<Score_element> extra (get_extra_dependencies());
+  for (int i=0; i < extra.size(); i++)
+    extra[i]->calculate_dependencies (final, busy, funcptr);
+  
+  (this->*funcptr)();
+  status_i_= final;
+}
+
+void
+Score_element::output_processing () 
+{
+  if (to_boolean  (get_elt_property ("transparent")))
+    return;
+
+  // we're being silly here. 
+  if (output_p_)
+    delete output_p_;
+  
+  output_p_ = do_brew_molecule_p ();
+  Offset o (relative_coordinate (0, X_AXIS), relative_coordinate (0, Y_AXIS));
+
+  SCM s = get_elt_property ("extra-offset");
+  if (gh_pair_p (s))
+    {
+      Real il = paper_l ()->get_var ("interline");
+      o[X_AXIS] += il * gh_scm2double (gh_car (s));
+      o[Y_AXIS] += il * gh_scm2double (gh_cdr (s));      
+    }
+  
+  pscore_l_->outputter_l_->output_molecule (output_p_,
+                                           o,
+                                           classname(this));
+
+  delete output_p_;
+  output_p_ =0;
+}
+
+/*
+  
+  VIRTUAL STUBS
+
+ */
+void
+Score_element::do_break_processing()
+{
+}
+
+void
+Score_element::do_post_processing()
+{
+}
+
+void
+Score_element::do_breakable_col_processing()
+{
+  handle_prebroken_dependencies();
+}
+
+void
+Score_element::do_pre_processing()
+{
+}
+
+void
+Score_element::do_space_processing ()
+{
+}
+
+void
+Score_element::do_add_processing()
+{
+}
+
+
+
+Molecule*
+Score_element::do_brew_molecule_p() const
+{
+  SCM glyph = get_elt_property ("glyph");
+  if (gh_string_p (glyph))
+    {
+      Molecule*output = new Molecule (lookup_l ()->afm_find (String (ly_scm2string (glyph))));
+      
+      return output;
+    }
+  else
+    {
+      Interval emp;
+      emp.set_empty ();
+      Molecule a (lookup_l ()->fill (Box (emp,emp)));
+      return new Molecule (a);
+    }
+}
+
+
+Line_of_score *
+Score_element::line_l() const
+{
+  return 0;
+}
+
+void
+Score_element::add_dependency (Score_element*e)
+{
+  if (e)
+    {
+      Group_interface gi (this, "dependencies");
+      gi.add_element (e);
+    }
+  else
+    programming_error ("Null dependency added");
+}
+
+
+
+
+/**
+      Do break substitution in S, using CRITERION. Return new value.
+         CRITERION is either a SMOB pointer to the desired line, or a number
+        representing the break direction.  */
+SCM
+Score_element::handle_broken_smobs (SCM s, SCM criterion)
+{
+ again:
+
+  
+  Score_element *sc = unsmob_element ( s);
+  if (sc)
+    {
+      if (criterion == SCM_UNDEFINED)
+       return SCM_UNDEFINED;
+      else if (gh_number_p (criterion))
+       {
+         Item * i = dynamic_cast<Item*> (sc);
+         Direction d = to_dir (criterion);
+         if (i && i->break_status_dir () != d)
+           {
+             Item *br = i->find_broken_piece (d);
+             return  (br) ? br->self_scm_ : SCM_UNDEFINED;
+           }
+       }
+      else
+       {
+         Score_element * ln = unsmob_element ( criterion);
+         Line_of_score * line = dynamic_cast<Line_of_score*> (ln);
+         Score_element * br =0;
+         Line_of_score * dep_line = sc->line_l ();
+         if (dep_line != line)
+           {
+             br = sc->find_broken_piece (line);
+             return  (br) ?  br->self_scm_ : SCM_UNDEFINED;
+           }
+         if (!dep_line)
+           return SCM_UNDEFINED;
+       }
+    }
+  else if (gh_pair_p (s))
+    {
+      /*
+       UGH! breaks on circular lists.
+      */
+      SCM car = handle_broken_smobs (gh_car (s), criterion);
+      SCM cdr = gh_cdr (s);
+      
+      if (car == SCM_UNDEFINED
+         && (gh_pair_p (cdr) || cdr == SCM_EOL))
+       {
+         /*
+           This is tail-recursion, ie. 
+           
+           return handle_broken_smobs (cdr, criterion);
+
+           We don't want to rely on the compiler to do this.  */
+         s =  cdr;     
+         goto again;
+       }
+
+      gh_set_car_x (s, car);
+      gh_set_cdr_x (s, handle_broken_smobs (cdr, criterion));
+      return s;
+    }
+  return s;
+}
+
+void
+Score_element::handle_broken_dependencies()
+{
+  Line_of_score *line  = line_l();
+  element_property_alist_ = handle_broken_smobs (element_property_alist_,
+                                                line ? line->self_scm_ : SCM_UNDEFINED);
+
+  if (!line)
+    return;
+}
+
+
+/*
+  TODO: cleanify.
+ */
+void
+Score_element::handle_prebroken_dependencies()
+{
+  if (Item*i =dynamic_cast<Item*> (this))
+    {
+      element_property_alist_
+       = handle_broken_smobs (element_property_alist_,
+                              gh_int2scm (i->break_status_dir ()));
+    }
+}
+
+
+
+
+
+Link_array<Score_element>
+Score_element::get_extra_dependencies() const
+{
+  Link_array<Score_element> empty;
+  return empty;
+}
+
+bool
+Score_element::linked_b() const
+{
+  return used_b_;
+}
+
+void
+Score_element::do_print () const
+{
+}
+
+Score_element*
+Score_element::find_broken_piece (Line_of_score*) const
+{
+  return 0;
+}
+
+
+
+void
+Score_element::translate_axis (Real y, Axis a)
+{
+  dim_cache_[a]->translate (y);
+}  
+
+Real
+Score_element::relative_coordinate (Score_element const*e, Axis a) const
+{
+  return dim_cache_[a]->relative_coordinate (e ? e->dim_cache_[a] : 0);
+}
+
+Score_element * 
+Score_element::common_refpoint (Score_element const* s, Axis a) const
+{
+  Dimension_cache *dim = dim_cache_[a]->common_refpoint (s->dim_cache_[a]);
+  return  dim ? dim->element_l () : 0;
+}
+
+void
+Score_element::set_empty (Axis a)
+{
+  dim_cache_[a]->callback_l_ =0;
+}
+
+bool
+Score_element::empty_b (Axis a)const
+{
+  return !dim_cache_[a]->callback_l_;
+}
+
+Interval
+Score_element::extent (Axis a) const
+{
+  Dimension_cache const * d = dim_cache_[a];
+
+  return d->get_dim ();
+}
+
+
+Score_element*
+Score_element::parent_l (Axis a) const
+{
+  Dimension_cache*d= dim_cache_[a]->parent_l_;
+  return d ? d->elt_l_ : 0;
+}
+
+Score_element *
+Score_element::common_refpoint (Link_array<Score_element> gs, Axis a) const
+{
+  Dimension_cache * common = dim_cache_[a];
+  for (int i=0; i < gs.size (); i++)
+    {
+      common = common->common_refpoint (gs[i]->dim_cache_[a]);
+    }
+
+  return common->element_l ();
+}
+
+char const *
+Score_element::name () const
+{
+  return classname (this);
+}
+
+
+void
+Score_element::set_parent (Score_element *g, Axis a)
+{
+  dim_cache_[a]->parent_l_ = g ? g->dim_cache_[a]: 0;
+}
+
+void
+Score_element::fixup_refpoint ()
+{
+  for (int a = X_AXIS; a < NO_AXES; a ++)
+    {
+      Axis ax = (Axis)a;
+      Score_element * par = parent_l (ax);
+
+      if (!par)
+       continue;
+      
+      if (par->line_l () != line_l ())
+       {
+         Score_element * newpar = par->find_broken_piece (line_l ());
+         set_parent (newpar, ax);
+       }
+
+      if (Item * i  = dynamic_cast<Item*> (this))
+       {
+         Item *pari = dynamic_cast<Item*> (par);
+
+         if (pari && i)
+           {
+             Direction  my_dir = i->break_status_dir () ;
+             if (my_dir!= pari->break_status_dir())
+               {
+                 Item *newpar =  pari->find_broken_piece (my_dir);
+                 set_parent (newpar, ax);
+               }
+           }
+       }
+    }
+}
+
+
+
+/****************************************************
+  SMOB funcs
+ ****************************************************/
+
+
+#include "ly-smobs.icc"
+
+IMPLEMENT_SMOBS(Score_element);
+IMPLEMENT_UNSMOB(Score_element, element);
+SCM
+Score_element::mark_smob (SCM ses)
+{
+  Score_element * s = SMOB_TO_TYPE (Score_element, ses);
+  if (s->self_scm_ != ses)
+    {
+      programming_error ("SMOB marking gone awry");
+      return SCM_EOL;
+    }
+  return s->element_property_alist_;
+}
+
+int
+Score_element::print_smob (SCM s, SCM port, scm_print_state *)
+{
+  Score_element *sc = (Score_element *) gh_cdr (s);
+     
+  scm_puts ("#<Score_element ", port);
+  scm_puts ((char *)sc->name (), port);
+
+  // scm_puts (" properties = ", port);
+  // scm_display (sc->element_property_alist_, port);
+  scm_puts (" >", port);
+  return 1;
+}
+
+void
+Score_element::do_smobify_self ()
+{
+}
+
+SCM
+Score_element::equal_p (SCM a, SCM b)
+{
+  return gh_cdr(a) == gh_cdr(b) ? SCM_BOOL_T : SCM_BOOL_F;
+}
index 812e94ff8f9e3c2457588139ded705bafe788614..8b9c53e05f5026892150d16c58e482a3a6906e3b 100644 (file)
@@ -171,28 +171,29 @@ void
 Score_engraver::set_columns (Paper_column *new_command_l, 
                             Paper_column *new_musical_l)
 {
-  if (command_column_l_ && command_column_l_->linked_b()) 
-    {
-      pscore_p_->add_column (command_column_l_);
-      scoreline_l_->add_column (command_column_l_);
-    }
-  else 
-    command_column_l_ =0;
-
-  if (new_command_l) 
-    command_column_l_ = new_command_l;
+  Paper_column * news[] = {new_command_l, new_musical_l};
+  Paper_column **current[] = {&command_column_l_, &musical_column_l_};
 
-  if (musical_column_l_ && musical_column_l_->linked_b()) 
-    {
-      pscore_p_->add_column (musical_column_l_);
-      scoreline_l_->add_column (musical_column_l_);      
-    }
-  else 
-    musical_column_l_ = 0;
-  
-  if (new_musical_l) 
+  for (int i=00; i< 2; i++) 
     {
-      musical_column_l_ = new_musical_l;
+      if (*current[i] && (*current[i])->linked_b()) 
+       {
+         pscore_p_->add_column ((*current[i]));
+         scoreline_l_->add_column ((*current[i]));
+       }
+      else
+       {
+         *current[i]  =0;
+         
+         /*
+           We're forgetting about this column. Dump it, and make SCM
+           forget it.
+
+           (UGH.)  */
+         scm_unprotect_object ((*current[i])->self_scm_);
+       }
+      if (news[i])
+       *current[i] = news[i];
     }
 }
 
index 3eda39de7005a371e4a37056c4f2b642c0afba1a..af396f13afe9aafaf6110a8bbbbf6940161724e8 100644 (file)
@@ -6,6 +6,8 @@
   (c)  1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
 */
 
+#include <iostream.h>
+
 #include "score.hh"
 #include "debug.hh"
 #include "music-output-def.hh"
@@ -22,7 +24,7 @@
 
 
 Score::Score()
-    : Input()
+  : Input()
 {
   header_p_ = 0;
   music_p_ = 0;
@@ -50,6 +52,11 @@ void
 Score::run_translator (Music_output_def *odef_l)
 {
   Cpu_timer timer;
+  scm_gc();
+  cout << "\nCells in use: " <<  scm_cells_allocated << endl;
+  cout <<    "protects: " << scm_ilength (scm_protects) << endl;
+
+  
   Global_translator * trans_p = odef_l->get_global_translator_p();
   if (!trans_p)
     {
@@ -94,6 +101,12 @@ Score::run_translator (Music_output_def *odef_l)
   progress_indication ("\n");
   output->process();
   delete output ;
+
+  // force GC
+  scm_gc();
+  cout << "\nCells in use: " <<  scm_cells_allocated <<endl;
+  cout <<    "protects " << scm_ilength (scm_protects) << endl;
+
 }
 
 void
index 5331074f1f2078d12a9d42499fdb7e509ff64905..f80b2c49de598672e9b21968e9fc269d0c48bde8 100644 (file)
@@ -436,7 +436,7 @@ Translator_group::get_property (SCM sym, Translator_group **where_l) const
     {
       if (where_l)
        *where_l = (Translator_group*) this; // ugh
-      return properties_dict_[sym];
+      return properties_dict_.get (sym);
     }
 
   if (daddy_trans_l_)
@@ -451,5 +451,5 @@ Translator_group::get_property (SCM sym, Translator_group **where_l) const
 void
 Translator_group::set_property (String id, SCM val)
 {
-  properties_dict_[ly_symbol2scm (id.ch_C())] = val;
+  properties_dict_.set (ly_symbol2scm (id.ch_C()), val);
 }