2 source-file.cc -- implement Source_file
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2000 Jan Nieuwenhuizen <janneke@gnu.org>
7 & Han-Wen Nienhuys <hanwen@cs.uu.nl>
17 #include <strstream.h>
18 #define istringstream(x) istrstream(x, length ())
22 #include "flower-proto.hh"
24 #include "source-file.hh"
28 Source_file::load_stdin ()
33 Array
<char> chs
; // ugh.
34 while ((c
= fgetc (stdin
)) != EOF
)
37 length_
= chs
.size ();
38 contents_str0_
= chs
.remove_array ();
44 gulp_file (String fn
, int* len
)
47 let's hope that "b" opens anything binary, and does not apply
50 FILE * f
= fopen (fn
.to_str0 (), "rb");
54 warning (_f ("can't open file: `%s'", fn
.to_str0 ()));
58 int ret
= fseek (f
, 0, SEEK_END
);
62 char * str
= new char[*len
+1];
64 ret
= fread (str
, sizeof (char), *len
, f
);
67 warning (_f ("Huh? Got %d, expected %d characters", ret
, *len
));
77 Source_file::Source_file (String filename
, String data
)
81 contents_str0_
= data
.get_copy_str0();
82 length_
= data
.length();
83 pos_str0_
= to_str0 ();
90 Source_file::Source_file (String filename_string
)
92 name_string_
= filename_string
;
96 if (filename_string
== "-")
99 contents_str0_
= gulp_file (filename_string
, &length_
);
101 pos_str0_
= to_str0 ();
105 for (int i
= 0; i
< length_
; i
++)
106 if (contents_str0_
[i
] == '\n')
107 newline_locations_
.push (contents_str0_
+ i
);
111 Source_file::init_port ()
113 SCM str
=scm_makfrom0str (contents_str0_
);
115 str_port_
= scm_mkstrport (SCM_INUM0
, str
, SCM_OPN
| SCM_RDNG
,
117 scm_set_port_filename_x (str_port_
,
118 scm_makfrom0str (name_string_
.get_str0()));
122 Source_file::tell () const
124 return pos_str0_
- contents_str0_
;
128 Source_file::get_istream ()
132 if (length ()) // can-t this be done without such a hack?
133 istream_
= new std::istringstream (to_str0 ());
136 istream_
= new std::istringstream ("");
137 istream_
->setstate (std::ios::eofbit
);
138 // istream_->set (ios::eofbit);
145 Source_file::file_line_column_string (char const *context_str0
) const
148 return " (" + _ ("position unknown") + ")";
150 return name_string () + ":" + to_string (get_line (context_str0
))
151 + ":" + to_string (get_char (context_str0
));
155 Source_file::name_string () const
160 Source_file::~Source_file ()
164 delete[] contents_str0_
;
168 Source_file::line_slice (char const* pos_str0
) const
170 if (!in_b (pos_str0
))
173 char const* data_str0
= to_str0 ();
174 char const * eof_C_
= data_str0
+ length ();
176 if (pos_str0
== eof_C_
)
178 char const* begin_str0
= pos_str0
;
179 while (begin_str0
> data_str0
)
180 if (*--begin_str0
== '\n')
186 char const* end_str0
= pos_str0
;
187 while (end_str0
< eof_C_
)
188 if (*end_str0
++ == '\n')
194 return Slice (begin_str0
- data_str0
, end_str0
- data_str0
);
198 Source_file::line_string (char const* pos_str0
) const
200 if (!in_b (pos_str0
))
203 Slice line
= line_slice (pos_str0
);
204 char const* data_str0
= to_str0 ();
205 return String ((Byte
const*)data_str0
+ line
[LEFT
], line
.length ());
209 Source_file::get_char (char const* pos_str0
) const
211 if (!in_b (pos_str0
))
214 char const* data_str0
= to_str0 ();
215 return pos_str0
- (line_slice (pos_str0
)[SMALLER
] + data_str0
);
219 Source_file::get_column (char const* pos_str0
) const
221 if (!in_b (pos_str0
))
224 int ch_i
= get_char (pos_str0
);
225 String line
= line_string (pos_str0
);
228 for (int i
= 0; i
< ch_i
; i
++)
230 col_i
= (col_i
/ 8 + 1) * 8;
238 Source_file::error_string (char const* pos_str0
) const
240 if (!in_b (pos_str0
))
241 return " (" + _ ("position unknown") + ")";
243 int ch_i
= get_char (pos_str0
);
244 String line
= line_string (pos_str0
);
245 String context
= line
.left_string (ch_i
)
247 + to_string (' ', get_column (pos_str0
))
248 + line
.cut_string (ch_i
, INT_MAX
);
254 Source_file::in_b (char const* pos_str0
) const
256 return (pos_str0
&& (pos_str0
>= to_str0 ()) && (pos_str0
<= to_str0 () + length ()));
260 Source_file::get_line (char const* pos_str0
) const
262 if (!in_b (pos_str0
))
265 if (!newline_locations_
.size())
270 int hi
= newline_locations_
.size();
271 if (newline_locations_
[lo
] > pos_str0
)
274 if (newline_locations_
[hi
-1] < pos_str0
)
277 binary_search_bounds (newline_locations_
,
279 Link_array
<char>::default_compare
,
282 if (*pos_str0
== '\n')
288 Source_file::length () const
294 Source_file::to_str0 () const
296 return contents_str0_
;
300 Source_file::set_pos (char const * pos_str0
)
303 pos_str0_
= pos_str0
;
305 error (error_string (pos_str0
) + "invalid pos");
309 Source_file::seek_str0 (int n
)
311 char const* new_str0
= to_str0 () + n
;
313 new_str0
+= length ();
315 pos_str0_
= new_str0
;
317 error (error_string (new_str0
) + "seek past eof");
323 Source_file::forward_str0 (int n
)
325 char const* old_pos
= pos_str0_
;
326 char const* new_str0
= pos_str0_
+ n
;
328 pos_str0_
= new_str0
;
330 error (error_string (new_str0
) + "forward past eof");
336 Source_file::get_string (int n
)
338 String str
= String ((Byte
const*)forward_str0 (n
), n
);