summaryrefslogtreecommitdiffabout
path: root/lib/component_factory.cc
authorMichael Krelin <hacker@klever.net>2005-04-25 16:36:32 (UTC)
committer Michael Krelin <hacker@klever.net>2005-04-25 16:36:32 (UTC)
commit981b219f5297ad2ccc1fc1d0e24e41ec009c35a3 (patch) (unidiff)
tree9fa81d7fe70883ad26d946c902ba06edcebd4516 /lib/component_factory.cc
parent54e344b7e3623e807b893b7febad3adfc6c1648f (diff)
downloadsitecing-981b219f5297ad2ccc1fc1d0e24e41ec009c35a3.zip
sitecing-981b219f5297ad2ccc1fc1d0e24e41ec009c35a3.tar.gz
sitecing-981b219f5297ad2ccc1fc1d0e24e41ec009c35a3.tar.bz2
moved a few utility functions to konforka and bumped konforka version requirement accordingly
Diffstat (limited to 'lib/component_factory.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/component_factory.cc31
1 files changed, 16 insertions, 15 deletions
diff --git a/lib/component_factory.cc b/lib/component_factory.cc
index d9692de..af3d911 100644
--- a/lib/component_factory.cc
+++ b/lib/component_factory.cc
@@ -2,45 +2,46 @@
2 #include "pch.h" 2 #include "pch.h"
3#else 3#else
4 #include <sys/types.h> 4 #include <sys/types.h>
5 #include <sys/stat.h> 5 #include <sys/stat.h>
6 #include <unistd.h> 6 #include <unistd.h>
7 #include <sys/wait.h> 7 #include <sys/wait.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <iostream> 9 #include <iostream>
10 #include <fstream> 10 #include <fstream>
11 #include <stdexcept> 11 #include <stdexcept>
12 #include <vector> 12 #include <vector>
13 using namespace std; 13 using namespace std;
14 #include <konforka/util.h>
14 #include "sitecing/component_factory.h" 15 #include "sitecing/component_factory.h"
15 #include "sitecing/sitecing_util.h" 16 #include "sitecing/sitecing_util.h"
16 #include "sitecing/sitecing_parser.h" 17 #include "sitecing/sitecing_parser.h"
17 #include "sitecing/sitecing_exception.h" 18 #include "sitecing/sitecing_exception.h"
18#endif 19#endif
19 20
20namespace sitecing { 21namespace sitecing {
21 22
22 static const char *pp_targets[] = { ".cc", ".h", ".imports", ".classname", ".baseclassname", ".ancestors", ".pp_stamp" }; 23 static const char *pp_targets[] = { ".cc", ".h", ".imports", ".classname", ".baseclassname", ".ancestors", ".pp_stamp" };
23 static const char *cc_targets[] = { ".o", ".d" }; 24 static const char *cc_targets[] = { ".o", ".d" };
24 25
25 component_factory::component_factory(configuration& c) 26 component_factory::component_factory(configuration& c)
26 : config(c), 27 : config(c),
27 root_source(normalize_path(c.root_source,strip_trailing_slash)+'/'), 28 root_source(konforka::normalize_path(c.root_source,konforka::strip_trailing_slash)+'/'),
28 root_intermediate(normalize_path(c.root_intermediate,strip_trailing_slash)+'/'), 29 root_intermediate(konforka::normalize_path(c.root_intermediate,konforka::strip_trailing_slash)+'/'),
29 root_so(normalize_path(c.root_so,strip_trailing_slash)+'/') { 30 root_so(konforka::normalize_path(c.root_so,konforka::strip_trailing_slash)+'/') {
30 } 31 }
31 32
32 void component_factory::get_dependencies(const string& dst,file_list_t& deps) { 33 void component_factory::get_dependencies(const string& dst,file_list_t& deps) {
33 deps.clear(); 34 deps.clear();
34 string dp = normalize_path(dst,strip_trailing_slash); 35 string dp = konforka::normalize_path(dst,konforka::strip_trailing_slash);
35 // source documents 36 // source documents
36 try { // XXX: or just compare it off? 37 try { // XXX: or just compare it off?
37 string noro = strip_prefix(dp,root_source); 38 string noro = strip_prefix(dp,root_source);
38 return; 39 return;
39 }catch(utility_no_affix& una) { } 40 }catch(utility_no_affix& una) { }
40 // .so binaries 41 // .so binaries
41 try { 42 try {
42 string noso = strip_suffix(dp,".so"); 43 string noso = strip_suffix(dp,".so");
43 string noro = strip_prefix(noso,root_so); 44 string noro = strip_prefix(noso,root_so);
44 deps.push_back(root_intermediate+noro+".o"); 45 deps.push_back(root_intermediate+noro+".o");
45 config_options *co_so_deps = config.lookup_config(noro,config_options::flag_so_deps); 46 config_options *co_so_deps = config.lookup_config(noro,config_options::flag_so_deps);
46 if(co_so_deps) { 47 if(co_so_deps) {
@@ -89,77 +90,77 @@ namespace sitecing {
89 for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) { 90 for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) {
90 try { 91 try {
91 string nos = strip_suffix(noro,cc_targets[cct]); 92 string nos = strip_suffix(noro,cc_targets[cct]);
92 deps.push_back(root_intermediate+nos+".cc"); 93 deps.push_back(root_intermediate+nos+".cc");
93 config_options *co_cpp_deps = config.lookup_config(noro,config_options::flag_cpp_deps); 94 config_options *co_cpp_deps = config.lookup_config(noro,config_options::flag_cpp_deps);
94 if( (!co_cpp_deps) || co_cpp_deps->cpp_deps) { 95 if( (!co_cpp_deps) || co_cpp_deps->cpp_deps) {
95 ifstream df((root_intermediate+nos+".d").c_str(),ios::in); 96 ifstream df((root_intermediate+nos+".d").c_str(),ios::in);
96 if(df.good()) { 97 if(df.good()) {
97 string str; 98 string str;
98 while(!df.eof()) { 99 while(!df.eof()) {
99 df >> str; 100 df >> str;
100 if(str.find_first_of("\\:")==string::npos) 101 if(str.find_first_of("\\:")==string::npos)
101 deps.push_back(combine_path(config.root_source+nos,str)); 102 deps.push_back(konforka::combine_path(config.root_source+nos,str));
102 } 103 }
103 } 104 }
104 } 105 }
105 // XXX: intermediate_deps should be broken down 106 // XXX: intermediate_deps should be broken down
106 config_options *co_intermediate_deps = config.lookup_config(nos,config_options::flag_intermediate_deps); 107 config_options *co_intermediate_deps = config.lookup_config(nos,config_options::flag_intermediate_deps);
107 if(co_intermediate_deps) { 108 if(co_intermediate_deps) {
108 for(list<string>::const_iterator i=co_intermediate_deps->intermediate_deps.begin();i!=co_intermediate_deps->intermediate_deps.end();++i) 109 for(list<string>::const_iterator i=co_intermediate_deps->intermediate_deps.begin();i!=co_intermediate_deps->intermediate_deps.end();++i)
109 deps.push_back(*i); 110 deps.push_back(*i);
110 } 111 }
111 }catch(utility_no_suffix& uns) { } 112 }catch(utility_no_suffix& uns) { }
112 } 113 }
113 }catch(utility_no_prefix& unp) { } 114 }catch(utility_no_prefix& unp) { }
114 } 115 }
115 116
116 bool component_factory::is_uptodate(const string& dst,file_list_t *deps) { 117 bool component_factory::is_uptodate(const string& dst,file_list_t *deps) {
117 string dp = normalize_path(dst,strip_trailing_slash); 118 string dp = konforka::normalize_path(dst,konforka::strip_trailing_slash);
118 try { 119 try {
119 string noro = strip_prefix(dp,root_intermediate); 120 string noro = strip_prefix(dp,root_intermediate);
120 for(int ppt=0;(ppt+1)<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { 121 for(int ppt=0;(ppt+1)<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) {
121 try { 122 try {
122 string nos = strip_suffix(noro,pp_targets[ppt]); 123 string nos = strip_suffix(noro,pp_targets[ppt]);
123 return file_factory::is_uptodate(root_intermediate+nos+".pp_stamp",deps); 124 return file_factory::is_uptodate(root_intermediate+nos+".pp_stamp",deps);
124 }catch(utility_no_suffix& uns) { } 125 }catch(utility_no_suffix& uns) { }
125 } 126 }
126 bool rv = file_factory::is_uptodate(dst,deps); 127 bool rv = file_factory::is_uptodate(dst,deps);
127 return rv; 128 return rv;
128 }catch(utility_no_prefix& unp) { } 129 }catch(utility_no_prefix& unp) { }
129 // XXX: or just compare it off, instead of throwing things around. 130 // XXX: or just compare it off, instead of throwing things around.
130 try { 131 try {
131 strip_prefix(dp,root_so); 132 strip_prefix(dp,root_so);
132 return file_factory::is_uptodate(dst,deps); 133 return file_factory::is_uptodate(dst,deps);
133 }catch(utility_no_prefix& unp) { } 134 }catch(utility_no_prefix& unp) { }
134 return true; 135 return true;
135 } 136 }
136 137
137 void component_factory::build(const string& dst) { 138 void component_factory::build(const string& dst) {
138 string dp = normalize_path(dst,strip_trailing_slash); 139 string dp = konforka::normalize_path(dst,konforka::strip_trailing_slash);
139 // sources 140 // sources
140 try { 141 try {
141 string noro = strip_prefix(dp,root_source); 142 string noro = strip_prefix(dp,root_source);
142 // building the sources is left up to developer 143 // building the sources is left up to developer
143 return; 144 return;
144 }catch(utility_no_prefix& unp) { } 145 }catch(utility_no_prefix& unp) { }
145 // .so files 146 // .so files
146 try { 147 try {
147 string noso = strip_suffix(dp,".so"); 148 string noso = strip_suffix(dp,".so");
148 string noro = strip_prefix(noso,root_so); 149 string noro = strip_prefix(noso,root_so);
149 string o = root_intermediate+noro+".o"; 150 string o = root_intermediate+noro+".o";
150 cerr << "Linking " << noro << endl; 151 cerr << "Linking " << noro << endl;
151 if(access(o.c_str(),R_OK)) 152 if(access(o.c_str(),R_OK))
152 throw konforka::exception(CODEPOINT,string("can't access compiled component code (")+o+")"); 153 throw konforka::exception(CODEPOINT,string("can't access compiled component code (")+o+")");
153 make_path(dir_name(root_so+noro),0755); 154 konforka::make_path(konforka::dir_name(root_so+noro),0755);
154 file_lock lock_cc(root_intermediate+noro+".o.lock"); 155 file_lock lock_cc(root_intermediate+noro+".o.lock");
155 file_lock lock_so(root_so+noro+".so.lock"); 156 file_lock lock_so(root_so+noro+".so.lock");
156 int stdO = open((root_intermediate+noro+".ld.stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); 157 int stdO = open((root_intermediate+noro+".ld.stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664);
157 if(stdO<0) 158 if(stdO<0)
158 throw konforka::exception(CODEPOINT,"failed to open/create linker stdout"); 159 throw konforka::exception(CODEPOINT,"failed to open/create linker stdout");
159 int stdE = open((root_intermediate+noro+".ld.stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); 160 int stdE = open((root_intermediate+noro+".ld.stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664);
160 if(stdE<0) { 161 if(stdE<0) {
161 close(stdO); 162 close(stdO);
162 throw konforka::exception(CODEPOINT,"failed to open/create linker stderr"); 163 throw konforka::exception(CODEPOINT,"failed to open/create linker stderr");
163 } 164 }
164 list<string> args; 165 list<string> args;
165 config_options *co_ld_flags = config.lookup_config(noro,config_options::flag_ld_flags); 166 config_options *co_ld_flags = config.lookup_config(noro,config_options::flag_ld_flags);
@@ -186,26 +187,26 @@ namespace sitecing {
186 }catch(utility_no_suffix& uns) { } 187 }catch(utility_no_suffix& uns) { }
187 try { 188 try {
188 string noro = strip_prefix(dp,root_intermediate); 189 string noro = strip_prefix(dp,root_intermediate);
189 // compiler targets 190 // compiler targets
190 for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) { 191 for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) {
191 try { 192 try {
192 string nos = strip_suffix(noro,cc_targets[cct]); 193 string nos = strip_suffix(noro,cc_targets[cct]);
193 string cc = root_intermediate+nos+".cc"; 194 string cc = root_intermediate+nos+".cc";
194 string o = root_intermediate+nos+".o"; 195 string o = root_intermediate+nos+".o";
195 cerr << "Compiling " << nos << endl; 196 cerr << "Compiling " << nos << endl;
196 if(access(cc.c_str(),R_OK)) 197 if(access(cc.c_str(),R_OK))
197 throw konforka::exception(CODEPOINT,string("can't access preprocessed component code (")+cc+")"); 198 throw konforka::exception(CODEPOINT,string("can't access preprocessed component code (")+cc+")");
198 make_path(dir_name(cc),0755); 199 konforka::make_path(konforka::dir_name(cc),0755);
199 string pwd = dir_name(root_source+nos); 200 string pwd = konforka::dir_name(root_source+nos);
200 auto_chdir dir_changer(pwd); 201 auto_chdir dir_changer(pwd);
201 file_lock lock_source(root_intermediate+nos+".lock"); 202 file_lock lock_source(root_intermediate+nos+".lock");
202 file_lock lock_cc(root_intermediate+nos+".o.lock"); 203 file_lock lock_cc(root_intermediate+nos+".o.lock");
203 int stdO = open((root_intermediate+nos+".stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); 204 int stdO = open((root_intermediate+nos+".stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664);
204 if(stdO<0) 205 if(stdO<0)
205 throw konforka::exception(CODEPOINT,"failed to open/create compiler stdout"); 206 throw konforka::exception(CODEPOINT,"failed to open/create compiler stdout");
206 int stdE = open((root_intermediate+nos+".stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); 207 int stdE = open((root_intermediate+nos+".stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664);
207 if(stdE<0) { 208 if(stdE<0) {
208 close(stdO); 209 close(stdO);
209 throw konforka::exception(CODEPOINT,"failed to open/create compiler's stderr"); 210 throw konforka::exception(CODEPOINT,"failed to open/create compiler's stderr");
210 } 211 }
211 list<string> args; 212 list<string> args;
@@ -226,32 +227,32 @@ namespace sitecing {
226 throw compile_error(CODEPOINT,"failed to compile component",nos); 227 throw compile_error(CODEPOINT,"failed to compile component",nos);
227 return; 228 return;
228 }catch(utility_no_suffix& uns) { } 229 }catch(utility_no_suffix& uns) { }
229 } 230 }
230 // preprocessor targets 231 // preprocessor targets
231 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++) {
232 try { 233 try {
233 string nos = strip_suffix(noro,pp_targets[ppt]); 234 string nos = strip_suffix(noro,pp_targets[ppt]);
234 string src = root_source+nos; 235 string src = root_source+nos;
235 cerr << "Preprocessing " << nos << endl; 236 cerr << "Preprocessing " << nos << endl;
236 if(access(src.c_str(),R_OK)) 237 if(access(src.c_str(),R_OK))
237 throw konforka::exception(CODEPOINT,string("can't access component source (")+src+")"); 238 throw konforka::exception(CODEPOINT,string("can't access component source (")+src+")");
238 make_path(dir_name(root_intermediate+nos),0755); 239 konforka::make_path(konforka::dir_name(root_intermediate+nos),0755);
239 file_lock lock(root_intermediate+nos+".lock"); 240 file_lock lock(root_intermediate+nos+".lock");
240 sitecing_parser parser(*this); 241 sitecing_parser parser(*this);
241 config_options *co_skeleton = config.lookup_config(nos,config_options::flag_skeleton); 242 config_options *co_skeleton = config.lookup_config(nos,config_options::flag_skeleton);
242 if(co_skeleton) 243 if(co_skeleton)
243 parser.skeleton = co_skeleton->skeleton; 244 parser.skeleton = co_skeleton->skeleton;
244 static const char *id_chars = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 245 static const char *id_chars = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
245 parser.class_name = normalize_path(nos,strip_leading_slash|strip_trailing_slash); 246 parser.class_name = konforka::normalize_path(nos,konforka::strip_leading_slash|konforka::strip_trailing_slash);
246 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)) {
247 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);
248 int n = ((lc==string::npos)?parser.class_name.length():lc)-illc; 249 int n = ((lc==string::npos)?parser.class_name.length():lc)-illc;
249 parser.class_name.replace(illc,n,n,'_'); 250 parser.class_name.replace(illc,n,n,'_');
250 } 251 }
251 parser.class_name = "_SCC_"+parser.class_name; 252 parser.class_name = "_SCC_"+parser.class_name;
252 parser.output_basename = root_intermediate+nos; 253 parser.output_basename = root_intermediate+nos;
253 parser.component_basename = nos; 254 parser.component_basename = nos;
254 try { 255 try {
255 parser.preprocess(src); 256 parser.preprocess(src);
256 string sf = root_intermediate+nos+".pp_stamp"; 257 string sf = root_intermediate+nos+".pp_stamp";
257 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,25 +260,25 @@ namespace sitecing {
259 pe.component_name = nos; 260 pe.component_name = nos;
260 pe.see(CODEPOINT); 261 pe.see(CODEPOINT);
261 throw; 262 throw;
262 } 263 }
263 return; 264 return;
264 }catch(utility_no_suffix& uns) { } 265 }catch(utility_no_suffix& uns) { }
265 } 266 }
266 }catch(utility_no_prefix& unp) { } 267 }catch(utility_no_prefix& unp) { }
267 cerr << "ignoring build request for " << dp << endl; 268 cerr << "ignoring build request for " << dp << endl;
268 } 269 }
269 270
270 void component_factory::make(const string& dst) { 271 void component_factory::make(const string& dst) {
271 string dp = normalize_path(dst,strip_trailing_slash); 272 string dp = konforka::normalize_path(dst,konforka::strip_trailing_slash);
272 try { 273 try {
273 string noso = strip_suffix(dp,".so"); 274 string noso = strip_suffix(dp,".so");
274 string noro = strip_prefix(noso,root_so); 275 string noro = strip_prefix(noso,root_so);
275 file_list_t a; 276 file_list_t a;
276 get_ancestors(noro,a); 277 get_ancestors(noro,a);
277 for(file_list_t::const_iterator i=a.begin();i!=a.end();++i) { 278 for(file_list_t::const_iterator i=a.begin();i!=a.end();++i) {
278 make(root_so+*i+".so"); 279 make(root_so+*i+".so");
279 } 280 }
280 }catch(utility_no_affix& una) { } 281 }catch(utility_no_affix& una) { }
281 file_factory::make(dst); 282 file_factory::make(dst);
282 } 283 }
283 284
@@ -308,35 +309,35 @@ namespace sitecing {
308 execvp(cmd.c_str(),(char**)&argv.front()); 309 execvp(cmd.c_str(),(char**)&argv.front());
309 _exit(-1); 310 _exit(-1);
310 } 311 }
311 // parent 312 // parent
312 close(stdo); close(stde); 313 close(stdo); close(stde);
313 int rv; 314 int rv;
314 if(waitpid(pid,&rv,0)<0) 315 if(waitpid(pid,&rv,0)<0)
315 throw konforka::exception(CODEPOINT,"failed to waitpid()"); 316 throw konforka::exception(CODEPOINT,"failed to waitpid()");
316 return rv; 317 return rv;
317 } 318 }
318 319
319 string component_factory::get_classname(const string& component) { 320 string component_factory::get_classname(const string& component) {
320 string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".classname"; 321 string cn = root_intermediate+konforka::normalize_path(component,konforka::strip_trailing_slash|konforka::strip_leading_slash)+".classname";
321 make(cn); 322 make(cn);
322 ifstream ifs(cn.c_str()); 323 ifstream ifs(cn.c_str());
323 if(!ifs.good()) 324 if(!ifs.good())
324 throw konforka::exception(CODEPOINT,"failed to access component .classname"); 325 throw konforka::exception(CODEPOINT,"failed to access component .classname");
325 ifs >> cn; 326 ifs >> cn;
326 return cn; 327 return cn;
327 } 328 }
328 329
329 void component_factory::get_ancestors(const string& component,file_list_t& rv) { 330 void component_factory::get_ancestors(const string& component,file_list_t& rv) {
330 string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".ancestors"; 331 string cn = root_intermediate+konforka::normalize_path(component,konforka::strip_trailing_slash|konforka::strip_leading_slash)+".ancestors";
331 make(cn); 332 make(cn);
332 ifstream ifs(cn.c_str()); 333 ifstream ifs(cn.c_str());
333 if(!ifs.good()) 334 if(!ifs.good())
334 throw konforka::exception(CODEPOINT,string("failed to access component '")+component+"' .ancestors"); 335 throw konforka::exception(CODEPOINT,string("failed to access component '")+component+"' .ancestors");
335 rv.clear(); 336 rv.clear();
336 while(!ifs.eof()) { 337 while(!ifs.eof()) {
337 string a; 338 string a;
338 ifs >> a; 339 ifs >> a;
339 if(!a.empty()) 340 if(!a.empty())
340 rv.push_back(a); 341 rv.push_back(a);
341 } 342 }
342 } 343 }