]> git.donarmstrong.com Git - lilypond.git/blob - lily/input.cc
19f6ac019ee1fc2272cc549034771adbc4ae1427
[lilypond.git] / lily / input.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1997--2015 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 "input.hh"
21
22 #include <cstdio>
23
24 #include "international.hh"
25 #include "lily-imports.hh"
26 #include "program-option.hh"
27 #include "source-file.hh"
28 #include "sources.hh"
29 #include "warn.hh"
30
31 using std::string;
32
33 Input::Input (Input const &i)
34 {
35   source_file_ = i.source_file_;
36   start_ = i.start_;
37   end_ = i.end_;
38 }
39
40 Input::Input ()
41 {
42   source_file_ = 0;
43   start_ = 0;
44   end_ = 0;
45 }
46
47 Input
48 Input::spot () const
49 {
50   return *this;
51 }
52
53 void
54 Input::set_spot (Input const &i)
55 {
56   *this = i;
57 }
58
59 void
60 Input::step_forward ()
61 {
62   if (end_ == start_)
63     end_++;
64   start_++;
65 }
66
67 void
68 Input::set_location (Input const &i_start, Input const &i_end)
69 {
70   source_file_ = i_start.source_file_;
71   start_ = i_start.start_;
72   end_ = i_end.end_;
73 }
74
75 /*
76   Produce GNU-compliant error message.  Correcting lilypond source is
77   such a breeze if you ('re edidor) know (s) the error column too
78
79   Format:
80
81   [file:line:column:][warning:]message
82 */
83 string
84 Input::message_string (const string &msg) const
85 {
86   if (source_file_)
87     return msg + "\n" + source_file_->quote_input (start_);
88   else
89     return msg;
90 }
91
92 string
93 Input::message_location () const
94 {
95   return (source_file_) ? location_string () : "";
96 }
97
98 void
99 Input::error (const string &s) const
100 {
101   ::error (message_string (s), message_location ());
102 }
103
104 void
105 Input::programming_error (const string &s) const
106 {
107   ::programming_error (message_string (s), message_location ());
108 }
109
110 void
111 Input::non_fatal_error (const string &s) const
112 {
113   ::non_fatal_error (message_string (s), message_location ());
114 }
115
116 void
117 Input::warning (const string &s) const
118 {
119   ::warning (message_string (s), message_location ());
120 }
121
122 void
123 Input::message (const string &s) const
124 {
125   ::message (message_string (s), true, message_location ());
126 }
127
128 void
129 Input::debug_output (const string &s) const
130 {
131   ::debug_output (message_string (s), true, message_location ());
132 }
133
134 string
135 Input::location_string () const
136 {
137   if (source_file_)
138     return source_file_->file_line_column_string (start_);
139   return " (" + _ ("position unknown") + ")";
140 }
141
142 string
143 Input::line_number_string () const
144 {
145   if (source_file_)
146     return ::to_string (source_file_->get_line (start_));
147   return "?";
148 }
149
150 string
151 Input::file_string () const
152 {
153   if (source_file_)
154     return source_file_->name_string ();
155   return "";
156 }
157
158 int
159 Input::line_number () const
160 {
161   if (source_file_)
162     return source_file_->get_line (start_);
163   return 0;
164 }
165
166 int
167 Input::column_number () const
168 {
169   int line, chr, col, offset = 0;
170   source_file_->get_counts (start_, &line, &chr, &col, &offset);
171
172   return col;
173 }
174
175 int
176 Input::end_line_number () const
177 {
178   if (source_file_)
179     return source_file_->get_line (end_);
180   return 0;
181 }
182
183 int
184 Input::end_column_number () const
185 {
186   int line, chr, col, offset = 0;
187   source_file_->get_counts (end_, &line, &chr, &col, &offset);
188
189   return col;
190 }
191
192 void
193 Input::get_counts (int *line, int *chr, int *col, int *offset) const
194 {
195   source_file_->get_counts (start_, line, chr, col, offset);
196 }
197
198 void
199 Input::set (Source_file *sf, char const *start, char const *end)
200 {
201   source_file_ = sf;
202   start_ = start;
203   end_ = end;
204 }
205
206 Source_file *
207 Input::get_source_file () const
208 {
209   return source_file_;
210 }
211
212 char const *
213 Input::start () const
214 {
215   return start_;
216 }
217
218 char const *
219 Input::end () const
220 {
221   return end_;
222 }
223
224 static SCM
225 with_location_hook_0 (void *it)
226 {
227   SCM *args = static_cast <SCM *> (it);
228   return scm_call_0 (args[0]);
229 }
230
231 SCM
232 with_location (SCM loc, SCM proc)
233 {
234   return scm_c_with_fluid (Lily::f_location,
235                            unsmob<Input> (loc) ? loc : SCM_BOOL_F,
236                            with_location_hook_0,
237                            static_cast <void *> (&proc));
238 }
239
240 static SCM
241 with_location_hook_1 (void *it)
242 {
243   SCM *args = static_cast <SCM *> (it);
244   return scm_call_1 (args[0], args[1]);
245 }
246
247 SCM
248 with_location (SCM loc, SCM proc, SCM arg1)
249 {
250   SCM args[] = { proc, arg1 };
251   return scm_c_with_fluid (Lily::f_location,
252                            unsmob<Input> (loc) ? loc : SCM_BOOL_F,
253                            with_location_hook_1,
254                            static_cast <void *> (&args));
255 }
256
257 static SCM
258 with_location_hook_2 (void *it)
259 {
260   SCM *args = static_cast <SCM *> (it);
261   return scm_call_2 (args[0], args[1], args[2]);
262 }
263
264 SCM
265 with_location (SCM loc, SCM proc, SCM arg1, SCM arg2)
266 {
267   SCM args[] = { proc, arg1, arg2 };
268   return scm_c_with_fluid (Lily::f_location,
269                            unsmob<Input> (loc) ? loc : SCM_BOOL_F,
270                            with_location_hook_2,
271                            static_cast <void *> (&args));
272 }
273
274 static SCM
275 with_location_hook_3 (void *it)
276 {
277   SCM *args = static_cast <SCM *> (it);
278   return scm_call_3 (args[0], args[1], args[2], args[3]);
279 }
280
281 SCM
282 with_location (SCM loc, SCM proc, SCM arg1, SCM arg2, SCM arg3)
283 {
284   SCM args[] = { proc, arg1, arg2, arg3 };
285   return scm_c_with_fluid (Lily::f_location,
286                            unsmob<Input> (loc) ? loc : SCM_BOOL_F,
287                            with_location_hook_3,
288                            static_cast <void *> (&args));
289 }
290
291 static SCM
292 with_location_hook_4 (void *it)
293 {
294   SCM *args = static_cast <SCM *> (it);
295   return scm_call_4 (args[0], args[1], args[2], args[3], args[4]);
296 }
297
298 SCM
299 with_location (SCM loc, SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4)
300 {
301   SCM args[] = { proc, arg1, arg2, arg3, arg4 };
302   return scm_c_with_fluid (Lily::f_location,
303                            unsmob<Input> (loc) ? loc : SCM_BOOL_F,
304                            with_location_hook_4,
305                            static_cast <void *> (&args));
306 }
307
308 static SCM
309 with_location_hook_n (void *it)
310 {
311   SCM *args = static_cast <SCM *> (it);
312   return scm_apply_0 (args[0], args[1]);
313 }
314
315 SCM
316 with_location (SCM loc, SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5)
317 {
318   SCM args[] = { proc, scm_list_5 (arg1, arg2, arg3, arg4, arg5) };
319   return scm_c_with_fluid (Lily::f_location,
320                            unsmob<Input> (loc) ? loc : SCM_BOOL_F,
321                            with_location_hook_n,
322                            static_cast <void *> (&args));
323 }