-rw-r--r-- | lib/component_factory.cc | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/lib/component_factory.cc b/lib/component_factory.cc index f8666dc..b8f5a16 100644 --- a/lib/component_factory.cc +++ b/lib/component_factory.cc | |||
@@ -1,46 +1,46 @@ | |||
1 | #ifdef USE_PCH | 1 | #ifdef USE_PCH |
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 "sitecing/component_factory.h" | 14 | #include "sitecing/component_factory.h" |
15 | #include "sitecing/sitecing_util.h" | 15 | #include "sitecing/sitecing_util.h" |
16 | #include "sitecing/sitecing_parser.h" | 16 | #include "sitecing/sitecing_parser.h" |
17 | #include "sitecing/sitecing_exception.h" | 17 | #include "sitecing/sitecing_exception.h" |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | namespace sitecing { | 20 | namespace sitecing { |
21 | 21 | ||
22 | static const char *pp_targets[] = { ".cc", ".h", ".imports", ".classname", ".baseclassname", ".ancestors" }; | 22 | static const char *pp_targets[] = { ".cc", ".h", ".imports", ".classname", ".baseclassname", ".ancestors", ".pp_stamp" }; |
23 | static const char *cc_targets[] = { ".o", ".d" }; | 23 | static const char *cc_targets[] = { ".o", ".d" }; |
24 | 24 | ||
25 | component_factory::component_factory(configuration& c) | 25 | component_factory::component_factory(configuration& c) |
26 | : config(c), | 26 | : config(c), |
27 | root_source(normalize_path(c.root_source,strip_trailing_slash)+'/'), | 27 | root_source(normalize_path(c.root_source,strip_trailing_slash)+'/'), |
28 | root_intermediate(normalize_path(c.root_intermediate,strip_trailing_slash)+'/'), | 28 | root_intermediate(normalize_path(c.root_intermediate,strip_trailing_slash)+'/'), |
29 | root_so(normalize_path(c.root_so,strip_trailing_slash)+'/') { | 29 | root_so(normalize_path(c.root_so,strip_trailing_slash)+'/') { |
30 | } | 30 | } |
31 | 31 | ||
32 | void component_factory::get_dependencies(const string& dst,file_list_t& deps) { | 32 | void component_factory::get_dependencies(const string& dst,file_list_t& deps) { |
33 | deps.clear(); | 33 | deps.clear(); |
34 | string dp = normalize_path(dst,strip_trailing_slash); | 34 | string dp = normalize_path(dst,strip_trailing_slash); |
35 | // source documents | 35 | // source documents |
36 | try { // XXX: or just compare it off? | 36 | try { // XXX: or just compare it off? |
37 | string noro = strip_prefix(dp,root_source); | 37 | string noro = strip_prefix(dp,root_source); |
38 | return; | 38 | return; |
39 | }catch(utility_no_affix& una) { | 39 | }catch(utility_no_affix& una) { |
40 | } | 40 | } |
41 | // .so binaries | 41 | // .so binaries |
42 | try { | 42 | try { |
43 | string noso = strip_suffix(dp,".so"); | 43 | string noso = strip_suffix(dp,".so"); |
44 | string noro = strip_prefix(noso,root_so); | 44 | string noro = strip_prefix(noso,root_so); |
45 | deps.push_back(root_intermediate+noro+".o"); | 45 | deps.push_back(root_intermediate+noro+".o"); |
46 | 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); |
@@ -95,57 +95,62 @@ namespace sitecing { | |||
95 | deps.push_back(root_intermediate+noro+".cc"); | 95 | deps.push_back(root_intermediate+noro+".cc"); |
96 | config_options *co_cpp_deps = config.lookup_config(noro,config_options::flag_cpp_deps); | 96 | config_options *co_cpp_deps = config.lookup_config(noro,config_options::flag_cpp_deps); |
97 | if( (!co_cpp_deps) || co_cpp_deps->cpp_deps) { | 97 | if( (!co_cpp_deps) || co_cpp_deps->cpp_deps) { |
98 | ifstream df((root_intermediate+noro+".d").c_str(),ios::in); | 98 | ifstream df((root_intermediate+noro+".d").c_str(),ios::in); |
99 | if(df.good()) { | 99 | if(df.good()) { |
100 | string str; | 100 | string str; |
101 | while(!df.eof()) { | 101 | while(!df.eof()) { |
102 | df >> str; | 102 | df >> str; |
103 | if(str.find_first_of("\\:")==string::npos) | 103 | if(str.find_first_of("\\:")==string::npos) |
104 | deps.push_back(combine_path(config.root_source+noro,str)); | 104 | deps.push_back(combine_path(config.root_source+noro,str)); |
105 | } | 105 | } |
106 | } | 106 | } |
107 | } | 107 | } |
108 | // XXX: extra deps like IntermediateDeps? | 108 | // XXX: extra deps like IntermediateDeps? |
109 | }catch(utility_no_affix& una) { | 109 | }catch(utility_no_affix& una) { |
110 | // do nothing. | 110 | // do nothing. |
111 | } | 111 | } |
112 | } | 112 | } |
113 | } | 113 | } |
114 | 114 | ||
115 | bool component_factory::is_uptodate(const string& dst,file_list_t *deps) { | 115 | bool component_factory::is_uptodate(const string& dst,file_list_t *deps) { |
116 | string dp = normalize_path(dst,strip_trailing_slash); | 116 | string dp = normalize_path(dst,strip_trailing_slash); |
117 | // XXX: or just compare it off, instead of throwing things around. | 117 | // XXX: or just compare it off, instead of throwing things around. |
118 | try { | 118 | try { |
119 | strip_prefix(dp,root_intermediate); | 119 | string noro = strip_prefix(dp,root_intermediate); |
120 | return file_factory::is_uptodate(dst,deps); | 120 | for(int ppt=0;(ppt+1)<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { |
121 | }catch(utility_no_prefix& unp) { | 121 | try { |
122 | } | 122 | string nos = strip_suffix(noro,pp_targets[ppt]); |
123 | return file_factory::is_uptodate(root_intermediate+nos+".pp_stamp",deps); | ||
124 | }catch(utility_no_suffix& uns) { } | ||
125 | } | ||
126 | bool rv = file_factory::is_uptodate(dst,deps); | ||
127 | return rv; | ||
128 | }catch(utility_no_prefix& unp) { } | ||
123 | try { | 129 | try { |
124 | strip_prefix(dp,root_so); | 130 | strip_prefix(dp,root_so); |
125 | return file_factory::is_uptodate(dst,deps); | 131 | return file_factory::is_uptodate(dst,deps); |
126 | }catch(utility_no_prefix& unp) { | 132 | }catch(utility_no_prefix& unp) { } |
127 | } | ||
128 | return true; | 133 | return true; |
129 | } | 134 | } |
130 | 135 | ||
131 | void component_factory::build(const string& dst) { | 136 | void component_factory::build(const string& dst) { |
132 | string dp = normalize_path(dst,strip_trailing_slash); | 137 | string dp = normalize_path(dst,strip_trailing_slash); |
133 | // sources | 138 | // sources |
134 | try { | 139 | try { |
135 | string noro = strip_prefix(dp,root_source); | 140 | string noro = strip_prefix(dp,root_source); |
136 | // building the sources is left up to developer | 141 | // building the sources is left up to developer |
137 | return; | 142 | return; |
138 | }catch(utility_no_prefix& unp) { | 143 | }catch(utility_no_prefix& unp) { |
139 | } | 144 | } |
140 | // .so files | 145 | // .so files |
141 | try { | 146 | try { |
142 | string noso = strip_suffix(dp,".so"); | 147 | string noso = strip_suffix(dp,".so"); |
143 | string noro = strip_prefix(noso,root_so); | 148 | string noro = strip_prefix(noso,root_so); |
144 | string o = root_intermediate+noro+".o"; | 149 | string o = root_intermediate+noro+".o"; |
145 | if(access(o.c_str(),R_OK)) | 150 | if(access(o.c_str(),R_OK)) |
146 | 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+")"); |
147 | make_path(dir_name(root_so+noro),0755); | 152 | make_path(dir_name(root_so+noro),0755); |
148 | file_lock lock_cc(root_intermediate+noro+".o.lock"); | 153 | file_lock lock_cc(root_intermediate+noro+".o.lock"); |
149 | file_lock lock_so(root_so+noro+".so.lock"); | 154 | file_lock lock_so(root_so+noro+".so.lock"); |
150 | 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); |
151 | if(stdO<0) | 156 | if(stdO<0) |
@@ -228,48 +233,50 @@ namespace sitecing { | |||
228 | try { | 233 | try { |
229 | string nos = strip_suffix(dp,pp_targets[ppt]); | 234 | string nos = strip_suffix(dp,pp_targets[ppt]); |
230 | string noro = strip_prefix(nos,root_intermediate); | 235 | string noro = strip_prefix(nos,root_intermediate); |
231 | string src = root_source+noro; | 236 | string src = root_source+noro; |
232 | if(access(src.c_str(),R_OK)) | 237 | if(access(src.c_str(),R_OK)) |
233 | throw konforka::exception(CODEPOINT,string("can't access component source (")+src+")"); | 238 | throw konforka::exception(CODEPOINT,string("can't access component source (")+src+")"); |
234 | make_path(dir_name(root_intermediate+noro),0755); | 239 | make_path(dir_name(root_intermediate+noro),0755); |
235 | file_lock lock(root_intermediate+noro+".lock"); | 240 | file_lock lock(root_intermediate+noro+".lock"); |
236 | sitecing_parser parser(*this); | 241 | sitecing_parser parser(*this); |
237 | 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); |
238 | if(co_skeleton) | 243 | if(co_skeleton) |
239 | parser.skeleton = co_skeleton->skeleton; | 244 | parser.skeleton = co_skeleton->skeleton; |
240 | static const char *id_chars = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | 245 | static const char *id_chars = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
241 | 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); |
242 | 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)) { |
243 | 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); |
244 | int n = ((lc==string::npos)?parser.class_name.length():lc)-illc; | 249 | int n = ((lc==string::npos)?parser.class_name.length():lc)-illc; |
245 | parser.class_name.replace(illc,n,n,'_'); | 250 | parser.class_name.replace(illc,n,n,'_'); |
246 | } | 251 | } |
247 | parser.class_name = "_SCC_"+parser.class_name; | 252 | parser.class_name = "_SCC_"+parser.class_name; |
248 | parser.output_basename = nos; | 253 | parser.output_basename = nos; |
249 | parser.component_basename = noro; | 254 | parser.component_basename = noro; |
250 | try { | 255 | try { |
251 | parser.preprocess(src); | 256 | parser.preprocess(src); |
257 | string sf = root_intermediate+noro+".pp_stamp"; | ||
258 | ofstream sfs(sf.c_str(),ios::trunc|ios::out); // touch .pp_stamp | ||
252 | }catch(preprocessor_error& pe) { | 259 | }catch(preprocessor_error& pe) { |
253 | pe.component_name = noro; | 260 | pe.component_name = noro; |
254 | pe.see(CODEPOINT); | 261 | pe.see(CODEPOINT); |
255 | throw; | 262 | throw; |
256 | } | 263 | } |
257 | return; | 264 | return; |
258 | }catch(utility_no_affix& una) { | 265 | }catch(utility_no_affix& una) { |
259 | // must be a crap from .d file | 266 | // must be a crap from .d file |
260 | } | 267 | } |
261 | } | 268 | } |
262 | cerr << "ignoring build request for " << dp << endl; | 269 | cerr << "ignoring build request for " << dp << endl; |
263 | } | 270 | } |
264 | 271 | ||
265 | 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) { |
266 | // 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? |
267 | cerr << "executing: " << cmd; | 274 | cerr << "executing: " << cmd; |
268 | vector<const char*> argv(args.size()+2); | 275 | vector<const char*> argv(args.size()+2); |
269 | argv[0]=cmd.c_str(); | 276 | argv[0]=cmd.c_str(); |
270 | int an = 1; | 277 | int an = 1; |
271 | 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++) { |
272 | cerr << " " << *i ; | 279 | cerr << " " << *i ; |
273 | argv[an++] = i->c_str(); | 280 | argv[an++] = i->c_str(); |
274 | } | 281 | } |
275 | cerr << endl; | 282 | cerr << endl; |