From: David Kastrup <dak@gnu.org>
Date: Sat, 11 Jan 2014 13:08:55 +0000 (+0100)
Subject: Issue 3797: Music_wrapper_iterator does not follow original context setting of child
X-Git-Tag: release/2.18.1-1~5
X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=536cad5ac3c8518d6ab738e04aad9aee9804e691;p=lilypond.git

Issue 3797: Music_wrapper_iterator does not follow original context setting of child

We do this by making Music_iterator::get_handle and
Music_iterator::set_context virtual and letting Music_wrapper_iterator
redirect them to the child iterator.

\score {
  <<
    { { a4 a b b } a a b b }
    { \absolute { a4 a b b } a a b b }
  >>
}

splits off a new Staff after \absolute { a4 a b b }.
---

diff --git a/lily/include/music-iterator.hh b/lily/include/music-iterator.hh
index a34e300903..3fcfa8d58c 100644
--- a/lily/include/music-iterator.hh
+++ b/lily/include/music-iterator.hh
@@ -73,8 +73,8 @@ public:
   Moment music_start_mom () const;
   Music_iterator ();
   void report_event (Music *);
-  Context *get_outlet () const;
-  void set_context (Context *);
+  virtual Context *get_outlet () const;
+  virtual void set_context (Context *);
   static SCM get_static_get_iterator (Music *mus);
   void init_context (Music *, Context *);
   void quit ();
diff --git a/lily/include/music-wrapper-iterator.hh b/lily/include/music-wrapper-iterator.hh
index a306226724..8553b3958a 100644
--- a/lily/include/music-wrapper-iterator.hh
+++ b/lily/include/music-wrapper-iterator.hh
@@ -34,6 +34,8 @@ public:
   Music_wrapper_iterator ();
   DECLARE_CLASSNAME (Music_wrapper_iterator);
 
+  virtual Context *get_outlet () const;
+  virtual void set_context (Context *trans);
   virtual void derived_substitute (Context *f, Context *t);
   virtual void derived_mark () const;
   virtual void construct_children ();
diff --git a/lily/music-iterator.cc b/lily/music-iterator.cc
index c076b7ad65..6ba70eb63d 100644
--- a/lily/music-iterator.cc
+++ b/lily/music-iterator.cc
@@ -207,8 +207,11 @@ Music_iterator::mark_smob (SCM smob)
     Careful with GC, although we intend the following as pointers
     only, we _must_ mark them.
   */
-  if (mus->get_outlet ())
-    scm_gc_mark (mus->get_outlet ()->self_scm ());
+  /* Use handle_ directly as get_outlet is a virtual function and we
+     need to protect the context until Music_iterator::quit is being
+     run. */
+  if (mus->handle_.get_context ())
+    scm_gc_mark (mus->handle_.get_context ()->self_scm ());
   if (mus->music_)
     scm_gc_mark (mus->music_->self_scm ());
 
diff --git a/lily/music-wrapper-iterator.cc b/lily/music-wrapper-iterator.cc
index e208d135f5..8f201a65c1 100644
--- a/lily/music-wrapper-iterator.cc
+++ b/lily/music-wrapper-iterator.cc
@@ -79,6 +79,22 @@ Music_wrapper_iterator::pending_moment () const
     return Music_iterator::pending_moment ();
 }
 
+Context *
+Music_wrapper_iterator::get_outlet () const
+{
+  if (child_iter_)
+    return child_iter_->get_outlet ();
+  return Music_iterator::get_outlet ();
+}
+
+void
+Music_wrapper_iterator::set_context (Context *trans)
+{
+  if (child_iter_)
+    child_iter_->set_context (trans);
+  Music_iterator::set_context (trans);
+}
+
 IMPLEMENT_CTOR_CALLBACK (Music_wrapper_iterator);
 
 bool