LEFT | RIGHT |
1 /* | 1 /* |
2 translator-def.cc -- implement Context_def | 2 translator-def.cc -- implement Context_def |
3 | 3 |
4 source file of the GNU LilyPond music typesetter | 4 source file of the GNU LilyPond music typesetter |
5 | 5 |
6 (c) 2000--2007 Han-Wen Nienhuys <hanwen@xs4all.nl> | 6 (c) 2000--2007 Han-Wen Nienhuys <hanwen@xs4all.nl> |
7 */ | 7 */ |
8 | 8 |
9 /* TODO: should junk this class an replace by | 9 /* TODO: should junk this class an replace by |
10 a single list of context modifications? */ | 10 a single list of context modifications? */ |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 definitions such that: | 198 definitions such that: |
199 - the first element in the list defines a context that is a valid child of | 199 - the first element in the list defines a context that is a valid child of |
200 the context defined by this Context_def | 200 the context defined by this Context_def |
201 - each subsequent element in the list defines a context that is a valid child | 201 - each subsequent element in the list defines a context that is a valid child |
202 of the the context defined by the preceding element in the list | 202 of the the context defined by the preceding element in the list |
203 - the last element in the list defines a context with the given name | 203 - the last element in the list defines a context with the given name |
204 | 204 |
205 The ADDITIONAL_ACCEPTS parameter is a list of additional contexts that this | 205 The ADDITIONAL_ACCEPTS parameter is a list of additional contexts that this |
206 specific context def (but not any of the child context defs) should accept. | 206 specific context def (but not any of the child context defs) should accept. |
207 */ | 207 */ |
| 208 vector<Context_def *> |
| 209 Context_def::path_to_acceptable_context (SCM type_sym, |
| 210 Output_def *odef, |
| 211 SCM additional_accepts) const |
| 212 { |
| 213 set<const Context_def *> seen; |
| 214 return internal_path_to_acceptable_context (type_sym, odef, additional_accepts
, &seen); |
| 215 } |
| 216 |
| 217 /* |
| 218 The SEEN parameter is a set which keeps track of visited contexts, allowing |
| 219 contexts of the same type to be nested.· |
| 220 */ |
208 vector<Context_def*> | 221 vector<Context_def*> |
209 Context_def::path_to_acceptable_context (SCM type_sym, Output_def *odef, SCM add
itional_accepts, set<const Context_def *> *seen) const | 222 Context_def::internal_path_to_acceptable_context (SCM type_sym, |
| 223 » » » » » » Output_def *odef, |
| 224 » » » » » » SCM additional_accepts, |
| 225 » » » » » » set<const Context_def *> *seen
) const |
210 { | 226 { |
211 assert (scm_is_symbol (type_sym)); | 227 assert (scm_is_symbol (type_sym)); |
212 | |
213 bool create_seen = !seen; | |
214 if (create_seen) | |
215 seen = new set<const Context_def *> (); | |
216 | 228 |
217 SCM accepted = get_accepted (additional_accepts); | 229 SCM accepted = get_accepted (additional_accepts); |
218 | 230 |
219 vector<Context_def*> accepteds; | 231 vector<Context_def*> accepteds; |
220 for (SCM s = accepted; scm_is_pair (s); s = scm_cdr (s)) | 232 for (SCM s = accepted; scm_is_pair (s); s = scm_cdr (s)) |
221 if (Context_def *t = unsmob_context_def (find_context_def (odef, | 233 if (Context_def *t = unsmob_context_def (find_context_def (odef, |
222 scm_car (s)))) | 234 scm_car (s)))) |
223 accepteds.push_back (t); | 235 accepteds.push_back (t); |
224 | 236 |
225 vector<Context_def*> best_result; | 237 vector<Context_def*> best_result; |
(...skipping 10 matching lines...) Expand all Loading... |
236 | 248 |
237 seen->insert (this); | 249 seen->insert (this); |
238 vsize best_depth = INT_MAX; | 250 vsize best_depth = INT_MAX; |
239 for (vsize i = 0; i < accepteds.size (); i++) | 251 for (vsize i = 0; i < accepteds.size (); i++) |
240 { | 252 { |
241 Context_def *g = accepteds[i]; | 253 Context_def *g = accepteds[i]; |
242 | 254 |
243 if (!seen->count (g)) | 255 if (!seen->count (g)) |
244 { | 256 { |
245 vector<Context_def*> result | 257 vector<Context_def*> result |
246 » = g->path_to_acceptable_context (type_sym, odef, SCM_EOL, seen); | 258 » = g->internal_path_to_acceptable_context (type_sym, odef, SCM_EOL, s
een); |
247 if (result.size () && result.size () < best_depth) | 259 if (result.size () && result.size () < best_depth) |
248 { | 260 { |
249 best_depth = result.size (); | 261 best_depth = result.size (); |
250 result.insert (result.begin (), g); | 262 result.insert (result.begin (), g); |
251 best_result = result; | 263 best_result = result; |
252 } | 264 } |
253 } | 265 } |
254 } | 266 } |
255 seen->erase (this); | 267 seen->erase (this); |
256 | |
257 if (create_seen) | |
258 delete seen; | |
259 | 268 |
260 return best_result; | 269 return best_result; |
261 } | 270 } |
262 | 271 |
263 SCM | 272 SCM |
264 Context_def::get_translator_names (SCM user_mod) const | 273 Context_def::get_translator_names (SCM user_mod) const |
265 { | 274 { |
266 SCM l1 = SCM_EOL; | 275 SCM l1 = SCM_EOL; |
267 | 276 |
268 SCM mods = scm_reverse_x (scm_list_copy (translator_mods_), user_mod); | 277 SCM mods = scm_reverse_x (scm_list_copy (translator_mods_), user_mod); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 ell); | 334 ell); |
326 ell = scm_cons (scm_cons (ly_symbol2scm ("context-name"), context_name_), | 335 ell = scm_cons (scm_cons (ly_symbol2scm ("context-name"), context_name_), |
327 ell); | 336 ell); |
328 | 337 |
329 if (scm_is_symbol (translator_group_type_)) | 338 if (scm_is_symbol (translator_group_type_)) |
330 ell = scm_cons (scm_cons (ly_symbol2scm ("group-type"), | 339 ell = scm_cons (scm_cons (ly_symbol2scm ("group-type"), |
331 translator_group_type_), ell); | 340 translator_group_type_), ell); |
332 return ell; | 341 return ell; |
333 } | 342 } |
334 | 343 |
LEFT | RIGHT |