On 26 Jun 2002, Laura Conrad wrote:

> The attached file runs fine, until I introduce the paper block from
> ambitus.ly, whereupon lilypond segfaults.

Shoould be fixed with the attached patch.


On 30 Jun 2002, Han-Wen wrote:

> I have a nitpick:
> ...
> for every note head, a new pitch smob is put into
> pitch-{min,max}. That is wasteful. It is more efficient to postpone
> writing ambitus_p_->set_grob_property() to
> Ambitus_engraver::finalize(). This creates less garbage

Done.

Greetings,
Juergen
diff -Naur lilypond-1.5.64/ChangeLog lilypond-1.5.64.NEW/ChangeLog
--- lilypond-1.5.64/ChangeLog   Mon Jul  1 12:25:22 2002
+++ lilypond-1.5.64.NEW/ChangeLog       Tue Jul  2 00:41:39 2002
@@ -1,3 +1,10 @@
+2002-07-02  Juergen Reuter  <[EMAIL PROTECTED]>
+
+       * lily/ambitus-engraver.cc, lily/ambitus.cc: Various bugfixes:
+       avoid segfault on undefined ambitus pitch; avoid wasteful creation
+       of pitch smobs; defer computation of centralCPosition beyond first
+       timestep to catch also clefs outside of the current voice context.
+
 2002-07-01  Han-Wen Nienhuys  <[EMAIL PROTECTED]>
 
        * VERSION (MAJOR_VERSION): 1.5.64
diff -Naur lilypond-1.5.64/lily/ambitus-engraver.cc 
lilypond-1.5.64.NEW/lily/ambitus-engraver.cc
--- lilypond-1.5.64/lily/ambitus-engraver.cc    Wed Jun 26 13:15:21 2002
+++ lilypond-1.5.64.NEW/lily/ambitus-engraver.cc        Tue Jul  2 00:48:33 2002
@@ -64,10 +64,9 @@
 {
 public:
 TRANSLATOR_DECLARATIONS(Ambitus_engraver);
-  virtual void start_translation_timestep ();
   virtual void acknowledge_grob (Grob_info);
-  virtual void create_grobs ();
   virtual void stop_translation_timestep ();
+  virtual void finalize ();
 
 private:
   void create_ambitus ();
@@ -90,6 +89,14 @@
 Ambitus_engraver::stop_translation_timestep ()
 {
   if (!ambitus_p_) {
+    // Create ambitus not before stopping timestep.  centralCPosition
+    // will then be the same as that for the first timestep.
+    //
+    // TODO: is this really a good idea?  At least, creating the
+    // ambitus in start_translation_timestep is a *bad* idea, since we
+    // may then oversee a clef that is defined in a staff context if
+    // we are in a voice context; centralCPosition would then be
+    // assumed to be 0.
     create_ambitus ();
   }
   if (ambitus_p_ && isActive)
@@ -97,28 +104,11 @@
       SCM key_signature = get_property ("keySignature");
       ambitus_p_->set_grob_property ("keySignature", key_signature);
       typeset_grob (ambitus_p_);
-      //ambitus_p_ = 0;
       isActive = 0;
     }
 }
 
 void
-Ambitus_engraver::start_translation_timestep ()
-{
-  if (!ambitus_p_) {
-    create_ambitus ();
-  }
-}
-
-void
-Ambitus_engraver::create_grobs ()
-{
-  if (!ambitus_p_) {
-    create_ambitus ();
-  }
-}
-
-void
 Ambitus_engraver::acknowledge_grob (Grob_info info)
 {
   if (!ambitus_p_) {
@@ -140,22 +130,14 @@
                  // not yet init'd; use current pitch to init min/max
                  pitch_min = pitch;
                  pitch_max = pitch;
-                 ambitus_p_->set_grob_property ("pitch-min",
-                                                pitch_min.smobbed_copy ());
-                 ambitus_p_->set_grob_property ("pitch-max",
-                                                pitch_max.smobbed_copy ());
                }
              else if (Pitch::compare (pitch, pitch_max) > 0) // new max?
                {
                  pitch_max = pitch;
-                 ambitus_p_->set_grob_property ("pitch-max",
-                                                pitch_max.smobbed_copy ());
                }
              else if (Pitch::compare (pitch, pitch_min) < 0) // new min?
                {
                  pitch_min = pitch;
-                 ambitus_p_->set_grob_property ("pitch-min",
-                                                pitch_min.smobbed_copy ());
                }
            }
        }
@@ -170,6 +152,31 @@
   ambitus_p_ = new Item (basicProperties); isActive = 1;
   ambitus_p_->set_grob_property ("centralCPosition", c0);
   announce_grob (ambitus_p_, SCM_EOL);
+}
+
+void
+Ambitus_engraver::finalize ()
+{
+  if (ambitus_p_)
+    {
+      if (Pitch::compare (pitch_min, pitch_max) <= 0)
+       {
+         ambitus_p_->set_grob_property ("pitch-min",
+                                        pitch_min.smobbed_copy ());
+         ambitus_p_->set_grob_property ("pitch-max",
+                                        pitch_max.smobbed_copy ());
+       }
+      else // have not seen any pitch, so forget about the ambitus
+       {
+         // Do not print a warning on empty ambitus range, since this
+         // most probably arises from an empty voice, such as shared
+         // global timesig/clef definitions.
+#if 0
+         ambitus_p_->warning("empty ambitus range [ignored]");
+#endif
+         ambitus_p_->suicide();
+       }
+    }
 }
 
 ENTER_DESCRIPTION(Ambitus_engraver,
diff -Naur lilypond-1.5.64/lily/ambitus.cc lilypond-1.5.64.NEW/lily/ambitus.cc
--- lilypond-1.5.64/lily/ambitus.cc     Wed Jun 26 13:15:21 2002
+++ lilypond-1.5.64.NEW/lily/ambitus.cc Mon Jul  1 23:31:52 2002
@@ -146,15 +146,30 @@
       return SCM_EOL;
     }
 
+  int p_min, p_max;
   Pitch *pitch_min = unsmob_pitch (me->get_grob_property ("pitch-min"));
-  int p_min = pitch_min->steps ();
+  if (!pitch_min)
+    {
+      me->programming_error("Ambitus: pitch_min undefined; assuming 0");
+      p_min = 0;
+    }
+  else
+    {
+      p_min = pitch_min->steps ();
+    }
   Pitch *pitch_max = unsmob_pitch (me->get_grob_property ("pitch-max"));
-  int p_max = pitch_max->steps ();
+  if (!pitch_max)
+    {
+      me->programming_error("Ambitus: pitch_max undefined; assuming 0");
+      p_max = 0;
+    }
+  else
+    {
+      p_max = pitch_max->steps ();
+    }
   if (p_min > p_max)
     {
-      String message = "Ambitus: no range to output";
-      me->warning (_ (message.ch_C ()));
-      return SCM_EOL;
+      me->programming_error ("Ambitus: reverse range");
     }
 
   SCM c0 = me->get_grob_property ("centralCPosition");

Reply via email to