]> git.donarmstrong.com Git - lilypond.git/blob - lib/source-file.cc
patch::: 0.1.9.jcn2: pats
[lilypond.git] / lib / source-file.cc
1 /*
2   source-file.cc -- implement 
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     if ( !name_str_.length_i())
33         return &cin;
34     
35     if ( !istream_p_ ) 
36       {
37         if ( length_i() ) // can-t this be done without such a hack?
38             istream_p_ = new istrstream( ch_C(), length_i() );
39         else 
40           {
41             istream_p_ = new istrstream( "", 0 );
42             istream_p_->set(ios::eofbit);
43           }
44       }
45     return istream_p_;
46 }
47
48 String
49 Source_file::file_line_no_str(char const *ch_C )const
50 {
51     return name_str() + ": "
52         + String( line_i( ch_C ) );
53 }
54
55 String
56 Source_file::name_str()const
57 {
58     return name_str_;
59 }
60
61 Source_file::~Source_file()
62 {
63     delete istream_p_;
64     istream_p_ = 0;
65     delete storage_p_;
66 }
67
68 String
69 Source_file::error_str( char const* pos_ch_C )const
70 {
71     char const* data_ch_C = ch_C();
72     char const * eof_C_ = data_ch_C + length_i();
73     if ( !in_b( pos_ch_C ) )
74         return "(position unknown)";
75
76     
77     if ( pos_ch_C == eof_C_)
78         pos_ch_C --;
79     char const* begin_ch_C = pos_ch_C;
80     while ( begin_ch_C > data_ch_C )
81         if ( *--begin_ch_C == '\n' ) 
82           {
83             begin_ch_C++;
84             break;
85           }
86
87     char const* end_ch_C = pos_ch_C;
88     while ( end_ch_C < eof_C_ )
89         if ( *end_ch_C++ == '\n' ) 
90           {
91           end_ch_C--;
92           break;
93           }
94   
95         //    String( char const* p, int length ) is missing!?
96     String line_str( (Byte const*)begin_ch_C, end_ch_C - begin_ch_C );
97
98     int error_col_i = 0;
99     char const* scan_ch_C = begin_ch_C;
100     while ( scan_ch_C < pos_ch_C )
101         if ( *scan_ch_C++ == '\t' )
102             error_col_i = ( error_col_i / 8 + 1 ) * 8;
103         else
104             error_col_i++;
105
106     String str = line_str.left_str( pos_ch_C - begin_ch_C ) 
107         + String( '\n' )
108         + String( ' ', error_col_i ) 
109         + line_str.mid_str( pos_ch_C - begin_ch_C, INT_MAX ); // String::mid should take 0 arg..
110     return str;
111 }
112
113 bool
114 Source_file::in_b( char const* pos_ch_C )const
115 {
116     return ( pos_ch_C && ( pos_ch_C >= ch_C() ) && ( pos_ch_C <= ch_C() + length_i() ) );
117 }
118
119
120 int
121 Source_file::line_i( char const* pos_ch_C )const
122 {
123     if ( !in_b( pos_ch_C ) )
124         return 0;
125
126     int i = 1;
127     char const* scan_ch_C = ch_C();
128     while ( scan_ch_C < pos_ch_C )
129         if ( *scan_ch_C++ == '\n' )
130                 i++;
131     return i;
132 }
133
134 int
135 Source_file::length_i()const
136 {
137     return storage_p_->length_i();
138 }
139
140 char const *
141 Source_file::ch_C()const
142 {
143     return storage_p_->ch_C();
144 }