summaryrefslogtreecommitdiffabout
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
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 (more/less context) (ignore whitespace changes)
-rw-r--r--components/exception_dev7
-rw-r--r--configure.ac4
-rw-r--r--include/sitecing/sitecing_util.h87
-rw-r--r--lib/component_factory.cc31
-rw-r--r--lib/configuration.cc9
-rw-r--r--lib/sitecing_parser.ll13
-rw-r--r--lib/sitecing_util.cc117
-rw-r--r--lib/sitespace.cc3
-rw-r--r--src/sitecing-build.cc5
-rw-r--r--src/sitecing-fastcgi.cc4
-rw-r--r--src/sitecing-plaincgi.cc4
11 files changed, 48 insertions, 236 deletions
diff --git a/components/exception_dev b/components/exception_dev
index d8c84e1..d62f462 100644
--- a/components/exception_dev
+++ b/components/exception_dev
@@ -1,36 +1,37 @@
1%%decl using namespace std; 1%%decl using namespace std;
2<%impl> 2<%impl>
3 #include <iostream> 3 #include <iostream>
4 #include <fstream> 4 #include <fstream>
5 #include <sstream> 5 #include <sstream>
6 #include <cassert> 6 #include <cassert>
7 #include <cstdarg> 7 #include <cstdarg>
8 #include <stdexcept> 8 #include <stdexcept>
9 #include <cxxabi.h> 9 #include <cxxabi.h>
10 #include <sitecing/sitecing_util.h> 10 #include <sitecing/sitecing_util.h>
11 #include <sitecing/util.h> 11 #include <sitecing/util.h>
12 #include <sitecing/magic.h> 12 #include <sitecing/magic.h>
13 #include <konforka/util.h>
13 #include <konforka/exception.h> 14 #include <konforka/exception.h>
14</%impl> 15</%impl>
15%%var string message; 16%%var string message;
16%%var string root_source; 17%%var string root_source;
17%%var string root_intermediate; 18%%var string root_intermediate;
18%%var string root_so; 19%%var string root_so;
19%%var string component; 20%%var string component;
20%%var int line_number = -1; 21%%var int line_number = -1;
21%%var const exception* exception_caught; 22%%var const exception* exception_caught;
22<%code> 23<%code>
23 __SCIF->headers.clear(); 24 __SCIF->headers.clear();
24 __SCIF->out->seekp(0); 25 __SCIF->out->seekp(0);
25 int magic = _magic; 26 int magic = _magic;
26 va_list va = _args; 27 va_list va = _args;
27 switch(magic) { 28 switch(magic) {
28 case sitecing::__magic_compile_error: 29 case sitecing::__magic_compile_error:
29 message = va_arg(va,const char*); 30 message = va_arg(va,const char*);
30 root_source = va_arg(va,const char*); 31 root_source = va_arg(va,const char*);
31 root_intermediate = va_arg(va,const char*); 32 root_intermediate = va_arg(va,const char*);
32 root_so = va_arg(va,const char*); 33 root_so = va_arg(va,const char*);
33 component = va_arg(va,const char*); 34 component = va_arg(va,const char*);
34 break; 35 break;
35 case sitecing::__magic_preprocess_error: 36 case sitecing::__magic_preprocess_error:
36 message = va_arg(va,const char*); 37 message = va_arg(va,const char*);
@@ -233,59 +234,59 @@
233 while(!err.eof()) { 234 while(!err.eof()) {
234 string oef = error_file; 235 string oef = error_file;
235 long oel = error_line; 236 long oel = error_line;
236 string line; 237 string line;
237 getline(err,line); 238 getline(err,line);
238 if(line[0]!=' ') { 239 if(line[0]!=' ') {
239 string::size_type c = line.find(':'); 240 string::size_type c = line.find(':');
240 if(c!=string::npos) { 241 if(c!=string::npos) {
241 string fn = line.substr(0,c); 242 string fn = line.substr(0,c);
242 string::size_type c1 = line.find(':',c+1); 243 string::size_type c1 = line.find(':',c+1);
243 if(c1!=string::npos) { 244 if(c1!=string::npos) {
244 string ln = line.substr(c+1,c1-c-1); 245 string ln = line.substr(c+1,c1-c-1);
245 string::size_type nd = ln.find_first_not_of("0123456789"); 246 string::size_type nd = ln.find_first_not_of("0123456789");
246 if(nd==string::npos) { 247 if(nd==string::npos) {
247 try { 248 try {
248 error_file = sitecing::strip_prefix(fn,"In file included from "); 249 error_file = sitecing::strip_prefix(fn,"In file included from ");
249 }catch(sitecing::utility_no_prefix& unp) { 250 }catch(sitecing::utility_no_prefix& unp) {
250 error_file = fn; 251 error_file = fn;
251 } 252 }
252 error_line = strtol(ln.c_str(),0,10); 253 error_line = strtol(ln.c_str(),0,10);
253 } 254 }
254 } 255 }
255 } 256 }
256 if((oel>0 && !oef.empty()) && (oel!=error_line || oef!=error_file)) { 257 if((oel>0 && !oef.empty()) && (oel!=error_line || oef!=error_file)) {
257 string ef = "/"+sitecing::combine_path(root_source+component,oef); 258 string ef = "/"+konforka::combine_path(root_source+component,oef);
258 report_error(ef,oel,remove_roots(cumulative)); 259 report_error(ef,oel,remove_roots(cumulative));
259 cumulative.clear(); 260 cumulative.clear();
260 } 261 }
261 } 262 }
262 if(!cumulative.empty()) 263 if(!cumulative.empty())
263 cumulative += '\n'; 264 cumulative += '\n';
264 cumulative += line; 265 cumulative += line;
265 } 266 }
266 if(!(cumulative.empty() || error_file.empty() || error_line<0)) { 267 if(!(cumulative.empty() || error_file.empty() || error_line<0)) {
267 error_file = "/"+sitecing::combine_path(root_source+component,error_file); 268 error_file = "/"+konforka::combine_path(root_source+component,error_file);
268 report_error(error_file,error_line,remove_roots(cumulative)); 269 report_error(error_file,error_line,remove_roots(cumulative));
269 } 270 }
270 } 271 }
271 </%code> 272 </%code>
272 </div> 273 </div>
273</%method> 274</%method>
274<%method void handle_unknown_error() %> 275<%method void handle_unknown_error() %>
275 <div class="exception-unknown"> 276 <div class="exception-unknown">
276 <h1>unknown error</h1> 277 <h1>unknown error</h1>
277 </div> 278 </div>
278</%method> 279</%method>
279<%method void report_error(const string& file,long line,const string& message) %> 280<%method void report_error(const string& file,long line,const string& message) %>
280 <div class="exception-codepoint-report"> 281 <div class="exception-codepoint-report">
281 <h3><% sitecing::html_escape(strip_roots(file)) %></h3> 282 <h3><% sitecing::html_escape(strip_roots(file)) %></h3>
282 <%code> 283 <%code>
283 if(line>=0) { 284 if(line>=0) {
284 int firstline = line-5, lastline = line+5; 285 int firstline = line-5, lastline = line+5;
285 if(firstline<1) 286 if(firstline<1)
286 firstline = 1; 287 firstline = 1;
287 ifstream ifs(file.c_str(),ios::in); 288 ifstream ifs(file.c_str(),ios::in);
288 if(ifs.bad()) { 289 if(ifs.bad()) {
289 // TODO: 290 // TODO:
290 }else{ 291 }else{
291 for(int l=1;l<firstline && !ifs.eof();l++) { 292 for(int l=1;l<firstline && !ifs.eof();l++) {
@@ -297,49 +298,49 @@
297 <%output><ul></%output> 298 <%output><ul></%output>
298 for(int l=firstline;l<=lastline && !ifs.eof();l++) { 299 for(int l=firstline;l<=lastline && !ifs.eof();l++) {
299 string str; 300 string str;
300 getline(ifs,str); 301 getline(ifs,str);
301 for(string::size_type t=str.find('\t');t!=string::npos;t=str.find('\t')) { 302 for(string::size_type t=str.find('\t');t!=string::npos;t=str.find('\t')) {
302 str.replace(t,1,8-(t%8),' '); 303 str.replace(t,1,8-(t%8),' ');
303 } 304 }
304 char tln[16]; 305 char tln[16];
305 snprintf(tln,sizeof(tln),"%5d",l); 306 snprintf(tln,sizeof(tln),"%5d",l);
306 <%output> 307 <%output>
307 <li class="<% l==line?"focused":"unfocused" %>"><span class="lineno"><% sitecing::html_escape(tln,sitecing::html_escape_nbsp) %></span>&nbsp;<span class="line"><% sitecing::html_escape(str,sitecing::html_escape_nbsp) %></span></li> 308 <li class="<% l==line?"focused":"unfocused" %>"><span class="lineno"><% sitecing::html_escape(tln,sitecing::html_escape_nbsp) %></span>&nbsp;<span class="line"><% sitecing::html_escape(str,sitecing::html_escape_nbsp) %></span></li>
308 </%output> 309 </%output>
309 } 310 }
310 <%output></ul></%output> 311 <%output></ul></%output>
311 } 312 }
312 } 313 }
313 } 314 }
314 </%code> 315 </%code>
315 <div class="what"> 316 <div class="what">
316 <% sitecing::html_escape(message,sitecing::html_escape_br) %> 317 <% sitecing::html_escape(message,sitecing::html_escape_br) %>
317 </div> 318 </div>
318 </div> 319 </div>
319</%method> 320</%method>
320<%codemethod string strip_roots(const string& filename) %> 321<%codemethod string strip_roots(const string& filename) %>
321 string np = sitecing::normalize_path(filename); 322 string np = konforka::normalize_path(filename);
322 try{ 323 try{
323 return sitecing::strip_prefix(np,root_source); 324 return sitecing::strip_prefix(np,root_source);
324 }catch(sitecing::utility_no_prefix& e){ } 325 }catch(sitecing::utility_no_prefix& e){ }
325 try{ 326 try{
326 return sitecing::strip_prefix(np,root_intermediate); 327 return sitecing::strip_prefix(np,root_intermediate);
327 }catch(sitecing::utility_no_prefix& e){ } 328 }catch(sitecing::utility_no_prefix& e){ }
328</%codemethod> 329</%codemethod>
329<%codemethod string remove_roots(const string& str) %> 330<%codemethod string remove_roots(const string& str) %>
330 string rv = str; 331 string rv = str;
331 string::size_type rp; 332 string::size_type rp;
332 string::size_type rl = root_source.length(); 333 string::size_type rl = root_source.length();
333 while((rp=rv.find(root_source))!=string::npos) { 334 while((rp=rv.find(root_source))!=string::npos) {
334 rv.erase(rp,rl); 335 rv.erase(rp,rl);
335 } 336 }
336 rl = root_intermediate.length(); 337 rl = root_intermediate.length();
337 while((rp=rv.find(root_intermediate))!=string::npos) { 338 while((rp=rv.find(root_intermediate))!=string::npos) {
338 rv.erase(rp,rl); 339 rv.erase(rp,rl);
339 } 340 }
340 rl = root_so.length(); 341 rl = root_so.length();
341 while((rp=rv.find(root_so))!=string::npos) { 342 while((rp=rv.find(root_so))!=string::npos) {
342 rv.erase(rp,rl); 343 rv.erase(rp,rl);
343 } 344 }
344 return rv; 345 return rv;
345</%codemethod> 346</%codemethod>
diff --git a/configure.ac b/configure.ac
index a8aa142..fde326b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,46 +1,50 @@
1AC_INIT([sitecing], [0.0.1], [sitecing-bugs@klever.net]) 1AC_INIT([sitecing], [0.0.1], [sitecing-bugs@klever.net])
2AC_CONFIG_SRCDIR([include/sitecing/sitecing_parser.h]) 2AC_CONFIG_SRCDIR([include/sitecing/sitecing_parser.h])
3AC_CONFIG_HEADER([config.h]) 3AC_CONFIG_HEADER([config.h])
4AM_INIT_AUTOMAKE([dist-bzip2]) 4AM_INIT_AUTOMAKE([dist-bzip2])
5 5
6AC_PROG_INSTALL 6AC_PROG_INSTALL
7AC_PROG_AWK 7AC_PROG_AWK
8AC_PROG_CXX 8AC_PROG_CXX
9AC_PROG_CC 9AC_PROG_CC
10AM_PROG_LEX 10AM_PROG_LEX
11AC_PROG_LIBTOOL 11AC_PROG_LIBTOOL
12 12
13AC_HEADER_STDC 13AC_HEADER_STDC
14AC_CHECK_HEADERS([stdlib.h unistd.h]) 14AC_CHECK_HEADERS([stdlib.h unistd.h])
15 15
16AC_C_CONST 16AC_C_CONST
17 17
18AC_FUNC_MALLOC 18AC_FUNC_MALLOC
19AC_FUNC_REALLOC 19AC_FUNC_REALLOC
20 20
21AC_WITH_PKGCONFIG 21AC_WITH_PKGCONFIG
22 22
23PKG_CHECK_MODULES([KONFORKA],[konforka >= 0.0.1],,[
24 AC_MSG_ERROR([no proper version of konforka library found, get it at http://kin.klever.net/konforka/])
25])
26
23PKG_CHECK_MODULES([KINGATE],[kingate >= 0.0.1],,[ 27PKG_CHECK_MODULES([KINGATE],[kingate >= 0.0.1],,[
24 AC_MSG_ERROR([no kingate library found, get it at http://kin.klever.net/kingate/]) 28 AC_MSG_ERROR([no kingate library found, get it at http://kin.klever.net/kingate/])
25]) 29])
26HAVE_FCGI=false 30HAVE_FCGI=false
27HAVE_PLAINCGI=false 31HAVE_PLAINCGI=false
28PKG_CHECK_MODULES([KINGATE_FCGI],[kingate-fcgi >= 0.0.1],[ 32PKG_CHECK_MODULES([KINGATE_FCGI],[kingate-fcgi >= 0.0.1],[
29 HAVE_FCGI=true 33 HAVE_FCGI=true
30],[ 34],[
31 AC_MSG_NOTICE([no fastcgi support in kingate library]) 35 AC_MSG_NOTICE([no fastcgi support in kingate library])
32]) 36])
33PKG_CHECK_MODULES([KINGATE_PLAINCGI],[kingate-plaincgi >= 0.0.1],[ 37PKG_CHECK_MODULES([KINGATE_PLAINCGI],[kingate-plaincgi >= 0.0.1],[
34 HAVE_PLAINCGI=true 38 HAVE_PLAINCGI=true
35],[ 39],[
36 AC_MSG_NOTICE([no plaincgi support in kingate library]) 40 AC_MSG_NOTICE([no plaincgi support in kingate library])
37]) 41])
38if ! (${HAVE_FCGI} || ${HAVE_PLAINCGI}) ; then 42if ! (${HAVE_FCGI} || ${HAVE_PLAINCGI}) ; then
39 AC_MSG_ERROR([not a single CGI interface supported in kingate]) 43 AC_MSG_ERROR([not a single CGI interface supported in kingate])
40fi 44fi
41AM_CONDITIONAL([HAVE_FCGI],[${HAVE_FCGI}]) 45AM_CONDITIONAL([HAVE_FCGI],[${HAVE_FCGI}])
42AM_CONDITIONAL([HAVE_PLAINCGI],[${HAVE_PLAINCGI}]) 46AM_CONDITIONAL([HAVE_PLAINCGI],[${HAVE_PLAINCGI}])
43 47
44PKG_CHECK_MODULES([DOTCONF],[dotconf],,[ 48PKG_CHECK_MODULES([DOTCONF],[dotconf],,[
45 AC_MSG_ERROR([no dotconf library found]) 49 AC_MSG_ERROR([no dotconf library found])
46]) 50])
diff --git a/include/sitecing/sitecing_util.h b/include/sitecing/sitecing_util.h
index d1a6c4a..f642c74 100644
--- a/include/sitecing/sitecing_util.h
+++ b/include/sitecing/sitecing_util.h
@@ -1,91 +1,75 @@
1#ifndef __SITECING_SITECING_UTIL_H 1#ifndef __SITECING_SITECING_UTIL_H
2#define __SITECING_SITECING_UTIL_H 2#define __SITECING_SITECING_UTIL_H
3 3
4#include <sys/types.h> 4#include <sys/types.h>
5#include <string> 5#include <string>
6#include <konforka/exception.h> 6#include <konforka/exception.h>
7#include <konforka/util.h>
7 8
8/** 9/**
9 * @file 10 * @file
10 * @brief utility classes and functions. 11 * @brief utility classes and functions.
11 */ 12 */
12 13
13namespace sitecing { 14namespace sitecing {
14 using namespace std; 15 using namespace std;
15 16
16 /** 17 /**
17 * Base class for utility exceptions. 18 * Base class for utility exceptions.
18 */ 19 */
19 class utility_error : public konforka::exception { 20 class utility_error : public konforka::exception {
20 public: 21 public:
21 utility_error(const string& fi,const string& fu,int l,const string& w) 22 utility_error(const string& fi,const string& fu,int l,const string& w)
22 : konforka::exception(fi,fu,l,w) { } 23 : konforka::exception(fi,fu,l,w) { }
23 }; 24 };
24 /** 25
25 * Restricted sequence encountered.
26 */
27 class utility_restricted_sequence : public utility_error {
28 public:
29 utility_restricted_sequence(const string& fi,const string& fu,int l,const string& w)
30 : utility_error(fi,fu,l,w) { }
31 };
32 /** 26 /**
33 * No prefix or suffix found to strip out. 27 * No prefix or suffix found to strip out.
34 */ 28 */
35 class utility_no_affix : public utility_error { 29 class utility_no_affix : public utility_error {
36 public: 30 public:
37 utility_no_affix(const string& fi,const string& fu,int l,const string& w) 31 utility_no_affix(const string& fi,const string& fu,int l,const string& w)
38 : utility_error(fi,fu,l,w) { } 32 : utility_error(fi,fu,l,w) { }
39 }; 33 };
40 /** 34 /**
41 * No prefix to strip found. 35 * No prefix to strip found.
42 */ 36 */
43 class utility_no_prefix : public utility_no_affix { 37 class utility_no_prefix : public utility_no_affix {
44 public: 38 public:
45 utility_no_prefix(const string& fi,const string& fu,int l,const string& w) 39 utility_no_prefix(const string& fi,const string& fu,int l,const string& w)
46 : utility_no_affix(fi,fu,l,w) { } 40 : utility_no_affix(fi,fu,l,w) { }
47 }; 41 };
48 /** 42 /**
49 * No suffix to strip found. 43 * No suffix to strip found.
50 */ 44 */
51 class utility_no_suffix : public utility_no_affix { 45 class utility_no_suffix : public utility_no_affix {
52 public: 46 public:
53 utility_no_suffix(const string& fi,const string& fu,int l,const string& w) 47 utility_no_suffix(const string& fi,const string& fu,int l,const string& w)
54 : utility_no_affix(fi,fu,l,w) { } 48 : utility_no_affix(fi,fu,l,w) { }
55 }; 49 };
56 50
57 /** 51 /**
58 * Went up beyond root.
59 * @todo TODO: wish I could remember the details -- document me.
60 */
61 class utility_beyond_root : public utility_error {
62 public:
63 utility_beyond_root(const string& fi,const string& fu,int l,const string& w)
64 : utility_error(fi,fu,l,w) { }
65 };
66
67 /**
68 * The file lock object. Released at the object destruction. 52 * The file lock object. Released at the object destruction.
69 */ 53 */
70 class file_lock { 54 class file_lock {
71 public: 55 public:
72 /** 56 /**
73 * The file descriptor. 57 * The file descriptor.
74 */ 58 */
75 int fd; 59 int fd;
76 60
77 file_lock() 61 file_lock()
78 : fd(-1) { } 62 : fd(-1) { }
79 /** 63 /**
80 * @param f file name. 64 * @param f file name.
81 */ 65 */
82 file_lock(const string& f) 66 file_lock(const string& f)
83 : fd(-1) { lock(f); } 67 : fd(-1) { lock(f); }
84 ~file_lock() { unlock(); } 68 ~file_lock() { unlock(); }
85 69
86 /** 70 /**
87 * Do lock. 71 * Do lock.
88 * @param f file name. 72 * @param f file name.
89 */ 73 */
90 void lock(const string& f); 74 void lock(const string& f);
91 /** 75 /**
@@ -194,129 +178,64 @@ namespace sitecing {
194 /** 178 /**
195 * @param s reference to the semaphore. 179 * @param s reference to the semaphore.
196 * @param l lock at creation? 180 * @param l lock at creation?
197 */ 181 */
198 semaphore_lock(semaphore& s,bool l=true) 182 semaphore_lock(semaphore& s,bool l=true)
199 : sem(&s), locked(false) { 183 : sem(&s), locked(false) {
200 if(l) lock(); 184 if(l) lock();
201 } 185 }
202 186
203 ~semaphore_lock() { 187 ~semaphore_lock() {
204 unlock(); 188 unlock();
205 } 189 }
206 190
207 /** 191 /**
208 * Lock it. 192 * Lock it.
209 */ 193 */
210 void lock(); 194 void lock();
211 /** 195 /**
212 * Unlock it. 196 * Unlock it.
213 */ 197 */
214 void unlock(); 198 void unlock();
215 }; 199 };
216 200
217 /** 201 /**
218 * normalize_path options enumeration.
219 * @see normalize_path()
220 */
221 enum normalize_path_options {
222 /**
223 * Restrict the /../ sequence.
224 */
225 restrict_dotdot = 1,
226 /**
227 * Strip out the leading slash.
228 */
229 strip_leading_slash = 2,
230 /**
231 * Strip out the trailing slash.
232 */
233 strip_trailing_slash = 4
234 };
235 /**
236 * combine_path options enumeration.
237 * @see combine_path()
238 */
239 enum combine_path_options {
240 /**
241 * The origin is file. Otherwise it is directory.
242 */
243 origin_is_file = 1,
244 /**
245 * Fail if we've gone up beyond root.
246 */
247 fail_beyond_root = 2
248 };
249
250 /**
251 * Normalize pathname by stripping duplicate slashes, etc.
252 * @param path the path name.
253 * @param opts options.
254 * @return the normalized path.
255 * @see normalize_path_options
256 * @todo TODO: document exceptions.
257 */
258 string normalize_path(const string& path,int opts=(restrict_dotdot|strip_trailing_slash));
259 /**
260 * Strip prefix from the string. 202 * Strip prefix from the string.
261 * @param str the string. 203 * @param str the string.
262 * @param prefix prefix to strip. 204 * @param prefix prefix to strip.
263 * @return the string without prefix. 205 * @return the string without prefix.
264 * @todo TODO: document exceptions. 206 * @todo TODO: document exceptions.
265 */ 207 */
266 string strip_prefix(const string& str,const string& prefix); 208 string strip_prefix(const string& str,const string& prefix);
267 /** 209 /**
268 * Strip suffix from the string. 210 * Strip suffix from the string.
269 * @param str the string. 211 * @param str the string.
270 * @param suffix suffix to strip. 212 * @param suffix suffix to strip.
271 * @return the string without suffix. 213 * @return the string without suffix.
272 * @todo TODO: document exceptions. 214 * @todo TODO: document exceptions.
273 */ 215 */
274 string strip_suffix(const string& str,const string& suffix); 216 string strip_suffix(const string& str,const string& suffix);
275 /** 217
276 * Get the directory part of the filename.
277 * @param filename the full file name.
278 * @return the directory part.
279 */
280 string dir_name(const string& filename);
281 /**
282 * Combine path with the relative path.
283 * @param origin the origin.
284 * @param relative relative path to combine origin with.
285 * @param opts options.
286 * @return the pathc combined.
287 * @see combine_path_options
288 * @todo TODO: document exceptions.
289 */
290 string combine_path(const string& origin,const string& relative,int opts=origin_is_file);
291
292 /**
293 * Create directory and parent directories if needed.
294 * @param path the pathname.
295 * @param mode the mode for newly created directories.
296 */
297 void make_path(const string& path,mode_t mode);
298
299 /** 218 /**
300 * Change to the directory and pop back at object's destruction (e.g. when 219 * Change to the directory and pop back at object's destruction (e.g. when
301 * the object goes out of scope). 220 * the object goes out of scope).
302 */ 221 */
303 class auto_chdir { 222 class auto_chdir {
304 public: 223 public:
305 /** 224 /**
306 * Saved working directory. 225 * Saved working directory.
307 */ 226 */
308 string saved_pwd; 227 string saved_pwd;
309 /** 228 /**
310 * Whether we want to change back automatically. 229 * Whether we want to change back automatically.
311 */ 230 */
312 bool autopop; 231 bool autopop;
313 232
314 auto_chdir() 233 auto_chdir()
315 : autopop(false) { } 234 : autopop(false) { }
316 /** 235 /**
317 * @param td destination path. 236 * @param td destination path.
318 * @param ap automatically come back? 237 * @param ap automatically come back?
319 */ 238 */
320 auto_chdir(const string& td,bool ap=true) 239 auto_chdir(const string& td,bool ap=true)
321 : autopop(false) { pushdir(td,ap); } 240 : autopop(false) { pushdir(td,ap); }
322 ~auto_chdir() { 241 ~auto_chdir() {
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
@@ -1,58 +1,59 @@
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 <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) {
47 for(list<string>::const_iterator i=co_so_deps->so_deps.begin();i!=co_so_deps->so_deps.end();++i) 48 for(list<string>::const_iterator i=co_so_deps->so_deps.begin();i!=co_so_deps->so_deps.end();++i)
48 deps.push_back(*i); 49 deps.push_back(*i);
49 } 50 }
50 return; 51 return;
51 }catch(utility_no_prefix& unp) { 52 }catch(utility_no_prefix& unp) {
52 throw konforka::exception(CODEPOINT,"component is outside of component root"); 53 throw konforka::exception(CODEPOINT,"component is outside of component root");
53 }catch(utility_no_suffix& uns) { } 54 }catch(utility_no_suffix& uns) { }
54 try { 55 try {
55 // preprocessor targets 56 // preprocessor targets
56 string noro = strip_prefix(dp,root_intermediate); 57 string noro = strip_prefix(dp,root_intermediate);
57 for(int ppt=0;ppt<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { 58 for(int ppt=0;ppt<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) {
58 try { 59 try {
@@ -77,268 +78,268 @@ namespace sitecing {
77 } 78 }
78 } 79 }
79 // XXX: intermediate_deps should be broken down 80 // XXX: intermediate_deps should be broken down
80 config_options *co_intermediate_deps = config.lookup_config(nos,config_options::flag_intermediate_deps); 81 config_options *co_intermediate_deps = config.lookup_config(nos,config_options::flag_intermediate_deps);
81 if(co_intermediate_deps) { 82 if(co_intermediate_deps) {
82 for(list<string>::const_iterator i=co_intermediate_deps->intermediate_deps.begin();i!=co_intermediate_deps->intermediate_deps.end();++i) 83 for(list<string>::const_iterator i=co_intermediate_deps->intermediate_deps.begin();i!=co_intermediate_deps->intermediate_deps.end();++i)
83 deps.push_back(*i); 84 deps.push_back(*i);
84 } 85 }
85 return; 86 return;
86 }catch(utility_no_suffix& uns) { } 87 }catch(utility_no_suffix& uns) { }
87 } 88 }
88 // compiler targets 89 // compiler targets
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);
166 if(co_ld_flags) { 167 if(co_ld_flags) {
167 args.insert(args.end(),co_ld_flags->ld_flags.begin(),co_ld_flags->ld_flags.end()); 168 args.insert(args.end(),co_ld_flags->ld_flags.begin(),co_ld_flags->ld_flags.end());
168 } 169 }
169 args.push_back("-shared"); 170 args.push_back("-shared");
170 args.push_back(o); 171 args.push_back(o);
171 file_list_t ancestors; 172 file_list_t ancestors;
172 get_ancestors(noro,ancestors); 173 get_ancestors(noro,ancestors);
173 for(file_list_t::const_iterator i=ancestors.begin();i!=ancestors.end();++i) { 174 for(file_list_t::const_iterator i=ancestors.begin();i!=ancestors.end();++i) {
174 string aso=root_so+*i+".so"; 175 string aso=root_so+*i+".so";
175 make(aso); 176 make(aso);
176 args.push_back(aso); 177 args.push_back(aso);
177 } 178 }
178 args.push_back("-o"); args.push_back(dp); 179 args.push_back("-o"); args.push_back(dp);
179 // TODO: "g++" configurable 180 // TODO: "g++" configurable
180 int rv = execute("g++",args,stdO,stdE); 181 int rv = execute("g++",args,stdO,stdE);
181 if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) ) 182 if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) )
182 throw link_error(CODEPOINT,"failed to link component",noro); 183 throw link_error(CODEPOINT,"failed to link component",noro);
183 return; 184 return;
184 }catch(utility_no_prefix& unp) { 185 }catch(utility_no_prefix& unp) {
185 throw konforka::exception(CODEPOINT,"component is outside of component root"); 186 throw konforka::exception(CODEPOINT,"component is outside of component root");
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;
212 config_options *co_cpp_flags = config.lookup_config(nos,config_options::flag_cpp_flags); 213 config_options *co_cpp_flags = config.lookup_config(nos,config_options::flag_cpp_flags);
213 if(co_cpp_flags) { 214 if(co_cpp_flags) {
214 args.insert(args.end(),co_cpp_flags->cpp_flags.begin(),co_cpp_flags->cpp_flags.end()); 215 args.insert(args.end(),co_cpp_flags->cpp_flags.begin(),co_cpp_flags->cpp_flags.end());
215 } 216 }
216 // TODO: maybe move it to separare config option like CoreCPPFLags? 217 // TODO: maybe move it to separare config option like CoreCPPFLags?
217 args.push_back("-I"+root_intermediate); 218 args.push_back("-I"+root_intermediate);
218 args.push_back("-I"+root_source); 219 args.push_back("-I"+root_source);
219 args.push_back("-MD"); args.push_back("-MF"); args.push_back(root_intermediate+nos+".d"); 220 args.push_back("-MD"); args.push_back("-MF"); args.push_back(root_intermediate+nos+".d");
220 args.push_back("-c"); 221 args.push_back("-c");
221 args.push_back(cc); 222 args.push_back(cc);
222 args.push_back("-o"); args.push_back(o); 223 args.push_back("-o"); args.push_back(o);
223 // TODO: "g++" configurable 224 // TODO: "g++" configurable
224 int rv = execute("g++",args,stdO,stdE); 225 int rv = execute("g++",args,stdO,stdE);
225 if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) ) 226 if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) )
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
258 }catch(preprocessor_error& pe) { 259 }catch(preprocessor_error& pe) {
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
284 int component_factory::execute(const string& cmd, const list<string>& args,int stdo,int stde) { 285 int component_factory::execute(const string& cmd, const list<string>& args,int stdo,int stde) {
285 // XXX: is it right that we do stdio/stderr tricks outside of the function? 286 // XXX: is it right that we do stdio/stderr tricks outside of the function?
286 // cerr << "executing: " << cmd; 287 // cerr << "executing: " << cmd;
287 vector<const char*> argv(args.size()+2); 288 vector<const char*> argv(args.size()+2);
288 argv[0]=cmd.c_str(); 289 argv[0]=cmd.c_str();
289 int an = 1; 290 int an = 1;
290 for(list<string>::const_iterator i=args.begin();i!=args.end();i++) { 291 for(list<string>::const_iterator i=args.begin();i!=args.end();i++) {
291 // cerr << " " << *i ; 292 // cerr << " " << *i ;
292 argv[an++] = i->c_str(); 293 argv[an++] = i->c_str();
293 } 294 }
294 // cerr << endl; 295 // cerr << endl;
295 argv[an++]=NULL; 296 argv[an++]=NULL;
296 pid_t pid = vfork(); 297 pid_t pid = vfork();
297 if(pid==-1) { 298 if(pid==-1) {
298 close(stdo); close(stde); 299 close(stdo); close(stde);
299 throw konforka::exception(CODEPOINT,"failed to vfork()"); 300 throw konforka::exception(CODEPOINT,"failed to vfork()");
300 } 301 }
301 if(!pid) { 302 if(!pid) {
302 // child 303 // child
303 if(dup2(stdo,1)!=1) 304 if(dup2(stdo,1)!=1)
304 _exit(-1); 305 _exit(-1);
305 if(dup2(stde,2)!=2) 306 if(dup2(stde,2)!=2)
306 _exit(-1); 307 _exit(-1);
307 close(0); 308 close(0);
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 }
343 344
344} 345}
diff --git a/lib/configuration.cc b/lib/configuration.cc
index 4ee1526..6b21690 100644
--- a/lib/configuration.cc
+++ b/lib/configuration.cc
@@ -1,32 +1,33 @@
1#ifdef USE_PCH 1#ifdef USE_PCH
2 #include "pch.h" 2 #include "pch.h"
3#else 3#else
4 #include <unistd.h> 4 #include <unistd.h>
5 #include <fnmatch.h> 5 #include <fnmatch.h>
6 #include <cassert> 6 #include <cassert>
7 #include <stdexcept> 7 #include <stdexcept>
8 using namespace std; 8 using namespace std;
9 #include <konforka/util.h>
9 #include <dotconf.h> 10 #include <dotconf.h>
10 #include "sitecing/configuration.h" 11 #include "sitecing/configuration.h"
11 #include "sitecing/sitecing_util.h" 12 #include "sitecing/sitecing_util.h"
12 #include "sitecing/scoreboard.h" 13 #include "sitecing/scoreboard.h"
13#endif 14#endif
14 15
15namespace sitecing { 16namespace sitecing {
16 17
17 configuration::configuration() 18 configuration::configuration()
18 : flags(0), autobuild(false) { } 19 : flags(0), autobuild(false) { }
19 configuration::configuration(const string& cfile,bool ab) 20 configuration::configuration(const string& cfile,bool ab)
20 : flags(0), autobuild(ab) { 21 : flags(0), autobuild(ab) {
21 parse(cfile); 22 parse(cfile);
22 } 23 }
23 24
24 enum dc_ctx { 25 enum dc_ctx {
25 DCC_ROOT = 1, 26 DCC_ROOT = 1,
26 DCC_PATH = 2, 27 DCC_PATH = 2,
27 DCC_SCRC = 4 28 DCC_SCRC = 4
28 }; 29 };
29 struct dc_context { 30 struct dc_context {
30 dc_ctx ctx; 31 dc_ctx ctx;
31 configuration* cf; 32 configuration* cf;
32 list<config_options*> co; 33 list<config_options*> co;
@@ -283,159 +284,159 @@ namespace sitecing {
283 i = ii.first; 284 i = ii.first;
284 } 285 }
285 assert(i!=loaded_specs.end()); 286 assert(i!=loaded_specs.end());
286 return &(i->second); 287 return &(i->second);
287 } 288 }
288 289
289 config_options::action_handler_t *config_options::lookup_action_handler(const string& target) { 290 config_options::action_handler_t *config_options::lookup_action_handler(const string& target) {
290 for(action_handlers_t::iterator i=action_handlers.begin();i!=action_handlers.end();++i) { 291 for(action_handlers_t::iterator i=action_handlers.begin();i!=action_handlers.end();++i) {
291 if(i->regex.search(target)) 292 if(i->regex.search(target))
292 return &*i; 293 return &*i;
293 } 294 }
294 return NULL; 295 return NULL;
295 } 296 }
296 297
297 string config_options::lookup_http_status_handler(const string& status) { 298 string config_options::lookup_http_status_handler(const string& status) {
298 http_status_handlers_t::const_iterator i = http_status_handlers.find(status); 299 http_status_handlers_t::const_iterator i = http_status_handlers.find(status);
299 string rv; 300 string rv;
300 if(i!=http_status_handlers.end()) 301 if(i!=http_status_handlers.end())
301 rv = i->second; 302 rv = i->second;
302 return rv; 303 return rv;
303 } 304 }
304 305
305 string configuration::lookup_http_status_handler(const string& target,const string& status) { 306 string configuration::lookup_http_status_handler(const string& target,const string& status) {
306 string t = "/"; 307 string t = "/";
307 t += normalize_path(target,strip_leading_slash); 308 t += konforka::normalize_path(target,konforka::strip_leading_slash);
308 string rv; 309 string rv;
309 for(;;) { 310 for(;;) {
310 if(t[t.length()-1]=='/') { 311 if(t[t.length()-1]=='/') {
311 loaded_options* lo = lookup_loaded_options(t); 312 loaded_options* lo = lookup_loaded_options(t);
312 if( lo && (lo->flags&config_options::flag_http_status_handlers) ) { 313 if( lo && (lo->flags&config_options::flag_http_status_handlers) ) {
313 rv = lo->lookup_http_status_handler(status); 314 rv = lo->lookup_http_status_handler(status);
314 if(!rv.empty()) 315 if(!rv.empty())
315 return rv; 316 return rv;
316 } 317 }
317 } 318 }
318 specs_t::iterator i = specs.find(t); 319 specs_t::iterator i = specs.find(t);
319 if( i!=specs.end() && (i->second.flags&&config_options::flag_http_status_handlers) ) { 320 if( i!=specs.end() && (i->second.flags&&config_options::flag_http_status_handlers) ) {
320 rv = i->second.lookup_http_status_handler(status); 321 rv = i->second.lookup_http_status_handler(status);
321 if(!rv.empty()) 322 if(!rv.empty())
322 return rv; 323 return rv;
323 } 324 }
324 if(t.empty()) 325 if(t.empty())
325 return rv; 326 return rv;
326 string::size_type sl=t.rfind('/'); 327 string::size_type sl=t.rfind('/');
327 if(sl==string::npos) { 328 if(sl==string::npos) {
328 t.erase(); 329 t.erase();
329 }else{ 330 }else{
330 if(sl==(t.length()-1)) 331 if(sl==(t.length()-1))
331 t.erase(sl); 332 t.erase(sl);
332 else 333 else
333 t.erase(sl+1); 334 t.erase(sl+1);
334 } 335 }
335 } 336 }
336 } 337 }
337 338
338 config_options::action_handler_t *configuration::lookup_action_handler(const string& target) { 339 config_options::action_handler_t *configuration::lookup_action_handler(const string& target) {
339 string t = "/"; 340 string t = "/";
340 t += normalize_path(target,strip_leading_slash); 341 t += konforka::normalize_path(target,konforka::strip_leading_slash);
341 for(;;) { 342 for(;;) {
342 if(t[t.length()-1]=='/') { 343 if(t[t.length()-1]=='/') {
343 loaded_options* lo = lookup_loaded_options(t); 344 loaded_options* lo = lookup_loaded_options(t);
344 if( lo && (lo->flags&config_options::flag_action_handlers) ) { 345 if( lo && (lo->flags&config_options::flag_action_handlers) ) {
345 config_options::action_handler_t *rv = lo->lookup_action_handler(target); 346 config_options::action_handler_t *rv = lo->lookup_action_handler(target);
346 if(rv) 347 if(rv)
347 return rv; 348 return rv;
348 } 349 }
349 } 350 }
350 specs_t::iterator i = specs.find(t); 351 specs_t::iterator i = specs.find(t);
351 if( i!=specs.end() && (i->second.flags&&config_options::flag_action_handlers) ) { 352 if( i!=specs.end() && (i->second.flags&&config_options::flag_action_handlers) ) {
352 config_options::action_handler_t *rv = i->second.lookup_action_handler(target); 353 config_options::action_handler_t *rv = i->second.lookup_action_handler(target);
353 if(rv) 354 if(rv)
354 return rv; 355 return rv;
355 } 356 }
356 if(t.empty()) 357 if(t.empty())
357 return NULL; 358 return NULL;
358 string::size_type sl=t.rfind('/'); 359 string::size_type sl=t.rfind('/');
359 if(sl==string::npos) { 360 if(sl==string::npos) {
360 t.erase(); 361 t.erase();
361 }else{ 362 }else{
362 if(sl==(t.length()-1)) 363 if(sl==(t.length()-1))
363 t.erase(sl); 364 t.erase(sl);
364 else 365 else
365 t.erase(sl+1); 366 t.erase(sl+1);
366 } 367 }
367 } 368 }
368 } 369 }
369 370
370 config_options* configuration::lookup_config(const string& target,int flag) { 371 config_options* configuration::lookup_config(const string& target,int flag) {
371 string t = "/"; // always assume leading slash 372 string t = "/"; // always assume leading slash
372 t += normalize_path(target,strip_leading_slash); 373 t += konforka::normalize_path(target,konforka::strip_leading_slash);
373 // XXX: reconsider precedence 374 // XXX: reconsider precedence
374 for(;;) { 375 for(;;) {
375 if(t[t.length()-1]=='/') { 376 if(t[t.length()-1]=='/') {
376 loaded_options* lo = lookup_loaded_options(t); 377 loaded_options* lo = lookup_loaded_options(t);
377 if( lo && (lo->flags&flag)==flag ) 378 if( lo && (lo->flags&flag)==flag )
378 return lo; 379 return lo;
379 } 380 }
380 specs_t::iterator i = specs.find(t); 381 specs_t::iterator i = specs.find(t);
381 if( i!=specs.end() && (i->second.flags&flag)==flag ) 382 if( i!=specs.end() && (i->second.flags&flag)==flag )
382 return &(i->second); 383 return &(i->second);
383 if(t.empty()) 384 if(t.empty())
384 return NULL; 385 return NULL;
385 string::size_type sl=t.rfind('/'); 386 string::size_type sl=t.rfind('/');
386 if(sl==string::npos) { 387 if(sl==string::npos) {
387 t.erase(); 388 t.erase();
388 }else{ 389 }else{
389 if(sl==(t.length()-1)) 390 if(sl==(t.length()-1))
390 t.erase(sl); 391 t.erase(sl);
391 else 392 else
392 t.erase(sl+1); 393 t.erase(sl+1);
393 } 394 }
394 } 395 }
395 } 396 }
396 397
397 bool config_options::match_autobuild_files(const char *fn,bool &rv) { 398 bool config_options::match_autobuild_files(const char *fn,bool &rv) {
398 for(list<string>::reverse_iterator i=auto_build_files.rbegin();i!=auto_build_files.rend();++i) { 399 for(list<string>::reverse_iterator i=auto_build_files.rbegin();i!=auto_build_files.rend();++i) {
399 const char *pat = i->c_str(); 400 const char *pat = i->c_str();
400 bool plus = true; 401 bool plus = true;
401 if((*pat)=='+') 402 if((*pat)=='+')
402 pat++; 403 pat++;
403 else if((*pat)=='-') { 404 else if((*pat)=='-') {
404 plus = false; 405 plus = false;
405 pat++; 406 pat++;
406 } 407 }
407 if(!fnmatch(pat,fn,FNM_NOESCAPE|FNM_PATHNAME|FNM_PERIOD)) { 408 if(!fnmatch(pat,fn,FNM_NOESCAPE|FNM_PATHNAME|FNM_PERIOD)) {
408 rv = plus; 409 rv = plus;
409 return true; 410 return true;
410 } 411 }
411 } 412 }
412 return false; 413 return false;
413 } 414 }
414 415
415 bool configuration::match_autobuild_files(const string& target,const char *fn) { 416 bool configuration::match_autobuild_files(const string& target,const char *fn) {
416 string t = "/"; 417 string t = "/";
417 t += normalize_path(target,strip_leading_slash|strip_trailing_slash); 418 t += konforka::normalize_path(target,konforka::strip_leading_slash|konforka::strip_trailing_slash);
418 t += "/"; 419 t += "/";
419 bool rv = false; 420 bool rv = false;
420 for(;;) { 421 for(;;) {
421 if(t[t.length()-1]=='/') { 422 if(t[t.length()-1]=='/') {
422 loaded_options* lo = lookup_loaded_options(t); 423 loaded_options* lo = lookup_loaded_options(t);
423 if(lo && (lo->flags&config_options::flag_auto_build_files) && lo->match_autobuild_files(fn,rv) ) 424 if(lo && (lo->flags&config_options::flag_auto_build_files) && lo->match_autobuild_files(fn,rv) )
424 return rv; 425 return rv;
425 } 426 }
426 specs_t::iterator i = specs.find(t); 427 specs_t::iterator i = specs.find(t);
427 if( i!=specs.end() && (i->second.flags&config_options::flag_auto_build_files) && i->second.match_autobuild_files(fn,rv) ) 428 if( i!=specs.end() && (i->second.flags&config_options::flag_auto_build_files) && i->second.match_autobuild_files(fn,rv) )
428 return rv; 429 return rv;
429 if(t.empty()) 430 if(t.empty())
430 return rv; 431 return rv;
431 string::size_type sl=t.rfind('/'); 432 string::size_type sl=t.rfind('/');
432 if(sl==string::npos) { 433 if(sl==string::npos) {
433 t.erase(); 434 t.erase();
434 }else{ 435 }else{
435 if(sl==(t.length()-1)) 436 if(sl==(t.length()-1))
436 t.erase(sl); 437 t.erase(sl);
437 else 438 else
438 t.erase(sl+1); 439 t.erase(sl+1);
439 } 440 }
440 } 441 }
441 } 442 }
diff --git a/lib/sitecing_parser.ll b/lib/sitecing_parser.ll
index 4fd6709..8dd8d5f 100644
--- a/lib/sitecing_parser.ll
+++ b/lib/sitecing_parser.ll
@@ -1,33 +1,34 @@
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 <konforka/util.h>
10#include "sitecing/sitecing_util.h" 11#include "sitecing/sitecing_util.h"
11#include "sitecing/sitecing_exception.h" 12#include "sitecing/sitecing_exception.h"
12using namespace sitecing; 13using namespace sitecing;
13#define sitecing_parser_flexlexer_once 14#define sitecing_parser_flexlexer_once
14#include "sitecing/sitecing_parser.h" 15#include "sitecing/sitecing_parser.h"
15#include "sitecing/sitecing_enflesher.h" 16#include "sitecing/sitecing_enflesher.h"
16#undef yyFlexLexer 17#undef yyFlexLexer
17#define yyFlexLexer sitecing_parserFlexLexer 18#define yyFlexLexer sitecing_parserFlexLexer
18%} 19%}
19%x SLASHSTAR_COMMENT SLASHSLASH_COMMENT STRING 20%x SLASHSTAR_COMMENT SLASHSLASH_COMMENT STRING
20%x CODELINE CLASSLINE DECLLINE IMPLLINE DECLBLOCK IMPLBLOCK VARLINE VARINIT 21%x CODELINE CLASSLINE DECLLINE IMPLLINE DECLBLOCK IMPLBLOCK VARLINE VARINIT
21%x IMPORTLINE IMPORTCOMPONENT 22%x IMPORTLINE IMPORTCOMPONENT
22%x IMPORTTYPELINE IMPORTTYPECOMPONENT 23%x IMPORTTYPELINE IMPORTTYPECOMPONENT
23%x DERIVELINE DERIVECOMPONENT 24%x DERIVELINE DERIVECOMPONENT
24%x CONSTRUCTOR DESTRUCTOR CODEMETHODLINE CODEMETHODARGS 25%x CONSTRUCTOR DESTRUCTOR CODEMETHODLINE CODEMETHODARGS
25%x CODEMETHODBLOCK INLINE METHODLINE METHODARGS METHODBLOCK CODEBLOCK OUTPUTBLOCK 26%x CODEMETHODBLOCK INLINE METHODLINE METHODARGS METHODBLOCK CODEBLOCK OUTPUTBLOCK
26%x PRAGMALINE 27%x PRAGMALINE
27%option 8bit c++ verbose noyywrap yyclass="sitecing_parser" prefix="sitecing_parser" stack yylineno 28%option 8bit c++ verbose noyywrap yyclass="sitecing_parser" prefix="sitecing_parser" stack yylineno
28 29
29 WHITESPACE[ \t] 30 WHITESPACE[ \t]
30 ID [A-Za-z_][A-Za-z0-9_]* 31 ID [A-Za-z_][A-Za-z0-9_]*
31 NOIDCHAR[^A-Za-z0-9_] 32 NOIDCHAR[^A-Za-z0-9_]
32 33
33%% 34%%
@@ -276,118 +277,118 @@ NOIDCHAR [^A-Za-z0-9_]
276 modus_operandi& m = M(); 277 modus_operandi& m = M();
277 if(!m._name.empty()) 278 if(!m._name.empty())
278 throw preprocessor_error(CODEPOINT,"syntax error",lineno()); 279 throw preprocessor_error(CODEPOINT,"syntax error",lineno());
279 m._name = yytext; 280 m._name = yytext;
280 } 281 }
281 \= { 282 \= {
282 M().output.clear(); 283 M().output.clear();
283 BEGIN(IMPORTCOMPONENT); 284 BEGIN(IMPORTCOMPONENT);
284 } 285 }
285} 286}
286<IMPORTCOMPONENT>{ 287<IMPORTCOMPONENT>{
287 {WHITESPACE}+{ } 288 {WHITESPACE}+{ }
288 \n{ 289 \n{
289 modus_operandi& m = M(); 290 modus_operandi& m = M();
290 string::size_type t = m.output.find_first_not_of(" \t"); 291 string::size_type t = m.output.find_first_not_of(" \t");
291 if(t!=string::npos) 292 if(t!=string::npos)
292 m.output.erase(0,t); 293 m.output.erase(0,t);
293 t = m.output.find_last_not_of(" \t;"); 294 t = m.output.find_last_not_of(" \t;");
294 if(t!=string::npos) 295 if(t!=string::npos)
295 m.output.erase(t+1); 296 m.output.erase(t+1);
296 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') { 297 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') {
297 m.output.erase(0,1); 298 m.output.erase(0,1);
298 m.output.erase(m.output.length()-1); 299 m.output.erase(m.output.length()-1);
299 } 300 }
300 string c = combine_path(component_basename,m.output); 301 string c = konforka::combine_path(component_basename,m.output);
301 member_variables.push_back(member_variable(m._type,m._name,normalize_path(c,strip_leading_slash),true)); 302 member_variables.push_back(member_variable(m._type,m._name,konforka::normalize_path(c,konforka::strip_leading_slash),true));
302 modi.pop_front(); 303 modi.pop_front();
303 BEGIN(INITIAL); 304 BEGIN(INITIAL);
304 } 305 }
305} 306}
306 307
307<IMPORTTYPELINE>{ 308<IMPORTTYPELINE>{
308 {WHITESPACE}+{ } 309 {WHITESPACE}+{ }
309 {ID}{ 310 {ID}{
310 modus_operandi& m = M(); 311 modus_operandi& m = M();
311 if(!m._name.empty()) 312 if(!m._name.empty())
312 throw preprocessor_error(CODEPOINT,"syntax error",lineno()); 313 throw preprocessor_error(CODEPOINT,"syntax error",lineno());
313 m._name = yytext; 314 m._name = yytext;
314 } 315 }
315 \= { 316 \= {
316 M().output.clear(); 317 M().output.clear();
317 BEGIN(IMPORTTYPECOMPONENT); 318 BEGIN(IMPORTTYPECOMPONENT);
318 } 319 }
319} 320}
320<IMPORTTYPECOMPONENT>{ 321<IMPORTTYPECOMPONENT>{
321 {WHITESPACE}+{ } 322 {WHITESPACE}+{ }
322 \n{ 323 \n{
323 modus_operandi& m = M(); 324 modus_operandi& m = M();
324 string::size_type t = m.output.find_first_not_of(" \t"); 325 string::size_type t = m.output.find_first_not_of(" \t");
325 if(t!=string::npos) 326 if(t!=string::npos)
326 m.output.erase(0,t); 327 m.output.erase(0,t);
327 t = m.output.find_last_not_of(" \t;"); 328 t = m.output.find_last_not_of(" \t;");
328 if(t!=string::npos) 329 if(t!=string::npos)
329 m.output.erase(t+1); 330 m.output.erase(t+1);
330 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') { 331 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') {
331 m.output.erase(0,1); 332 m.output.erase(0,1);
332 m.output.erase(m.output.length()-1); 333 m.output.erase(m.output.length()-1);
333 } 334 }
334 string c = combine_path(component_basename,m.output); 335 string c = konforka::combine_path(component_basename,m.output);
335 member_variables.push_back(member_variable(m._type,m._name,normalize_path(c,strip_leading_slash),true,true)); 336 member_variables.push_back(member_variable(m._type,m._name,konforka::normalize_path(c,konforka::strip_leading_slash),true,true));
336 modi.pop_front(); 337 modi.pop_front();
337 BEGIN(INITIAL); 338 BEGIN(INITIAL);
338 } 339 }
339} 340}
340 341
341<DERIVELINE>{ 342<DERIVELINE>{
342 {WHITESPACE}+{ } 343 {WHITESPACE}+{ }
343 {ID}{ 344 {ID}{
344 modus_operandi& m = M(); 345 modus_operandi& m = M();
345 if(!m._name.empty()) 346 if(!m._name.empty())
346 throw preprocessor_error(CODEPOINT,"syntax_error",lineno()); 347 throw preprocessor_error(CODEPOINT,"syntax_error",lineno());
347 m._name = yytext; 348 m._name = yytext;
348 } 349 }
349 \= { 350 \= {
350 M().output.clear(); 351 M().output.clear();
351 BEGIN(DERIVECOMPONENT); 352 BEGIN(DERIVECOMPONENT);
352 } 353 }
353} 354}
354<DERIVECOMPONENT>{ 355<DERIVECOMPONENT>{
355 {WHITESPACE}+{ } 356 {WHITESPACE}+{ }
356 \n { 357 \n {
357 modus_operandi& m = M(); 358 modus_operandi& m = M();
358 string::size_type t = m.output.find_first_not_of(" \t"); 359 string::size_type t = m.output.find_first_not_of(" \t");
359 if(t!=string::npos) 360 if(t!=string::npos)
360 m.output.erase(0,t); 361 m.output.erase(0,t);
361 t = m.output.find_last_not_of(" \t;"); 362 t = m.output.find_last_not_of(" \t;");
362 if(t!=string::npos) 363 if(t!=string::npos)
363 m.output.erase(t+1); 364 m.output.erase(t+1);
364 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') { 365 if(m.output[0]=='"' && m.output[m.output.length()-1]=='"') {
365 m.output.erase(0,1); 366 m.output.erase(0,1);
366 m.output.erase(m.output.length()-1); 367 m.output.erase(m.output.length()-1);
367 } 368 }
368 string c = combine_path(component_basename,m.output); 369 string c = konforka::combine_path(component_basename,m.output);
369 ancestor_classes.push_back(ancestor_class(m._name,normalize_path(c,strip_leading_slash))); 370 ancestor_classes.push_back(ancestor_class(m._name,konforka::normalize_path(c,konforka::strip_leading_slash)));
370 modi.pop_front(); 371 modi.pop_front();
371 BEGIN(INITIAL); 372 BEGIN(INITIAL);
372 } 373 }
373} 374}
374 375
375<VARLINE>{ 376<VARLINE>{
376 {WHITESPACE}+{ 377 {WHITESPACE}+{
377 modus_operandi& m = M(); 378 modus_operandi& m = M();
378 if(!m.output.empty()) { 379 if(!m.output.empty()) {
379 if(!m._lastid.empty()) { 380 if(!m._lastid.empty()) {
380 if(!m._type.empty()) m._type += ' '; 381 if(!m._type.empty()) m._type += ' ';
381 m._type += m._lastid; 382 m._type += m._lastid;
382 } 383 }
383 m._lastid = m.output; 384 m._lastid = m.output;
384 m.output.clear(); 385 m.output.clear();
385 } 386 }
386 } 387 }
387 \*{ 388 \*{
388 modus_operandi& m = M(); 389 modus_operandi& m = M();
389 ECHO; 390 ECHO;
390 if(!m._lastid.empty()) { 391 if(!m._lastid.empty()) {
391 if(!m._type.empty()) m._type += ' '; 392 if(!m._type.empty()) m._type += ' ';
392 m._type += m._lastid; 393 m._type += m._lastid;
393 } 394 }
diff --git a/lib/sitecing_util.cc b/lib/sitecing_util.cc
index f892a60..f1432df 100644
--- a/lib/sitecing_util.cc
+++ b/lib/sitecing_util.cc
@@ -1,120 +1,58 @@
1#ifdef USE_PCH 1#ifdef USE_PCH
2 #include "pch.h" 2 #include "pch.h"
3#else 3#else
4 #include <sys/stat.h> 4 #include <sys/stat.h>
5 #include <sys/types.h> 5 #include <sys/types.h>
6 #include <unistd.h> 6 #include <unistd.h>
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <sys/ipc.h> 8 #include <sys/ipc.h>
9 #include <sys/sem.h> 9 #include <sys/sem.h>
10 #include <errno.h> 10 #include <errno.h>
11 #include <iostream> 11 #include <iostream>
12 #include <fstream> 12 #include <fstream>
13 #include <cassert> 13 #include <cassert>
14 #include "sitecing/sitecing_util.h" 14 #include "sitecing/sitecing_util.h"
15#endif 15#endif
16 16
17namespace sitecing { 17namespace sitecing {
18 18
19 /* 19 /*
20 * XXX: all of these utilities could be sheerly optimized. 20 * XXX: all of these utilities could be sheerly optimized.
21 */ 21 */
22 22
23 string normalize_path(const string& path,int opts) {
24 const char *s = path.c_str();
25 string rv;
26 string::size_type notslash = 0;
27 if( (*s)=='.' && s[1]=='/' )
28 s+=2;
29 if(opts&strip_leading_slash)
30 for(;(*s) && (*s)=='/';s++);
31 for(;*s;s++) {
32 if( (*s)=='/' ) {
33 if(s[1]=='/')
34 continue;
35 if(s[1]=='.' && s[2]=='/') {
36 s+=2;
37 continue;
38 }
39 }
40 if(opts&restrict_dotdot) {
41 if(
42 ( rv.empty() && s[0]=='.' && s[1]=='.' && s[2]=='/' )// "^../"
43 || ( s[0]=='/' && s[1]=='.' && s[2]=='.' && (s[3]==0 || s[3]=='/') ) // "/..(/|$)"
44 )
45 throw utility_restricted_sequence(CODEPOINT,"restricted updir sequence encountered");
46 }
47 rv += *s;
48 if( (*s) != '/' )
49 notslash=rv.length();
50 }
51 if(!(opts&strip_trailing_slash))
52 notslash++;
53 if(notslash<rv.length())
54 rv.erase(notslash); // XXX: check the logic of stripping/not strippling trailing slash
55 return rv;
56 }
57
58 string strip_prefix(const string& str,const string& prefix) { 23 string strip_prefix(const string& str,const string& prefix) {
59 if( (str.length()<prefix.length()) || str.compare(0,prefix.length(),prefix)) 24 if( (str.length()<prefix.length()) || str.compare(0,prefix.length(),prefix))
60 throw utility_no_prefix(CODEPOINT,"no such prefix"); 25 throw utility_no_prefix(CODEPOINT,"no such prefix");
61 return str.substr(prefix.length()); 26 return str.substr(prefix.length());
62 } 27 }
63 28
64 string strip_suffix(const string& str,const string& suffix) { 29 string strip_suffix(const string& str,const string& suffix) {
65 if( (str.length()<suffix.length()) || str.compare(str.length()-suffix.length(),suffix.length(),suffix)) 30 if( (str.length()<suffix.length()) || str.compare(str.length()-suffix.length(),suffix.length(),suffix))
66 throw utility_no_suffix(CODEPOINT,"no such suffix"); 31 throw utility_no_suffix(CODEPOINT,"no such suffix");
67 return str.substr(0,str.length()-suffix.length()); 32 return str.substr(0,str.length()-suffix.length());
68 } 33 }
69 34
70 string dir_name(const string& filename) {
71 string::size_type sl = filename.find_last_of('/');
72 if(sl==string::npos)
73 return ""; // no slashes -- no dir.
74 string::size_type nosl = filename.find_last_not_of('/',sl);
75 if(nosl==string::npos)
76 return ""; // only slashes -- no dir. XXX: only slashes after the last slash... does it mean no dir?
77 return filename.substr(0,nosl+1);
78 }
79
80 void make_path(const string& path,mode_t mode) {
81 struct stat st;
82 for(string::size_type sl=0;sl!=string::npos;sl=path.find('/',sl+1)) {
83 if(!sl)
84 continue;
85 string p = path.substr(0,sl);
86 if(stat(p.c_str(),&st) || !S_ISDIR(st.st_mode)) {
87 if(mkdir(p.c_str(),mode))
88 throw konforka::exception(CODEPOINT,"failed to mkdir()");
89 }
90 }
91 if(stat(path.c_str(),&st) || !S_ISDIR(st.st_mode)) {
92 if(mkdir(path.c_str(),mode))
93 throw konforka::exception(CODEPOINT,"failed to mkdir()");
94 }
95 }
96
97 void file_lock::lock(const string& f) { 35 void file_lock::lock(const string& f) {
98 unlock(); 36 unlock();
99 fd = open(f.c_str(),O_CREAT|O_RDWR,S_IRUSR|S_IWUSR); 37 fd = open(f.c_str(),O_CREAT|O_RDWR,S_IRUSR|S_IWUSR);
100 if(fd<0) 38 if(fd<0)
101 throw konforka::exception(CODEPOINT,"failed to open/create lockfile"); 39 throw konforka::exception(CODEPOINT,"failed to open/create lockfile");
102 try { 40 try {
103 lock(); 41 lock();
104 }catch(konforka::exception& ke) { 42 }catch(konforka::exception& ke) {
105 ke.see(CODEPOINT); 43 ke.see(CODEPOINT);
106 close(fd); fd=-1; 44 close(fd); fd=-1;
107 throw; 45 throw;
108 }catch(...) { 46 }catch(...) {
109 close(fd); fd=-1; 47 close(fd); fd=-1;
110 throw; 48 throw;
111 } 49 }
112 } 50 }
113 void file_lock::lock() { 51 void file_lock::lock() {
114 assert(fd>=0); 52 assert(fd>=0);
115 struct flock fl; 53 struct flock fl;
116 fl.l_type = F_WRLCK; 54 fl.l_type = F_WRLCK;
117 fl.l_whence=SEEK_SET; 55 fl.l_whence=SEEK_SET;
118 fl.l_start=fl.l_len=0; 56 fl.l_start=fl.l_len=0;
119 for(int tries=3;tries;tries--) { 57 for(int tries=3;tries;tries--) {
120 if(!fcntl(fd,F_SETLK,&fl)) 58 if(!fcntl(fd,F_SETLK,&fl))
@@ -183,97 +121,42 @@ namespace sitecing {
183 sb.sem_op=1; 121 sb.sem_op=1;
184 sb.sem_flg = SEM_UNDO; 122 sb.sem_flg = SEM_UNDO;
185 while(semop(semid,&sb,1)<0) { 123 while(semop(semid,&sb,1)<0) {
186 if(errno!=EINTR) 124 if(errno!=EINTR)
187 throw konforka::exception(CODEPOINT,"failed to semop()"); 125 throw konforka::exception(CODEPOINT,"failed to semop()");
188 } 126 }
189 } 127 }
190 128
191 void semaphore_lock::lock() { 129 void semaphore_lock::lock() {
192 assert(sem); 130 assert(sem);
193 if(locked) 131 if(locked)
194 return; 132 return;
195 sem->on(); 133 sem->on();
196 locked = true; 134 locked = true;
197 } 135 }
198 void semaphore_lock::unlock() { 136 void semaphore_lock::unlock() {
199 if(!sem) 137 if(!sem)
200 return; 138 return;
201 if(!locked) 139 if(!locked)
202 return; 140 return;
203 sem->off(); 141 sem->off();
204 locked=false; 142 locked=false;
205 } 143 }
206 144
207 string combine_path(const string& origin,const string& relative,int opts) {
208 string r = normalize_path(relative,0);
209 string rv;
210 // XXX: what to do if relative is empty is a question, really.
211 if(r.empty()) {
212 return normalize_path( (opts&origin_is_file)?dir_name(origin):origin ,strip_leading_slash|restrict_dotdot|strip_trailing_slash);
213 }else{
214 if(r[0]=='/') {
215 r.erase(0,1);
216 }else{
217 rv = normalize_path((opts&origin_is_file)?dir_name(origin):origin,restrict_dotdot|strip_trailing_slash);
218 }
219 }
220 string::size_type lsl = rv.rfind('/');
221 for(string::size_type sl=r.find('/');sl!=string::npos;sl=r.find('/')) {
222 assert(sl!=0);
223 if(sl==1 && r[0]=='.') {
224 // it's a "./"
225 r.erase(0,2);
226 }else if(sl==2 && r[0]=='.' && r[1]=='.') {
227 // we have a "../"
228 if(lsl==string::npos) {
229 if(rv.empty() && (opts&fail_beyond_root))
230 throw utility_beyond_root(CODEPOINT,"went beyond root while combining path");
231 rv.clear();
232 }else{
233 rv.erase(lsl);
234 lsl = rv.rfind('/');
235 }
236 r.erase(0,3);
237 }else{
238 // we have a "something/"
239 lsl = rv.length();
240 rv += '/';
241 rv += r.substr(0,sl);
242 r.erase(0,sl+1);
243 }
244 }
245 if(r.empty())
246 return rv+'/';
247 if(r.length()==2 && r[0]=='.' && r[0]=='.') {
248 if(lsl==string::npos) {
249 if(rv.empty() & (opts&fail_beyond_root))
250 throw utility_beyond_root(CODEPOINT,"went beyond root while combining path");
251 return "/";
252 }else{
253 rv.erase(lsl+1);
254 return rv;
255 }
256 }
257 rv += '/';
258 rv += r;
259 return rv;
260 }
261
262 void auto_chdir::pushdir(const string& td,bool ap) { 145 void auto_chdir::pushdir(const string& td,bool ap) {
263 /* TODO: make use of fchdir(2) instead */ 146 /* TODO: make use of fchdir(2) instead */
264 char *tmp = getcwd(0,0); 147 char *tmp = getcwd(0,0);
265 assert(tmp); 148 assert(tmp);
266 saved_pwd = tmp; 149 saved_pwd = tmp;
267 free(tmp); 150 free(tmp);
268 autopop=ap; 151 autopop=ap;
269 if(chdir(td.c_str())) 152 if(chdir(td.c_str()))
270 throw konforka::exception(CODEPOINT,"failed to chdir()"); 153 throw konforka::exception(CODEPOINT,"failed to chdir()");
271 } 154 }
272 void auto_chdir::popdir() { 155 void auto_chdir::popdir() {
273 autopop=false; 156 autopop=false;
274 if(chdir(saved_pwd.c_str())) 157 if(chdir(saved_pwd.c_str()))
275 throw konforka::exception(CODEPOINT,"failed to chdir()"); 158 throw konforka::exception(CODEPOINT,"failed to chdir()");
276 // XXX: or should it be thrown? after all we call it from destructor... 159 // XXX: or should it be thrown? after all we call it from destructor...
277 } 160 }
278 161
279} 162}
diff --git a/lib/sitespace.cc b/lib/sitespace.cc
index 0406d11..d5592bf 100644
--- a/lib/sitespace.cc
+++ b/lib/sitespace.cc
@@ -1,47 +1,48 @@
1#ifdef USE_PCH 1#ifdef USE_PCH
2 #include "pch.h" 2 #include "pch.h"
3#else 3#else
4 #include <cassert> 4 #include <cassert>
5 #include <konforka/util.h>
5 #include "sitecing/sitespace.h" 6 #include "sitecing/sitespace.h"
6 #include "sitecing/sitecing_util.h" 7 #include "sitecing/sitecing_util.h"
7#endif 8#endif
8 9
9namespace sitecing { 10namespace sitecing {
10 11
11 sitespace::sitespace(configuration& c) 12 sitespace::sitespace(configuration& c)
12 : config(c), factory(c) { } 13 : config(c), factory(c) { }
13 14
14 sitespace::~sitespace() { 15 sitespace::~sitespace() {
15 for(sentenced_t::iterator i = sentenced.begin();i!=sentenced.end();++i) { 16 for(sentenced_t::iterator i = sentenced.begin();i!=sentenced.end();++i) {
16 assert((*i)->chickens_used.empty()); 17 assert((*i)->chickens_used.empty());
17 delete *i; 18 delete *i;
18 } 19 }
19 } 20 }
20 21
21 so_component sitespace::fetch(const string& c,sitecing_interface* scif) { 22 so_component sitespace::fetch(const string& c,sitecing_interface* scif) {
22 execute_sentenced(); 23 execute_sentenced();
23 string sobase = normalize_path(c); 24 string sobase = konforka::normalize_path(c);
24 string sopath = factory.root_so+sobase+".so"; 25 string sopath = factory.root_so+sobase+".so";
25 config_options *co_build = config.lookup_config(sobase,config_options::flag_build); 26 config_options *co_build = config.lookup_config(sobase,config_options::flag_build);
26 if( (!co_build) || co_build->build ) 27 if( (!co_build) || co_build->build )
27 factory.make(sopath); 28 factory.make(sopath);
28 components_t::iterator i = components.find(sopath); 29 components_t::iterator i = components.find(sopath);
29 if(i!=components.end()) { 30 if(i!=components.end()) {
30 if(i->second->is_uptodate()) 31 if(i->second->is_uptodate())
31 return so_component(i->second,scif); 32 return so_component(i->second,scif);
32 if(i->second->chickens_used.empty()) { 33 if(i->second->chickens_used.empty()) {
33 delete i->second; 34 delete i->second;
34 }else{ 35 }else{
35 sentenced.push_back(i->second); 36 sentenced.push_back(i->second);
36 } 37 }
37 components.erase(i); 38 components.erase(i);
38 } 39 }
39 pair<components_t::iterator,bool> ins = components.insert(components_t::value_type(sopath,new component_so(sopath))); 40 pair<components_t::iterator,bool> ins = components.insert(components_t::value_type(sopath,new component_so(sopath)));
40 return so_component(ins.first->second,scif); 41 return so_component(ins.first->second,scif);
41 } 42 }
42 43
43 void sitespace::execute_sentenced() { 44 void sitespace::execute_sentenced() {
44 for(sentenced_t::iterator i = sentenced.begin();i!=sentenced.end();++i) { 45 for(sentenced_t::iterator i = sentenced.begin();i!=sentenced.end();++i) {
45 if((*i)->chickens_used.empty()) { 46 if((*i)->chickens_used.empty()) {
46 delete *i; 47 delete *i;
47 sentenced.erase(i); 48 sentenced.erase(i);
diff --git a/src/sitecing-build.cc b/src/sitecing-build.cc
index 4cad0a3..887ef83 100644
--- a/src/sitecing-build.cc
+++ b/src/sitecing-build.cc
@@ -1,33 +1,34 @@
1#include <sys/types.h> 1#include <sys/types.h>
2#include <dirent.h> 2#include <dirent.h>
3#include <getopt.h> 3#include <getopt.h>
4#include <iostream> 4#include <iostream>
5#include <memory> 5#include <memory>
6#include <fstream> 6#include <fstream>
7#include <cassert> 7#include <cassert>
8#include <set> 8#include <set>
9using namespace std; 9using namespace std;
10#include <konforka/util.h>
10#include "sitecing/sitecing_util.h" 11#include "sitecing/sitecing_util.h"
11#include "sitecing/util.h" 12#include "sitecing/util.h"
12#include "sitecing/sitespace.h" 13#include "sitecing/sitespace.h"
13#include "sitecing/sitecing_interface_cgi.h" 14#include "sitecing/sitecing_interface_cgi.h"
14#include "sitecing/cgi_component.h" 15#include "sitecing/cgi_component.h"
15#include "sitecing/configuration.h" 16#include "sitecing/configuration.h"
16#include "sitecing/magic.h" 17#include "sitecing/magic.h"
17#include "sitecing/sitecing_exception.h" 18#include "sitecing/sitecing_exception.h"
18#include "sitecing/exception.h" 19#include "sitecing/exception.h"
19using namespace sitecing; 20using namespace sitecing;
20 21
21#include "config.h" 22#include "config.h"
22#define PHEADER PACKAGE "-build Version " VERSION 23#define PHEADER PACKAGE "-build Version " VERSION
23#define PCOPY "Copyright (c) 2004 Klever Group" 24#define PCOPY "Copyright (c) 2004 Klever Group"
24 25
25static sitespace* site_space = NULL; 26static sitespace* site_space = NULL;
26typedef pair<dev_t,ino_t> the_inode_t; 27typedef pair<dev_t,ino_t> the_inode_t;
27set<the_inode_t> built_inodes; 28set<the_inode_t> built_inodes;
28 29
29void build_component(const string& component) { 30void build_component(const string& component) {
30 assert(site_space); 31 assert(site_space);
31 cerr << "Building " << component << endl; 32 cerr << "Building " << component << endl;
32 try { 33 try {
33 site_space->factory.make(site_space->config.root_so+component+".so"); 34 site_space->factory.make(site_space->config.root_so+component+".so");
@@ -57,49 +58,49 @@ void build_with_imports(const string& component) {
57 built_inodes.insert(the_inode_t(st.st_dev,st.st_ino)); 58 built_inodes.insert(the_inode_t(st.st_dev,st.st_ino));
58 } 59 }
59 build_component(component); 60 build_component(component);
60 build_imports(component); 61 build_imports(component);
61} 62}
62 63
63void build_imports(const string& component) { 64void build_imports(const string& component) {
64 assert(site_space); 65 assert(site_space);
65 ifstream ifs((site_space->config.root_intermediate+component+".imports").c_str(),ios::in); 66 ifstream ifs((site_space->config.root_intermediate+component+".imports").c_str(),ios::in);
66 cerr << "Building components imported by " << component << endl; 67 cerr << "Building components imported by " << component << endl;
67 if(ifs) { 68 if(ifs) {
68 string import; 69 string import;
69 while(!ifs.eof()) { 70 while(!ifs.eof()) {
70 ifs >> import; 71 ifs >> import;
71 if(!import.empty()) 72 if(!import.empty())
72 build_with_imports(import); 73 build_with_imports(import);
73 } 74 }
74 } 75 }
75} 76}
76 77
77void build_http_status_handlers(const string& target) { 78void build_http_status_handlers(const string& target) {
78 assert(site_space); 79 assert(site_space);
79 set<string> stop_list; 80 set<string> stop_list;
80 string t = "/"; 81 string t = "/";
81 t += normalize_path(target,strip_leading_slash); 82 t += konforka::normalize_path(target,konforka::strip_leading_slash);
82 for(;;) { 83 for(;;) {
83 if(t[t.length()-1]=='/') { 84 if(t[t.length()-1]=='/') {
84 loaded_options* lo = site_space->config.lookup_loaded_options(t); 85 loaded_options* lo = site_space->config.lookup_loaded_options(t);
85 if( lo && (lo->flags&config_options::flag_http_status_handlers) ) { 86 if( lo && (lo->flags&config_options::flag_http_status_handlers) ) {
86 for(config_options::http_status_handlers_t::const_iterator i=lo->http_status_handlers.begin();i!=lo->http_status_handlers.end();++i) { 87 for(config_options::http_status_handlers_t::const_iterator i=lo->http_status_handlers.begin();i!=lo->http_status_handlers.end();++i) {
87 if(stop_list.find(i->first)==stop_list.end()) { 88 if(stop_list.find(i->first)==stop_list.end()) {
88 build_with_imports(i->second); 89 build_with_imports(i->second);
89 stop_list.insert(i->first); 90 stop_list.insert(i->first);
90 } 91 }
91 } 92 }
92 } 93 }
93 } 94 }
94 configuration::specs_t::iterator i=site_space->config.specs.find(t); 95 configuration::specs_t::iterator i=site_space->config.specs.find(t);
95 if( i!=site_space->config.specs.end() && (i->second.flags&config_options::flag_http_status_handlers) ) { 96 if( i!=site_space->config.specs.end() && (i->second.flags&config_options::flag_http_status_handlers) ) {
96 for(config_options::http_status_handlers_t::const_iterator ii=i->second.http_status_handlers.begin();ii!=i->second.http_status_handlers.end();++i) { 97 for(config_options::http_status_handlers_t::const_iterator ii=i->second.http_status_handlers.begin();ii!=i->second.http_status_handlers.end();++i) {
97 if(stop_list.find(ii->first)==stop_list.end()) { 98 if(stop_list.find(ii->first)==stop_list.end()) {
98 build_with_imports(ii->second); 99 build_with_imports(ii->second);
99 stop_list.insert(ii->first); 100 stop_list.insert(ii->first);
100 } 101 }
101 } 102 }
102 } 103 }
103 if(t.empty()) 104 if(t.empty())
104 return; 105 return;
105 string::size_type sl=t.rfind('/'); 106 string::size_type sl=t.rfind('/');
@@ -126,49 +127,49 @@ void build_target(const string& target) {
126void build(const string& target) { 127void build(const string& target) {
127 assert(site_space); 128 assert(site_space);
128 build_http_status_handlers(target); 129 build_http_status_handlers(target);
129 config_options *co_exception_handler = site_space->config.lookup_config(target,config_options::flag_exception_handler); 130 config_options *co_exception_handler = site_space->config.lookup_config(target,config_options::flag_exception_handler);
130 if(co_exception_handler) { 131 if(co_exception_handler) {
131 string handler = co_exception_handler->exception_handler; 132 string handler = co_exception_handler->exception_handler;
132 build_with_imports(handler); 133 build_with_imports(handler);
133 } 134 }
134 string target_source = site_space->config.root_source+target; 135 string target_source = site_space->config.root_source+target;
135 struct stat st; 136 struct stat st;
136 if(stat(target_source.c_str(),&st)) 137 if(stat(target_source.c_str(),&st))
137 throw konforka::exception(CODEPOINT,"failed to stat() target"); 138 throw konforka::exception(CODEPOINT,"failed to stat() target");
138 if(S_ISREG(st.st_mode)) { 139 if(S_ISREG(st.st_mode)) {
139 build_target(target); 140 build_target(target);
140 }else if(S_ISDIR(st.st_mode)) { 141 }else if(S_ISDIR(st.st_mode)) {
141 build_http_status_handlers(target); 142 build_http_status_handlers(target);
142 DIR *d=opendir(target_source.c_str()); 143 DIR *d=opendir(target_source.c_str());
143 if(!d) 144 if(!d)
144 throw konforka::exception(CODEPOINT,"failed to opendir()"); 145 throw konforka::exception(CODEPOINT,"failed to opendir()");
145 for(struct dirent *de=readdir(d);de;de=readdir(d)) { 146 for(struct dirent *de=readdir(d);de;de=readdir(d)) {
146 if(!strcmp(de->d_name,".")) 147 if(!strcmp(de->d_name,"."))
147 continue; 148 continue;
148 if(!strcmp(de->d_name,"..")) 149 if(!strcmp(de->d_name,".."))
149 continue; 150 continue;
150 string subtarget = normalize_path(target+"/"+de->d_name); 151 string subtarget = konforka::normalize_path(target+"/"+de->d_name);
151 struct stat sts; 152 struct stat sts;
152 if(stat((site_space->config.root_source+subtarget).c_str(),&sts)) 153 if(stat((site_space->config.root_source+subtarget).c_str(),&sts))
153 throw konforka::exception(CODEPOINT,"failed to stat() subtarget"); 154 throw konforka::exception(CODEPOINT,"failed to stat() subtarget");
154 if(S_ISDIR(sts.st_mode)) { 155 if(S_ISDIR(sts.st_mode)) {
155 build(subtarget); 156 build(subtarget);
156 }else{ 157 }else{
157 if(site_space->config.match_autobuild_files(target,de->d_name)){ 158 if(site_space->config.match_autobuild_files(target,de->d_name)){
158 build_target(subtarget); 159 build_target(subtarget);
159 } 160 }
160 } 161 }
161 } 162 }
162 closedir(d); 163 closedir(d);
163 } 164 }
164} 165}
165 166
166int main(int argc,char **argv) { 167int main(int argc,char **argv) {
167 try { 168 try {
168 string config_file = "sitecing.conf"; 169 string config_file = "sitecing.conf";
169 while(true) { 170 while(true) {
170 static struct option opts[] = { 171 static struct option opts[] = {
171 { "help", no_argument, 0, 'h' }, 172 { "help", no_argument, 0, 'h' },
172 { "usage", no_argument, 0, 'h' }, 173 { "usage", no_argument, 0, 'h' },
173 { "version", no_argument, 0, 'V' }, 174 { "version", no_argument, 0, 'V' },
174 { "license", no_argument, 0, 'L' }, 175 { "license", no_argument, 0, 'L' },
diff --git a/src/sitecing-fastcgi.cc b/src/sitecing-fastcgi.cc
index 756dcee..03587aa 100644
--- a/src/sitecing-fastcgi.cc
+++ b/src/sitecing-fastcgi.cc
@@ -144,68 +144,68 @@ void sitecing_fastcgi_pm::process(int slot) {
144 sitespace ss(config); 144 sitespace ss(config);
145 fcgi_socket& fs = *fss; 145 fcgi_socket& fs = *fss;
146 sitecing_interface_cgi scif(&ss); 146 sitecing_interface_cgi scif(&ss);
147 string component_path; 147 string component_path;
148 string action; 148 string action;
149 config_options::action_handler_t *action_handler; 149 config_options::action_handler_t *action_handler;
150 int rpc = 0; 150 int rpc = 0;
151 if(config.flags&configuration::flag_requests_per_child) 151 if(config.flags&configuration::flag_requests_per_child)
152 rpc = config.requests_per_child; 152 rpc = config.requests_per_child;
153 for(int req=0;(rpc<=0) || (req<rpc);rpc++) { 153 for(int req=0;(rpc<=0) || (req<rpc);rpc++) {
154 semaphore_lock sl; 154 semaphore_lock sl;
155 if(multi) { 155 if(multi) {
156 sslot->state = scoreboard_slot::state_idle; 156 sslot->state = scoreboard_slot::state_idle;
157 sl.sem = &sem; 157 sl.sem = &sem;
158 sl.lock(); 158 sl.lock();
159 } 159 }
160 sslot->state = scoreboard_slot::state_accept; 160 sslot->state = scoreboard_slot::state_accept;
161 fcgi_interface fi(fs); 161 fcgi_interface fi(fs);
162 sslot->state = scoreboard_slot::state_processing; 162 sslot->state = scoreboard_slot::state_processing;
163 if(multi) 163 if(multi)
164 sl.unlock(); 164 sl.unlock();
165 cgi_gateway gw(fi); 165 cgi_gateway gw(fi);
166 scif.prepare(&gw); 166 scif.prepare(&gw);
167 try { 167 try {
168 component_path = normalize_path(gw.path_info(),strip_leading_slash|strip_trailing_slash); 168 component_path = konforka::normalize_path(gw.path_info(),konforka::strip_leading_slash|konforka::strip_trailing_slash);
169 string full_component_path; 169 string full_component_path;
170 string sitecing_path_info; 170 string sitecing_path_info;
171 while(true) { 171 while(true) {
172 full_component_path = config.root_source+'/'+component_path; 172 full_component_path = config.root_source+'/'+component_path;
173 if(!access(full_component_path.c_str(),F_OK)) 173 if(!access(full_component_path.c_str(),F_OK))
174 break; 174 break;
175 string::size_type sl = component_path.rfind('/'); 175 string::size_type sl = component_path.rfind('/');
176 if(sl==string::npos) 176 if(sl==string::npos)
177 throw konforka::exception(CODEPOINT,"can't find the target component"); 177 throw konforka::exception(CODEPOINT,"can't find the target component");
178 sitecing_path_info.insert(0,component_path,sl,string::npos); 178 sitecing_path_info.insert(0,component_path,sl,string::npos);
179 component_path.erase(sl); 179 component_path.erase(sl);
180 } 180 }
181 fi.metavars["SITECING_PATH_INFO"]=sitecing_path_info; 181 fi.metavars["SITECING_PATH_INFO"]=sitecing_path_info;
182 action = component_path; 182 action = component_path;
183 action_handler = config.lookup_action_handler(component_path); 183 action_handler = config.lookup_action_handler(component_path);
184 if(action_handler) { 184 if(action_handler) {
185 action = action_handler->action; 185 action = action_handler->action;
186 } 186 }
187 string pwd = dir_name(full_component_path); 187 string pwd = konforka::dir_name(full_component_path);
188 if(chdir(pwd.c_str())) 188 if(chdir(pwd.c_str()))
189 throw konforka::exception(CODEPOINT,"failed to chdir() into document's directory"); 189 throw konforka::exception(CODEPOINT,"failed to chdir() into document's directory");
190 so_component soc = ss.fetch(action,&scif); 190 so_component soc = ss.fetch(action,&scif);
191 if(action_handler) { 191 if(action_handler) {
192 soc.ac->run(__magic_action, 192 soc.ac->run(__magic_action,
193 config.root_source.c_str(), config.root_intermediate.c_str(), config.root_so.c_str(), 193 config.root_source.c_str(), config.root_intermediate.c_str(), config.root_so.c_str(),
194 &(action_handler->args) 194 &(action_handler->args)
195 ); 195 );
196 }else{ 196 }else{
197 soc.ac->main(0,NULL); 197 soc.ac->main(0,NULL);
198 } 198 }
199 }catch(http_status& hs) { 199 }catch(http_status& hs) {
200 scif.headers["Status"] = hs.status+" "+hs.message; 200 scif.headers["Status"] = hs.status+" "+hs.message;
201 string hshp = config.lookup_http_status_handler(component_path,hs.status); 201 string hshp = config.lookup_http_status_handler(component_path,hs.status);
202 if(!hshp.empty()) { 202 if(!hshp.empty()) {
203 so_component hsh = ss.fetch(hshp,&scif); // TODO: handle error trying to handle status 203 so_component hsh = ss.fetch(hshp,&scif); // TODO: handle error trying to handle status
204 hsh.ac->run(__magic_http_status,config.root_source.c_str(),config.root_intermediate.c_str(), 204 hsh.ac->run(__magic_http_status,config.root_source.c_str(),config.root_intermediate.c_str(),
205 config.root_so.c_str(),action.c_str(),&hs); 205 config.root_so.c_str(),action.c_str(),&hs);
206 } 206 }
207 }catch(compile_error& ce) { 207 }catch(compile_error& ce) {
208 config_options *co_exception_handler = config.lookup_config(component_path,config_options::flag_exception_handler); 208 config_options *co_exception_handler = config.lookup_config(component_path,config_options::flag_exception_handler);
209 if(co_exception_handler) { 209 if(co_exception_handler) {
210 so_component eh = ss.fetch(co_exception_handler->exception_handler,&scif); // TODO: handle error trying to handle error. 210 so_component eh = ss.fetch(co_exception_handler->exception_handler,&scif); // TODO: handle error trying to handle error.
211 eh.ac->run(__magic_compile_error,ce.what(),config.root_source.c_str(),config.root_intermediate.c_str(),config.root_so.c_str(),ce.component_path.c_str()); 211 eh.ac->run(__magic_compile_error,ce.what(),config.root_source.c_str(),config.root_intermediate.c_str(),config.root_so.c_str(),ce.component_path.c_str());
diff --git a/src/sitecing-plaincgi.cc b/src/sitecing-plaincgi.cc
index 3bd291a..2f93cc5 100644
--- a/src/sitecing-plaincgi.cc
+++ b/src/sitecing-plaincgi.cc
@@ -29,68 +29,68 @@ using namespace sitecing;
29#define PCOPY "Copyright (c) 2005 Klever Group" 29#define PCOPY "Copyright (c) 2005 Klever Group"
30 30
31class cdummyClass : public acomponent { 31class cdummyClass : public acomponent {
32 public: 32 public:
33 void main(int _magic,va_list _args) {} 33 void main(int _magic,va_list _args) {}
34 void *__the_most_derived_this() { return NULL; } 34 void *__the_most_derived_this() { return NULL; }
35} cdummyInstance; 35} cdummyInstance;
36class adummyClass : public cgi_component { 36class adummyClass : public cgi_component {
37 public: 37 public:
38 void main(int _magic,va_list _args) {} 38 void main(int _magic,va_list _args) {}
39 void *__the_most_derived_this() { return NULL; } 39 void *__the_most_derived_this() { return NULL; }
40} adummyInstance; 40} adummyInstance;
41 41
42void process_request(configuration& config) { 42void process_request(configuration& config) {
43 try { 43 try {
44 sitespace ss(config); 44 sitespace ss(config);
45 sitecing_interface_cgi scif(&ss); 45 sitecing_interface_cgi scif(&ss);
46 string component_path; 46 string component_path;
47 string action; 47 string action;
48 config_options::action_handler_t *action_handler; 48 config_options::action_handler_t *action_handler;
49 plaincgi_interface ci; 49 plaincgi_interface ci;
50 cgi_gateway gw(ci); 50 cgi_gateway gw(ci);
51 scif.prepare(&gw); 51 scif.prepare(&gw);
52 try { 52 try {
53 component_path = normalize_path(gw.path_info(),strip_leading_slash|strip_trailing_slash); 53 component_path = konforka::normalize_path(gw.path_info(),konforka::strip_leading_slash|konforka::strip_trailing_slash);
54 string full_component_path; 54 string full_component_path;
55 string sitecing_path_info; 55 string sitecing_path_info;
56 while(true) { 56 while(true) {
57 full_component_path = config.root_source+'/'+component_path; 57 full_component_path = config.root_source+'/'+component_path;
58 if(!access(full_component_path.c_str(),F_OK)) 58 if(!access(full_component_path.c_str(),F_OK))
59 break; 59 break;
60 string::size_type sl = component_path.rfind('/'); 60 string::size_type sl = component_path.rfind('/');
61 if(sl==string::npos) 61 if(sl==string::npos)
62 throw konforka::exception(CODEPOINT,"can't find the target component"); 62 throw konforka::exception(CODEPOINT,"can't find the target component");
63 sitecing_path_info.insert(0,component_path,sl,string::npos); 63 sitecing_path_info.insert(0,component_path,sl,string::npos);
64 component_path.erase(sl); 64 component_path.erase(sl);
65 } 65 }
66 ci.metavars["SITECING_PATH_INFO"]=sitecing_path_info; 66 ci.metavars["SITECING_PATH_INFO"]=sitecing_path_info;
67 action = component_path; 67 action = component_path;
68 action_handler = config.lookup_action_handler(component_path); 68 action_handler = config.lookup_action_handler(component_path);
69 if(action_handler) { 69 if(action_handler) {
70 action = action_handler->action; 70 action = action_handler->action;
71 } 71 }
72 string pwd = dir_name(full_component_path); 72 string pwd = konforka::dir_name(full_component_path);
73 if(chdir(pwd.c_str())) 73 if(chdir(pwd.c_str()))
74 throw konforka::exception(CODEPOINT,"failed to chdir() into document's directory"); 74 throw konforka::exception(CODEPOINT,"failed to chdir() into document's directory");
75 so_component soc = ss.fetch(action,&scif); 75 so_component soc = ss.fetch(action,&scif);
76 if(action_handler) { 76 if(action_handler) {
77 soc.ac->run(__magic_action, 77 soc.ac->run(__magic_action,
78 config.root_source.c_str(), config.root_intermediate.c_str(), config.root_so.c_str(), 78 config.root_source.c_str(), config.root_intermediate.c_str(), config.root_so.c_str(),
79 &(action_handler->args) 79 &(action_handler->args)
80 ); 80 );
81 }else{ 81 }else{
82 soc.ac->main(0,NULL); 82 soc.ac->main(0,NULL);
83 } 83 }
84 }catch(http_status& hs) { 84 }catch(http_status& hs) {
85 scif.headers["Status"] = hs.status+" "+hs.message; 85 scif.headers["Status"] = hs.status+" "+hs.message;
86 string hshp = config.lookup_http_status_handler(component_path,hs.status); 86 string hshp = config.lookup_http_status_handler(component_path,hs.status);
87 if(!hshp.empty()) { 87 if(!hshp.empty()) {
88 so_component hsh = ss.fetch(hshp,&scif); // TODO: handle error trying to handle status 88 so_component hsh = ss.fetch(hshp,&scif); // TODO: handle error trying to handle status
89 hsh.ac->run(__magic_http_status,config.root_source.c_str(),config.root_intermediate.c_str(), 89 hsh.ac->run(__magic_http_status,config.root_source.c_str(),config.root_intermediate.c_str(),
90 config.root_so.c_str(),action.c_str(),&hs); 90 config.root_so.c_str(),action.c_str(),&hs);
91 } 91 }
92 }catch(compile_error& ce) { 92 }catch(compile_error& ce) {
93 config_options *co_exception_handler = config.lookup_config(component_path,config_options::flag_exception_handler); 93 config_options *co_exception_handler = config.lookup_config(component_path,config_options::flag_exception_handler);
94 if(co_exception_handler) { 94 if(co_exception_handler) {
95 so_component eh = ss.fetch(co_exception_handler->exception_handler,&scif); // TODO: handle error trying to handle error. 95 so_component eh = ss.fetch(co_exception_handler->exception_handler,&scif); // TODO: handle error trying to handle error.
96 eh.ac->run(__magic_compile_error,ce.what(),config.root_source.c_str(),config.root_intermediate.c_str(),config.root_so.c_str(),ce.component_path.c_str()); 96 eh.ac->run(__magic_compile_error,ce.what(),config.root_source.c_str(),config.root_intermediate.c_str(),config.root_so.c_str(),ce.component_path.c_str());