1 /*
2 This file is part of LilyPond, the GNU music typesetter.
3
4 Copyright (C) 2002--2020 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "music-wrapper-iterator.hh"
21
22 #include "context.hh"
23 #include "input.hh"
24 #include "international.hh"
25 #include "music.hh"
26 #include "warn.hh"
27
28 using std::string;
29
30 class Context_specced_music_iterator final : public Music_wrapper_iterator
31 {
32 public:
33 DECLARE_SCHEME_CALLBACK (constructor, ());
34
35 protected:
36 void create_contexts () override;
37 };
38
39 void
create_contexts()40 Context_specced_music_iterator::create_contexts ()
41 {
42 // Change context in the wrapper before creating contexts for the wrapped
43 // iterators.
44
45 SCM ct = get_property (get_music (), "context-type");
46
47 string c_id;
48 SCM ci = get_property (get_music (), "context-id");
49 if (scm_is_string (ci))
50 c_id = ly_scm2string (ci);
51 SCM ops = get_property (get_music (), "property-operations");
52 Direction dir
53 = from_scm (get_property (get_music (), "search-direction"), CENTER);
54
55 Context *a = 0;
56
57 if (from_scm<bool> (get_property (get_music (), "create-new")))
58 {
59 a = get_own_context ()->create_unique_context (dir, ct, c_id, ops);
60 if (!a)
61 {
62 warning (_f ("cannot create context: %s",
63 Context::diagnostic_id (ct, c_id).c_str ()));
64 }
65 }
66 else
67 {
68 a = get_own_context ()->find_create_context (dir, ct, c_id, ops);
69 // Warnings in regression tests would be pretty common if we didn't
70 // ignore them for DOWN.
71 //
72 // TODO: Not warning about a failure in DOWN mode smells funny. It
73 // suggests that the fallback (remaining in the current context) is a
74 // fully acceptable alternative (from the perspective of the end user) in
75 // all cases; however, that seems unlikely. But if this is the desired
76 // behavior for DOWN mode, should we do it for UP too?
77 if (!a && (dir != DOWN))
78 {
79 warning (_f ("cannot find or create context: %s",
80 Context::diagnostic_id (ct, c_id).c_str ()));
81 }
82 }
83
84 if (a)
85 set_own_context (a);
86
87 Music_wrapper_iterator::create_contexts ();
88 }
89
90 IMPLEMENT_CTOR_CALLBACK (Context_specced_music_iterator);
91