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>
12 #include <strstream.h>
15 #include "flower-proto.hh"
17 #include "source-file.hh"
18 #include "simple-file-storage.hh"
19 #include "string-storage.hh"
21 Source_file::Source_file (String filename_str
)
23 name_str_
= filename_str
;
25 storage_p_
= new Simple_file_storage (filename_str
);
29 Source_file::Source_file (String name_str
, String data_str
)
33 storage_p_
= new String_storage (data_str
);
38 Source_file::istream_l ()
41 if (!name_str_.length_i ())
47 if (length_i ()) // can-t this be done without such a hack?
48 istream_p_
= new istrstream (ch_C (), length_i ());
51 istream_p_
= new istrstream ("", 0);
52 istream_p_
->setstate (ios::eofbit
);
53 // istream_p_->set (ios::eofbit);
60 Source_file::file_line_column_str (char const *context_ch_C
) const
63 return " (" + _ ("position unknown") + ")";
65 return name_str () + ":" + to_str (line_i (context_ch_C
))
66 + ":" + to_str (char_i (context_ch_C
));
70 Source_file::name_str () const
75 Source_file::~Source_file ()
83 Source_file::line_slice (char const* pos_ch_C
) const
88 char const* data_ch_C
= ch_C ();
89 char const * eof_C_
= data_ch_C
+ length_i ();
91 if (pos_ch_C
== eof_C_
)
93 char const* begin_ch_C
= pos_ch_C
;
94 while (begin_ch_C
> data_ch_C
)
95 if (*--begin_ch_C
== '\n')
101 char const* end_ch_C
= pos_ch_C
;
102 while (end_ch_C
< eof_C_
)
103 if (*end_ch_C
++ == '\n')
109 return Slice (begin_ch_C
- data_ch_C
, end_ch_C
- data_ch_C
);
113 Source_file::line_str (char const* pos_ch_C
) const
115 if (!in_b (pos_ch_C
))
118 Slice line
= line_slice (pos_ch_C
);
119 char const* data_ch_C
= ch_C ();
120 return String ((Byte
const*)data_ch_C
+ line
[LEFT
], line
.length ());
124 Source_file::char_i (char const* pos_ch_C
) const
126 if (!in_b (pos_ch_C
))
129 char const* data_ch_C
= ch_C ();
130 return pos_ch_C
- (line_slice (pos_ch_C
)[SMALLER
] + data_ch_C
);
134 Source_file::column_i (char const* pos_ch_C
) const
136 if (!in_b (pos_ch_C
))
139 int ch_i
= char_i (pos_ch_C
);
140 String line
= line_str (pos_ch_C
);
143 for (int i
= 0; i
< ch_i
; i
++)
145 col_i
= (col_i
/ 8 + 1) * 8;
153 Source_file::error_str (char const* pos_ch_C
) const
155 if (!in_b (pos_ch_C
))
156 return " (" + _ ("position unknown") + ")";
158 int ch_i
= char_i (pos_ch_C
);
159 String line
= line_str (pos_ch_C
);
160 String context
= line
.left_str (ch_i
)
162 + to_str (' ', column_i (pos_ch_C
))
163 + line
.cut_str (ch_i
, INT_MAX
);
169 Source_file::in_b (char const* pos_ch_C
) const
171 return (pos_ch_C
&& (pos_ch_C
>= ch_C ()) && (pos_ch_C
<= ch_C () + length_i ()));
175 Source_file::line_i (char const* pos_ch_C
) const
177 if (!in_b (pos_ch_C
))
181 char const* scan_ch_C
= ch_C ();
185 while (scan_ch_C
< pos_ch_C
)
186 if (*scan_ch_C
++ == '\n')
192 Source_file::length_i () const
194 return storage_p_
->length_i ();
198 Source_file::ch_C () const
200 return storage_p_
->ch_C ();
204 Source_file::set_pos (char const * pos_ch_C
)
207 pos_ch_C_
= pos_ch_C
;
209 error (error_str (pos_ch_C
) + "invalid pos");
213 Source_file::seek_ch_C (int n
)
215 char const* new_ch_C
= ch_C () + n
;
217 new_ch_C
+= length_i ();
219 pos_ch_C_
= new_ch_C
;
221 error (error_str (new_ch_C
) + "seek past eof");
227 Source_file::forward_ch_C (int n
)
229 char const* old_pos_C
= pos_ch_C_
;
230 char const* new_ch_C
= pos_ch_C_
+ n
;
232 pos_ch_C_
= new_ch_C
;
234 error (error_str (new_ch_C
) + "forward past eof");
240 Source_file::get_str (int n
)
242 String
str ((Byte
const*)forward_ch_C (n
), n
);