From 52981e6e7d59d72f61f6618dd7e6ba40a5559d9e Mon Sep 17 00:00:00 2001 From: Joe Neeman Date: Wed, 4 Jun 2008 23:11:32 +1000 Subject: [PATCH] Fix 65. Use the accepts_list_ of a context (not just the accepts_list_ of the associated context def) to determine which children may be added to a context. This allows the accepts list to be modified using \with instead of just in \layout. --- lily/context-def.cc | 18 +++++++++++++++--- lily/context.cc | 35 ++++++++++++++++++++++++----------- lily/include/context-def.hh | 2 +- lily/include/context.hh | 3 +-- lily/output-def.cc | 2 +- 5 files changed, 42 insertions(+), 18 deletions(-) diff --git a/lily/context-def.cc b/lily/context-def.cc index f4023a09a1..2d7cace9bf 100644 --- a/lily/context-def.cc +++ b/lily/context-def.cc @@ -193,12 +193,24 @@ Context_def::get_default_child (SCM user_mod) const return name; } +/* + Given a name of a context that we want to create, finds a list of context + definitions such that: + - the first element in the list defines a context that is a valid child of + the context defined by this Context_def + - each subsequent element in the list defines a context that is a valid child + of the the context defined by the preceding element in the list + - the last element in the list defines a context with the given name + + The ADDITIONAL_ACCEPTS parameter is a list of additional contexts that this + specific output def (but not and of the child output defs) should accept. +*/ vector -Context_def::path_to_acceptable_context (SCM type_sym, Output_def *odef) const +Context_def::path_to_acceptable_context (SCM type_sym, Output_def *odef, SCM additional_accepts) const { assert (scm_is_symbol (type_sym)); - SCM accepted = get_accepted (SCM_EOL); + SCM accepted = get_accepted (additional_accepts); vector accepteds; for (SCM s = accepted; scm_is_pair (s); s = scm_cdr (s)) @@ -224,7 +236,7 @@ Context_def::path_to_acceptable_context (SCM type_sym, Output_def *odef) const Context_def *g = accepteds[i]; vector result - = g->path_to_acceptable_context (type_sym, odef); + = g->path_to_acceptable_context (type_sym, odef, SCM_EOL); if (result.size () && result.size () < best_depth) { best_depth = result.size (); diff --git a/lily/context.cc b/lily/context.cc index 3c982751fd..dc6216403f 100644 --- a/lily/context.cc +++ b/lily/context.cc @@ -104,17 +104,12 @@ Context::create_unique_context (SCM name, string id, SCM operations) if (gthis && gthis->get_score_context ()) return gthis->get_score_context ()->create_unique_context (name, id, operations); - /* - TODO: use accepts_list_. - */ - vector path - = unsmob_context_def (definition_)->path_to_acceptable_context (name, get_output_def ()); - + vector path = path_to_acceptable_context (name); if (path.size ()) { Context *current = this; - // start at 1. The first one (index 0) will be us. + // Iterate through the path and create all of the implicit contexts. for (vsize i = 0; i < path.size (); i++) { SCM ops = SCM_EOL; @@ -170,8 +165,7 @@ Context::find_create_context (SCM n, string id, SCM operations) /* TODO: use accepts_list_. */ - vector path - = unsmob_context_def (definition_)->path_to_acceptable_context (n, get_output_def ()); + vector path = path_to_acceptable_context (n); if (path.size ()) { @@ -261,8 +255,8 @@ Context::create_context_from_event (SCM sev) SCM type_scm = ev->get_property ("type"); string type = ly_symbol2string (type_scm); - vector path - = unsmob_context_def (definition_)->path_to_acceptable_context (type_scm, get_output_def ()); + vector path = path_to_acceptable_context (type_scm); + if (path.size () != 1) { programming_error (_f ("Invalid CreateContext event: Cannot create %s context", type.c_str ())); @@ -312,6 +306,25 @@ Context::create_context_from_event (SCM sev) ly_symbol2scm ("creator"), sev); } +vector +Context::path_to_acceptable_context (SCM name) const +{ + // definition_mods_ is a list of (symbol string), but the Context_def expects + // to see a list of (symbol symbol). + SCM accepts = SCM_EOL; + for (SCM s = scm_reverse (definition_mods_); scm_is_pair (s); s = scm_cdr (s)) + if (scm_caar (s) == ly_symbol2scm ("accepts")) + { + SCM elt = scm_list_2 (scm_caar (s), scm_string_to_symbol (scm_cadar (s))); + accepts = scm_cons (elt, accepts); + } + + return unsmob_context_def (definition_)->path_to_acceptable_context (name, + get_output_def (), + accepts); + +} + Context * Context::create_context (Context_def *cdef, string id, diff --git a/lily/include/context-def.hh b/lily/include/context-def.hh index dd4df4c802..ea81eb1295 100644 --- a/lily/include/context-def.hh +++ b/lily/include/context-def.hh @@ -49,7 +49,7 @@ public: VIRTUAL_COPY_CONSTRUCTOR(Context_def, Context_def); vector path_to_acceptable_context (SCM type_string, - Output_def *) const; + Output_def *, SCM) const; Context *instantiate (SCM extra_ops); SCM to_alist () const; diff --git a/lily/include/context.hh b/lily/include/context.hh index 88019f4b88..648a52ae3b 100644 --- a/lily/include/context.hh +++ b/lily/include/context.hh @@ -114,8 +114,7 @@ public: string id, SCM ops); Context *create_unique_context (SCM context_name, string context_id, SCM ops); - vector path_to_acceptable_context (SCM alias, - Output_def *) const; + vector path_to_acceptable_context (SCM alias) const; }; /* diff --git a/lily/output-def.cc b/lily/output-def.cc index 853704c5c9..0e0259f128 100644 --- a/lily/output-def.cc +++ b/lily/output-def.cc @@ -81,7 +81,7 @@ assign_context_def (Output_def * m, SCM transdef) /* find the translator for NAME. NAME must be a symbol. */ SCM find_context_def (Output_def const *m, SCM name) -{ +{ Context_def *cd = unsmob_context_def (m->lookup_variable (name)); return cd ? cd->self_scm () : SCM_EOL; } -- 2.39.5