lilypond-0.1.45
[lilypond.git] / lib / source-file.cc
blobb6153c984ad6994fe8f5031df1ec1c6475d913e4
1 /*
2 source-file.cc -- implement Source_file
4 source file of the GNU LilyPond music typesetter
6 (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
7 & Han-Wen Nienhuys <hanwen@stack.nl>
8 */
11 #include <assert.h>
12 #include <strstream.h>
14 #include "string.hh"
15 #include "proto.hh"
16 #include "plist.hh"
17 #include "warn.hh"
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;
25 istream_p_ = 0;
26 storage_p_ = new Simple_file_storage (filename_str);
29 istream*
30 Source_file::istream_l ()
33 if (!name_str_.length_i ())
34 return &cin;
37 if (!istream_p_)
39 if (length_i ()) // can-t this be done without such a hack?
40 istream_p_ = new istrstream (ch_C (), length_i ());
41 else
43 istream_p_ = new istrstream ("", 0);
44 istream_p_->set (ios::eofbit);
47 return istream_p_;
50 String
51 Source_file::file_line_no_str (char const *context_ch_C) const
53 if (!ch_C ())
54 return _ ("(unknown)");
55 else
56 return name_str () + ": "
57 + String (line_i (context_ch_C));
60 String
61 Source_file::name_str () const
63 return name_str_;
66 Source_file::~Source_file ()
68 delete istream_p_;
69 istream_p_ = 0;
70 delete storage_p_;
73 String
74 Source_file::error_str (char const* pos_ch_C) const
76 char const* data_ch_C = ch_C ();
77 char const * eof_C_ = data_ch_C + length_i ();
78 if (!in_b (pos_ch_C))
79 return _ ("(position unknown)");
82 if (pos_ch_C == eof_C_)
83 pos_ch_C --;
84 char const* begin_ch_C = pos_ch_C;
85 while (begin_ch_C > data_ch_C)
86 if (*--begin_ch_C == '\n')
88 begin_ch_C++;
89 break;
92 char const* end_ch_C = pos_ch_C;
93 while (end_ch_C < eof_C_)
94 if (*end_ch_C++ == '\n')
96 end_ch_C--;
97 break;
100 // String (char const* p, int length) is missing!?
101 String line_str ((Byte const*)begin_ch_C, end_ch_C - begin_ch_C);
103 int error_col_i = 0;
104 char const* scan_ch_C = begin_ch_C;
105 while (scan_ch_C < pos_ch_C)
106 if (*scan_ch_C++ == '\t')
107 error_col_i = (error_col_i / 8 + 1) * 8;
108 else
109 error_col_i++;
111 String str = line_str.left_str (pos_ch_C - begin_ch_C)
112 + String ('\n')
113 + String (' ', error_col_i)
114 + line_str.cut (pos_ch_C - begin_ch_C, INT_MAX); // String::mid should take 0 arg..
115 return str;
118 bool
119 Source_file::in_b (char const* pos_ch_C) const
121 return (pos_ch_C && (pos_ch_C >= ch_C ()) && (pos_ch_C <= ch_C () + length_i ()));
126 Source_file::line_i (char const* pos_ch_C) const
128 if (!in_b (pos_ch_C))
129 return 0;
131 int i = 1;
132 char const* scan_ch_C = ch_C ();
133 if (!scan_ch_C)
134 return 0;
136 while (scan_ch_C < pos_ch_C)
137 if (*scan_ch_C++ == '\n')
138 i++;
139 return i;
143 Source_file::length_i () const
145 return storage_p_->length_i ();
148 char const *
149 Source_file::ch_C () const
151 return storage_p_->ch_C ();