]> git.donarmstrong.com Git - lilypond.git/blob - lib/source-file.cc
release: 0.1.39
[lilypond.git] / lib / source-file.cc
1 /*
2   source-file.cc -- implement Source_file
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
7   & Han-Wen Nienhuys <hanwen@stack.nl>
8 */
9
10
11 #include <assert.h>
12 #include <strstream.h>
13
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 "file-storage.hh"
21
22 Source_file::Source_file(String filename_str)
23 {
24   name_str_ = filename_str;
25   istream_p_ = 0;
26   storage_p_ = new Simple_file_storage(filename_str);
27 }
28
29 istream*
30 Source_file::istream_l()
31 {
32   /*
33     if (!name_str_.length_i())
34       return &cin;
35     */
36
37   if (!istream_p_)
38     {
39       if (length_i()) // can-t this be done without such a hack?
40         istream_p_ = new istrstream(ch_C(), length_i());
41       else
42         {
43           istream_p_ = new istrstream("", 0);
44           istream_p_->set(ios::eofbit);
45         }
46     }
47   return istream_p_;
48 }
49
50 String
51 Source_file::file_line_no_str(char const *context_ch_C) const
52 {
53   if  (!ch_C())
54     return _("(unknown)");
55   else
56     return name_str() + ": "
57       + String(line_i(context_ch_C));
58 }
59
60 String
61 Source_file::name_str() const
62 {
63   return name_str_;
64 }
65
66 Source_file::~Source_file()
67 {
68   delete istream_p_;
69   istream_p_ = 0;
70   delete storage_p_;
71 }
72
73 String
74 Source_file::error_str(char const* pos_ch_C) const
75 {
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)");
80
81
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')
87       {
88         begin_ch_C++;
89         break;
90       }
91
92   char const* end_ch_C = pos_ch_C;
93   while (end_ch_C < eof_C_)
94     if (*end_ch_C++ == '\n')
95       {
96         end_ch_C--;
97         break;
98       }
99
100   //    String(char const* p, int length) is missing!?
101   String line_str((Byte const*)begin_ch_C, end_ch_C - begin_ch_C);
102
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++;
110
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;
116 }
117
118 bool
119 Source_file::in_b(char const* pos_ch_C) const
120 {
121   return (pos_ch_C && (pos_ch_C >= ch_C()) && (pos_ch_C <= ch_C() + length_i()));
122 }
123
124
125 int
126 Source_file::line_i(char const* pos_ch_C) const
127 {
128   if (!in_b(pos_ch_C))
129     return 0;
130
131   int i = 1;
132   char const* scan_ch_C = ch_C();
133   if (!scan_ch_C)
134     return 0;
135
136   while (scan_ch_C < pos_ch_C)
137     if (*scan_ch_C++ == '\n')
138       i++;
139   return i;
140 }
141
142 int
143 Source_file::length_i() const
144 {
145   return storage_p_->length_i();
146 }
147
148 char const *
149 Source_file::ch_C() const
150 {
151   return storage_p_->ch_C();
152 }