Understanding the LilyPond source often boils down to figuring out what is happening to the Grobs. Where (and why) are they being created, modified and destroyed? I've spent many hours tracing Lily through a debugger and it is mind-blowingly tedious.
So I quickly hacked a few things together and came up with something a bit better. I added hooks into internal_grob_set_property and make_grob_from_properties. You can register a scheme callback which will get called whenever a Grob is modified or created. The scheme callback will receive the file and line numbers in the C++ source where the call was made. This can help you to trace cause and effect through the C++ source. This is very hackish right now (I only started this morning), but I thought I'd share a quick application. The file test.ly produces a graphviz output file, "graph.dot", that lets you visualise the changes in Grobs throughout LilyPond execution. For now, you'll need to add a closing brace to the end of graph.dot. I attach a patch, an example input file and a sample output.
diff --git a/lily/accidental-engraver.cc b/lily/accidental-engraver.cc index 39a66ba..20f0103 100644 --- a/lily/accidental-engraver.cc +++ b/lily/accidental-engraver.cc @@ -402,7 +402,7 @@ Accidental_engraver::make_standard_accid = make_grob_from_properties (trans, ly_symbol2scm ("Accidental"), note_head->self_scm (), - "Accidental"); + "Accidental", __FILE__, __LINE__); /* We add the accidentals to the support of the arpeggio, @@ -442,7 +442,7 @@ Accidental_engraver::make_suggested_acci = make_grob_from_properties (trans, ly_symbol2scm ("AccidentalSuggestion"), note_head->self_scm (), - "AccidentalSuggestion"); + "AccidentalSuggestion", __FILE__, __LINE__); Side_position_interface::add_support (a, note_head); if (Grob *stem = unsmob_grob (a->get_object ("stem"))) diff --git a/lily/align-interface.cc b/lily/align-interface.cc index afe4702..b2160d0 100644 --- a/lily/align-interface.cc +++ b/lily/align-interface.cc @@ -323,7 +323,7 @@ Align_interface::add_element (Grob *me, SCM sym = axis_offset_symbol (a); SCM proc = axis_parent_positioning (a); - element->internal_set_property (sym, proc); + element->internal_set_property (sym, proc, __FILE__, __LINE__); Axis_group_interface::add_element (me, element); } diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index 1d509f0..2727751 100644 --- a/lily/axis-group-interface.cc +++ b/lily/axis-group-interface.cc @@ -37,7 +37,7 @@ Axis_group_interface::add_element (Grob e->internal_set_object ((a == X_AXIS) ? ly_symbol2scm ("axis-group-parent-X") : ly_symbol2scm ("axis-group-parent-Y"), - me->self_scm ()); + me->self_scm (), __FILE__, __LINE__); } /* must be ordered, because Align_interface also uses diff --git a/lily/break-align-engraver.cc b/lily/break-align-engraver.cc index e6a7935..7b4f4b7 100644 --- a/lily/break-align-engraver.cc +++ b/lily/break-align-engraver.cc @@ -85,7 +85,7 @@ Break_align_engraver::acknowledge_break_ left_edge_ = make_item_from_properties (random_source, ly_symbol2scm ("LeftEdge"), SCM_EOL, - "LeftEdge"); + "LeftEdge", __FILE__, __LINE__); add_to_group (left_edge_->get_property ("break-align-symbol"), left_edge_); } diff --git a/lily/break-substitution.cc b/lily/break-substitution.cc index 0c1e996..8d65f6b 100644 --- a/lily/break-substitution.cc +++ b/lily/break-substitution.cc @@ -397,7 +397,7 @@ Spanner::fast_substitute_grob_array (SCM if (!unsmob_grob_array (newval)) { newval = Grob_array::make_array (); - sc->internal_set_object (sym, newval); + sc->internal_set_object (sym, newval, __FILE__, __LINE__); } Grob_array *new_array = unsmob_grob_array (newval); @@ -500,14 +500,14 @@ Spanner::substitute_one_mutable_property if (!unsmob_grob_array (newval)) { newval = Grob_array::make_array (); - sc->internal_set_object (sym, newval); + sc->internal_set_object (sym, newval, __FILE__, __LINE__); } substitute_grob_array (grob_array, unsmob_grob_array (newval)); } else { SCM newval = do_break_substitution (val); - sc->internal_set_object (sym, newval); + sc->internal_set_object (sym, newval, __FILE__, __LINE__); } } } diff --git a/lily/context-property.cc b/lily/context-property.cc index 502fc92..0f77cfd 100644 --- a/lily/context-property.cc +++ b/lily/context-property.cc @@ -118,7 +118,7 @@ execute_general_pushpop_property (Contex { SCM base = updated_grob_properties (context, context_property); current_context_val = scm_cons (base, base); - context->internal_set_property (context_property, current_context_val); + context->internal_set_property (context_property, current_context_val, __FILE__, __LINE__); } if (!scm_is_pair (current_context_val)) @@ -180,7 +180,7 @@ execute_general_pushpop_property (Contex if (new_alist == daddy) context->unset_property (context_property); else - context->internal_set_property (context_property, scm_cons (new_alist, daddy)); + context->internal_set_property (context_property, scm_cons (new_alist, daddy), __FILE__, __LINE__); } } @@ -224,7 +224,7 @@ apply_property_operations (Context *tg, execute_general_pushpop_property (tg, context_prop, grob_prop_path, val); } else if (type == ly_symbol2scm ("assign")) - tg->internal_set_property (scm_car (entry), scm_cadr (entry)); + tg->internal_set_property (scm_car (entry), scm_cadr (entry), __FILE__, __LINE__); } } @@ -275,8 +275,23 @@ updated_grob_properties (Context *tg, SC } } +static SCM creation_callback = SCM_EOL; +LY_DEFINE (ly_set_grob_creation_callback, "ly:set-grob-creation-callback", + 1, 0, 0, (SCM cb), + "Specify a procedure that will be called every time a new grob " + "is created. The callback will receive as arguments the grob " + "that was created, the name of the C++ source file that caused " + "the grob to be created and the corresponding line number in the " + "C++ source file.") +{ + if (!ly_is_procedure (cb)) + warning (_ ("not setting creation callback: not a procedure")); + else + creation_callback = cb; +} + Grob * -make_grob_from_properties (Engraver *tr, SCM symbol, SCM cause, char const *name) +make_grob_from_properties (Engraver *tr, SCM symbol, SCM cause, char const *name, char const *file, int line) { Context *context = tr->context (); @@ -298,27 +313,31 @@ make_grob_from_properties (Engraver *tr, assert (grob); dynamic_cast<Engraver *> (tr)->announce_grob (grob, cause); + if (ly_is_procedure (creation_callback)) + scm_apply_0 (creation_callback, + scm_list_n (grob->self_scm (), scm_makfrom0str (file), scm_from_int (line), SCM_UNDEFINED)); + return grob; } Item * -make_item_from_properties (Engraver *tr, SCM x, SCM cause, char const *name) +make_item_from_properties (Engraver *tr, SCM x, SCM cause, char const *name, char const *file, int line) { - Item *it = dynamic_cast<Item *> (make_grob_from_properties (tr, x, cause, name)); + Item *it = dynamic_cast<Item *> (make_grob_from_properties (tr, x, cause, name, file, line)); assert (it); return it; } Paper_column * -make_paper_column_from_properties (Engraver *tr, SCM x, char const *name) +make_paper_column_from_properties (Engraver *tr, SCM x, char const *name, char const *file, int line) { - return dynamic_cast<Paper_column *> (make_grob_from_properties (tr, x, SCM_EOL, name)); + return dynamic_cast<Paper_column *> (make_grob_from_properties (tr, x, SCM_EOL, name, file, line)); } Spanner * -make_spanner_from_properties (Engraver *tr, SCM x, SCM cause, char const *name) +make_spanner_from_properties (Engraver *tr, SCM x, SCM cause, char const *name, char const *file, int line) { - Spanner *sp = dynamic_cast<Spanner *> (make_grob_from_properties (tr, x, cause, name)); + Spanner *sp = dynamic_cast<Spanner *> (make_grob_from_properties (tr, x, cause, name, file, line)); assert (sp); return sp; } diff --git a/lily/context-scheme.cc b/lily/context-scheme.cc index 92240a9..1a28a1e 100644 --- a/lily/context-scheme.cc +++ b/lily/context-scheme.cc @@ -84,7 +84,7 @@ LY_DEFINE (ly_context_set_property, "ly: SCM_ASSERT_TYPE (tr, context, SCM_ARG1, __FUNCTION__, "Context"); SCM_ASSERT_TYPE (scm_is_symbol (name), name, SCM_ARG2, __FUNCTION__, "symbol"); - tr->internal_set_property (name, val); + tr->internal_set_property (name, val, __FILE__, __LINE__); return SCM_UNSPECIFIED; } diff --git a/lily/context.cc b/lily/context.cc index 5211cbb..e625509 100644 --- a/lily/context.cc +++ b/lily/context.cc @@ -238,7 +238,7 @@ Context::set_property_from_event (SCM se if (val != SCM_EOL) ok = type_check_assignment (sym, val, ly_symbol2scm ("translation-type?")); if (ok) - internal_set_property (sym, val); + internal_set_property (sym, val, __FILE__, __LINE__); } } @@ -444,7 +444,7 @@ Context::internal_send_stream_event (SCM Stream_event *e = new Stream_event (type, origin); for (int i = 0; props[i]; i += 2) { - e->internal_set_property (props[i], props[i+1]); + e->internal_set_property (props[i], props[i+1], __FILE__, __LINE__); } event_source_->broadcast (e); e->unprotect (); @@ -469,7 +469,7 @@ Context::add_alias (SCM sym) } void -Context::internal_set_property (SCM sym, SCM val) +Context::internal_set_property (SCM sym, SCM val, char const *file, int line) { #ifndef NDEBUG if (do_internal_type_checking_global) @@ -737,7 +737,7 @@ measure_position (Context const *context void set_context_property_on_children (Context *trans, SCM sym, SCM val) { - trans->internal_set_property (sym, ly_deep_copy (val)); + trans->internal_set_property (sym, ly_deep_copy (val), __FILE__, __LINE__); for (SCM p = trans->children_contexts (); scm_is_pair (p); p = scm_cdr (p)) { Context *trg = unsmob_context (scm_car (p)); diff --git a/lily/grob-closure.cc b/lily/grob-closure.cc index 81bd393..e258f81 100644 --- a/lily/grob-closure.cc +++ b/lily/grob-closure.cc @@ -38,7 +38,7 @@ add_offset_callback (Grob *g, SCM proc, && !is_simple_closure (data)) { g->internal_set_property (axis_offset_symbol (a), - proc); + proc, __FILE__, __LINE__); return ; } @@ -54,7 +54,7 @@ add_offset_callback (Grob *g, SCM proc, SCM expr = scm_list_3 (plus, proc, data); g->internal_set_property (axis_offset_symbol (a), - ly_make_simple_closure (expr)); + ly_make_simple_closure (expr), __FILE__, __LINE__); } @@ -85,5 +85,6 @@ chain_offset_callback (Grob *g, SCM proc // twice: one as a wrapper for grob property routines, // once for the actual delayed binding. - ly_make_simple_closure (ly_make_simple_closure (expr))); + ly_make_simple_closure (ly_make_simple_closure (expr)), + __FILE__, __LINE__); } diff --git a/lily/grob-property.cc b/lily/grob-property.cc index 8d7ecc0..7d090d2 100644 --- a/lily/grob-property.cc +++ b/lily/grob-property.cc @@ -11,12 +11,32 @@ #include "misc.hh" #include "paper-score.hh" #include "output-def.hh" #include "spanner.hh" +#include "international.hh" #include "item.hh" #include "misc.hh" #include "item.hh" #include "program-option.hh" #include "profile.hh" #include "simple-closure.hh" +#include "warn.hh" + +static SCM modification_callback = SCM_EOL; + +LY_DEFINE (ly_set_grob_modification_callback, "ly:set-grob-modification-callback", + 1, 0, 0, (SCM cb), + "Specify a procedure that will be called every time lilypond modifies " + "a grob property. The callback will receive as arguments " + "the grob that is being modified, the name of the C++ file in which " + "the modification was requested, the line number in the C++ file in " + "which the modification was requested, the property to be changed and " + "the new value for the property.") +{ + if (!ly_is_procedure (cb)) + warning (_ ("not setting modification callback: not a procedure")); + else + modification_callback = cb; + return SCM_EOL; +} SCM Grob::get_property_alist_chain (SCM def) const @@ -31,7 +51,7 @@ Grob::get_property_alist_chain (SCM def) extern void check_interfaces_for_property (Grob const *me, SCM sym); void -Grob::internal_set_property (SCM sym, SCM v) +Grob::internal_set_property (SCM sym, SCM v, char const *file, int line) { #ifndef NDEBUG SCM grob_p = ly_lily_module_constant ("ly:grob?"); @@ -60,6 +80,12 @@ #endif abort (); check_interfaces_for_property (this, sym); } + protect (); + if (ly_is_procedure (modification_callback)) + scm_apply_0 (modification_callback, + scm_list_n (self_scm (), scm_makfrom0str (file), scm_from_int (line), + sym, v, SCM_UNDEFINED)); + unprotect (); mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, sym, v); } @@ -155,23 +181,28 @@ #endif mutable_property_alist_ = scm_assq_remove_x (mutable_property_alist_, marker); } else - internal_set_property (sym, value); + internal_set_property (sym, value, __FILE__, __LINE__); return value; } void -Grob::internal_set_object (SCM s, SCM v) +Grob::internal_set_object (SCM s, SCM v, char const *file, int line) { /* Perhaps we simply do the assq_set, but what the heck. */ if (!is_live ()) return; + if (ly_is_procedure (modification_callback)) + scm_apply_0 (modification_callback, + scm_list_n (self_scm (), scm_makfrom0str (file), scm_from_int (line), + s, v, SCM_UNDEFINED)); + object_alist_ = scm_assq_set_x (object_alist_, s, v); } void -Grob::del_property (SCM sym) +Grob::internal_del_property (SCM sym, char const *file, int line) { mutable_property_alist_ = scm_assq_remove_x (mutable_property_alist_, sym); } diff --git a/lily/grob-scheme.cc b/lily/grob-scheme.cc index bca86f5..3245d33 100644 --- a/lily/grob-scheme.cc +++ b/lily/grob-scheme.cc @@ -42,7 +42,7 @@ LY_DEFINE (ly_grob_set_property_x, "ly:g && !type_check_assignment (sym, val, ly_symbol2scm ("backend-type?"))) error ("typecheck failed"); - sc->internal_set_property (sym, val); + sc->internal_set_property (sym, val, __FILE__, __LINE__); return SCM_UNSPECIFIED; } diff --git a/lily/grob.cc b/lily/grob.cc index 72b4637..fdbb2c8 100644 --- a/lily/grob.cc +++ b/lily/grob.cc @@ -336,7 +336,7 @@ Grob::get_offset (Axis a) const if (me->dim_cache_[a].offset_) { *me->dim_cache_[a].offset_ += off; - me->del_property (sym); + me->del_property ((a == X_AXIS) ? "X-offset" : "Y-offset"); return *me->dim_cache_[a].offset_; } else @@ -365,7 +365,7 @@ Grob::flush_extent_cache (Axis axis) Ugh, this is not accurate; will flush property, causing callback to be called if. */ - del_property ((axis == X_AXIS) ? ly_symbol2scm ("X-extent") : ly_symbol2scm ("Y-extent")); + del_property ((axis == X_AXIS) ? "X-extent" : "Y-extent"); delete dim_cache_[axis].extent_; dim_cache_[axis].extent_ = 0; if (get_parent (axis)) diff --git a/lily/include/context.hh b/lily/include/context.hh index 1a9c0c2..334aabe 100644 --- a/lily/include/context.hh +++ b/lily/include/context.hh @@ -87,7 +87,7 @@ public: /* properties: */ SCM internal_get_property (SCM name_sym) const; SCM properties_as_alist () const; - void internal_set_property (SCM var_sym, SCM value); + void internal_set_property (SCM var_sym, SCM value, char const *file, int line); Context *where_defined (SCM name_sym, SCM *value) const; void unset_property (SCM var_sym); diff --git a/lily/include/engraver.hh b/lily/include/engraver.hh index 04a7623..2c407d4 100644 --- a/lily/include/engraver.hh +++ b/lily/include/engraver.hh @@ -46,12 +46,12 @@ public: TRANSLATOR_DECLARATIONS (Engraver); }; -#define make_item(x, cause) make_item_from_properties (this, ly_symbol2scm (x), cause, x) -#define make_spanner(x, cause) make_spanner_from_properties (this, ly_symbol2scm (x), cause, x) -#define make_paper_column(x) make_paper_column_from_properties (this, ly_symbol2scm (x), x) -Grob *make_grob_from_properties (Engraver *tr, SCM symbol, SCM cause, char const *name); -Item *make_item_from_properties (Engraver *tg, SCM x, SCM cause, char const *name); -Spanner *make_spanner_from_properties (Engraver *tg, SCM x, SCM cause, char const *name); -Paper_column *make_paper_column_from_properties (Engraver *tg, SCM x, char const *name); +#define make_item(x, cause) make_item_from_properties (this, ly_symbol2scm (x), cause, x, __FILE__, __LINE__) +#define make_spanner(x, cause) make_spanner_from_properties (this, ly_symbol2scm (x), cause, x, __FILE__, __LINE__) +#define make_paper_column(x) make_paper_column_from_properties (this, ly_symbol2scm (x), x, __FILE__, __LINE__) +Grob *make_grob_from_properties (Engraver *tr, SCM symbol, SCM cause, char const *name, char const *file, int line); +Item *make_item_from_properties (Engraver *tg, SCM x, SCM cause, char const *name, char const *file, int line); +Spanner *make_spanner_from_properties (Engraver *tg, SCM x, SCM cause, char const *name, char const *file, int line); +Paper_column *make_paper_column_from_properties (Engraver *tg, SCM x, char const *name, char const *file, int line); #endif // ENGRAVER_HH diff --git a/lily/include/grob.hh b/lily/include/grob.hh index e2bc015..a4184ac 100644 --- a/lily/include/grob.hh +++ b/lily/include/grob.hh @@ -80,9 +80,9 @@ public: SCM internal_get_property (SCM symbol) const; SCM get_property_data (SCM symbol) const; SCM internal_get_object (SCM symbol) const; - void del_property (SCM symbol); - void internal_set_property (SCM sym, SCM val); - void internal_set_object (SCM sym, SCM val); + void internal_del_property (SCM symbol, char const *file, int line); + void internal_set_property (SCM sym, SCM val, char const *file, int line); + void internal_set_object (SCM sym, SCM val, char const *file, int line); /* messages */ void warning (string) const; @@ -146,5 +146,4 @@ void chain_offset_callback (Grob *g, SCM SCM axis_offset_symbol (Axis a); SCM axis_parent_positioning (Axis a); - #endif /* GROB_HH */ diff --git a/lily/include/lily-guile-macros.hh b/lily/include/lily-guile-macros.hh index ef0db47..7002c0f 100644 --- a/lily/include/lily-guile-macros.hh +++ b/lily/include/lily-guile-macros.hh @@ -150,7 +150,8 @@ #define LY_DEFINE_MEMBER_FUNCTION(CLASS, #define get_property(x) internal_get_property (ly_symbol2scm (x)) #define get_object(x) internal_get_object (ly_symbol2scm (x)) -#define set_property(x, y) internal_set_property (ly_symbol2scm (x), y) -#define set_object(x, y) internal_set_object (ly_symbol2scm (x), y) +#define del_property(x) internal_del_property (ly_symbol2scm (x), __FILE__, __LINE__) +#define set_property(x, y) internal_set_property (ly_symbol2scm (x), y, __FILE__, __LINE__) +#define set_object(x, y) internal_set_object (ly_symbol2scm (x), y, __FILE__, __LINE__) #endif /* LILY_GUILE_MACROS_HH */ diff --git a/lily/include/prob.hh b/lily/include/prob.hh index 141aba4..04ef769 100644 --- a/lily/include/prob.hh +++ b/lily/include/prob.hh @@ -40,7 +40,7 @@ public: SCM type () const { return type_; } SCM get_property_alist (bool mutble) const; SCM internal_get_property (SCM sym) const; - void internal_set_property (SCM sym, SCM val); + void internal_set_property (SCM sym, SCM val, const char *file, int line); }; DECLARE_UNSMOB(Prob,prob); SCM ly_prob_set_property_x (SCM system, SCM sym, SCM value); diff --git a/lily/parenthesis-engraver.cc b/lily/parenthesis-engraver.cc index 01ea191..d8bda5d 100644 --- a/lily/parenthesis-engraver.cc +++ b/lily/parenthesis-engraver.cc @@ -43,7 +43,7 @@ Parenthesis_engraver::acknowledge_grob ( Item *paren = make_item_from_properties (eng, ly_symbol2scm ("ParenthesesItem"), victim->self_scm (), - "ParenthesesItem"); + "ParenthesesItem", __FILE__, __LINE__); Pointer_group_interface::add_grob (paren, ly_symbol2scm ("elements"), victim); diff --git a/lily/parser.yy b/lily/parser.yy index ef215c3..defa3b9 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -2491,7 +2491,7 @@ void set_music_properties (Music *p, SCM a) { for (SCM k = a; scm_is_pair (k); k = scm_cdr (k)) - p->internal_set_property (scm_caar (k), scm_cdar (k)); + p->internal_set_property (scm_caar (k), scm_cdar (k), __FILE__, __LINE__); } diff --git a/lily/pointer-group-interface.cc b/lily/pointer-group-interface.cc index 1ab1d02..508f9ea 100644 --- a/lily/pointer-group-interface.cc +++ b/lily/pointer-group-interface.cc @@ -42,7 +42,7 @@ Pointer_group_interface::get_grob_array { scm_arr = Grob_array::make_array (); arr = unsmob_grob_array (scm_arr); - me->internal_set_object (sym, scm_arr); + me->internal_set_object (sym, scm_arr, __FILE__, __LINE__); } return arr; } diff --git a/lily/prob-scheme.cc b/lily/prob-scheme.cc index ceadabd..2d473b3 100644 --- a/lily/prob-scheme.cc +++ b/lily/prob-scheme.cc @@ -16,7 +16,7 @@ LY_DEFINE (ly_prob_set_property_x, "ly:p SCM_ASSERT_TYPE (ps, obj, SCM_ARG1, __FUNCTION__, "Prob"); SCM_ASSERT_TYPE (scm_is_symbol (sym), sym, SCM_ARG2, __FUNCTION__, "symbol"); - ps->internal_set_property (sym, value); + ps->internal_set_property (sym, value, __FILE__, __LINE__); return SCM_UNSPECIFIED; } @@ -70,7 +70,7 @@ LY_DEFINE (ly_make_prob, "ly:make-prob", SCM sym = scm_car (s); SCM val = scm_cadr (s); - pr->internal_set_property (sym, val); + pr->internal_set_property (sym, val, __FILE__, __LINE__); } return pr->unprotect (); diff --git a/lily/prob.cc b/lily/prob.cc index 2640bdf..de80894 100644 --- a/lily/prob.cc +++ b/lily/prob.cc @@ -99,7 +99,7 @@ Prob::internal_get_property (SCM sym) co } void -Prob::internal_set_property (SCM sym, SCM val) +Prob::internal_set_property (SCM sym, SCM val, char const *file, int line) { if (do_internal_type_checking_global) type_check_assignment (sym, val); diff --git a/lily/script-engraver.cc b/lily/script-engraver.cc index 7c05131..9c67037 100644 --- a/lily/script-engraver.cc +++ b/lily/script-engraver.cc @@ -84,7 +84,7 @@ copy_property (Grob *g, SCM sym, SCM ali { SCM entry = scm_assoc (sym, alist); if (scm_is_pair (entry)) - g->internal_set_property (sym, scm_cdr (entry)); + g->internal_set_property (sym, scm_cdr (entry), __FILE__, __LINE__); } } @@ -135,7 +135,7 @@ void make_script_from_event (Grob *p, C SCM preset = p->get_property_data (sym); if (val == SCM_EOL || scm_call_1 (type, preset) == SCM_BOOL_F) - p->internal_set_property (sym, val); + p->internal_set_property (sym, val, __FILE__, __LINE__); } if (!priority_found) diff --git a/lily/span-bar-engraver.cc b/lily/span-bar-engraver.cc index 503bdf2..6d4bbb4 100644 --- a/lily/span-bar-engraver.cc +++ b/lily/span-bar-engraver.cc @@ -65,7 +65,7 @@ Span_bar_engraver::stop_translation_time SCM vissym = ly_symbol2scm ("break-visibility"); SCM vis = bars_[0]->internal_get_property (vissym); if (ly_is_equal (spanbar_->internal_get_property (vissym), vis)) - spanbar_->internal_set_property (vissym, vis); + spanbar_->internal_set_property (vissym, vis, __FILE__, __LINE__); spanbar_ = 0; } diff --git a/lily/system-start-delimiter-engraver.cc b/lily/system-start-delimiter-engraver.cc index b03c1d2..9de8039 100644 --- a/lily/system-start-delimiter-engraver.cc +++ b/lily/system-start-delimiter-engraver.cc @@ -77,7 +77,7 @@ Bracket_nesting_group::create_grobs (Eng { SCM type = scm_is_symbol (symbol_) ? symbol_ : default_type; delimiter_ = make_spanner_from_properties (engraver, type, - SCM_EOL, ly_symbol2string (type).c_str ()); + SCM_EOL, ly_symbol2string (type).c_str (), __FILE__, __LINE__); for (vsize i = 0 ; i < children_.size (); i++) { diff --git a/lily/tuplet-bracket.cc b/lily/tuplet-bracket.cc index fa5d9a9..b81107c 100644 --- a/lily/tuplet-bracket.cc +++ b/lily/tuplet-bracket.cc @@ -70,7 +70,7 @@ flatten_number_pair_property (Grob *me, = robust_scm2drul (me->internal_get_property (sym), zero); pair[xdir] = 0.0; - me->internal_set_property (sym, ly_interval2scm (pair)); + me->internal_set_property (sym, ly_interval2scm (pair), __FILE__, __LINE__); } diff --git a/lily/tweak-engraver.cc b/lily/tweak-engraver.cc index 9843dce..a479935 100644 --- a/lily/tweak-engraver.cc +++ b/lily/tweak-engraver.cc @@ -33,7 +33,7 @@ Tweak_engraver::acknowledge_grob (Grob_i for (SCM s = music->get_property ("tweaks"); scm_is_pair (s); s = scm_cdr (s)) { - info.grob ()->internal_set_property (scm_caar (s), scm_cdar (s)); + info.grob ()->internal_set_property (scm_caar (s), scm_cdar (s), __FILE__, __LINE__); } } } diff --git a/lily/volta-repeat-iterator.cc b/lily/volta-repeat-iterator.cc index 31f6295..a94101a 100644 --- a/lily/volta-repeat-iterator.cc +++ b/lily/volta-repeat-iterator.cc @@ -69,7 +69,7 @@ Volta_repeat_iterator::add_repeat_comman && current_reps == SCM_EOL || scm_is_pair (current_reps)) { current_reps = scm_cons (what, current_reps); - where->internal_set_property (reps, current_reps); + where->internal_set_property (reps, current_reps, __FILE__, __LINE__); } }
graph.ps.gz
Description: application/gzpostscript
\version "2.9.17" #(define output (open-output-file "graph.dot")) #(define node-num 0) #(define last-grob-action '()) #(define sym-blacklist '(cause font)) #(define sym-whitelist '(left-neighbors right-neighbors left-items right-items)) #(define file-line-blacklist '()) #(define file-line-whitelist '()) % an event is relevant if % (it is on some whitelist or all whitelists are empty) % and % (it isn't on any blacklist) #(define (relevant? grob file line prop) (let ((file-line `(,file . ,line))) (and (or (= 0 (length file-line-whitelist) (length sym-whitelist)) (memq prop sym-whitelist) (member file-line file-line-whitelist)) (and (not (memq prop sym-blacklist)) (not (member file-line file-line-blacklist)))))) #(display "digraph G {\nrankdir=\"LR\"\nnode [shape=rectangle]\n" output) #(define (grob-mod grob file line prop val) (let* ((prev (assv grob last-grob-action)) (val-str0 (format "~a" val)) (val-str (string-take val-str0 (min 50 (string-length val-str0))))) (if (relevant? grob file line prop) (begin (display (format "~a [label=\"~a\\n~a:~a\\n~a <- ~a\"]\n" node-num grob file line prop val-str) output) (display (format "subgraph cluster_~a {\nlabel = \"~a\"\ncolor=blue\n~a\n}\n" (string-filter file char-alphabetic?) file node-num) output) (if (pair? prev) (display (format "~a -> ~a\n" (cdr prev) node-num) output)) (set! last-grob-action (assv-set! last-grob-action grob node-num)) (set! node-num (1+ node-num)))))) #(define (grob-create grob file line) (display (format "~a [label=\"~a\\n~a:~a\",color=green]\n" node-num grob file line) output) (display (format "subgraph cluster_~a {\nlabel = \"~a\"\ncolor=blue\n~a\n}\n" (string-filter file char-alphabetic?) file node-num) output) (set! last-grob-action (assv-set! last-grob-action grob node-num)) (set! node-num (1+ node-num))) #(ly:set-grob-modification-callback grob-mod) #(ly:set-grob-creation-callback grob-create) { a b c d a b c d }
_______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel