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>
22 #include "parseconstruct.hh"
23 #include "main.hh" // find_file
25 #include "sourcefile.hh"
27 Source_file::Source_file( String
&filename_str
)
32 name_str_
= filename_str
;
37 // ugh!?, should call name_str() !
38 filename_str
= name_str_
;
41 Source_file::~Source_file()
53 return (char const*)data_caddr_
;
66 Source_file::error_str( char const* pos_ch_c_l
)
69 if ( !in_b( pos_ch_c_l
) )
72 char const* begin_ch_c_l
= pos_ch_c_l
;
73 char const* data_ch_c_l
= ch_c_l();
74 while ( begin_ch_c_l
> data_ch_c_l
)
75 if ( *--begin_ch_c_l
== '\n' ) {
80 char const* end_ch_c_l
= pos_ch_c_l
;
81 while ( end_ch_c_l
< data_ch_c_l
+ size_off_
)
82 if ( *end_ch_c_l
++ == '\n' ) {
88 // String( char const* p, int length ) is missing!?
89 String
line_str( (Byte
const*)begin_ch_c_l
, end_ch_c_l
- begin_ch_c_l
);
91 int length_i
= end_ch_c_l
- begin_ch_c_l
;
92 char* ch_p
= new char[ length_i
+ 1 ];
93 strncpy( ch_p
, begin_ch_c_l
, length_i
);
95 String
line_str( ch_p
);
100 char const* scan_ch_c_l
= begin_ch_c_l
;
101 while ( scan_ch_c_l
< pos_ch_c_l
)
102 if ( *scan_ch_c_l
++ == '\t' )
103 error_col_i
= ( error_col_i
/ 8 + 1 ) * 8;
107 String str
= line_str
.left_str( pos_ch_c_l
- begin_ch_c_l
)
109 + String( ' ', error_col_i
)
110 + line_str
.mid_str( pos_ch_c_l
- begin_ch_c_l
+ 1, INT_MAX
); // String::mid should take 0 arg..
115 Source_file::in_b( char const* pos_ch_c_l
)
117 return ( pos_ch_c_l
&& ( pos_ch_c_l
>= ch_c_l() ) && ( pos_ch_c_l
< ch_c_l() + size_off_
) );
121 Source_file::istream_l()
125 if ( size_off_
) // can-t this be done without such a hack?
126 istream_p_
= new istrstream( ch_c_l(), size_off_
);
128 istream_p_
= new istrstream( "", 0 );
129 istream_p_
->set(ios::eofbit
);
136 Source_file::length_off()
142 Source_file::line_i( char const* pos_ch_c_l
)
144 if ( !in_b( pos_ch_c_l
) )
148 char const* scan_ch_c_l
= ch_c_l();
149 while ( scan_ch_c_l
< pos_ch_c_l
)
150 if ( *scan_ch_c_l
++ == '\n' )
158 if ( fildes_i_
== -1 )
161 data_caddr_
= (caddr_t
)mmap( (void*)0, size_off_
, PROT_READ
, MAP_SHARED
, fildes_i_
, 0 );
163 if ( (int)data_caddr_
== -1 )
164 // ugh: defined_ch_c_l...
165 warning( String( "can't map: " ) + name_str_
+ String( ": " ) + strerror( errno
), defined_ch_c_l
); //lexer->here_ch_c_l() );
169 Source_file::name_str()
177 String name_str
= find_file( name_str_
);
178 if ( name_str
!= "" )
179 name_str_
= name_str
;
181 fildes_i_
= ::open( name_str_
, O_RDONLY
);
183 if ( fildes_i_
== -1 ) {
184 warning( String( "can't open: " ) + name_str_
+ String( ": " ) + strerror( errno
), defined_ch_c_l
); // lexer->here_ch_c_l() );
188 struct stat file_stat
;
189 fstat( fildes_i_
, &file_stat
);
190 size_off_
= file_stat
.st_size
;
197 munmap( data_caddr_
, size_off_
);
203 Source_file::file_line_no_str(char const *ch_c_l
)
205 return name_str() + ": "
206 + String( line_i( ch_c_l
) );