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>
15 #include <strstream.h>
16 #define istringstream(x) istrstream(x, length_i ())
20 #include "flower-proto.hh"
22 #include "source-file.hh"
23 #include "simple-file-storage.hh"
24 #include "string-storage.hh"
26 Source_file::Source_file (String filename_str)
28 name_str_ = filename_str;
30 storage_p_ = new Simple_file_storage (filename_str);
34 Source_file::Source_file (String name_str, String data_str)
38 storage_p_ = new String_storage (data_str);
43 Source_file::istream_l ()
46 if (!name_str_.length_i ())
52 if (length_i ()) // can-t this be done without such a hack?
53 istream_p_ = new std::istringstream (ch_C ());
56 istream_p_ = new std::istringstream ("");
57 istream_p_->setstate (std::ios::eofbit);
58 // istream_p_->set (ios::eofbit);
65 Source_file::file_line_column_str (char const *context_ch_C) const
68 return " (" + _ ("position unknown") + ")";
70 return name_str () + ":" + to_str (line_i (context_ch_C))
71 + ":" + to_str (char_i (context_ch_C));
75 Source_file::name_str () const
80 Source_file::~Source_file ()
88 Source_file::line_slice (char const* pos_ch_C) const
93 char const* data_ch_C = ch_C ();
94 char const * eof_C_ = data_ch_C + length_i ();
96 if (pos_ch_C == eof_C_)
98 char const* begin_ch_C = pos_ch_C;
99 while (begin_ch_C > data_ch_C)
100 if (*--begin_ch_C == '\n')
106 char const* end_ch_C = pos_ch_C;
107 while (end_ch_C < eof_C_)
108 if (*end_ch_C++ == '\n')
114 return Slice (begin_ch_C - data_ch_C, end_ch_C - data_ch_C);
118 Source_file::line_str (char const* pos_ch_C) const
120 if (!in_b (pos_ch_C))
123 Slice line = line_slice (pos_ch_C);
124 char const* data_ch_C = ch_C ();
125 return String ((Byte const*)data_ch_C + line[LEFT], line.length ());
129 Source_file::char_i (char const* pos_ch_C) const
131 if (!in_b (pos_ch_C))
134 char const* data_ch_C = ch_C ();
135 return pos_ch_C - (line_slice (pos_ch_C)[SMALLER] + data_ch_C);
139 Source_file::column_i (char const* pos_ch_C) const
141 if (!in_b (pos_ch_C))
144 int ch_i = char_i (pos_ch_C);
145 String line = line_str (pos_ch_C);
148 for (int i = 0; i < ch_i; i++)
150 col_i = (col_i / 8 + 1) * 8;
158 Source_file::error_str (char const* pos_ch_C) const
160 if (!in_b (pos_ch_C))
161 return " (" + _ ("position unknown") + ")";
163 int ch_i = char_i (pos_ch_C);
164 String line = line_str (pos_ch_C);
165 String context = line.left_str (ch_i)
167 + to_str (' ', column_i (pos_ch_C))
168 + line.cut_str (ch_i, INT_MAX);
174 Source_file::in_b (char const* pos_ch_C) const
176 return (pos_ch_C && (pos_ch_C >= ch_C ()) && (pos_ch_C <= ch_C () + length_i ()));
180 Source_file::line_i (char const* pos_ch_C) const
182 if (!in_b (pos_ch_C))
186 char const* scan_ch_C = ch_C ();
190 while (scan_ch_C < pos_ch_C)
191 if (*scan_ch_C++ == '\n')
197 Source_file::length_i () const
199 return storage_p_->length_i ();
203 Source_file::ch_C () const
205 return storage_p_->ch_C ();
209 Source_file::set_pos (char const * pos_ch_C)
212 pos_ch_C_ = pos_ch_C;
214 error (error_str (pos_ch_C) + "invalid pos");
218 Source_file::seek_ch_C (int n)
220 char const* new_ch_C = ch_C () + n;
222 new_ch_C += length_i ();
224 pos_ch_C_ = new_ch_C;
226 error (error_str (new_ch_C) + "seek past eof");
232 Source_file::forward_ch_C (int n)
234 char const* old_pos_C = pos_ch_C_;
235 char const* new_ch_C = pos_ch_C_ + n;
237 pos_ch_C_ = new_ch_C;
239 error (error_str (new_ch_C) + "forward past eof");
245 Source_file::get_str (int n)
247 String str ((Byte const*)forward_ch_C (n), n);