summaryrefslogtreecommitdiffabout
path: root/lib
Unidiff
Diffstat (limited to 'lib') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/component_factory.cc2
-rw-r--r--lib/sitecing_enflesher.ll8
-rw-r--r--lib/sitecing_parser.ll49
3 files changed, 55 insertions, 4 deletions
diff --git a/lib/component_factory.cc b/lib/component_factory.cc
index b8f5a16..1253111 100644
--- a/lib/component_factory.cc
+++ b/lib/component_factory.cc
@@ -130,203 +130,203 @@ namespace sitecing {
130 strip_prefix(dp,root_so); 130 strip_prefix(dp,root_so);
131 return file_factory::is_uptodate(dst,deps); 131 return file_factory::is_uptodate(dst,deps);
132 }catch(utility_no_prefix& unp) { } 132 }catch(utility_no_prefix& unp) { }
133 return true; 133 return true;
134 } 134 }
135 135
136 void component_factory::build(const string& dst) { 136 void component_factory::build(const string& dst) {
137 string dp = normalize_path(dst,strip_trailing_slash); 137 string dp = normalize_path(dst,strip_trailing_slash);
138 // sources 138 // sources
139 try { 139 try {
140 string noro = strip_prefix(dp,root_source); 140 string noro = strip_prefix(dp,root_source);
141 // building the sources is left up to developer 141 // building the sources is left up to developer
142 return; 142 return;
143 }catch(utility_no_prefix& unp) { 143 }catch(utility_no_prefix& unp) {
144 } 144 }
145 // .so files 145 // .so files
146 try { 146 try {
147 string noso = strip_suffix(dp,".so"); 147 string noso = strip_suffix(dp,".so");
148 string noro = strip_prefix(noso,root_so); 148 string noro = strip_prefix(noso,root_so);
149 string o = root_intermediate+noro+".o"; 149 string o = root_intermediate+noro+".o";
150 if(access(o.c_str(),R_OK)) 150 if(access(o.c_str(),R_OK))
151 throw konforka::exception(CODEPOINT,string("can't access compiled component code (")+o+")"); 151 throw konforka::exception(CODEPOINT,string("can't access compiled component code (")+o+")");
152 make_path(dir_name(root_so+noro),0755); 152 make_path(dir_name(root_so+noro),0755);
153 file_lock lock_cc(root_intermediate+noro+".o.lock"); 153 file_lock lock_cc(root_intermediate+noro+".o.lock");
154 file_lock lock_so(root_so+noro+".so.lock"); 154 file_lock lock_so(root_so+noro+".so.lock");
155 int stdO = open((root_intermediate+noro+".ld.stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); 155 int stdO = open((root_intermediate+noro+".ld.stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664);
156 if(stdO<0) 156 if(stdO<0)
157 throw konforka::exception(CODEPOINT,"failed to open/create linker stdout"); 157 throw konforka::exception(CODEPOINT,"failed to open/create linker stdout");
158 int stdE = open((root_intermediate+noro+".ld.stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); 158 int stdE = open((root_intermediate+noro+".ld.stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664);
159 if(stdE<0) { 159 if(stdE<0) {
160 close(stdO); 160 close(stdO);
161 throw konforka::exception(CODEPOINT,"failed to open/create linker stderr"); 161 throw konforka::exception(CODEPOINT,"failed to open/create linker stderr");
162 } 162 }
163 list<string> args; 163 list<string> args;
164 config_options *co_ld_flags = config.lookup_config(noro,config_options::flag_ld_flags); 164 config_options *co_ld_flags = config.lookup_config(noro,config_options::flag_ld_flags);
165 if(co_ld_flags) { 165 if(co_ld_flags) {
166 args.insert(args.end(),co_ld_flags->ld_flags.begin(),co_ld_flags->ld_flags.end()); 166 args.insert(args.end(),co_ld_flags->ld_flags.begin(),co_ld_flags->ld_flags.end());
167 } 167 }
168 args.push_back("-shared"); 168 args.push_back("-shared");
169 args.push_back(o); 169 args.push_back(o);
170 file_list_t ancestors; 170 file_list_t ancestors;
171 get_ancestors(noro,ancestors); 171 get_ancestors(noro,ancestors);
172 for(file_list_t::const_iterator i=ancestors.begin();i!=ancestors.end();++i) { 172 for(file_list_t::const_iterator i=ancestors.begin();i!=ancestors.end();++i) {
173 string aso=root_so+*i+".so"; 173 string aso=root_so+*i+".so";
174 make(aso); 174 make(aso);
175 args.push_back(aso); 175 args.push_back(aso);
176 } 176 }
177 args.push_back("-o"); args.push_back(dp); 177 args.push_back("-o"); args.push_back(dp);
178 // TODO: "g++" configurable 178 // TODO: "g++" configurable
179 int rv = execute("g++",args,stdO,stdE); 179 int rv = execute("g++",args,stdO,stdE);
180 if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) ) 180 if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) )
181 // TODO:TODO: linker_error 181 // TODO:TODO: linker_error
182 throw compile_error(CODEPOINT,"failed to link component",noro); 182 throw compile_error(CODEPOINT,"failed to link component",noro);
183 return; 183 return;
184 }catch(utility_no_prefix& unp) { 184 }catch(utility_no_prefix& unp) {
185 throw konforka::exception(CODEPOINT,"component is outside of component root"); 185 throw konforka::exception(CODEPOINT,"component is outside of component root");
186 }catch(utility_no_suffix& uns) { 186 }catch(utility_no_suffix& uns) {
187 } 187 }
188 // compiler targets 188 // compiler targets
189 for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) { 189 for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) {
190 try { 190 try {
191 string nos = strip_suffix(dp,cc_targets[cct]); 191 string nos = strip_suffix(dp,cc_targets[cct]);
192 string noro = strip_prefix(nos,root_intermediate); 192 string noro = strip_prefix(nos,root_intermediate);
193 string cc = root_intermediate+noro+".cc"; 193 string cc = root_intermediate+noro+".cc";
194 string o = root_intermediate+noro+".o"; 194 string o = root_intermediate+noro+".o";
195 if(access(cc.c_str(),R_OK)) 195 if(access(cc.c_str(),R_OK))
196 throw konforka::exception(CODEPOINT,string("can't access preprocessed component code (")+cc+")"); 196 throw konforka::exception(CODEPOINT,string("can't access preprocessed component code (")+cc+")");
197 make_path(dir_name(cc),0755); 197 make_path(dir_name(cc),0755);
198 string pwd = dir_name(root_source+noro); 198 string pwd = dir_name(root_source+noro);
199 auto_chdir dir_changer(pwd); 199 auto_chdir dir_changer(pwd);
200 file_lock lock_source(root_intermediate+noro+".lock"); 200 file_lock lock_source(root_intermediate+noro+".lock");
201 file_lock lock_cc(root_intermediate+noro+".o.lock"); 201 file_lock lock_cc(root_intermediate+noro+".o.lock");
202 int stdO = open((root_intermediate+noro+".stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); 202 int stdO = open((root_intermediate+noro+".stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664);
203 if(stdO<0) 203 if(stdO<0)
204 throw konforka::exception(CODEPOINT,"failed to open/create compiler stdout"); 204 throw konforka::exception(CODEPOINT,"failed to open/create compiler stdout");
205 int stdE = open((root_intermediate+noro+".stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); 205 int stdE = open((root_intermediate+noro+".stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664);
206 if(stdE<0) { 206 if(stdE<0) {
207 close(stdO); 207 close(stdO);
208 throw konforka::exception(CODEPOINT,"failed to open/create compiler's stderr"); 208 throw konforka::exception(CODEPOINT,"failed to open/create compiler's stderr");
209 } 209 }
210 list<string> args; 210 list<string> args;
211 config_options *co_cpp_flags = config.lookup_config(noro,config_options::flag_cpp_flags); 211 config_options *co_cpp_flags = config.lookup_config(noro,config_options::flag_cpp_flags);
212 if(co_cpp_flags) { 212 if(co_cpp_flags) {
213 args.insert(args.end(),co_cpp_flags->cpp_flags.begin(),co_cpp_flags->cpp_flags.end()); 213 args.insert(args.end(),co_cpp_flags->cpp_flags.begin(),co_cpp_flags->cpp_flags.end());
214 } 214 }
215 // TODO: maybe move it to separare config option like CoreCPPFLags? 215 // TODO: maybe move it to separare config option like CoreCPPFLags?
216 args.push_back("-I"+root_intermediate); 216 args.push_back("-I"+root_intermediate);
217 args.push_back("-I"+root_source); 217 args.push_back("-I"+root_source);
218 args.push_back("-MD"); args.push_back("-MF"); args.push_back(root_intermediate+noro+".d"); 218 args.push_back("-MD"); args.push_back("-MF"); args.push_back(root_intermediate+noro+".d");
219 args.push_back("-c"); 219 args.push_back("-c");
220 args.push_back(cc); 220 args.push_back(cc);
221 args.push_back("-o"); args.push_back(o); 221 args.push_back("-o"); args.push_back(o);
222 // TODO: "g++" configurable 222 // TODO: "g++" configurable
223 int rv = execute("g++",args,stdO,stdE); 223 int rv = execute("g++",args,stdO,stdE);
224 if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) ) 224 if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) )
225 throw compile_error(CODEPOINT,"failed to compile component",noro); 225 throw compile_error(CODEPOINT,"failed to compile component",noro);
226 return; 226 return;
227 }catch(utility_no_affix& una) { 227 }catch(utility_no_affix& una) {
228 // do nothing, not a compiler target 228 // do nothing, not a compiler target
229 } 229 }
230 } 230 }
231 // preprocessor targets 231 // preprocessor targets
232 for(int ppt=0;ppt<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { 232 for(int ppt=0;ppt<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) {
233 try { 233 try {
234 string nos = strip_suffix(dp,pp_targets[ppt]); 234 string nos = strip_suffix(dp,pp_targets[ppt]);
235 string noro = strip_prefix(nos,root_intermediate); 235 string noro = strip_prefix(nos,root_intermediate);
236 string src = root_source+noro; 236 string src = root_source+noro;
237 if(access(src.c_str(),R_OK)) 237 if(access(src.c_str(),R_OK))
238 throw konforka::exception(CODEPOINT,string("can't access component source (")+src+")"); 238 throw konforka::exception(CODEPOINT,string("can't access component source (")+src+")");
239 make_path(dir_name(root_intermediate+noro),0755); 239 make_path(dir_name(root_intermediate+noro),0755);
240 file_lock lock(root_intermediate+noro+".lock"); 240 file_lock lock(root_intermediate+noro+".lock");
241 sitecing_parser parser(*this); 241 sitecing_parser parser(*this);
242 config_options *co_skeleton = config.lookup_config(noro,config_options::flag_skeleton); 242 config_options *co_skeleton = config.lookup_config(noro,config_options::flag_skeleton);
243 if(co_skeleton) 243 if(co_skeleton)
244 parser.skeleton = co_skeleton->skeleton; 244 parser.skeleton = co_skeleton->skeleton;
245 static const char *id_chars = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 245 static const char *id_chars = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
246 parser.class_name = normalize_path(noro,strip_leading_slash|strip_trailing_slash); 246 parser.class_name = normalize_path(noro,strip_leading_slash|strip_trailing_slash);
247 for(string::size_type illc = parser.class_name.find_first_not_of(id_chars);illc!=string::npos;illc=parser.class_name.find_first_not_of(id_chars,illc)) { 247 for(string::size_type illc = parser.class_name.find_first_not_of(id_chars);illc!=string::npos;illc=parser.class_name.find_first_not_of(id_chars,illc)) {
248 string::size_type lc = parser.class_name.find_first_of(id_chars,illc); 248 string::size_type lc = parser.class_name.find_first_of(id_chars,illc);
249 int n = ((lc==string::npos)?parser.class_name.length():lc)-illc; 249 int n = ((lc==string::npos)?parser.class_name.length():lc)-illc;
250 parser.class_name.replace(illc,n,n,'_'); 250 parser.class_name.replace(illc,n,n,'_');
251 } 251 }
252 parser.class_name = "_SCC_"+parser.class_name; 252 parser.class_name = "_SCC_"+parser.class_name;
253 parser.output_basename = nos; 253 parser.output_basename = nos;
254 parser.component_basename = noro; 254 parser.component_basename = noro;
255 try { 255 try {
256 parser.preprocess(src); 256 parser.preprocess(src);
257 string sf = root_intermediate+noro+".pp_stamp"; 257 string sf = root_intermediate+noro+".pp_stamp";
258 ofstream sfs(sf.c_str(),ios::trunc|ios::out); // touch .pp_stamp 258 ofstream sfs(sf.c_str(),ios::trunc|ios::out); // touch .pp_stamp
259 }catch(preprocessor_error& pe) { 259 }catch(preprocessor_error& pe) {
260 pe.component_name = noro; 260 pe.component_name = noro;
261 pe.see(CODEPOINT); 261 pe.see(CODEPOINT);
262 throw; 262 throw;
263 } 263 }
264 return; 264 return;
265 }catch(utility_no_affix& una) { 265 }catch(utility_no_affix& una) {
266 // must be a crap from .d file 266 // must be a crap from .d file
267 } 267 }
268 } 268 }
269 cerr << "ignoring build request for " << dp << endl; 269 cerr << "ignoring build request for " << dp << endl;
270 } 270 }
271 271
272 int component_factory::execute(const string& cmd, const list<string>& args,int stdo,int stde) { 272 int component_factory::execute(const string& cmd, const list<string>& args,int stdo,int stde) {
273 // XXX: is it right that we do stdio/stderr tricks outside of the function? 273 // XXX: is it right that we do stdio/stderr tricks outside of the function?
274 cerr << "executing: " << cmd; 274 cerr << "executing: " << cmd;
275 vector<const char*> argv(args.size()+2); 275 vector<const char*> argv(args.size()+2);
276 argv[0]=cmd.c_str(); 276 argv[0]=cmd.c_str();
277 int an = 1; 277 int an = 1;
278 for(list<string>::const_iterator i=args.begin();i!=args.end();i++) { 278 for(list<string>::const_iterator i=args.begin();i!=args.end();i++) {
279 cerr << " " << *i ; 279 cerr << " " << *i ;
280 argv[an++] = i->c_str(); 280 argv[an++] = i->c_str();
281 } 281 }
282 cerr << endl; 282 cerr << endl;
283 argv[an++]=NULL; 283 argv[an++]=NULL;
284 pid_t pid = vfork(); 284 pid_t pid = vfork();
285 if(pid==-1) { 285 if(pid==-1) {
286 close(stdo); close(stde); 286 close(stdo); close(stde);
287 throw konforka::exception(CODEPOINT,"failed to vfork()"); 287 throw konforka::exception(CODEPOINT,"failed to vfork()");
288 } 288 }
289 if(!pid) { 289 if(!pid) {
290 // child 290 // child
291 if(dup2(stdo,1)!=1) 291 if(dup2(stdo,1)!=1)
292 _exit(-1); 292 _exit(-1);
293 if(dup2(stde,2)!=2) 293 if(dup2(stde,2)!=2)
294 _exit(-1); 294 _exit(-1);
295 close(0); 295 close(0);
296 execvp(cmd.c_str(),(char**)&argv.front()); 296 execvp(cmd.c_str(),(char**)&argv.front());
297 _exit(-1); 297 _exit(-1);
298 } 298 }
299 // parent 299 // parent
300 close(stdo); close(stde); 300 close(stdo); close(stde);
301 int rv; 301 int rv;
302 if(waitpid(pid,&rv,0)<0) 302 if(waitpid(pid,&rv,0)<0)
303 throw konforka::exception(CODEPOINT,"failed to waitpid()"); 303 throw konforka::exception(CODEPOINT,"failed to waitpid()");
304 return rv; 304 return rv;
305 } 305 }
306 306
307 string component_factory::get_classname(const string& component) { 307 string component_factory::get_classname(const string& component) {
308 string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".classname"; 308 string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".classname";
309 make(cn); 309 make(cn);
310 ifstream ifs(cn.c_str()); 310 ifstream ifs(cn.c_str());
311 if(!ifs.good()) 311 if(!ifs.good())
312 throw konforka::exception(CODEPOINT,"failed to access component .classname"); 312 throw konforka::exception(CODEPOINT,"failed to access component .classname");
313 ifs >> cn; 313 ifs >> cn;
314 return cn; 314 return cn;
315 } 315 }
316 316
317 void component_factory::get_ancestors(const string& component,file_list_t& rv) { 317 void component_factory::get_ancestors(const string& component,file_list_t& rv) {
318 string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".ancestors"; 318 string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".ancestors";
319 make(cn); 319 make(cn);
320 ifstream ifs(cn.c_str()); 320 ifstream ifs(cn.c_str());
321 if(!ifs.good()) 321 if(!ifs.good())
322 throw konforka::exception(CODEPOINT,"filed to access component .ancestors"); 322 throw konforka::exception(CODEPOINT,string("failed to access component '")+component+"' .ancestors");
323 rv.clear(); 323 rv.clear();
324 while(!ifs.eof()) { 324 while(!ifs.eof()) {
325 string a; 325 string a;
326 ifs >> a; 326 ifs >> a;
327 if(!a.empty()) 327 if(!a.empty())
328 rv.push_back(a); 328 rv.push_back(a);
329 } 329 }
330 } 330 }
331 331
332} 332}
diff --git a/lib/sitecing_enflesher.ll b/lib/sitecing_enflesher.ll
index 46489c7..bb667be 100644
--- a/lib/sitecing_enflesher.ll
+++ b/lib/sitecing_enflesher.ll
@@ -1,254 +1,260 @@
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_open(parser.output_basename+line); 25 outs_open(parser.output_basename+line);
26 anchor(); 26 anchor();
27 anchoraged = true; 27 anchoraged = true;
28} 28}
29 ^\%\%[^\n]+\n{ 29 ^\%\%[^\n]+\n{
30 string line = yytext; 30 string line = yytext;
31 line.erase(0,2); 31 line.erase(0,2);
32 line.erase(line.length()-1); 32 line.erase(line.length()-1);
33 outs_open(parser.output_basename+line); 33 outs_open(parser.output_basename+line);
34 anchoraged = false; 34 anchoraged = false;
35} 35}
36 36
37 \<\%component_basename\%\>outs << parser.component_basename; anchor_time = true; 37 \<\%component_basename\%\>outs << parser.component_basename; anchor_time = true;
38 \<\%impl\%\> outs << parser.impl; anchor_time = true; 38 \<\%impl\%\> outs << parser.impl; anchor_time = true;
39 \<\%member_functions:impl\%\>{ 39 \<\%member_functions:impl\%\>{
40 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++) {
41 outs << i->type << " " << parser.class_name << "::"; 41 outs << i->type << " " << parser.class_name << "::";
42 if(i->name.empty()) { 42 if(i->name.empty()) {
43 outs << parser.class_name << "()"; 43 outs << parser.class_name << "()";
44 bool first = true; 44 bool first = true;
45 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++) {
46 if(i->initializer.empty()) 46 if(i->initializer.empty())
47 continue; 47 continue;
48 if(first) { 48 if(first) {
49 outs << ":"; 49 outs << ":";
50 first=false; 50 first=false;
51 }else{ 51 }else{
52 outs << ","; 52 outs << ",";
53 } 53 }
54 if(i->bComponent) { 54 if(i->bComponent) {
55 outs << i->name << "(NULL)"; 55 outs << i->name << "(NULL)";
56 }else { 56 }else {
57 outs << i->name << "(" << i->initializer << ")"; 57 outs << i->name << "(" << i->initializer << ")";
58 } 58 }
59 } 59 }
60 }else if(i->name == "~") 60 }else if(i->name == "~")
61 outs << "~" << parser.class_name << "()"; 61 outs << "~" << parser.class_name << "()";
62 else 62 else
63 outs << i->name << i->args; 63 outs << i->name << i->args;
64 outs << "{\n" << i->body << "\n}\n"; 64 outs << "{\n" << i->body << "\n}\n";
65 } 65 }
66 anchor_time = true; 66 anchor_time = true;
67} 67}
68 \<\%class_name\%\> outs << parser.class_name; anchor_time = true; 68 \<\%class_name\%\> outs << parser.class_name; anchor_time = true;
69 \<\%baseclass_header\%\>outs << parser.base_header; anchor_time = true; 69 \<\%baseclass_header\%\>outs << parser.base_header; anchor_time = true;
70 \<\%decl\%\> outs << parser.decl; anchor_time = true; 70 \<\%decl\%\> outs << parser.decl; anchor_time = true;
71 \<\%baseclass_name\%\> outs << parser.base_class; anchor_time = true; 71 \<\%baseclass_name\%\> outs << parser.base_class; anchor_time = true;
72 \<\%member_variables:decl\%\>{ 72 \<\%member_variables:decl\%\>{
73 for(sitecing_parser::member_variables_t::iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) { 73 for(sitecing_parser::member_variables_t::iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) {
74 if(i->bComponent) { 74 if(i->bComponent) {
75 if(i->type.empty()) { 75 if(i->type.empty()) {
76 i->type = parser.factory.get_classname(i->initializer); 76 i->type = parser.factory.get_classname(i->initializer);
77 } 77 }
78 if(i->bTypeOnly) { 78 if(i->bTypeOnly) {
79 outs << "typedef " << i->type << " " << i->name << ";\n"; 79 outs << "typedef " << i->type << " " << i->name << ";\n";
80 }else{ 80 }else{
81 outs << "typedef " << i->type << " __type_" << i->name << ";\nsitecing::so_component __soc_" << i->name << ";\n__type_" << i->name << " *" << i->name << ";\n"; 81 outs << "typedef " << i->type << " __type_" << i->name << ";\nsitecing::so_component __soc_" << i->name << ";\n__type_" << i->name << " *" << i->name << ";\n";
82 } 82 }
83 }else{ 83 }else{
84 outs << i->type << " " << i->name << ";\n"; 84 outs << i->type << " " << i->name << ";\n";
85 } 85 }
86 } 86 }
87 anchor_time = true; 87 anchor_time = true;
88} 88}
89 \<\%member_functions:decl\%\>{ 89 \<\%member_functions:decl\%\>{
90 for(sitecing_parser::member_functions_t::const_iterator i=parser.member_functions.begin();i!=parser.member_functions.end();i++) { 90 for(sitecing_parser::member_functions_t::const_iterator i=parser.member_functions.begin();i!=parser.member_functions.end();i++) {
91 (i->name.empty()?outs:outs << "virtual ") 91 (i->name.empty()?outs:outs << "virtual ")
92 << i->type << " "; 92 << i->type << " ";
93 if(i->name.empty()) { 93 if(i->name.empty()) {
94 outs << parser.class_name << "()"; 94 outs << parser.class_name << "()";
95 }else if(i->name == "~") 95 }else if(i->name == "~")
96 outs << "~" << parser.class_name << "()"; 96 outs << "~" << parser.class_name << "()";
97 else 97 else
98 outs << i->name << i->args; 98 outs << i->name << i->args;
99 outs << ";\n"; 99 outs << ";\n";
100 } 100 }
101 anchor_time = true; 101 anchor_time = true;
102} 102}
103 \<\%imports:list\%\> { 103 \<\%imports:list\%\> {
104 for(sitecing_parser::member_variables_t::const_iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) { 104 for(sitecing_parser::member_variables_t::const_iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) {
105 if(i->bComponent) 105 if(i->bComponent)
106 outs << i->initializer << endl; 106 outs << i->initializer << endl;
107 } 107 }
108 anchor_time = true; 108 anchor_time = true;
109} 109}
110 \<\%imports:includes\%\>{ 110 \<\%imports:includes\%\>{
111 for(sitecing_parser::member_variables_t::iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) { 111 for(sitecing_parser::member_variables_t::iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) {
112 if(i->bComponent) 112 if(i->bComponent)
113 outs << "\n#include \"" << i->initializer << ".h\"\n"; 113 outs << "\n#include \"" << i->initializer << ".h\"\n";
114 } 114 }
115 anchor_time = true; 115 anchor_time = true;
116} 116}
117 \<\%imports:import\%\>{ 117 \<\%imports:import\%\>{
118 for(sitecing_parser::member_variables_t::iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) { 118 for(sitecing_parser::member_variables_t::iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) {
119 if(!i->bComponent) 119 if(!i->bComponent)
120 continue; 120 continue;
121 if(i->bTypeOnly) 121 if(i->bTypeOnly)
122 continue; 122 continue;
123 outs << "__soc_" << i->name << "=__SCIF->ss->fetch(\"" << i->initializer << "\",__SCIF); " << i->name << "=static_cast<__type_" << i->name << "*>(__soc_" << i->name << ".ac->__the_most_derived_this());\n"; 123 outs << "__soc_" << i->name << "=__SCIF->ss->fetch(\"" << i->initializer << "\",__SCIF); " << i->name << "=static_cast<__type_" << i->name << "*>(__soc_" << i->name << ".ac->__the_most_derived_this());\n";
124 } 124 }
125 anchor_time = true; 125 anchor_time = true;
126} 126}
127 127
128 \<\%base_component\%\> { 128 \<\%base_component\%\> {
129 // TODO: 129 // TODO:
130 anchor_time = true; 130 anchor_time = true;
131} 131}
132 132
133 \<\%ancestors:includes\%\>{ 133 \<\%ancestors:includes\%\>{
134 for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) { 134 for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) {
135 outs << "#include \"" << i->path << ".h\"\n"; 135 outs << "#include \"" << i->path << ".h\"\n";
136 } 136 }
137 anchor_time = true; 137 anchor_time = true;
138} 138}
139 \<\%ancestors:component_list\%\>{ 139 \<\%ancestors:component_list\%\>{
140 for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) { 140 for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) {
141 outs << i->path << "\n"; 141 outs << i->path << "\n";
142 } 142 }
143 anchor_time = true; 143 anchor_time = true;
144} 144}
145 \<\%ancestors:base_clause_part\%\>{ 145 \<\%ancestors:base_clause_part\%\>{
146 for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) { 146 for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) {
147 outs << ", virtual public " << parser.factory.get_classname(i->path); 147 outs << ", virtual public " << parser.factory.get_classname(i->path);
148 } 148 }
149} 149}
150 \<\%ancestors:typedefs\%\> { 150 \<\%ancestors:typedefs\%\> {
151 for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) { 151 for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) {
152 outs << "typedef class " << parser.factory.get_classname(i->path) << " " << i->name << ";\n"; 152 outs << "typedef class " << parser.factory.get_classname(i->path) << " " << i->name << ";\n";
153 } 153 }
154 anchor_time = true; 154 anchor_time = true;
155} 155}
156 \<\%ancestors:import\%\> { 156 \<\%ancestors:import\%\> {
157 for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) { 157 for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) {
158 outs << i->name << "::__do_imports();\n"; 158 outs << i->name << "::__do_imports();\n";
159 } 159 }
160 anchor_time = true; 160 anchor_time = true;
161} 161}
162 162
163 \n { 163 \n {
164 if(anchor_time) 164 if(anchor_time)
165 anchor(); 165 anchor();
166 ECHO; 166 ECHO;
167} 167}
168 . ECHO; 168 . ECHO;
169 169
170%% 170%%
171 171
172void sitecing_enflesher::LexerOutput(const char *buf,int size) { 172void sitecing_enflesher::LexerOutput(const char *buf,int size) {
173 outs.write(buf,size); 173 outs.write(buf,size);
174} 174}
175 175
176void sitecing_enflesher::enflesh() { 176void sitecing_enflesher::enflesh() {
177 ifstream ifs(parser.skeleton.c_str()); 177 ifstream ifs(parser.skeleton.c_str());
178 if(!ifs.good()) 178 if(!ifs.good())
179 throw preprocessor_error(CODEPOINT,"failed to open skeleton file"); 179 throw preprocessor_error(CODEPOINT,"failed to open skeleton file");
180 switch_streams(&ifs,NULL); 180 switch_streams(&ifs,NULL);
181 yylex(); 181 yylex();
182 outs_close();
182} 183}
183 184
184void sitecing_enflesher::anchor() { 185void sitecing_enflesher::anchor() {
185 if(!anchoraged) 186 if(!anchoraged)
186 return; 187 return;
187 outs << "\n#line " << lineno() << " \"" << parser.skeleton << "\"\n"; 188 outs << "\n#line " << lineno() << " \"" << parser.skeleton << "\"\n";
188 anchor_time = false; 189 anchor_time = false;
189} 190}
190 191
191void sitecing_enflesher::outs_open(const string& nfile) { 192void sitecing_enflesher::outs_close() {
192 if(!outs_filename.empty()) { 193 if(!outs_filename.empty()) {
193 outs.flush(); 194 outs.flush();
194 outs.close(); 195 outs.close();
195 outs.clear(); 196 outs.clear();
196 /* 197 /*
197 * compare source and destination files. 198 * compare source and destination files.
198 * 199 *
199 * one can also keep a hash for the old one and compute one for the 200 * 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 * 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 * bit less accurate, unless we're going to compare it in case of
202 * difference, anyway. 203 * difference, anyway.
203 */ 204 */
204 bool overwrite = false; 205 bool overwrite = false;
205 struct stat st_s, st_d; 206 struct stat st_s, st_d;
206 string fn_s = outs_filename+".new"; 207 string fn_s = outs_filename+".new";
207 string fn_d = outs_filename; 208 string fn_d = outs_filename;
208 if(stat(fn_d.c_str(),&st_d)) { 209 if(stat(fn_d.c_str(),&st_d)) {
209 overwrite = true; 210 overwrite = true;
210 }else{ 211 }else{
211 if(stat(fn_s.c_str(),&st_s)) 212 if(stat(fn_s.c_str(),&st_s))
212 throw preprocessor_error(CODEPOINT,"failed to stat() supposedly created file"); 213 throw preprocessor_error(CODEPOINT,"failed to stat() supposedly created file");
213 if(st_s.st_size!=st_d.st_size) { 214 if(st_s.st_size!=st_d.st_size) {
214 overwrite = true; 215 overwrite = true;
215 }else{ 216 }else{
216 ifstream i_s(fn_s.c_str(),ios::in); 217 ifstream i_s(fn_s.c_str(),ios::in);
217 if(!i_s) 218 if(!i_s)
218 throw preprocessor_error(CODEPOINT,"failed to open supposedly created file"); 219 throw preprocessor_error(CODEPOINT,"failed to open supposedly created file");
219 ifstream i_d(fn_d.c_str(),ios::in); 220 ifstream i_d(fn_d.c_str(),ios::in);
220 if(!i_d) 221 if(!i_d)
221 throw preprocessor_error(CODEPOINT,"failed to open the old preprocessed source"); 222 throw preprocessor_error(CODEPOINT,"failed to open the old preprocessed source");
222 off_t remaining = st_s.st_size; 223 off_t remaining = st_s.st_size;
223 char t1[2048]; 224 char t1[2048];
224 char t2[sizeof(t1)]; 225 char t2[sizeof(t1)];
225 while(remaining) { 226 while(remaining) {
226 int rb = remaining; 227 int rb = remaining;
227 if(rb>sizeof(t1)) 228 if(rb>sizeof(t1))
228 rb = sizeof(t1); 229 rb = sizeof(t1);
229 if(i_s.read(t1,rb).gcount()!=rb) 230 if(i_s.read(t1,rb).gcount()!=rb)
230 throw preprocessor_error(CODEPOINT,"error reading just created file"); 231 throw preprocessor_error(CODEPOINT,"error reading just created file");
231 if(i_d.read(t2,rb).gcount()!=rb) 232 if(i_d.read(t2,rb).gcount()!=rb)
232 throw preprocessor_error(CODEPOINT,"error reading the old preprocessed source"); 233 throw preprocessor_error(CODEPOINT,"error reading the old preprocessed source");
233 if(memcmp(t1,t2,rb)) { 234 if(memcmp(t1,t2,rb)) {
234 overwrite = true; 235 overwrite = true;
235 break; 236 break;
236 } 237 }
237 remaining -= rb; 238 remaining -= rb;
238 } 239 }
239 } 240 }
240 } 241 }
241 if(overwrite) { 242 if(overwrite) {
242 cerr << "renaming '" << fn_s << "'" << endl; 243 cerr << "renaming '" << fn_s << "'" << endl;
243 if(rename(fn_s.c_str(),fn_d.c_str())) 244 if(rename(fn_s.c_str(),fn_d.c_str()))
244 throw preprocessor_error(CODEPOINT,"failed to rename() generated output"); 245 throw preprocessor_error(CODEPOINT,"failed to rename() generated output");
245 } 246 }
246 } 247 }
248 outs_filename.erase();
249}
250
251void sitecing_enflesher::outs_open(const string& nfile) {
252 outs_close();
247 outs_filename = nfile; 253 outs_filename = nfile;
248 outs.open((nfile+".new").c_str(),ios::trunc); 254 outs.open((nfile+".new").c_str(),ios::trunc);
249 if(!outs.good()) 255 if(!outs.good())
250 throw preprocessor_error(CODEPOINT,"failed to write preprocessor output"); 256 throw preprocessor_error(CODEPOINT,"failed to write preprocessor output");
251} 257}
252/* 258/*
253 * vim:set ft=lex: 259 * vim:set ft=lex:
254 */ 260 */
diff --git a/lib/sitecing_parser.ll b/lib/sitecing_parser.ll
index 6cb78f3..8ba8673 100644
--- a/lib/sitecing_parser.ll
+++ b/lib/sitecing_parser.ll
@@ -1,594 +1,639 @@
1%{ 1%{
2 /* 2 /*
3 * XXX: I have a strong feeling that this parser should be completely rewritten. 3 * XXX: I have a strong feeling that this parser should be completely rewritten.
4 */ 4 */
5#include <iostream> 5#include <iostream>
6#include <fstream> 6#include <fstream>
7#include <cassert> 7#include <cassert>
8#include <stdexcept> 8#include <stdexcept>
9using namespace std; 9using namespace std;
10#include "sitecing/sitecing_util.h" 10#include "sitecing/sitecing_util.h"
11#include "sitecing/sitecing_exception.h" 11#include "sitecing/sitecing_exception.h"
12using namespace sitecing; 12using namespace sitecing;
13#define sitecing_parser_flexlexer_once 13#define sitecing_parser_flexlexer_once
14#include "sitecing/sitecing_parser.h" 14#include "sitecing/sitecing_parser.h"
15#include "sitecing/sitecing_enflesher.h" 15#include "sitecing/sitecing_enflesher.h"
16#undef yyFlexLexer 16#undef yyFlexLexer
17#define yyFlexLexer sitecing_parserFlexLexer 17#define yyFlexLexer sitecing_parserFlexLexer
18%} 18%}
19%x SLASHSTAR_COMMENT SLASHSLASH_COMMENT STRING 19%x SLASHSTAR_COMMENT SLASHSLASH_COMMENT STRING
20%x CODELINE CLASSLINE DECLLINE IMPLLINE DECLBLOCK IMPLBLOCK VARLINE VARINIT 20%x CODELINE CLASSLINE DECLLINE IMPLLINE DECLBLOCK IMPLBLOCK VARLINE VARINIT
21%x IMPORTLINE IMPORTCOMPONENT 21%x IMPORTLINE IMPORTCOMPONENT
22%x IMPORTTYPELINE IMPORTTYPECOMPONENT 22%x IMPORTTYPELINE IMPORTTYPECOMPONENT
23%x DERIVELINE DERIVECOMPONENT 23%x DERIVELINE DERIVECOMPONENT
24%x CONSTRUCTOR DESTRUCTOR CODEMETHODLINE CODEMETHODARGS 24%x CONSTRUCTOR DESTRUCTOR CODEMETHODLINE CODEMETHODARGS
25%x CODEMETHODBLOCK INLINE METHODLINE METHODARGS METHODBLOCK CODEBLOCK OUTPUTBLOCK 25%x CODEMETHODBLOCK INLINE METHODLINE METHODARGS METHODBLOCK CODEBLOCK OUTPUTBLOCK
26%x PRAGMALINE
26%option 8bit c++ verbose noyywrap yyclass="sitecing_parser" prefix="sitecing_parser" stack yylineno 27%option 8bit c++ verbose noyywrap yyclass="sitecing_parser" prefix="sitecing_parser" stack yylineno
27 28
28 WHITESPACE[ \t] 29 WHITESPACE[ \t]
29 ID [A-Za-z_][A-Za-z0-9_]* 30 ID [A-Za-z_][A-Za-z0-9_]*
30 NOIDCHAR[^A-Za-z0-9_] 31 NOIDCHAR[^A-Za-z0-9_]
31 32
32%% 33%%
33 34
34<INITIAL>{ 35<INITIAL>{
35 ^\%\%class{WHITESPACE}+{ 36 ^\%\%class{WHITESPACE}+{
36 // TODO: signal error if we already have class name acquired from source. 37 // TODO: signal error if we already have class name acquired from source.
37 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments|modus_operandi::flag_devour_whitespace)); 38 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments|modus_operandi::flag_devour_whitespace));
38 BEGIN(CLASSLINE); 39 BEGIN(CLASSLINE);
39 } 40 }
40 ^\%\%decl{WHITESPACE}+{ 41 ^\%\%decl{WHITESPACE}+{
41 modi.push_front(modus_operandi(0)); 42 modi.push_front(modus_operandi(0));
42 anchor(); 43 anchor();
43 BEGIN(DECLLINE); 44 BEGIN(DECLLINE);
44 } 45 }
45 ^\%\%impl{WHITESPACE}+{ 46 ^\%\%impl{WHITESPACE}+{
46 modi.push_front(modus_operandi(0)); 47 modi.push_front(modus_operandi(0));
47 anchor(); 48 anchor();
48 BEGIN(IMPLLINE); 49 BEGIN(IMPLLINE);
49 } 50 }
50 \<\%decl\> { 51 \<\%decl\> {
51 modi.push_front(modus_operandi(0)); 52 modi.push_front(modus_operandi(0));
52 anchor(); 53 anchor();
53 BEGIN(DECLBLOCK); 54 BEGIN(DECLBLOCK);
54 } 55 }
55 \<\%impl\> { 56 \<\%impl\> {
56 modi.push_front(modus_operandi(0)); 57 modi.push_front(modus_operandi(0));
57 anchor(); 58 anchor();
58 BEGIN(IMPLBLOCK); 59 BEGIN(IMPLBLOCK);
59 } 60 }
60 ^\%\%var{WHITESPACE}+{ 61 ^\%\%var{WHITESPACE}+{
61 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); 62 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
62 anchor(); 63 anchor();
63 BEGIN(VARLINE); 64 BEGIN(VARLINE);
64 } 65 }
65 ^\%\%import{WHITESPACE}+{ 66 ^\%\%import{WHITESPACE}+{
66 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); 67 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
67 BEGIN(IMPORTLINE); 68 BEGIN(IMPORTLINE);
68 } 69 }
69 ^\%\%import_type{WHITESPACE}+ { 70 ^\%\%import_type{WHITESPACE}+ {
70 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); 71 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
71 BEGIN(IMPORTTYPELINE); 72 BEGIN(IMPORTTYPELINE);
72 } 73 }
73 ^\%\%derive{WHITESPACE}+{ 74 ^\%\%derive{WHITESPACE}+{
74 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); 75 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
75 BEGIN(DERIVELINE); 76 BEGIN(DERIVELINE);
76 } 77 }
77 \<\%constructor\>{ 78 \<\%constructor\>{
78 modi.push_front(modus_operandi()); 79 modi.push_front(modus_operandi());
79 anchor(); 80 anchor();
80 BEGIN(CONSTRUCTOR); 81 BEGIN(CONSTRUCTOR);
81 } 82 }
82 \<\%destructor\>{ 83 \<\%destructor\>{
83 modi.push_front(modus_operandi()); 84 modi.push_front(modus_operandi());
84 anchor(); 85 anchor();
85 BEGIN(DESTRUCTOR); 86 BEGIN(DESTRUCTOR);
86 } 87 }
87 \<\%codemethod{WHITESPACE}+{ 88 \<\%codemethod{WHITESPACE}+{
88 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); 89 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
89 anchor(); 90 anchor();
90 BEGIN(CODEMETHODLINE); 91 BEGIN(CODEMETHODLINE);
91 } 92 }
92 \<\%method{WHITESPACE}+ { 93 \<\%method{WHITESPACE}+ {
93 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); 94 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
94 anchor(); 95 anchor();
95 BEGIN(METHODLINE); 96 BEGIN(METHODLINE);
96 } 97 }
98 ^\%\%pragma{WHITESPACE}+{
99 modi.push_front(modus_operandi(modus_operandi::flag_devour_comments));
100 BEGIN(PRAGMALINE);
101 }
97 <<EOF>>{ 102 <<EOF>>{
98 assert(modi.size()==1); 103 assert(modi.size()==1);
99 M().modify(modus_operandi::modus_preop); 104 M().modify(modus_operandi::modus_preop);
100 LexerOutput(";",1); 105 LexerOutput(";",1);
101 return 0; 106 return 0;
102 } 107 }
103} 108}
104 <<EOF>>throw preprocessor_error(CODEPOINT,"unexpected end of file",lineno()); 109 <<EOF>>throw preprocessor_error(CODEPOINT,"unexpected end of file",lineno());
105 110
106<CODEBLOCK,CODEMETHODBLOCK>{ 111<CODEBLOCK,CODEMETHODBLOCK>{
107 "<%output>"{ 112 "<%output>"{
108 anchor(); 113 anchor();
109 yy_push_state(OUTPUTBLOCK); 114 yy_push_state(OUTPUTBLOCK);
110 } 115 }
111} 116}
112 117
118<PRAGMALINE>{
119 {WHITESPACE}+{
120 modus_operandi& m = M();
121 if(!m.output.empty()) {
122 string::size_type eq = m.output.find('=');
123 if(eq==string::npos) {
124 pragmas[m.output]=m.output;
125 }else{
126 pragmas[m.output.substr(0,eq)] = m.output.substr(eq+1);
127 }
128 m.output.erase();
129 }
130 }
131 \n {
132 modus_operandi& m = M();
133 if(!m.output.empty()) {
134 string::size_type eq = m.output.find('=');
135 if(eq==string::npos) {
136 pragmas[m.output]=m.output;
137 }else{
138 pragmas[m.output.substr(0,eq)] = m.output.substr(eq+1);
139 }
140 m.output.erase();
141 }
142 modi.pop_front();
143 BEGIN(INITIAL);
144 anchor();
145 }
146}
147
113<METHODLINE>{ 148<METHODLINE>{
114 {WHITESPACE}+{ 149 {WHITESPACE}+{
115 modus_operandi& m = modi.front(); 150 modus_operandi& m = modi.front();
116 if(!m.output.empty()) { 151 if(!m.output.empty()) {
117 if(!m._lastid.empty()) { 152 if(!m._lastid.empty()) {
118 if(!m._type.empty()) m._type += ' '; 153 if(!m._type.empty()) m._type += ' ';
119 m._type += m._lastid; 154 m._type += m._lastid;
120 } 155 }
121 m._lastid = m.output; 156 m._lastid = m.output;
122 m.output.clear(); 157 m.output.clear();
123 } 158 }
124 } 159 }
125 \*{ 160 \*{
126 modus_operandi& m = modi.front(); 161 modus_operandi& m = modi.front();
127 ECHO; 162 ECHO;
128 if(!m._lastid.empty()) { 163 if(!m._lastid.empty()) {
129 if(!m._type.empty()) m._type += ' '; 164 if(!m._type.empty()) m._type += ' ';
130 m._type += m._lastid; 165 m._type += m._lastid;
131 } 166 }
132 m._lastid = m.output; 167 m._lastid = m.output;
133 m.output.clear(); 168 m.output.clear();
134 } 169 }
135 \({ 170 \({
136 modus_operandi& m = modi.front(); 171 modus_operandi& m = modi.front();
137 if(m.output.empty()) { 172 if(m.output.empty()) {
138 m._name=m._lastid; 173 m._name=m._lastid;
139 }else{ 174 }else{
140 if(!m._lastid.empty()) { // XXX: lastid, I believe should never be emtpy... 175 if(!m._lastid.empty()) { // XXX: lastid, I believe should never be emtpy...
141 if(!m._type.empty()) m._type += ' '; 176 if(!m._type.empty()) m._type += ' ';
142 m._type += m._lastid; 177 m._type += m._lastid;
143 } 178 }
144 m._name = m.output; 179 m._name = m.output;
145 m.output.clear(); 180 m.output.clear();
146 } 181 }
147 ECHO; 182 ECHO;
148 BEGIN(METHODARGS); 183 BEGIN(METHODARGS);
149 } 184 }
150} 185}
151<METHODARGS>{ 186<METHODARGS>{
152 \%\>{ 187 \%\>{
153 modus_operandi& m = modi.front(); 188 modus_operandi& m = modi.front();
154 m._args = m.output; 189 m._args = m.output;
155 m.output.clear(); 190 m.output.clear();
156 anchor(); 191 anchor();
157 BEGIN(METHODBLOCK); 192 BEGIN(METHODBLOCK);
158 } 193 }
159} 194}
160 195
161<INITIAL,METHODBLOCK,OUTPUTBLOCK>{ 196<INITIAL,METHODBLOCK,OUTPUTBLOCK>{
162 \<\%{WHITESPACE}+{ 197 \<\%{WHITESPACE}+{
163 M().modify(modus_operandi::modus_postop); 198 M().modify(modus_operandi::modus_postop);
164 anchor(); 199 anchor();
165 LexerOutput("(",1); 200 LexerOutput("(",1);
166 yy_push_state(INLINE); 201 yy_push_state(INLINE);
167 } 202 }
168 ^\%{WHITESPACE}{ 203 ^\%{WHITESPACE}{
169 M().modify(modus_operandi::modus_code); 204 M().modify(modus_operandi::modus_code);
170 anchor(); 205 anchor();
171 yy_push_state(CODELINE); 206 yy_push_state(CODELINE);
172 } 207 }
173 \<\%code\>{ 208 \<\%code\>{
174 M().modify(modus_operandi::modus_code); 209 M().modify(modus_operandi::modus_code);
175 anchor(); 210 anchor();
176 yy_push_state(CODEBLOCK); 211 yy_push_state(CODEBLOCK);
177 } 212 }
178 "</%output>" { 213 "</%output>" {
179 if(YY_START!=OUTPUTBLOCK) throw preprocessor_error(CODEPOINT,"unexpected tag",lineno()); 214 if(YY_START!=OUTPUTBLOCK) throw preprocessor_error(CODEPOINT,"unexpected tag",lineno());
180 M().modify(modus_operandi::modus_code); 215 M().modify(modus_operandi::modus_code);
181 anchor(); 216 anchor();
182 yy_pop_state(); 217 yy_pop_state();
183 } 218 }
184} 219}
185 220
186 <INLINE>\%\>LexerOutput(")",1); M().modus=modus_operandi::modus_preop; yy_pop_state(); 221 <INLINE>\%\>LexerOutput(")",1); M().modus=modus_operandi::modus_preop; yy_pop_state();
187 <CODELINE>\nyy_pop_state(); 222 <CODELINE>\nyy_pop_state();
188 223
189<CODEMETHODLINE>{ 224<CODEMETHODLINE>{
190 {WHITESPACE}+{ 225 {WHITESPACE}+{
191 modus_operandi& m = modi.front(); 226 modus_operandi& m = modi.front();
192 if(!m.output.empty()) { 227 if(!m.output.empty()) {
193 if(!m._lastid.empty()) { 228 if(!m._lastid.empty()) {
194 if(!m._type.empty()) m._type += ' '; 229 if(!m._type.empty()) m._type += ' ';
195 m._type += m._lastid; 230 m._type += m._lastid;
196 } 231 }
197 m._lastid = m.output; 232 m._lastid = m.output;
198 m.output.clear(); 233 m.output.clear();
199 } 234 }
200 } 235 }
201 \*{ 236 \*{
202 modus_operandi& m = modi.front(); 237 modus_operandi& m = modi.front();
203 ECHO; 238 ECHO;
204 if(!m._lastid.empty()) { 239 if(!m._lastid.empty()) {
205 if(!m._type.empty()) m._type += ' '; 240 if(!m._type.empty()) m._type += ' ';
206 m._type += m._lastid; 241 m._type += m._lastid;
207 } 242 }
208 m._lastid = m.output; 243 m._lastid = m.output;
209 m.output.clear(); 244 m.output.clear();
210 } 245 }
211 \({ 246 \({
212 modus_operandi& m = modi.front(); 247 modus_operandi& m = modi.front();
213 if(m.output.empty()) { 248 if(m.output.empty()) {
214 m._name=m._lastid; 249 m._name=m._lastid;
215 }else{ 250 }else{
216 if(!m._lastid.empty()) { // XXX: lastid, I believe should never be emtpy... 251 if(!m._lastid.empty()) { // XXX: lastid, I believe should never be emtpy...
217 if(!m._type.empty()) m._type += ' '; 252 if(!m._type.empty()) m._type += ' ';
218 m._type += m._lastid; 253 m._type += m._lastid;
219 } 254 }
220 m._name = m.output; 255 m._name = m.output;
221 m.output.clear(); 256 m.output.clear();
222 } 257 }
223 ECHO; 258 ECHO;
224 BEGIN(CODEMETHODARGS); 259 BEGIN(CODEMETHODARGS);
225 } 260 }
226} 261}
227<CODEMETHODARGS>{ 262<CODEMETHODARGS>{
228 \%\>{ 263 \%\>{
229 modus_operandi& m = modi.front(); 264 modus_operandi& m = modi.front();
230 m._args = m.output; 265 m._args = m.output;
231 m.output.clear(); 266 m.output.clear();
232 m.flags=0; 267 m.flags=0;
233 anchor(); 268 anchor();
234 BEGIN(CODEMETHODBLOCK); 269 BEGIN(CODEMETHODBLOCK);
235 } 270 }
236} 271}
237 272
238<IMPORTLINE>{ 273<IMPORTLINE>{
239 {WHITESPACE}+{ } 274 {WHITESPACE}+{ }
240 {ID}{ 275 {ID}{
241 if(!modi.front()._name.empty()) 276 if(!modi.front()._name.empty())
242 throw preprocessor_error(CODEPOINT,"syntax error",lineno()); 277 throw preprocessor_error(CODEPOINT,"syntax error",lineno());
243 modi.front()._name = yytext; 278 modi.front()._name = yytext;
244 } 279 }
245 \= { 280 \= {
246 modi.front().output.clear(); 281 modi.front().output.clear();
247 BEGIN(IMPORTCOMPONENT); 282 BEGIN(IMPORTCOMPONENT);
248 } 283 }
249} 284}
250<IMPORTCOMPONENT>{ 285<IMPORTCOMPONENT>{
251 {WHITESPACE}+{ } 286 {WHITESPACE}+{ }
252 \n{ 287 \n{
253 modus_operandi& m = M(); 288 modus_operandi& m = M();
254 string::size_type t = m.output.find_first_not_of(" \t"); 289 string::size_type t = m.output.find_first_not_of(" \t");
255 if(t!=string::npos) 290 if(t!=string::npos)
256 m.output.erase(0,t); 291 m.output.erase(0,t);
257 t = m.output.find_last_not_of(" \t;"); 292 t = m.output.find_last_not_of(" \t;");
258 if(t!=string::npos) 293 if(t!=string::npos)
259 m.output.erase(t+1); 294 m.output.erase(t+1);
260 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') { 295 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') {
261 m.output.erase(0,1); 296 m.output.erase(0,1);
262 m.output.erase(m.output.length()-1); 297 m.output.erase(m.output.length()-1);
263 } 298 }
264 string c = combine_path(component_basename,m.output); 299 string c = combine_path(component_basename,m.output);
265 member_variables.push_back(member_variable(m._type,m._name,normalize_path(c,strip_leading_slash),true)); 300 member_variables.push_back(member_variable(m._type,m._name,normalize_path(c,strip_leading_slash),true));
266 modi.pop_front(); 301 modi.pop_front();
267 BEGIN(INITIAL); 302 BEGIN(INITIAL);
268 } 303 }
269} 304}
270 305
271<IMPORTTYPELINE>{ 306<IMPORTTYPELINE>{
272 {WHITESPACE}+{ } 307 {WHITESPACE}+{ }
273 {ID}{ 308 {ID}{
274 if(!modi.front()._name.empty()) 309 if(!modi.front()._name.empty())
275 throw preprocessor_error(CODEPOINT,"syntax error",lineno()); 310 throw preprocessor_error(CODEPOINT,"syntax error",lineno());
276 modi.front()._name = yytext; 311 modi.front()._name = yytext;
277 } 312 }
278 \= { 313 \= {
279 modi.front().output.clear(); 314 modi.front().output.clear();
280 BEGIN(IMPORTTYPECOMPONENT); 315 BEGIN(IMPORTTYPECOMPONENT);
281 } 316 }
282} 317}
283<IMPORTTYPECOMPONENT>{ 318<IMPORTTYPECOMPONENT>{
284 {WHITESPACE}+{ } 319 {WHITESPACE}+{ }
285 \n{ 320 \n{
286 modus_operandi& m = M(); 321 modus_operandi& m = M();
287 string::size_type t = m.output.find_first_not_of(" \t"); 322 string::size_type t = m.output.find_first_not_of(" \t");
288 if(t!=string::npos) 323 if(t!=string::npos)
289 m.output.erase(0,t); 324 m.output.erase(0,t);
290 t = m.output.find_last_not_of(" \t;"); 325 t = m.output.find_last_not_of(" \t;");
291 if(t!=string::npos) 326 if(t!=string::npos)
292 m.output.erase(t+1); 327 m.output.erase(t+1);
293 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') { 328 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') {
294 m.output.erase(0,1); 329 m.output.erase(0,1);
295 m.output.erase(m.output.length()-1); 330 m.output.erase(m.output.length()-1);
296 } 331 }
297 string c = combine_path(component_basename,m.output); 332 string c = combine_path(component_basename,m.output);
298 member_variables.push_back(member_variable(m._type,m._name,normalize_path(c,strip_leading_slash),true,true)); 333 member_variables.push_back(member_variable(m._type,m._name,normalize_path(c,strip_leading_slash),true,true));
299 modi.pop_front(); 334 modi.pop_front();
300 BEGIN(INITIAL); 335 BEGIN(INITIAL);
301 } 336 }
302} 337}
303 338
304<DERIVELINE>{ 339<DERIVELINE>{
305 {WHITESPACE}+{ } 340 {WHITESPACE}+{ }
306 {ID}{ 341 {ID}{
307 if(!modi.front()._name.empty()) 342 if(!modi.front()._name.empty())
308 throw preprocessor_error(CODEPOINT,"syntax_error",lineno()); 343 throw preprocessor_error(CODEPOINT,"syntax_error",lineno());
309 modi.front()._name = yytext; 344 modi.front()._name = yytext;
310 } 345 }
311 \= { 346 \= {
312 modi.front().output.clear(); 347 modi.front().output.clear();
313 BEGIN(DERIVECOMPONENT); 348 BEGIN(DERIVECOMPONENT);
314 } 349 }
315} 350}
316<DERIVECOMPONENT>{ 351<DERIVECOMPONENT>{
317 {WHITESPACE}+{ } 352 {WHITESPACE}+{ }
318 \n { 353 \n {
319 modus_operandi& m = M(); 354 modus_operandi& m = M();
320 string::size_type t = m.output.find_first_not_of(" \t"); 355 string::size_type t = m.output.find_first_not_of(" \t");
321 if(t!=string::npos) 356 if(t!=string::npos)
322 m.output.erase(0,t); 357 m.output.erase(0,t);
323 t = m.output.find_last_not_of(" \t;"); 358 t = m.output.find_last_not_of(" \t;");
324 if(t!=string::npos) 359 if(t!=string::npos)
325 m.output.erase(t+1); 360 m.output.erase(t+1);
326 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') { 361 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') {
327 m.output.erase(0,1); 362 m.output.erase(0,1);
328 m.output.erase(m.output.length()-1); 363 m.output.erase(m.output.length()-1);
329 } 364 }
330 string c = combine_path(component_basename,m.output); 365 string c = combine_path(component_basename,m.output);
331 ancestor_classes.push_back(ancestor_class(m._name,normalize_path(c,strip_leading_slash))); 366 ancestor_classes.push_back(ancestor_class(m._name,normalize_path(c,strip_leading_slash)));
332 modi.pop_front(); 367 modi.pop_front();
333 BEGIN(INITIAL); 368 BEGIN(INITIAL);
334 } 369 }
335} 370}
336 371
337<VARLINE>{ 372<VARLINE>{
338 {WHITESPACE}+{ 373 {WHITESPACE}+{
339 modus_operandi& m = modi.front(); 374 modus_operandi& m = modi.front();
340 if(!m.output.empty()) { 375 if(!m.output.empty()) {
341 if(!m._lastid.empty()) { 376 if(!m._lastid.empty()) {
342 if(!m._type.empty()) m._type += ' '; 377 if(!m._type.empty()) m._type += ' ';
343 m._type += m._lastid; 378 m._type += m._lastid;
344 } 379 }
345 m._lastid = m.output; 380 m._lastid = m.output;
346 m.output.clear(); 381 m.output.clear();
347 } 382 }
348 } 383 }
349 \*{ 384 \*{
350 modus_operandi& m = modi.front(); 385 modus_operandi& m = modi.front();
351 ECHO; 386 ECHO;
352 if(!m._lastid.empty()) { 387 if(!m._lastid.empty()) {
353 if(!m._type.empty()) m._type += ' '; 388 if(!m._type.empty()) m._type += ' ';
354 m._type += m._lastid; 389 m._type += m._lastid;
355 } 390 }
356 m._lastid = m.output; 391 m._lastid = m.output;
357 m.output.clear(); 392 m.output.clear();
358 } 393 }
359 \;|\n|\={ 394 \;|\n|\={
360 modus_operandi& m = modi.front(); 395 modus_operandi& m = modi.front();
361 if(m.output.empty()) { 396 if(m.output.empty()) {
362 m._name=m._lastid; 397 m._name=m._lastid;
363 }else{ 398 }else{
364 if(!m._lastid.empty()) { // XXX: lastid should never be emtpy, I believe? 399 if(!m._lastid.empty()) { // XXX: lastid should never be emtpy, I believe?
365 if(!m._type.empty()) m._type += ' '; 400 if(!m._type.empty()) m._type += ' ';
366 m._type += m._lastid; 401 m._type += m._lastid;
367 } 402 }
368 m._name=m.output; 403 m._name=m.output;
369 m.output.clear(); 404 m.output.clear();
370 } 405 }
371 BEGIN(VARINIT); 406 BEGIN(VARINIT);
372 if(*yytext!='=') 407 if(*yytext!='=')
373 unput('\n'); 408 unput('\n');
374 } 409 }
375} 410}
376<VARINIT>{ 411<VARINIT>{
377 \n{ 412 \n{
378 modus_operandi& m = modi.front(); 413 modus_operandi& m = modi.front();
379 string::size_type t = m.output.find_first_not_of(" \t"); 414 string::size_type t = m.output.find_first_not_of(" \t");
380 if(t!=string::npos) 415 if(t!=string::npos)
381 m.output.erase(0,t); 416 m.output.erase(0,t);
382 t = m.output.find_last_not_of(" \t;"); 417 t = m.output.find_last_not_of(" \t;");
383 if(t!=string::npos) 418 if(t!=string::npos)
384 m.output.erase(t+1); 419 m.output.erase(t+1);
385 member_variables.push_back(member_variable(m._type,m._name,m.output)); 420 member_variables.push_back(member_variable(m._type,m._name,m.output));
386 if(!m.output.empty()) 421 if(!m.output.empty())
387 have_initializers=true; 422 have_initializers=true;
388 modi.pop_front(); 423 modi.pop_front();
389 BEGIN(INITIAL); 424 BEGIN(INITIAL);
390 } 425 }
391} 426}
392 <DECLLINE>\n{ 427 <DECLLINE>\n{
393 ECHO; 428 ECHO;
394 decl += modi.front().output; 429 decl += modi.front().output;
395 modi.pop_front(); 430 modi.pop_front();
396 BEGIN(INITIAL); 431 BEGIN(INITIAL);
397} 432}
398 <IMPLLINE>\n{ 433 <IMPLLINE>\n{
399 ECHO; 434 ECHO;
400 impl += modi.front().output; 435 impl += modi.front().output;
401 modi.pop_front(); 436 modi.pop_front();
402 BEGIN(INITIAL); 437 BEGIN(INITIAL);
403} 438}
404 <CLASSLINE>\n{ 439 <CLASSLINE>\n{
405 class_name = modi.front().output; 440 class_name = modi.front().output;
406 modi.pop_front(); 441 modi.pop_front();
407 BEGIN(INITIAL); 442 BEGIN(INITIAL);
408} 443}
409<CLASSLINE,DECLLINE,IMPLLINE,VARLINE,VARINIT,IMPORTLINE,IMPORTCOMPONENT,CODEMETHODLINE,CODEMETHODARGS,INLINE,METHODLINE,METHODARGS,DECLBLOCK,IMPLBLOCK,CONSTRUCTOR,DESTRUCTOR,CODEMETHODBLOCK,CODELINE,CODEBLOCK>{ 444<CLASSLINE,DECLLINE,IMPLLINE,VARLINE,VARINIT,IMPORTLINE,IMPORTCOMPONENT,CODEMETHODLINE,CODEMETHODARGS,INLINE,METHODLINE,METHODARGS,DECLBLOCK,IMPLBLOCK,CONSTRUCTOR,DESTRUCTOR,CODEMETHODBLOCK,CODELINE,CODEBLOCK,PRAGMALINE>{
410 "/*"{ 445 "/*"{
411 yy_push_state(SLASHSTAR_COMMENT); 446 yy_push_state(SLASHSTAR_COMMENT);
412 if(!M().devour_comments()) { 447 if(!M().devour_comments()) {
413 ECHO; 448 ECHO;
414 } 449 }
415 } 450 }
416 "//"{ 451 "//"{
417 yy_push_state(SLASHSLASH_COMMENT); 452 yy_push_state(SLASHSLASH_COMMENT);
418 if(!M().devour_comments()) { 453 if(!M().devour_comments()) {
419 ECHO; 454 ECHO;
420 } 455 }
421 } 456 }
422 \" { 457 \" {
423 yy_push_state(STRING); 458 yy_push_state(STRING);
424 ECHO; 459 ECHO;
425 } 460 }
426 \'\\.\'{ 461 \'\\.\'{
427 ECHO; 462 ECHO;
428 } 463 }
429} 464}
430 465
431<INITIAL,METHODBLOCK,OUTPUTBLOCK>{ 466<INITIAL,METHODBLOCK,OUTPUTBLOCK>{
432 \"soft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\\"",2); 467 \"soft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\\"",2);
433 \nsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\n",2); 468 \nsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\n",2);
434 \rsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\r",2); 469 \rsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\r",2);
435 \tsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\t",2); 470 \tsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\t",2);
436 \bsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\b",2); 471 \bsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\b",2);
437 \asoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\a",2); 472 \asoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\a",2);
438 .soft_anchor(); M().modify(modus_operandi::modus_text); ECHO; 473 .soft_anchor(); M().modify(modus_operandi::modus_text); ECHO;
439 {WHITESPACE}+soft_anchor(); M().modify(modus_operandi::modus_text); ECHO; 474 {WHITESPACE}+soft_anchor(); M().modify(modus_operandi::modus_text); ECHO;
440} 475}
441 476
442<DECLBLOCK,IMPLBLOCK,CONSTRUCTOR,DESTRUCTOR,CODEMETHODBLOCK,METHODBLOCK,CODEBLOCK>{ 477<DECLBLOCK,IMPLBLOCK,CONSTRUCTOR,DESTRUCTOR,CODEMETHODBLOCK,METHODBLOCK,CODEBLOCK>{
443 \<\/\%decl\>{ 478 \<\/\%decl\>{
444 if(YY_START!=DECLBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 479 if(YY_START!=DECLBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
445 decl += modi.front().output; 480 decl += modi.front().output;
446 modi.pop_front(); 481 modi.pop_front();
447 BEGIN(INITIAL); 482 BEGIN(INITIAL);
448 } 483 }
449 \<\/\%impl\>{ 484 \<\/\%impl\>{
450 if(YY_START!=IMPLBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 485 if(YY_START!=IMPLBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
451 impl += modi.front().output; 486 impl += modi.front().output;
452 modi.pop_front(); 487 modi.pop_front();
453 BEGIN(INITIAL); 488 BEGIN(INITIAL);
454 } 489 }
455 \<\/\%constructor\>{ 490 \<\/\%constructor\>{
456 if(YY_START!=CONSTRUCTOR) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 491 if(YY_START!=CONSTRUCTOR) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
457 member_functions.push_back(member_function("","","",modi.front().output)); 492 member_functions.push_back(member_function("","","",modi.front().output));
458 have_constructor = true; 493 have_constructor = true;
459 modi.pop_front(); 494 modi.pop_front();
460 BEGIN(INITIAL); 495 BEGIN(INITIAL);
461 } 496 }
462 \<\/\%destructor\>{ 497 \<\/\%destructor\>{
463 if(YY_START!=DESTRUCTOR) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 498 if(YY_START!=DESTRUCTOR) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
464 member_functions.push_back(member_function("","~","",modi.front().output)); 499 member_functions.push_back(member_function("","~","",modi.front().output));
465 modi.pop_front(); 500 modi.pop_front();
466 BEGIN(INITIAL); 501 BEGIN(INITIAL);
467 } 502 }
468 \<\/\%codemethod\>{ 503 \<\/\%codemethod\>{
469 if(YY_START!=CODEMETHODBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 504 if(YY_START!=CODEMETHODBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
470 modus_operandi& m = modi.front(); 505 modus_operandi& m = modi.front();
471 member_functions.push_back(member_function(m._type,m._name,m._args,m.output)); 506 member_functions.push_back(member_function(m._type,m._name,m._args,m.output));
472 modi.pop_front(); 507 modi.pop_front();
473 BEGIN(INITIAL); 508 BEGIN(INITIAL);
474 } 509 }
475 \<\/%method\> { 510 \<\/%method\> {
476 if(YY_START!=METHODBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 511 if(YY_START!=METHODBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
477 modus_operandi& m = modi.front(); 512 modus_operandi& m = modi.front();
478 m.modify(modus_operandi::modus_code); 513 m.modify(modus_operandi::modus_code);
479 member_functions.push_back(member_function(m._type,m._name,m._args,m.output)); 514 member_functions.push_back(member_function(m._type,m._name,m._args,m.output));
480 modi.pop_front(); 515 modi.pop_front();
481 BEGIN(INITIAL); 516 BEGIN(INITIAL);
482 } 517 }
483 \<\/%code\> { 518 \<\/%code\> {
484 if(YY_START!=CODEBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); 519 if(YY_START!=CODEBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno());
485 yy_pop_state(); 520 yy_pop_state();
486 } 521 }
487 \n ECHO; 522 \n ECHO;
488} 523}
489 524
490<SLASHSTAR_COMMENT>{ 525<SLASHSTAR_COMMENT>{
491 "*/"{ 526 "*/"{
492 if(!M().devour_comments()) { 527 if(!M().devour_comments()) {
493 ECHO; 528 ECHO;
494 } 529 }
495 yy_pop_state(); 530 yy_pop_state();
496 unput(' '); 531 unput(' ');
497 } 532 }
498 \n{ 533 \n{
499 if(!M().devour_comments()) { 534 if(!M().devour_comments()) {
500 ECHO; 535 ECHO;
501 } 536 }
502 } 537 }
503} 538}
504<SLASHSLASH_COMMENT>{ 539<SLASHSLASH_COMMENT>{
505 \n{ 540 \n{
506 if(!M().devour_comments()) { 541 if(!M().devour_comments()) {
507 ECHO; 542 ECHO;
508 } 543 }
509 yy_pop_state(); 544 yy_pop_state();
510 if(YY_START!=CODEBLOCK && YY_START!=CODEMETHODBLOCK && YY_START!=IMPLBLOCK && YY_START!=DECLBLOCK) 545 if(YY_START!=CODEBLOCK && YY_START!=CODEMETHODBLOCK && YY_START!=IMPLBLOCK && YY_START!=DECLBLOCK)
511 unput('\n'); 546 unput('\n');
512 } 547 }
513} 548}
514 <SLASHSTAR_COMMENT,SLASHSLASH_COMMENT>.{ 549 <SLASHSTAR_COMMENT,SLASHSLASH_COMMENT>.{
515 if(!M().devour_comments()) { 550 if(!M().devour_comments()) {
516 ECHO; 551 ECHO;
517 } 552 }
518} 553}
519<STRING>{ 554<STRING>{
520 \\.ECHO; 555 \\.ECHO;
521 \"ECHO; yy_pop_state(); 556 \"ECHO; yy_pop_state();
522 .ECHO; 557 .ECHO;
523} 558}
524 559
525 {WHITESPACE}+{ 560 {WHITESPACE}+{
526 if(!(M().flags&modus_operandi::flag_devour_whitespace)) { 561 if(!(M().flags&modus_operandi::flag_devour_whitespace)) {
527 ECHO; 562 ECHO;
528 } 563 }
529} 564}
530 565
531%% 566%%
532 567
533sitecing_parser::sitecing_parser(component_factory& f) 568sitecing_parser::sitecing_parser(component_factory& f)
534 : factory(f), have_initializers(false), have_constructor(false), 569 : factory(f), have_initializers(false), have_constructor(false),
535 base_class("sitecing::cgi_component"), 570 base_class("sitecing::cgi_component"),
536 base_header("sitecing/cgi_component.h"), 571 base_header("sitecing/cgi_component.h"),
537 skeleton(__SC_DEFAULT_SKELETON) { 572 skeleton(__SC_DEFAULT_SKELETON) {
538 } 573 }
539 574
540void sitecing_parser::preprocess(const string& in) { 575void sitecing_parser::preprocess(const string& in) {
541 ifstream ifs(in.c_str(),ios::in); 576 ifstream ifs(in.c_str(),ios::in);
542 if(!ifs.good()) 577 if(!ifs.good())
543 throw preprocessor_error(CODEPOINT,"failed to open input file"); 578 throw preprocessor_error(CODEPOINT,"failed to open input file");
544 input_file = in; 579 input_file = in;
545 modi.push_front(modus_operandi(0)); 580 modi.push_front(modus_operandi(0));
546 switch_streams(&ifs,NULL); 581 switch_streams(&ifs,NULL);
547 if(yylex()) 582 if(yylex())
548 throw preprocessor_error(CODEPOINT,"unknown error"); 583 throw preprocessor_error(CODEPOINT,"unknown error");
549 member_functions.push_back(member_function("void","main","(int _magic,va_list _args)",M().output)); 584 pragmas_t::const_iterator mp = pragmas.find("main");
585 if(mp==pragmas.end()) {
586 member_functions.push_back(member_function("void","main","(int _magic,va_list _args)",M().output));
587 }else{
588 member_functions.push_back(
589 member_function(
590 "void","main","(int _magic,va_list _args)",
591 mp->second+"::main(_magic,_args);"
592 )
593 );
594 }
550 if(have_initializers && !have_constructor) 595 if(have_initializers && !have_constructor)
551 member_functions.push_back(member_function("","","","")); 596 member_functions.push_back(member_function("","","",""));
552 sitecing_enflesher enflesher(*this); 597 sitecing_enflesher enflesher(*this);
553 enflesher.enflesh(); 598 enflesher.enflesh();
554} 599}
555 600
556void sitecing_parser::LexerOutput(const char* buf,int size) { 601void sitecing_parser::LexerOutput(const char* buf,int size) {
557 assert(modi.size()); 602 assert(modi.size());
558 M().output.append(buf,size); 603 M().output.append(buf,size);
559} 604}
560 605
561static const char *modus_transitions 606static const char *modus_transitions
562 [sitecing_parser::modus_operandi::modi] 607 [sitecing_parser::modus_operandi::modi]
563 [sitecing_parser::modus_operandi::modi] = { 608 [sitecing_parser::modus_operandi::modi] = {
564// To: 609// To:
565// code preop postop text From: 610// code preop postop text From:
566 { "", "(*(__SCIF->out))", "(*(__SCIF->out))<<", "(*(__SCIF->out))<<\"" }, // code 611 { "", "(*(__SCIF->out))", "(*(__SCIF->out))<<", "(*(__SCIF->out))<<\"" }, // code
567 { ";", "", "<<", "<<\"" }, // preop 612 { ";", "", "<<", "<<\"" }, // preop
568 { NULL, NULL, "", "\"" }, // postop 613 { NULL, NULL, "", "\"" }, // postop
569 { "\";", "\"", "\"<<", "" } // text 614 { "\";", "\"", "\"<<", "" } // text
570}; 615};
571 616
572void sitecing_parser::modus_operandi::modify(modus_t m) { 617void sitecing_parser::modus_operandi::modify(modus_t m) {
573 const char * x = modus_transitions[modus][m]; 618 const char * x = modus_transitions[modus][m];
574 assert(x); 619 assert(x);
575 output += x; 620 output += x;
576 modus = m; 621 modus = m;
577} 622}
578 623
579void sitecing_parser::soft_anchor() { 624void sitecing_parser::soft_anchor() {
580 if(M().modus!=modus_operandi::modus_text) 625 if(M().modus!=modus_operandi::modus_text)
581 anchor(); 626 anchor();
582} 627}
583void sitecing_parser::anchor() { 628void sitecing_parser::anchor() {
584 if(M().modus==modus_operandi::modus_text) 629 if(M().modus==modus_operandi::modus_text)
585 M().modify(modus_operandi::modus_preop); 630 M().modify(modus_operandi::modus_preop);
586 M().output += "\n#line "; 631 M().output += "\n#line ";
587 char tmp[7]; 632 char tmp[7];
588 snprintf(tmp,sizeof(tmp),"%d",lineno()); 633 snprintf(tmp,sizeof(tmp),"%d",lineno());
589 M().output += tmp; 634 M().output += tmp;
590 M().output += " \""; 635 M().output += " \"";
591 M().output += input_file; 636 M().output += input_file;
592 M().output += "\"\n"; 637 M().output += "\"\n";
593} 638}
594/* vim:set ft=lex: */ 639/* vim:set ft=lex: */