2 source-file.cc -- implement Source_file
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--1998 Jan Nieuwenhuizen <jan@digicash.com>
7 & Han-Wen Nienhuys <hanwen@stack.nl>
12 #include <strstream.h>
18 #include "windhoos-suck-suck-suck-thank-you-cygnus.hh"
19 #include "source-file.hh"
20 #include "simple-file-storage.hh"
22 Source_file::Source_file (String filename_str)
24 name_str_ = filename_str;
26 storage_p_ = new Simple_file_storage (filename_str);
30 Source_file::istream_l ()
33 if (!name_str_.length_i ())
39 if (length_i ()) // can-t this be done without such a hack?
40 istream_p_ = new istrstream (ch_C (), length_i ());
43 istream_p_ = new istrstream ("", 0);
44 istream_p_->set (ios::eofbit);
51 Source_file::file_line_column_str (char const *context_ch_C) const
54 return _ ("(unknown)");
56 return name_str () + ":" + String (line_i (context_ch_C))
57 + ":" + String (position_i (context_ch_C));
61 Source_file::name_str () const
66 Source_file::~Source_file ()
74 Source_file::line_slice (char const* pos_ch_C) const
79 char const* data_ch_C = ch_C ();
80 char const * eof_C_ = data_ch_C + length_i ();
82 if (pos_ch_C == eof_C_)
84 char const* begin_ch_C = pos_ch_C;
85 while (begin_ch_C > data_ch_C)
86 if (*--begin_ch_C == '\n')
92 char const* end_ch_C = pos_ch_C;
93 while (end_ch_C < eof_C_)
94 if (*end_ch_C++ == '\n')
100 return Slice (begin_ch_C - data_ch_C, end_ch_C - data_ch_C);
104 Source_file::line_str (char const* pos_ch_C) const
106 if (!in_b (pos_ch_C))
109 Slice line = line_slice (pos_ch_C);
110 char const* data_ch_C = ch_C ();
111 return String ((Byte const*)data_ch_C + line.min (), line.length ());
115 Source_file::position_i (char const* pos_ch_C) const
117 if (!in_b (pos_ch_C))
120 char const* data_ch_C = ch_C ();
121 return pos_ch_C - (line_slice (pos_ch_C).min () + data_ch_C);
125 Source_file::column_i (char const* pos_ch_C) const
127 if (!in_b (pos_ch_C))
130 int pos_i = position_i (pos_ch_C);
131 String line = line_str (pos_ch_C);
134 for (int i = 0; i < pos_i; i++)
136 col_i = (col_i / 8 + 1) * 8;
144 Source_file::error_str (char const* pos_ch_C) const
146 if (!in_b (pos_ch_C))
147 return _ ("(position unknown)");
149 int pos_i = position_i (pos_ch_C);
150 String line = line_str (pos_ch_C);
151 String context = line.left_str (pos_i)
153 + String (' ', column_i (pos_ch_C))
154 + line.cut (pos_i, INT_MAX);
160 Source_file::in_b (char const* pos_ch_C) const
162 return (pos_ch_C && (pos_ch_C >= ch_C ()) && (pos_ch_C <= ch_C () + length_i ()));
166 Source_file::line_i (char const* pos_ch_C) const
168 if (!in_b (pos_ch_C))
172 char const* scan_ch_C = ch_C ();
176 while (scan_ch_C < pos_ch_C)
177 if (*scan_ch_C++ == '\n')
183 Source_file::length_i () const
185 return storage_p_->length_i ();
189 Source_file::ch_C () const
191 return storage_p_->ch_C ();