5 #include <sys/types.h> // open, mmap
6 #include <sys/stat.h> // open
7 #include <sys/mman.h> // mmap
8 #include <limits.h> // INT_MAX
9 #include <fcntl.h> // open
10 #include <unistd.h> // close, stat
11 #include <stdio.h> // fdopen
12 #include <string.h> // strerror
13 #include <errno.h> // errno
15 #include <strstream.h>
23 #include "windhoos-suck-suck-suck-thank-you-cygnus.hh"
25 #include "source-file.hh"
27 Source_file::Source_file( String filename_str )
32 name_str_ = filename_str;
41 Source_file::istream_l()
46 if ( size_off_ ) // can-t this be done without such a hack?
47 istream_p_ = new istrstream( ch_C(), size_off_ );
49 istream_p_ = new istrstream( "", 0 );
50 istream_p_->set(ios::eofbit);
56 Source_file::~Source_file()
68 return (char const*)data_caddr_;
81 Source_file::error_str( char const* pos_ch_C )
83 char const* data_ch_C = ch_C();
84 char const * eof_C_ = data_ch_C + size_off_;
85 if ( !in_b( pos_ch_C ) )
86 return "(position unknown)";
89 if ( pos_ch_C == eof_C_)
91 char const* begin_ch_C = pos_ch_C;
92 while ( begin_ch_C > data_ch_C )
93 if ( *--begin_ch_C == '\n' ) {
98 char const* end_ch_C = pos_ch_C;
99 while ( end_ch_C < eof_C_ )
100 if ( *end_ch_C++ == '\n' ) {
105 // String( char const* p, int length ) is missing!?
106 String line_str( (Byte const*)begin_ch_C, end_ch_C - begin_ch_C );
109 char const* scan_ch_C = begin_ch_C;
110 while ( scan_ch_C < pos_ch_C )
111 if ( *scan_ch_C++ == '\t' )
112 error_col_i = ( error_col_i / 8 + 1 ) * 8;
116 String str = line_str.left_str( pos_ch_C - begin_ch_C )
118 + String( ' ', error_col_i )
119 + line_str.mid_str( pos_ch_C - begin_ch_C, INT_MAX ); // String::mid should take 0 arg..
124 Source_file::in_b( char const* pos_ch_C )
126 return ( pos_ch_C && ( pos_ch_C >= ch_C() ) && ( pos_ch_C <= ch_C() + size_off_ ) );
130 Source_file::length_off()
136 Source_file::line_i( char const* pos_ch_C )
138 if ( !in_b( pos_ch_C ) )
142 char const* scan_ch_C = ch_C();
143 while ( scan_ch_C < pos_ch_C )
144 if ( *scan_ch_C++ == '\n' )
152 if ( fildes_i_ == -1 )
155 data_caddr_ = (caddr_t)mmap( (void*)0, size_off_, PROT_READ, MAP_SHARED, fildes_i_, 0 );
157 if ( (int)data_caddr_ == -1 )
158 warning( String( "can't map: " ) + name_str_ + String( ": " ) + strerror( errno ));
162 Source_file::name_str()
170 if ( !name_str_.length_i() || ( name_str_ == "-" ) ) {
175 fildes_i_ = ::open( name_str_, O_RDONLY );
177 if ( fildes_i_ == -1 ) {
178 warning( String( "can't open: " ) + name_str_ + String( ": " ) + strerror( errno ));
182 struct stat file_stat;
183 fstat( fildes_i_, &file_stat );
184 size_off_ = file_stat.st_size;
191 munmap( data_caddr_, size_off_ );
197 Source_file::file_line_no_str(char const *ch_C )
199 return name_str() + ": "
200 + String( line_i( ch_C ) );