-rw-r--r-- | lib/sitecing_enflesher.ll | 76 |
1 files changed, 64 insertions, 12 deletions
diff --git a/lib/sitecing_enflesher.ll b/lib/sitecing_enflesher.ll index 5f631d7..46489c7 100644 --- a/lib/sitecing_enflesher.ll +++ b/lib/sitecing_enflesher.ll | |||
@@ -22,12 +22,7 @@ ID [A-Za-z_][A-Za-z0-9_]* | |||
22 | string line = yytext; | 22 | string line = yytext; |
23 | line.erase(0,3); | 23 | line.erase(0,3); |
24 | line.erase(line.length()-1); | 24 | line.erase(line.length()-1); |
25 | outs.flush(); | 25 | outs_open(parser.output_basename+line); |
26 | outs.close(); | ||
27 | outs.clear(); | ||
28 | outs.open((parser.output_basename+line).c_str(),ios::trunc); | ||
29 | if(!outs.good()) | ||
30 | throw preprocessor_error(CODEPOINT,"failed to write preprocessor output"); | ||
31 | anchor(); | 26 | anchor(); |
32 | anchoraged = true; | 27 | anchoraged = true; |
33 | } | 28 | } |
@@ -35,12 +30,7 @@ ID [A-Za-z_][A-Za-z0-9_]* | |||
35 | string line = yytext; | 30 | string line = yytext; |
36 | line.erase(0,2); | 31 | line.erase(0,2); |
37 | line.erase(line.length()-1); | 32 | line.erase(line.length()-1); |
38 | outs.flush(); | 33 | outs_open(parser.output_basename+line); |
39 | outs.close(); | ||
40 | outs.clear(); | ||
41 | outs.open((parser.output_basename+line).c_str(),ios::trunc); | ||
42 | if(!outs.good()) | ||
43 | throw preprocessor_error(CODEPOINT,"failed to write preprocessor output"); | ||
44 | anchoraged = false; | 34 | anchoraged = false; |
45 | } | 35 | } |
46 | 36 | ||
@@ -197,6 +187,68 @@ void sitecing_enflesher::anchor() { | |||
197 | outs << "\n#line " << lineno() << " \"" << parser.skeleton << "\"\n"; | 187 | outs << "\n#line " << lineno() << " \"" << parser.skeleton << "\"\n"; |
198 | anchor_time = false; | 188 | anchor_time = false; |
199 | } | 189 | } |
190 | |||
191 | void sitecing_enflesher::outs_open(const string& nfile) { | ||
192 | if(!outs_filename.empty()) { | ||
193 | outs.flush(); | ||
194 | outs.close(); | ||
195 | outs.clear(); | ||
196 | /* | ||
197 | * compare source and destination files. | ||
198 | * | ||
199 | * one can also keep a hash for the old one and compute one for the | ||
200 | * output while writing, but I'm not sure if it's any better. Surely a | ||
201 | * bit less accurate, unless we're going to compare it in case of | ||
202 | * difference, anyway. | ||
203 | */ | ||
204 | bool overwrite = false; | ||
205 | struct stat st_s, st_d; | ||
206 | string fn_s = outs_filename+".new"; | ||
207 | string fn_d = outs_filename; | ||
208 | if(stat(fn_d.c_str(),&st_d)) { | ||
209 | overwrite = true; | ||
210 | }else{ | ||
211 | if(stat(fn_s.c_str(),&st_s)) | ||
212 | throw preprocessor_error(CODEPOINT,"failed to stat() supposedly created file"); | ||
213 | if(st_s.st_size!=st_d.st_size) { | ||
214 | overwrite = true; | ||
215 | }else{ | ||
216 | ifstream i_s(fn_s.c_str(),ios::in); | ||
217 | if(!i_s) | ||
218 | throw preprocessor_error(CODEPOINT,"failed to open supposedly created file"); | ||
219 | ifstream i_d(fn_d.c_str(),ios::in); | ||
220 | if(!i_d) | ||
221 | throw preprocessor_error(CODEPOINT,"failed to open the old preprocessed source"); | ||
222 | off_t remaining = st_s.st_size; | ||
223 | char t1[2048]; | ||
224 | char t2[sizeof(t1)]; | ||
225 | while(remaining) { | ||
226 | int rb = remaining; | ||
227 | if(rb>sizeof(t1)) | ||
228 | rb = sizeof(t1); | ||
229 | if(i_s.read(t1,rb).gcount()!=rb) | ||
230 | throw preprocessor_error(CODEPOINT,"error reading just created file"); | ||
231 | if(i_d.read(t2,rb).gcount()!=rb) | ||
232 | throw preprocessor_error(CODEPOINT,"error reading the old preprocessed source"); | ||
233 | if(memcmp(t1,t2,rb)) { | ||
234 | overwrite = true; | ||
235 | break; | ||
236 | } | ||
237 | remaining -= rb; | ||
238 | } | ||
239 | } | ||
240 | } | ||
241 | if(overwrite) { | ||
242 | cerr << "renaming '" << fn_s << "'" << endl; | ||
243 | if(rename(fn_s.c_str(),fn_d.c_str())) | ||
244 | throw preprocessor_error(CODEPOINT,"failed to rename() generated output"); | ||
245 | } | ||
246 | } | ||
247 | outs_filename = nfile; | ||
248 | outs.open((nfile+".new").c_str(),ios::trunc); | ||
249 | if(!outs.good()) | ||
250 | throw preprocessor_error(CODEPOINT,"failed to write preprocessor output"); | ||
251 | } | ||
200 | /* | 252 | /* |
201 | * vim:set ft=lex: | 253 | * vim:set ft=lex: |
202 | */ | 254 | */ |