summaryrefslogtreecommitdiffabout
path: root/lib/sitecing_enflesher.ll
authorMichael Krelin <hacker@klever.net>2005-03-30 15:50:28 (UTC)
committer Michael Krelin <hacker@klever.net>2005-03-30 15:50:28 (UTC)
commit3ddbfeafde93d1aab16a710498d86eef4e787406 (patch) (unidiff)
treed53ef21cf3b2bddfeb957c98344d0be8759ed555 /lib/sitecing_enflesher.ll
parent642dc685bd0a3f1526e22827a4539aa0e06aeff7 (diff)
downloadsitecing-3ddbfeafde93d1aab16a710498d86eef4e787406.zip
sitecing-3ddbfeafde93d1aab16a710498d86eef4e787406.tar.gz
sitecing-3ddbfeafde93d1aab16a710498d86eef4e787406.tar.bz2
1. preprocessor doesn't touch unchanged files anymore
2. doublechedk on whether file is up to date when making 3. changed the way preprocessor targets depend on the timestamp file 4. a bugfix in strip_suffix/strip_prefix
Diffstat (limited to 'lib/sitecing_enflesher.ll') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/sitecing_enflesher.ll76
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
@@ -1,67 +1,57 @@
1%{ 1%{
2#include <iostream> 2#include <iostream>
3#include <fstream> 3#include <fstream>
4#include <cassert> 4#include <cassert>
5#include <stdexcept> 5#include <stdexcept>
6using namespace std; 6using namespace std;
7#include "sitecing/sitecing_exception.h" 7#include "sitecing/sitecing_exception.h"
8using namespace sitecing; 8using namespace sitecing;
9#define sitecing_enflesher_flexlexer_once 9#define sitecing_enflesher_flexlexer_once
10#include "sitecing/sitecing_enflesher.h" 10#include "sitecing/sitecing_enflesher.h"
11#include "sitecing/sitecing_parser.h" 11#include "sitecing/sitecing_parser.h"
12#undef yyFlexLexer 12#undef yyFlexLexer
13#define yyFlexLexer sitecing_enflesherFlexLexer 13#define yyFlexLexer sitecing_enflesherFlexLexer
14%} 14%}
15%option 8bit c++ verbose noyywrap yyclass="sitecing_enflesher" yylineno prefix="sitecing_enflesher" stack debug 15%option 8bit c++ verbose noyywrap yyclass="sitecing_enflesher" yylineno prefix="sitecing_enflesher" stack debug
16 16
17 ID[A-Za-z_][A-Za-z0-9_]* 17 ID[A-Za-z_][A-Za-z0-9_]*
18 18
19%% 19%%
20 20
21 ^\%\%\#[^\n]+\n{ 21 ^\%\%\#[^\n]+\n{
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}
34 ^\%\%[^\n]+\n{ 29 ^\%\%[^\n]+\n{
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
47 \<\%component_basename\%\>outs << parser.component_basename; anchor_time = true; 37 \<\%component_basename\%\>outs << parser.component_basename; anchor_time = true;
48 \<\%impl\%\> outs << parser.impl; anchor_time = true; 38 \<\%impl\%\> outs << parser.impl; anchor_time = true;
49 \<\%member_functions:impl\%\>{ 39 \<\%member_functions:impl\%\>{
50 for(sitecing_parser::member_functions_t::const_iterator i=parser.member_functions.begin();i!=parser.member_functions.end();i++) { 40 for(sitecing_parser::member_functions_t::const_iterator i=parser.member_functions.begin();i!=parser.member_functions.end();i++) {
51 outs << i->type << " " << parser.class_name << "::"; 41 outs << i->type << " " << parser.class_name << "::";
52 if(i->name.empty()) { 42 if(i->name.empty()) {
53 outs << parser.class_name << "()"; 43 outs << parser.class_name << "()";
54 bool first = true; 44 bool first = true;
55 for(sitecing_parser::member_variables_t::iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) { 45 for(sitecing_parser::member_variables_t::iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) {
56 if(i->initializer.empty()) 46 if(i->initializer.empty())
57 continue; 47 continue;
58 if(first) { 48 if(first) {
59 outs << ":"; 49 outs << ":";
60 first=false; 50 first=false;
61 }else{ 51 }else{
62 outs << ","; 52 outs << ",";
63 } 53 }
64 if(i->bComponent) { 54 if(i->bComponent) {
65 outs << i->name << "(NULL)"; 55 outs << i->name << "(NULL)";
66 }else { 56 }else {
67 outs << i->name << "(" << i->initializer << ")"; 57 outs << i->name << "(" << i->initializer << ")";
@@ -176,27 +166,89 @@ ID [A-Za-z_][A-Za-z0-9_]*
176 ECHO; 166 ECHO;
177} 167}
178 . ECHO; 168 . ECHO;
179 169
180%% 170%%
181 171
182void sitecing_enflesher::LexerOutput(const char *buf,int size) { 172void sitecing_enflesher::LexerOutput(const char *buf,int size) {
183 outs.write(buf,size); 173 outs.write(buf,size);
184} 174}
185 175
186void sitecing_enflesher::enflesh() { 176void sitecing_enflesher::enflesh() {
187 ifstream ifs(parser.skeleton.c_str()); 177 ifstream ifs(parser.skeleton.c_str());
188 if(!ifs.good()) 178 if(!ifs.good())
189 throw preprocessor_error(CODEPOINT,"failed to open skeleton file"); 179 throw preprocessor_error(CODEPOINT,"failed to open skeleton file");
190 switch_streams(&ifs,NULL); 180 switch_streams(&ifs,NULL);
191 yylex(); 181 yylex();
192} 182}
193 183
194void sitecing_enflesher::anchor() { 184void sitecing_enflesher::anchor() {
195 if(!anchoraged) 185 if(!anchoraged)
196 return; 186 return;
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
191void 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 */