-rw-r--r-- | components/exception_dev | 7 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | include/sitecing/sitecing_util.h | 87 | ||||
-rw-r--r-- | lib/component_factory.cc | 31 | ||||
-rw-r--r-- | lib/configuration.cc | 9 | ||||
-rw-r--r-- | lib/sitecing_parser.ll | 13 | ||||
-rw-r--r-- | lib/sitecing_util.cc | 117 | ||||
-rw-r--r-- | lib/sitespace.cc | 3 | ||||
-rw-r--r-- | src/sitecing-build.cc | 5 | ||||
-rw-r--r-- | src/sitecing-fastcgi.cc | 4 | ||||
-rw-r--r-- | src/sitecing-plaincgi.cc | 4 |
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,346 +1,347 @@ | |||
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*); |
37 | root_source = va_arg(va,const char*); | 38 | root_source = va_arg(va,const char*); |
38 | root_intermediate = va_arg(va,const char*); | 39 | root_intermediate = va_arg(va,const char*); |
39 | root_so = va_arg(va,const char*); | 40 | root_so = va_arg(va,const char*); |
40 | component = va_arg(va,const char*); | 41 | component = va_arg(va,const char*); |
41 | line_number = va_arg(va,int); | 42 | line_number = va_arg(va,int); |
42 | break; | 43 | break; |
43 | case sitecing::__magic_generic_exception: | 44 | case sitecing::__magic_generic_exception: |
44 | message = va_arg(va,const char*); | 45 | message = va_arg(va,const char*); |
45 | root_source = va_arg(va,const char*); | 46 | root_source = va_arg(va,const char*); |
46 | root_intermediate = va_arg(va,const char *); | 47 | root_intermediate = va_arg(va,const char *); |
47 | root_so = va_arg(va,const char *); | 48 | root_so = va_arg(va,const char *); |
48 | component = va_arg(va,const char*); | 49 | component = va_arg(va,const char*); |
49 | exception_caught = va_arg(va,const exception*); | 50 | exception_caught = va_arg(va,const exception*); |
50 | break; | 51 | break; |
51 | default: | 52 | default: |
52 | break; | 53 | break; |
53 | } | 54 | } |
54 | </%code> | 55 | </%code> |
55 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | 56 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
56 | <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> | 57 | <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> |
57 | <head> | 58 | <head> |
58 | <title><% message %></title> | 59 | <title><% message %></title> |
59 | <style type="text/css"> | 60 | <style type="text/css"> |
60 | <!-- | 61 | <!-- |
61 | body { | 62 | body { |
62 | font-family: sans-serif; | 63 | font-family: sans-serif; |
63 | font-size: 11pt; | 64 | font-size: 11pt; |
64 | } | 65 | } |
65 | 66 | ||
66 | h1 { | 67 | h1 { |
67 | font-family: serif; | 68 | font-family: serif; |
68 | font-size: 130%; | 69 | font-size: 130%; |
69 | font-weight: bold; | 70 | font-weight: bold; |
70 | text-align: center; | 71 | text-align: center; |
71 | } | 72 | } |
72 | p { | 73 | p { |
73 | text-indent: 2em; | 74 | text-indent: 2em; |
74 | text-align: justify; | 75 | text-align: justify; |
75 | } | 76 | } |
76 | 77 | ||
77 | dl.exception-props { | 78 | dl.exception-props { |
78 | margin: 1ex 1em; | 79 | margin: 1ex 1em; |
79 | padding: 0.5ex; | 80 | padding: 0.5ex; |
80 | border: solid 1px gray; | 81 | border: solid 1px gray; |
81 | background-color: #e0e0e0; | 82 | background-color: #e0e0e0; |
82 | } | 83 | } |
83 | dl.exception-props dt { | 84 | dl.exception-props dt { |
84 | font-weight: bold; | 85 | font-weight: bold; |
85 | color: blue; | 86 | color: blue; |
86 | } | 87 | } |
87 | dl.exception-props dd { | 88 | dl.exception-props dd { |
88 | color: gray; | 89 | color: gray; |
89 | } | 90 | } |
90 | 91 | ||
91 | div.exception-codepoint-report { | 92 | div.exception-codepoint-report { |
92 | border: solid 1px black; | 93 | border: solid 1px black; |
93 | margin: 0.5ex 1em 0.ex 3em; | 94 | margin: 0.5ex 1em 0.ex 3em; |
94 | } | 95 | } |
95 | div.exception-codepoint-report h3 { | 96 | div.exception-codepoint-report h3 { |
96 | display: block; | 97 | display: block; |
97 | color: blue; | 98 | color: blue; |
98 | border-bottom: 3px double black; | 99 | border-bottom: 3px double black; |
99 | padding: 0.3ex; margin: 0px; | 100 | padding: 0.3ex; margin: 0px; |
100 | background: #e0e0e0; | 101 | background: #e0e0e0; |
101 | } | 102 | } |
102 | div.exception-codepoint-report ul { | 103 | div.exception-codepoint-report ul { |
103 | padding: 0px; | 104 | padding: 0px; |
104 | margin: 0px; | 105 | margin: 0px; |
105 | background: #87fdff; | 106 | background: #87fdff; |
106 | font-size: 70%; | 107 | font-size: 70%; |
107 | } | 108 | } |
108 | div.exception-codepoint-report li { | 109 | div.exception-codepoint-report li { |
109 | font-family: monospace; | 110 | font-family: monospace; |
110 | list-style-type: none; | 111 | list-style-type: none; |
111 | white-space: nowrap; | 112 | white-space: nowrap; |
112 | overflow: hidden; | 113 | overflow: hidden; |
113 | } | 114 | } |
114 | div.exception-codepoint-report li.focused { | 115 | div.exception-codepoint-report li.focused { |
115 | color: red; | 116 | color: red; |
116 | border-top: solid 1px red; border-bottom: solid 1px red; | 117 | border-top: solid 1px red; border-bottom: solid 1px red; |
117 | } | 118 | } |
118 | div.exception-codepoint-report li .lineno { | 119 | div.exception-codepoint-report li .lineno { |
119 | padding-right: 0.5ex; | 120 | padding-right: 0.5ex; |
120 | border-right: dotted black 1px; | 121 | border-right: dotted black 1px; |
121 | } | 122 | } |
122 | div.exception-codepoint-report div.what { | 123 | div.exception-codepoint-report div.what { |
123 | border-top: double 3px black; | 124 | border-top: double 3px black; |
124 | padding: 0.5ex 2em; | 125 | padding: 0.5ex 2em; |
125 | font-weight: bold; color: #4040c0; | 126 | font-weight: bold; color: #4040c0; |
126 | overflow: auto; | 127 | overflow: auto; |
127 | } | 128 | } |
128 | div.backtrace div.exception-codepoint-report div.what { | 129 | div.backtrace div.exception-codepoint-report div.what { |
129 | color: gray; | 130 | color: gray; |
130 | } | 131 | } |
131 | 132 | ||
132 | div.exception-compile div.what { | 133 | div.exception-compile div.what { |
133 | font-weight: normal; | 134 | font-weight: normal; |
134 | color: red; | 135 | color: red; |
135 | } | 136 | } |
136 | 137 | ||
137 | div.powered { | 138 | div.powered { |
138 | margin: 2em 0px 0px 50%; | 139 | margin: 2em 0px 0px 50%; |
139 | padding: 1ex 2ex; | 140 | padding: 1ex 2ex; |
140 | text-align: right; | 141 | text-align: right; |
141 | font-family: serif; | 142 | font-family: serif; |
142 | font-size: 140%; | 143 | font-size: 140%; |
143 | font-weight: bold; | 144 | font-weight: bold; |
144 | border-top: solid 2px black; | 145 | border-top: solid 2px black; |
145 | border-left: solid 1px gray; border-right: solid 1px gray; border-bottom: solid 1px gray; | 146 | border-left: solid 1px gray; border-right: solid 1px gray; border-bottom: solid 1px gray; |
146 | background: #c0c0f0; | 147 | background: #c0c0f0; |
147 | } | 148 | } |
148 | --> | 149 | --> |
149 | </style> | 150 | </style> |
150 | % __SCIF->headers["Content-Type"]="text/html; charset=utf-8"; | 151 | % __SCIF->headers["Content-Type"]="text/html; charset=utf-8"; |
151 | % __SCIF->headers["Pragma"]="no-cache"; | 152 | % __SCIF->headers["Pragma"]="no-cache"; |
152 | </head> | 153 | </head> |
153 | <body> | 154 | <body> |
154 | <%code> | 155 | <%code> |
155 | switch(magic) { | 156 | switch(magic) { |
156 | case sitecing::__magic_compile_error: | 157 | case sitecing::__magic_compile_error: |
157 | handle_compile_error(); | 158 | handle_compile_error(); |
158 | break; | 159 | break; |
159 | case sitecing::__magic_preprocess_error: | 160 | case sitecing::__magic_preprocess_error: |
160 | handle_preprocess_error(); | 161 | handle_preprocess_error(); |
161 | break; | 162 | break; |
162 | case sitecing::__magic_generic_exception: | 163 | case sitecing::__magic_generic_exception: |
163 | handle_generic_exception(); | 164 | handle_generic_exception(); |
164 | break; | 165 | break; |
165 | default: | 166 | default: |
166 | handle_unknown_error(); | 167 | handle_unknown_error(); |
167 | break; | 168 | break; |
168 | } | 169 | } |
169 | </%code> | 170 | </%code> |
170 | <div class="powered">Powered by <a href="http://kin.klever.net/sitecing/" title="site-C-ing">site-C-ing</a>.</div> | 171 | <div class="powered">Powered by <a href="http://kin.klever.net/sitecing/" title="site-C-ing">site-C-ing</a>.</div> |
171 | </body> | 172 | </body> |
172 | </html> | 173 | </html> |
173 | <%method void handle_generic_exception() %> | 174 | <%method void handle_generic_exception() %> |
174 | <div class="exception-generic"> | 175 | <div class="exception-generic"> |
175 | <h1>exception caught while running component '<code><% component %></code>'</h1> | 176 | <h1>exception caught while running component '<code><% component %></code>'</h1> |
176 | <dl class="exception-props"> | 177 | <dl class="exception-props"> |
177 | <dt><code>typeid(<em>e</em>).name()</code></dt> | 178 | <dt><code>typeid(<em>e</em>).name()</code></dt> |
178 | % int destat; | 179 | % int destat; |
179 | % char *demangled = abi::__cxa_demangle(typeid(*exception_caught).name(),NULL,NULL,&destat); | 180 | % char *demangled = abi::__cxa_demangle(typeid(*exception_caught).name(),NULL,NULL,&destat); |
180 | <dd><code><% destat?typeid(*exception_caught).name():demangled %></code></dd> | 181 | <dd><code><% destat?typeid(*exception_caught).name():demangled %></code></dd> |
181 | % if(!destat) free(demangled); | 182 | % if(!destat) free(demangled); |
182 | <dt><code><em>e</em>.what()</code></dt> | 183 | <dt><code><em>e</em>.what()</code></dt> |
183 | <dd><% message %></dd> | 184 | <dd><% message %></dd> |
184 | % if(typeid(*exception_caught)==typeid(konforka::exception&)) { | 185 | % if(typeid(*exception_caught)==typeid(konforka::exception&)) { |
185 | % konforka::exception* ke = (konforka::exception*)exception_caught; | 186 | % konforka::exception* ke = (konforka::exception*)exception_caught; |
186 | <dt><code><em>e</em>.where()</code></dt> | 187 | <dt><code><em>e</em>.where()</code></dt> |
187 | <dd><code> | 188 | <dd><code> |
188 | % if(ke->_where.line<0) { | 189 | % if(ke->_where.line<0) { |
189 | <% ke->where() %> | 190 | <% ke->where() %> |
190 | % }else{ | 191 | % }else{ |
191 | <% strip_roots(ke->_where.file) %>:<% ke->_where.line %> [<% ke->_where.function %>] | 192 | <% strip_roots(ke->_where.file) %>:<% ke->_where.line %> [<% ke->_where.function %>] |
192 | % } | 193 | % } |
193 | </code></dd> | 194 | </code></dd> |
194 | % } | 195 | % } |
195 | </dl> | 196 | </dl> |
196 | % if(typeid(*exception_caught)==typeid(konforka::exception&)) { | 197 | % if(typeid(*exception_caught)==typeid(konforka::exception&)) { |
197 | % konforka::exception* ke = (konforka::exception*)exception_caught; | 198 | % konforka::exception* ke = (konforka::exception*)exception_caught; |
198 | % if(ke->_where.line>=0) { | 199 | % if(ke->_where.line>=0) { |
199 | % report_error(ke->_where.file,ke->_where.line,ke->what()); | 200 | % report_error(ke->_where.file,ke->_where.line,ke->what()); |
200 | % } | 201 | % } |
201 | % if(!ke->_seen.empty()) { | 202 | % if(!ke->_seen.empty()) { |
202 | <h2>seen at:</h2> | 203 | <h2>seen at:</h2> |
203 | <div class="backtrace"> | 204 | <div class="backtrace"> |
204 | % for(list<konforka::code_point>::const_iterator i=ke->_seen.begin();i!=ke->_seen.end();++i) { | 205 | % for(list<konforka::code_point>::const_iterator i=ke->_seen.begin();i!=ke->_seen.end();++i) { |
205 | % if(i->line>=0) { | 206 | % if(i->line>=0) { |
206 | % report_error(i->file,i->line,i->function); | 207 | % report_error(i->file,i->line,i->function); |
207 | % } | 208 | % } |
208 | % } | 209 | % } |
209 | </div> | 210 | </div> |
210 | % } | 211 | % } |
211 | % } | 212 | % } |
212 | </div> | 213 | </div> |
213 | </%method> | 214 | </%method> |
214 | <%method void handle_preprocess_error() %> | 215 | <%method void handle_preprocess_error() %> |
215 | <div class="exception-preprocess"> | 216 | <div class="exception-preprocess"> |
216 | <h1>error preprocessing component '<code><% component %></code>'</h1> | 217 | <h1>error preprocessing component '<code><% component %></code>'</h1> |
217 | % report_error(root_source+component,line_number,message); | 218 | % report_error(root_source+component,line_number,message); |
218 | </div> | 219 | </div> |
219 | </%method> | 220 | </%method> |
220 | <%method void handle_compile_error() %> | 221 | <%method void handle_compile_error() %> |
221 | <div class="exception-compile"> | 222 | <div class="exception-compile"> |
222 | <h1>error compiling component '<code><% component %></code>'</h1> | 223 | <h1>error compiling component '<code><% component %></code>'</h1> |
223 | <%code> | 224 | <%code> |
224 | ifstream err((root_intermediate+component+".stderr").c_str(),ios::in); | 225 | ifstream err((root_intermediate+component+".stderr").c_str(),ios::in); |
225 | if(err.bad()) { | 226 | if(err.bad()) { |
226 | <%output> | 227 | <%output> |
227 | Failed to access compiler output | 228 | Failed to access compiler output |
228 | </%output> | 229 | </%output> |
229 | }else{ | 230 | }else{ |
230 | string cumulative; | 231 | string cumulative; |
231 | string error_file; | 232 | string error_file; |
232 | long error_line = -1; | 233 | long error_line = -1; |
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++) { |
292 | ifs.ignore(65536,'\n'); | 293 | ifs.ignore(65536,'\n'); |
293 | } | 294 | } |
294 | if(ifs.eof()) { | 295 | if(ifs.eof()) { |
295 | // TODO: no such line in file | 296 | // TODO: no such line in file |
296 | }else{ | 297 | }else{ |
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> <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> <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> |
346 | % /* vim:set ft=sitecing: */ | 347 | % /* vim:set ft=sitecing: */ |
diff --git a/configure.ac b/configure.ac index a8aa142..fde326b 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -1,89 +1,93 @@ | |||
1 | AC_INIT([sitecing], [0.0.1], [sitecing-bugs@klever.net]) | 1 | AC_INIT([sitecing], [0.0.1], [sitecing-bugs@klever.net]) |
2 | AC_CONFIG_SRCDIR([include/sitecing/sitecing_parser.h]) | 2 | AC_CONFIG_SRCDIR([include/sitecing/sitecing_parser.h]) |
3 | AC_CONFIG_HEADER([config.h]) | 3 | AC_CONFIG_HEADER([config.h]) |
4 | AM_INIT_AUTOMAKE([dist-bzip2]) | 4 | AM_INIT_AUTOMAKE([dist-bzip2]) |
5 | 5 | ||
6 | AC_PROG_INSTALL | 6 | AC_PROG_INSTALL |
7 | AC_PROG_AWK | 7 | AC_PROG_AWK |
8 | AC_PROG_CXX | 8 | AC_PROG_CXX |
9 | AC_PROG_CC | 9 | AC_PROG_CC |
10 | AM_PROG_LEX | 10 | AM_PROG_LEX |
11 | AC_PROG_LIBTOOL | 11 | AC_PROG_LIBTOOL |
12 | 12 | ||
13 | AC_HEADER_STDC | 13 | AC_HEADER_STDC |
14 | AC_CHECK_HEADERS([stdlib.h unistd.h]) | 14 | AC_CHECK_HEADERS([stdlib.h unistd.h]) |
15 | 15 | ||
16 | AC_C_CONST | 16 | AC_C_CONST |
17 | 17 | ||
18 | AC_FUNC_MALLOC | 18 | AC_FUNC_MALLOC |
19 | AC_FUNC_REALLOC | 19 | AC_FUNC_REALLOC |
20 | 20 | ||
21 | AC_WITH_PKGCONFIG | 21 | AC_WITH_PKGCONFIG |
22 | 22 | ||
23 | PKG_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 | |||
23 | PKG_CHECK_MODULES([KINGATE],[kingate >= 0.0.1],,[ | 27 | PKG_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 | ]) |
26 | HAVE_FCGI=false | 30 | HAVE_FCGI=false |
27 | HAVE_PLAINCGI=false | 31 | HAVE_PLAINCGI=false |
28 | PKG_CHECK_MODULES([KINGATE_FCGI],[kingate-fcgi >= 0.0.1],[ | 32 | PKG_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 | ]) |
33 | PKG_CHECK_MODULES([KINGATE_PLAINCGI],[kingate-plaincgi >= 0.0.1],[ | 37 | PKG_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 | ]) |
38 | if ! (${HAVE_FCGI} || ${HAVE_PLAINCGI}) ; then | 42 | if ! (${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]) |
40 | fi | 44 | fi |
41 | AM_CONDITIONAL([HAVE_FCGI],[${HAVE_FCGI}]) | 45 | AM_CONDITIONAL([HAVE_FCGI],[${HAVE_FCGI}]) |
42 | AM_CONDITIONAL([HAVE_PLAINCGI],[${HAVE_PLAINCGI}]) | 46 | AM_CONDITIONAL([HAVE_PLAINCGI],[${HAVE_PLAINCGI}]) |
43 | 47 | ||
44 | PKG_CHECK_MODULES([DOTCONF],[dotconf],,[ | 48 | PKG_CHECK_MODULES([DOTCONF],[dotconf],,[ |
45 | AC_MSG_ERROR([no dotconf library found]) | 49 | AC_MSG_ERROR([no dotconf library found]) |
46 | ]) | 50 | ]) |
47 | 51 | ||
48 | AC_WITH_PCRE([ | 52 | AC_WITH_PCRE([ |
49 | AC_WITH_PCREPP(,[ | 53 | AC_WITH_PCREPP(,[ |
50 | AC_MSG_ERROR([no pcre++ library found]) | 54 | AC_MSG_ERROR([no pcre++ library found]) |
51 | ]) | 55 | ]) |
52 | ],[ | 56 | ],[ |
53 | AC_MSG_ERROR([no pcre library found]) | 57 | AC_MSG_ERROR([no pcre library found]) |
54 | ]) | 58 | ]) |
55 | 59 | ||
56 | AC_CHECK_FUNC([dlopen],,[ | 60 | AC_CHECK_FUNC([dlopen],,[ |
57 | AC_CHECK_LIB([dl],[dlopen],,[ | 61 | AC_CHECK_LIB([dl],[dlopen],,[ |
58 | AC_MSG_ERROR([no dlopen library found]) | 62 | AC_MSG_ERROR([no dlopen library found]) |
59 | ]) | 63 | ]) |
60 | ]) | 64 | ]) |
61 | 65 | ||
62 | AC_PATH_PROG([XSLTPROC],[xsltproc],[true]) | 66 | AC_PATH_PROG([XSLTPROC],[xsltproc],[true]) |
63 | 67 | ||
64 | WANT_DOXYGEN="yes" | 68 | WANT_DOXYGEN="yes" |
65 | AC_ARG_ENABLE([doxygen], | 69 | AC_ARG_ENABLE([doxygen], |
66 | AC_HELP_STRING([--disable-doxygen],[do not generate documentation]), | 70 | AC_HELP_STRING([--disable-doxygen],[do not generate documentation]), |
67 | [ | 71 | [ |
68 | test "${enableval}" = "no" && WANT_DOXYGEN="no" | 72 | test "${enableval}" = "no" && WANT_DOXYGEN="no" |
69 | ] | 73 | ] |
70 | ) | 74 | ) |
71 | if test "${WANT_DOXYGEN}" = "yes" ; then | 75 | if test "${WANT_DOXYGEN}" = "yes" ; then |
72 | AC_WITH_DOXYGEN | 76 | AC_WITH_DOXYGEN |
73 | AC_WITH_DOT | 77 | AC_WITH_DOT |
74 | else | 78 | else |
75 | AM_CONDITIONAL([HAVE_DOXYGEN],[false]) | 79 | AM_CONDITIONAL([HAVE_DOXYGEN],[false]) |
76 | AM_CONDITIONAL([HAVE_DOT],[false]) | 80 | AM_CONDITIONAL([HAVE_DOT],[false]) |
77 | fi | 81 | fi |
78 | 82 | ||
79 | AC_CONFIG_FILES([ | 83 | AC_CONFIG_FILES([ |
80 | Makefile | 84 | Makefile |
81 | Doxyfile | 85 | Doxyfile |
82 | sitecing.pc | 86 | sitecing.pc |
83 | include/Makefile | 87 | include/Makefile |
84 | lib/Makefile | 88 | lib/Makefile |
85 | share/Makefile | 89 | share/Makefile |
86 | src/Makefile | 90 | src/Makefile |
87 | components/Makefile | 91 | components/Makefile |
88 | ]) | 92 | ]) |
89 | AC_OUTPUT | 93 | AC_OUTPUT |
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,341 +1,260 @@ | |||
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 | ||
13 | namespace sitecing { | 14 | namespace 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 | /** |
92 | * @todo TODO: wish I could remember the details -- document me. | 76 | * @todo TODO: wish I could remember the details -- document me. |
93 | */ | 77 | */ |
94 | void lock(); | 78 | void lock(); |
95 | /** | 79 | /** |
96 | * Release the lock obtained. | 80 | * Release the lock obtained. |
97 | */ | 81 | */ |
98 | void unlock(); | 82 | void unlock(); |
99 | }; | 83 | }; |
100 | 84 | ||
101 | /** | 85 | /** |
102 | * The pid file. Removed at object destruction. | 86 | * The pid file. Removed at object destruction. |
103 | */ | 87 | */ |
104 | class pid_file { | 88 | class pid_file { |
105 | public: | 89 | public: |
106 | /** | 90 | /** |
107 | * The file name. | 91 | * The file name. |
108 | */ | 92 | */ |
109 | string file_name; | 93 | string file_name; |
110 | /** | 94 | /** |
111 | * Do we unlink the file after we're done? | 95 | * Do we unlink the file after we're done? |
112 | */ | 96 | */ |
113 | bool unlink_pid; | 97 | bool unlink_pid; |
114 | 98 | ||
115 | pid_file() | 99 | pid_file() |
116 | : unlink_pid(false) { } | 100 | : unlink_pid(false) { } |
117 | ~pid_file() { unlink(); } | 101 | ~pid_file() { unlink(); } |
118 | 102 | ||
119 | /** | 103 | /** |
120 | * @param f file name. | 104 | * @param f file name. |
121 | * @param u whether we want to unlink the file. | 105 | * @param u whether we want to unlink the file. |
122 | */ | 106 | */ |
123 | void set(const string& f,bool u=true); | 107 | void set(const string& f,bool u=true); |
124 | /** | 108 | /** |
125 | * Unlink the file if we wanted to in the first place. | 109 | * Unlink the file if we wanted to in the first place. |
126 | */ | 110 | */ |
127 | void unlink(); | 111 | void unlink(); |
128 | }; | 112 | }; |
129 | 113 | ||
130 | /** | 114 | /** |
131 | * The semaphore object. | 115 | * The semaphore object. |
132 | */ | 116 | */ |
133 | class semaphore { | 117 | class semaphore { |
134 | public: | 118 | public: |
135 | /** | 119 | /** |
136 | * The semaphore id. | 120 | * The semaphore id. |
137 | */ | 121 | */ |
138 | int semid; | 122 | int semid; |
139 | 123 | ||
140 | semaphore() | 124 | semaphore() |
141 | : semid(-1) { } | 125 | : semid(-1) { } |
142 | /** | 126 | /** |
143 | * @param sid semaphore id. | 127 | * @param sid semaphore id. |
144 | */ | 128 | */ |
145 | semaphore(int sid) | 129 | semaphore(int sid) |
146 | : semid(sid) { } | 130 | : semid(sid) { } |
147 | ~semaphore() { | 131 | ~semaphore() { |
148 | deinit(); | 132 | deinit(); |
149 | } | 133 | } |
150 | 134 | ||
151 | /** | 135 | /** |
152 | * Init semaphore. | 136 | * Init semaphore. |
153 | */ | 137 | */ |
154 | void init(); | 138 | void init(); |
155 | /** | 139 | /** |
156 | * Undo the init. | 140 | * Undo the init. |
157 | */ | 141 | */ |
158 | void deinit(); | 142 | void deinit(); |
159 | 143 | ||
160 | /** | 144 | /** |
161 | * Semaphore on. | 145 | * Semaphore on. |
162 | */ | 146 | */ |
163 | void on(); | 147 | void on(); |
164 | /** | 148 | /** |
165 | * Semaphore off. | 149 | * Semaphore off. |
166 | */ | 150 | */ |
167 | void off(); | 151 | void off(); |
168 | }; | 152 | }; |
169 | 153 | ||
170 | /** | 154 | /** |
171 | * The semaphor lock object, released at object destruction. | 155 | * The semaphor lock object, released at object destruction. |
172 | */ | 156 | */ |
173 | class semaphore_lock { | 157 | class semaphore_lock { |
174 | public: | 158 | public: |
175 | /** | 159 | /** |
176 | * Pointer to the semaphore we're operating on. | 160 | * Pointer to the semaphore we're operating on. |
177 | */ | 161 | */ |
178 | semaphore* sem; | 162 | semaphore* sem; |
179 | /** | 163 | /** |
180 | * Whether it is locked. | 164 | * Whether it is locked. |
181 | */ | 165 | */ |
182 | bool locked; | 166 | bool locked; |
183 | 167 | ||
184 | semaphore_lock() | 168 | semaphore_lock() |
185 | : sem(NULL), locked(false) {} | 169 | : sem(NULL), locked(false) {} |
186 | /** | 170 | /** |
187 | * @param s pointer to the semaphore. | 171 | * @param s pointer to the semaphore. |
188 | * @param l lock at creation? | 172 | * @param l lock at creation? |
189 | */ | 173 | */ |
190 | semaphore_lock(semaphore* s,bool l=true) | 174 | semaphore_lock(semaphore* s,bool l=true) |
191 | : sem(s), locked(false) { | 175 | : sem(s), locked(false) { |
192 | if(l) lock(); | 176 | if(l) lock(); |
193 | } | 177 | } |
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() { |
323 | if(autopop) | 242 | if(autopop) |
324 | popdir(); | 243 | popdir(); |
325 | } | 244 | } |
326 | 245 | ||
327 | /** | 246 | /** |
328 | * Change into directory. | 247 | * Change into directory. |
329 | * @param td the directory. | 248 | * @param td the directory. |
330 | * @param ap automaticall pop back? | 249 | * @param ap automaticall pop back? |
331 | */ | 250 | */ |
332 | void pushdir(const string& td,bool ap=true); | 251 | void pushdir(const string& td,bool ap=true); |
333 | /** | 252 | /** |
334 | * Change to the saved directory. | 253 | * Change to the saved directory. |
335 | */ | 254 | */ |
336 | void popdir(); | 255 | void popdir(); |
337 | }; | 256 | }; |
338 | 257 | ||
339 | } | 258 | } |
340 | 259 | ||
341 | #endif /* __SITECING_SITECING_UTIL_H */ | 260 | #endif /* __SITECING_SITECING_UTIL_H */ |
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,344 +1,345 @@ | |||
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 | ||
20 | namespace sitecing { | 21 | namespace 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 { |
59 | string nos = strip_suffix(noro,pp_targets[ppt]); | 60 | string nos = strip_suffix(noro,pp_targets[ppt]); |
60 | deps.push_back(root_source+nos); // depends on the source | 61 | deps.push_back(root_source+nos); // depends on the source |
61 | ifstream imports((root_intermediate+nos+".imports").c_str(),ios::in); | 62 | ifstream imports((root_intermediate+nos+".imports").c_str(),ios::in); |
62 | if(imports.good()) { | 63 | if(imports.good()) { |
63 | string str; | 64 | string str; |
64 | while(!imports.eof()) { | 65 | while(!imports.eof()) { |
65 | imports >> str; | 66 | imports >> str; |
66 | if(!str.empty()) | 67 | if(!str.empty()) |
67 | deps.push_back(root_intermediate+str+".classname"); | 68 | deps.push_back(root_intermediate+str+".classname"); |
68 | } | 69 | } |
69 | } | 70 | } |
70 | ifstream ancestors((root_intermediate+nos+".ancestors").c_str(),ios::in); | 71 | ifstream ancestors((root_intermediate+nos+".ancestors").c_str(),ios::in); |
71 | if(ancestors.good()) { | 72 | if(ancestors.good()) { |
72 | string str; | 73 | string str; |
73 | while(!ancestors.eof()) { | 74 | while(!ancestors.eof()) { |
74 | ancestors >> str; | 75 | ancestors >> str; |
75 | if(!str.empty()) | 76 | if(!str.empty()) |
76 | deps.push_back(root_intermediate+str+".classname"); | 77 | deps.push_back(root_intermediate+str+".classname"); |
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,474 +1,475 @@ | |||
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 | ||
15 | namespace sitecing { | 16 | namespace 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; |
33 | }; | 34 | }; |
34 | 35 | ||
35 | static DOTCONF_CB(dco_root_source) { dc_context *dcc = (dc_context*)ctx; | 36 | static DOTCONF_CB(dco_root_source) { dc_context *dcc = (dc_context*)ctx; |
36 | dcc->cf->root_source = cmd->data.str; | 37 | dcc->cf->root_source = cmd->data.str; |
37 | dcc->cf->flags |= configuration::flag_root_source; | 38 | dcc->cf->flags |= configuration::flag_root_source; |
38 | return NULL; | 39 | return NULL; |
39 | } | 40 | } |
40 | static DOTCONF_CB(dco_root_intermediate) { dc_context *dcc = (dc_context*)ctx; | 41 | static DOTCONF_CB(dco_root_intermediate) { dc_context *dcc = (dc_context*)ctx; |
41 | dcc->cf->root_intermediate = cmd->data.str; | 42 | dcc->cf->root_intermediate = cmd->data.str; |
42 | dcc->cf->flags |= configuration::flag_root_intermediate; | 43 | dcc->cf->flags |= configuration::flag_root_intermediate; |
43 | return NULL; | 44 | return NULL; |
44 | } | 45 | } |
45 | static DOTCONF_CB(dco_root_so) { dc_context *dcc = (dc_context*)ctx; | 46 | static DOTCONF_CB(dco_root_so) { dc_context *dcc = (dc_context*)ctx; |
46 | dcc->cf->root_so = cmd->data.str; | 47 | dcc->cf->root_so = cmd->data.str; |
47 | dcc->cf->flags |= configuration::flag_root_so; | 48 | dcc->cf->flags |= configuration::flag_root_so; |
48 | return NULL; | 49 | return NULL; |
49 | } | 50 | } |
50 | static DOTCONF_CB(dco_listen_socket) { dc_context *dcc = (dc_context*)ctx; | 51 | static DOTCONF_CB(dco_listen_socket) { dc_context *dcc = (dc_context*)ctx; |
51 | dcc->cf->listen_socket = cmd->data.str; | 52 | dcc->cf->listen_socket = cmd->data.str; |
52 | dcc->cf->flags |= configuration::flag_listen_socket; | 53 | dcc->cf->flags |= configuration::flag_listen_socket; |
53 | return NULL; | 54 | return NULL; |
54 | } | 55 | } |
55 | static DOTCONF_CB(dco_rc_file_name) { dc_context *dcc = (dc_context*)ctx; | 56 | static DOTCONF_CB(dco_rc_file_name) { dc_context *dcc = (dc_context*)ctx; |
56 | dcc->cf->rc_file_name = cmd->data.str; | 57 | dcc->cf->rc_file_name = cmd->data.str; |
57 | dcc->cf->flags |= configuration::flag_rc_file_name; | 58 | dcc->cf->flags |= configuration::flag_rc_file_name; |
58 | return NULL; | 59 | return NULL; |
59 | } | 60 | } |
60 | static DOTCONF_CB(dco_min_children) { dc_context *dcc = (dc_context*)ctx; | 61 | static DOTCONF_CB(dco_min_children) { dc_context *dcc = (dc_context*)ctx; |
61 | if(cmd->data.value>=MAX_SITECING_SCOREBOARD_SLOTS) | 62 | if(cmd->data.value>=MAX_SITECING_SCOREBOARD_SLOTS) |
62 | return "MinChildren is too big"; | 63 | return "MinChildren is too big"; |
63 | dcc->cf->min_children = cmd->data.value; | 64 | dcc->cf->min_children = cmd->data.value; |
64 | dcc->cf->flags |= configuration::flag_min_children; | 65 | dcc->cf->flags |= configuration::flag_min_children; |
65 | return NULL; | 66 | return NULL; |
66 | } | 67 | } |
67 | static DOTCONF_CB(dco_max_children) { dc_context *dcc = (dc_context*)ctx; | 68 | static DOTCONF_CB(dco_max_children) { dc_context *dcc = (dc_context*)ctx; |
68 | if(cmd->data.value>=MAX_SITECING_SCOREBOARD_SLOTS) | 69 | if(cmd->data.value>=MAX_SITECING_SCOREBOARD_SLOTS) |
69 | return "MaxChildren is too big"; | 70 | return "MaxChildren is too big"; |
70 | dcc->cf->max_children = cmd->data.value; | 71 | dcc->cf->max_children = cmd->data.value; |
71 | dcc->cf->flags |= configuration::flag_max_children; | 72 | dcc->cf->flags |= configuration::flag_max_children; |
72 | return NULL; | 73 | return NULL; |
73 | } | 74 | } |
74 | static DOTCONF_CB(dco_min_spare_children) { dc_context *dcc = (dc_context*)ctx; | 75 | static DOTCONF_CB(dco_min_spare_children) { dc_context *dcc = (dc_context*)ctx; |
75 | if(cmd->data.value>=MAX_SITECING_SCOREBOARD_SLOTS) | 76 | if(cmd->data.value>=MAX_SITECING_SCOREBOARD_SLOTS) |
76 | return "MinSpareChildren is too big"; | 77 | return "MinSpareChildren is too big"; |
77 | dcc->cf->min_spare_children = cmd->data.value; | 78 | dcc->cf->min_spare_children = cmd->data.value; |
78 | dcc->cf->flags |= configuration::flag_min_spare_children; | 79 | dcc->cf->flags |= configuration::flag_min_spare_children; |
79 | return NULL; | 80 | return NULL; |
80 | } | 81 | } |
81 | static DOTCONF_CB(dco_max_spare_children) { dc_context *dcc = (dc_context*)ctx; | 82 | static DOTCONF_CB(dco_max_spare_children) { dc_context *dcc = (dc_context*)ctx; |
82 | if(cmd->data.value>=MAX_SITECING_SCOREBOARD_SLOTS) | 83 | if(cmd->data.value>=MAX_SITECING_SCOREBOARD_SLOTS) |
83 | return "MaxSpareChildren is too big"; | 84 | return "MaxSpareChildren is too big"; |
84 | dcc->cf->max_spare_children = cmd->data.value; | 85 | dcc->cf->max_spare_children = cmd->data.value; |
85 | dcc->cf->flags |= configuration::flag_max_spare_children; | 86 | dcc->cf->flags |= configuration::flag_max_spare_children; |
86 | return NULL; | 87 | return NULL; |
87 | } | 88 | } |
88 | static DOTCONF_CB(dco_requests_per_child) { dc_context *dcc = (dc_context*)ctx; | 89 | static DOTCONF_CB(dco_requests_per_child) { dc_context *dcc = (dc_context*)ctx; |
89 | dcc->cf->requests_per_child = cmd->data.value; | 90 | dcc->cf->requests_per_child = cmd->data.value; |
90 | dcc->cf->flags |= configuration::flag_requests_per_child; | 91 | dcc->cf->flags |= configuration::flag_requests_per_child; |
91 | return NULL; | 92 | return NULL; |
92 | } | 93 | } |
93 | static DOTCONF_CB(dco_multi_process) { dc_context *dcc = (dc_context*)ctx; | 94 | static DOTCONF_CB(dco_multi_process) { dc_context *dcc = (dc_context*)ctx; |
94 | dcc->cf->multi_process = cmd->data.value; | 95 | dcc->cf->multi_process = cmd->data.value; |
95 | dcc->cf->flags |= configuration::flag_multi_process; | 96 | dcc->cf->flags |= configuration::flag_multi_process; |
96 | return NULL; | 97 | return NULL; |
97 | } | 98 | } |
98 | static DOTCONF_CB(dco_user) { dc_context *dcc = (dc_context*)ctx; | 99 | static DOTCONF_CB(dco_user) { dc_context *dcc = (dc_context*)ctx; |
99 | dcc->cf->user = cmd->data.str; | 100 | dcc->cf->user = cmd->data.str; |
100 | dcc->cf->flags |= configuration::flag_user; | 101 | dcc->cf->flags |= configuration::flag_user; |
101 | return NULL; | 102 | return NULL; |
102 | } | 103 | } |
103 | static DOTCONF_CB(dco_group) { dc_context *dcc = (dc_context*)ctx; | 104 | static DOTCONF_CB(dco_group) { dc_context *dcc = (dc_context*)ctx; |
104 | dcc->cf->group = cmd->data.str; | 105 | dcc->cf->group = cmd->data.str; |
105 | dcc->cf->flags |= configuration::flag_group; | 106 | dcc->cf->flags |= configuration::flag_group; |
106 | return NULL; | 107 | return NULL; |
107 | } | 108 | } |
108 | static DOTCONF_CB(dco_chroot) { dc_context *dcc = (dc_context*)ctx; | 109 | static DOTCONF_CB(dco_chroot) { dc_context *dcc = (dc_context*)ctx; |
109 | dcc->cf->chroot = cmd->data.str; | 110 | dcc->cf->chroot = cmd->data.str; |
110 | dcc->cf->flags |= configuration::flag_chroot; | 111 | dcc->cf->flags |= configuration::flag_chroot; |
111 | return NULL; | 112 | return NULL; |
112 | } | 113 | } |
113 | static DOTCONF_CB(dco_pid_file) { dc_context *dcc = (dc_context*)ctx; | 114 | static DOTCONF_CB(dco_pid_file) { dc_context *dcc = (dc_context*)ctx; |
114 | dcc->cf->pid_file = cmd->data.str; | 115 | dcc->cf->pid_file = cmd->data.str; |
115 | dcc->cf->flags |= configuration::flag_pid_file; | 116 | dcc->cf->flags |= configuration::flag_pid_file; |
116 | return NULL; | 117 | return NULL; |
117 | } | 118 | } |
118 | static DOTCONF_CB(dco_daemonize) { dc_context *dcc = (dc_context*) ctx; | 119 | static DOTCONF_CB(dco_daemonize) { dc_context *dcc = (dc_context*) ctx; |
119 | dcc->cf->daemonize = cmd->data.value; | 120 | dcc->cf->daemonize = cmd->data.value; |
120 | dcc->cf->flags |= configuration::flag_daemonize; | 121 | dcc->cf->flags |= configuration::flag_daemonize; |
121 | return NULL; | 122 | return NULL; |
122 | } | 123 | } |
123 | 124 | ||
124 | static DOTCONF_CB(dco_path) { dc_context *dcc = (dc_context*)ctx; | 125 | static DOTCONF_CB(dco_path) { dc_context *dcc = (dc_context*)ctx; |
125 | string path = cmd->data.str; | 126 | string path = cmd->data.str; |
126 | if(path[path.length()-1]=='>') | 127 | if(path[path.length()-1]=='>') |
127 | path.erase(path.length()-1); | 128 | path.erase(path.length()-1); |
128 | // TODO: normalize path | 129 | // TODO: normalize path |
129 | dcc->co.push_front(&(dcc->cf->specs[path])); | 130 | dcc->co.push_front(&(dcc->cf->specs[path])); |
130 | dcc->ctx = DCC_PATH; // TODO: stack it, instead | 131 | dcc->ctx = DCC_PATH; // TODO: stack it, instead |
131 | return NULL; | 132 | return NULL; |
132 | } | 133 | } |
133 | static DOTCONF_CB(dco__path) { dc_context *dcc = (dc_context*)ctx; | 134 | static DOTCONF_CB(dco__path) { dc_context *dcc = (dc_context*)ctx; |
134 | dcc->co.pop_front(); | 135 | dcc->co.pop_front(); |
135 | assert(dcc->co.size()); | 136 | assert(dcc->co.size()); |
136 | dcc->ctx = DCC_ROOT; // TODO: stack it, instead | 137 | dcc->ctx = DCC_ROOT; // TODO: stack it, instead |
137 | return NULL; | 138 | return NULL; |
138 | } | 139 | } |
139 | 140 | ||
140 | static DOTCONF_CB(dco_skeleton) { dc_context *dcc = (dc_context*)ctx; | 141 | static DOTCONF_CB(dco_skeleton) { dc_context *dcc = (dc_context*)ctx; |
141 | dcc->co.front()->skeleton = cmd->data.str; | 142 | dcc->co.front()->skeleton = cmd->data.str; |
142 | dcc->co.front()->flags |= config_options::flag_skeleton; | 143 | dcc->co.front()->flags |= config_options::flag_skeleton; |
143 | return NULL; | 144 | return NULL; |
144 | } | 145 | } |
145 | static DOTCONF_CB(dco_cpp_flags) { dc_context *dcc = (dc_context*)ctx; | 146 | static DOTCONF_CB(dco_cpp_flags) { dc_context *dcc = (dc_context*)ctx; |
146 | for(char **arg=cmd->data.list;*arg;arg++) | 147 | for(char **arg=cmd->data.list;*arg;arg++) |
147 | dcc->co.front()->cpp_flags.push_back(*arg); | 148 | dcc->co.front()->cpp_flags.push_back(*arg); |
148 | dcc->co.front()->flags |= config_options::flag_cpp_flags; | 149 | dcc->co.front()->flags |= config_options::flag_cpp_flags; |
149 | return NULL; | 150 | return NULL; |
150 | } | 151 | } |
151 | static DOTCONF_CB(dco_ld_flags) { dc_context *dcc = (dc_context*)ctx; | 152 | static DOTCONF_CB(dco_ld_flags) { dc_context *dcc = (dc_context*)ctx; |
152 | for(char **arg=cmd->data.list;*arg;arg++) | 153 | for(char **arg=cmd->data.list;*arg;arg++) |
153 | dcc->co.front()->ld_flags.push_back(*arg); | 154 | dcc->co.front()->ld_flags.push_back(*arg); |
154 | dcc->co.front()->flags |= config_options::flag_ld_flags; | 155 | dcc->co.front()->flags |= config_options::flag_ld_flags; |
155 | return NULL; | 156 | return NULL; |
156 | } | 157 | } |
157 | static DOTCONF_CB(dco_intermediate_deps) { dc_context *dcc = (dc_context*) ctx; | 158 | static DOTCONF_CB(dco_intermediate_deps) { dc_context *dcc = (dc_context*) ctx; |
158 | for(char **arg=cmd->data.list;*arg;arg++) | 159 | for(char **arg=cmd->data.list;*arg;arg++) |
159 | dcc->co.front()->intermediate_deps.push_back(*arg); | 160 | dcc->co.front()->intermediate_deps.push_back(*arg); |
160 | dcc->co.front()->flags |= config_options::flag_intermediate_deps; | 161 | dcc->co.front()->flags |= config_options::flag_intermediate_deps; |
161 | return NULL; | 162 | return NULL; |
162 | } | 163 | } |
163 | static DOTCONF_CB(dco_so_deps) { dc_context *dcc = (dc_context*) ctx; | 164 | static DOTCONF_CB(dco_so_deps) { dc_context *dcc = (dc_context*) ctx; |
164 | for(char **arg=cmd->data.list;*arg;arg++) | 165 | for(char **arg=cmd->data.list;*arg;arg++) |
165 | dcc->co.front()->so_deps.push_back(*arg); | 166 | dcc->co.front()->so_deps.push_back(*arg); |
166 | dcc->co.front()->flags |= config_options::flag_so_deps; | 167 | dcc->co.front()->flags |= config_options::flag_so_deps; |
167 | return NULL; | 168 | return NULL; |
168 | } | 169 | } |
169 | static DOTCONF_CB(dco_build) { dc_context *dcc = (dc_context*)ctx; | 170 | static DOTCONF_CB(dco_build) { dc_context *dcc = (dc_context*)ctx; |
170 | dcc->co.front()->build = cmd->data.value; | 171 | dcc->co.front()->build = cmd->data.value; |
171 | dcc->co.front()->flags |= config_options::flag_build; | 172 | dcc->co.front()->flags |= config_options::flag_build; |
172 | return NULL; | 173 | return NULL; |
173 | } | 174 | } |
174 | static DOTCONF_CB(dco_cpp_deps) { dc_context *dcc = (dc_context*)ctx; | 175 | static DOTCONF_CB(dco_cpp_deps) { dc_context *dcc = (dc_context*)ctx; |
175 | dcc->co.front()->cpp_deps = cmd->data.value; | 176 | dcc->co.front()->cpp_deps = cmd->data.value; |
176 | dcc->co.front()->flags |= config_options::flag_cpp_deps; | 177 | dcc->co.front()->flags |= config_options::flag_cpp_deps; |
177 | return NULL; | 178 | return NULL; |
178 | } | 179 | } |
179 | static DOTCONF_CB(dco_exception_handler) { dc_context *dcc = (dc_context*)ctx; | 180 | static DOTCONF_CB(dco_exception_handler) { dc_context *dcc = (dc_context*)ctx; |
180 | dcc->co.front()->exception_handler = cmd->data.str; | 181 | dcc->co.front()->exception_handler = cmd->data.str; |
181 | dcc->co.front()->flags |= config_options::flag_exception_handler; | 182 | dcc->co.front()->flags |= config_options::flag_exception_handler; |
182 | return NULL; | 183 | return NULL; |
183 | } | 184 | } |
184 | static DOTCONF_CB(dco_http_status_handler) { dc_context *dcc = (dc_context*)ctx; | 185 | static DOTCONF_CB(dco_http_status_handler) { dc_context *dcc = (dc_context*)ctx; |
185 | if(cmd->arg_count!=2) | 186 | if(cmd->arg_count!=2) |
186 | return "Invalid number of arguments"; | 187 | return "Invalid number of arguments"; |
187 | dcc->co.front()->http_status_handlers[cmd->data.list[0]] = cmd->data.list[1]; | 188 | dcc->co.front()->http_status_handlers[cmd->data.list[0]] = cmd->data.list[1]; |
188 | dcc->co.front()->flags |= config_options::flag_http_status_handlers; | 189 | dcc->co.front()->flags |= config_options::flag_http_status_handlers; |
189 | return NULL; | 190 | return NULL; |
190 | } | 191 | } |
191 | static DOTCONF_CB(dco_action) { dc_context *dcc = (dc_context*)ctx; | 192 | static DOTCONF_CB(dco_action) { dc_context *dcc = (dc_context*)ctx; |
192 | if(cmd->arg_count<2) | 193 | if(cmd->arg_count<2) |
193 | return "Invalid number of arguments"; | 194 | return "Invalid number of arguments"; |
194 | try { | 195 | try { |
195 | char **arg=cmd->data.list; | 196 | char **arg=cmd->data.list; |
196 | dcc->co.front()->action_handlers.push_back(config_options::action_handler_t(arg[0],arg[1])); | 197 | dcc->co.front()->action_handlers.push_back(config_options::action_handler_t(arg[0],arg[1])); |
197 | for(arg+=2;*arg;arg++) | 198 | for(arg+=2;*arg;arg++) |
198 | dcc->co.front()->action_handlers.back().args.push_back(*arg); | 199 | dcc->co.front()->action_handlers.back().args.push_back(*arg); |
199 | dcc->co.front()->flags |= config_options::flag_action_handlers; | 200 | dcc->co.front()->flags |= config_options::flag_action_handlers; |
200 | }catch(exception& e) { | 201 | }catch(exception& e) { |
201 | return "Error processing Action directive"; // XXX: could be done better | 202 | return "Error processing Action directive"; // XXX: could be done better |
202 | } | 203 | } |
203 | return NULL; | 204 | return NULL; |
204 | } | 205 | } |
205 | static DOTCONF_CB(dco_auto_build_files) { dc_context *dcc = (dc_context*)ctx; | 206 | static DOTCONF_CB(dco_auto_build_files) { dc_context *dcc = (dc_context*)ctx; |
206 | if(!( dcc->cf && dcc->cf->autobuild)) | 207 | if(!( dcc->cf && dcc->cf->autobuild)) |
207 | return NULL; | 208 | return NULL; |
208 | for(char **arg=cmd->data.list;*arg;arg++) | 209 | for(char **arg=cmd->data.list;*arg;arg++) |
209 | dcc->co.front()->auto_build_files.push_back(*arg); | 210 | dcc->co.front()->auto_build_files.push_back(*arg); |
210 | dcc->co.front()->flags |= config_options::flag_auto_build_files; | 211 | dcc->co.front()->flags |= config_options::flag_auto_build_files; |
211 | return NULL; | 212 | return NULL; |
212 | } | 213 | } |
213 | 214 | ||
214 | static const configoption_t dc_options[] = { | 215 | static const configoption_t dc_options[] = { |
215 | { "RootSource", ARG_STR, dco_root_source, NULL, DCC_ROOT }, | 216 | { "RootSource", ARG_STR, dco_root_source, NULL, DCC_ROOT }, |
216 | { "RootIntermediate", ARG_STR, dco_root_intermediate, NULL, DCC_ROOT }, | 217 | { "RootIntermediate", ARG_STR, dco_root_intermediate, NULL, DCC_ROOT }, |
217 | { "RootSO", ARG_STR, dco_root_so, NULL, DCC_ROOT }, | 218 | { "RootSO", ARG_STR, dco_root_so, NULL, DCC_ROOT }, |
218 | { "ListenSocket", ARG_STR, dco_listen_socket, NULL, DCC_ROOT }, | 219 | { "ListenSocket", ARG_STR, dco_listen_socket, NULL, DCC_ROOT }, |
219 | { "RCFileName", ARG_STR, dco_rc_file_name, NULL, DCC_ROOT }, | 220 | { "RCFileName", ARG_STR, dco_rc_file_name, NULL, DCC_ROOT }, |
220 | { "MinChildren", ARG_INT, dco_min_children, NULL, DCC_ROOT }, | 221 | { "MinChildren", ARG_INT, dco_min_children, NULL, DCC_ROOT }, |
221 | { "MaxChildren", ARG_INT, dco_max_children, NULL, DCC_ROOT }, | 222 | { "MaxChildren", ARG_INT, dco_max_children, NULL, DCC_ROOT }, |
222 | { "MinSpareChildren", ARG_INT, dco_min_spare_children, NULL, DCC_ROOT }, | 223 | { "MinSpareChildren", ARG_INT, dco_min_spare_children, NULL, DCC_ROOT }, |
223 | { "MaxSpareChildren", ARG_INT, dco_max_spare_children, NULL, DCC_ROOT }, | 224 | { "MaxSpareChildren", ARG_INT, dco_max_spare_children, NULL, DCC_ROOT }, |
224 | { "RequestsPerChild", ARG_INT, dco_requests_per_child, NULL, DCC_ROOT }, | 225 | { "RequestsPerChild", ARG_INT, dco_requests_per_child, NULL, DCC_ROOT }, |
225 | { "MultiProcess", ARG_TOGGLE, dco_multi_process, NULL, DCC_ROOT }, | 226 | { "MultiProcess", ARG_TOGGLE, dco_multi_process, NULL, DCC_ROOT }, |
226 | { "User", ARG_STR, dco_user, NULL, DCC_ROOT }, | 227 | { "User", ARG_STR, dco_user, NULL, DCC_ROOT }, |
227 | { "Group", ARG_STR, dco_group, NULL, DCC_ROOT }, | 228 | { "Group", ARG_STR, dco_group, NULL, DCC_ROOT }, |
228 | { "Chroot", ARG_STR, dco_chroot, NULL, DCC_ROOT }, | 229 | { "Chroot", ARG_STR, dco_chroot, NULL, DCC_ROOT }, |
229 | { "PidFile", ARG_STR, dco_pid_file, NULL, DCC_ROOT }, | 230 | { "PidFile", ARG_STR, dco_pid_file, NULL, DCC_ROOT }, |
230 | { "Daemonize", ARG_TOGGLE, dco_daemonize, NULL, DCC_ROOT }, | 231 | { "Daemonize", ARG_TOGGLE, dco_daemonize, NULL, DCC_ROOT }, |
231 | { "<Path", ARG_STR, dco_path, NULL, DCC_ROOT }, | 232 | { "<Path", ARG_STR, dco_path, NULL, DCC_ROOT }, |
232 | { "Skeleton", ARG_STR, dco_skeleton, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, | 233 | { "Skeleton", ARG_STR, dco_skeleton, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, |
233 | { "CPPFLAGS", ARG_LIST, dco_cpp_flags, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, | 234 | { "CPPFLAGS", ARG_LIST, dco_cpp_flags, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, |
234 | { "LDFLAGS", ARG_LIST, dco_ld_flags, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, | 235 | { "LDFLAGS", ARG_LIST, dco_ld_flags, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, |
235 | { "Build", ARG_TOGGLE, dco_build, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, | 236 | { "Build", ARG_TOGGLE, dco_build, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, |
236 | { "CPPDeps", ARG_TOGGLE, dco_cpp_deps, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, | 237 | { "CPPDeps", ARG_TOGGLE, dco_cpp_deps, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, |
237 | { "ExceptionHandler", ARG_STR, dco_exception_handler, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, | 238 | { "ExceptionHandler", ARG_STR, dco_exception_handler, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, |
238 | { "HTTPStatusHandler", ARG_LIST, dco_http_status_handler, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, | 239 | { "HTTPStatusHandler", ARG_LIST, dco_http_status_handler, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, |
239 | { "IntermediateDeps", ARG_LIST, dco_intermediate_deps, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, | 240 | { "IntermediateDeps", ARG_LIST, dco_intermediate_deps, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, |
240 | { "SODeps", ARG_LIST, dco_so_deps, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, | 241 | { "SODeps", ARG_LIST, dco_so_deps, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, |
241 | { "Action", ARG_LIST, dco_action, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, | 242 | { "Action", ARG_LIST, dco_action, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, |
242 | { "AutoBuildFiles", ARG_LIST, dco_auto_build_files, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, | 243 | { "AutoBuildFiles", ARG_LIST, dco_auto_build_files, NULL, DCC_ROOT|DCC_PATH|DCC_SCRC }, |
243 | { "</Path>", ARG_NONE, dco__path, NULL, DCC_PATH }, | 244 | { "</Path>", ARG_NONE, dco__path, NULL, DCC_PATH }, |
244 | LAST_OPTION | 245 | LAST_OPTION |
245 | }; | 246 | }; |
246 | 247 | ||
247 | static const char *dc_context_checker(command_t *cmd,unsigned long mask) { | 248 | static const char *dc_context_checker(command_t *cmd,unsigned long mask) { |
248 | dc_context *dcc = (dc_context*)cmd->context; | 249 | dc_context *dcc = (dc_context*)cmd->context; |
249 | if( (mask==CTX_ALL) || ((mask&dcc->ctx)==dcc->ctx) ) | 250 | if( (mask==CTX_ALL) || ((mask&dcc->ctx)==dcc->ctx) ) |
250 | return NULL; | 251 | return NULL; |
251 | return "misplaced option"; | 252 | return "misplaced option"; |
252 | } | 253 | } |
253 | static FUNC_ERRORHANDLER(dc_error_handler) { | 254 | static FUNC_ERRORHANDLER(dc_error_handler) { |
254 | throw konforka::exception(CODEPOINT,string("error parsing config file: ")+msg); | 255 | throw konforka::exception(CODEPOINT,string("error parsing config file: ")+msg); |
255 | } | 256 | } |
256 | 257 | ||
257 | bool loaded_options::is_valid() { | 258 | bool loaded_options::is_valid() { |
258 | struct stat nst; | 259 | struct stat nst; |
259 | if(stat(source_file.c_str(),&nst)) | 260 | if(stat(source_file.c_str(),&nst)) |
260 | return false; | 261 | return false; |
261 | if(st.st_mtime!=nst.st_mtime) | 262 | if(st.st_mtime!=nst.st_mtime) |
262 | return false; | 263 | return false; |
263 | return true; | 264 | return true; |
264 | } | 265 | } |
265 | 266 | ||
266 | loaded_options *configuration::lookup_loaded_options(const string& target) { | 267 | loaded_options *configuration::lookup_loaded_options(const string& target) { |
267 | // we assume 'target' is a directory with trailing slash appended | 268 | // we assume 'target' is a directory with trailing slash appended |
268 | string scrc = root_source+target; | 269 | string scrc = root_source+target; |
269 | if(flags&flag_rc_file_name) | 270 | if(flags&flag_rc_file_name) |
270 | scrc += rc_file_name; | 271 | scrc += rc_file_name; |
271 | else | 272 | else |
272 | scrc += ".scrc"; | 273 | scrc += ".scrc"; |
273 | // TODO: normalize me, anyway. | 274 | // TODO: normalize me, anyway. |
274 | if(access(scrc.c_str(),R_OK)) | 275 | if(access(scrc.c_str(),R_OK)) |
275 | return 0; // TODO FIXME: this approach leaves already loaded .scrcs around in case of removal | 276 | return 0; // TODO FIXME: this approach leaves already loaded .scrcs around in case of removal |
276 | loaded_specs_t::iterator i = loaded_specs.find(target); | 277 | loaded_specs_t::iterator i = loaded_specs.find(target); |
277 | if(i==loaded_specs.end() || !i->second.is_valid()) { | 278 | if(i==loaded_specs.end() || !i->second.is_valid()) { |
278 | if(i!=loaded_specs.end()) | 279 | if(i!=loaded_specs.end()) |
279 | loaded_specs.erase(i); | 280 | loaded_specs.erase(i); |
280 | pair<loaded_specs_t::iterator,bool> ii = loaded_specs.insert(loaded_specs_t::value_type(target,loaded_options())); | 281 | pair<loaded_specs_t::iterator,bool> ii = loaded_specs.insert(loaded_specs_t::value_type(target,loaded_options())); |
281 | assert(ii.first!=loaded_specs.end()); | 282 | assert(ii.first!=loaded_specs.end()); |
282 | ii.first->second.parse(this,scrc); | 283 | ii.first->second.parse(this,scrc); |
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 | } |
442 | 443 | ||
443 | void configuration::parse(const string& cfile) { | 444 | void configuration::parse(const string& cfile) { |
444 | struct dc_context dcc; | 445 | struct dc_context dcc; |
445 | dcc.cf = this; | 446 | dcc.cf = this; |
446 | dcc.ctx = DCC_ROOT; | 447 | dcc.ctx = DCC_ROOT; |
447 | dcc.co.push_front(&root_options()); | 448 | dcc.co.push_front(&root_options()); |
448 | configfile_t *cf = dotconf_create((char*)cfile.c_str(),dc_options,(context_t*)&dcc,CASE_INSENSITIVE); | 449 | configfile_t *cf = dotconf_create((char*)cfile.c_str(),dc_options,(context_t*)&dcc,CASE_INSENSITIVE); |
449 | if(!cf) | 450 | if(!cf) |
450 | throw konforka::exception(CODEPOINT,"failed to dotconf_create()"); | 451 | throw konforka::exception(CODEPOINT,"failed to dotconf_create()"); |
451 | cf->errorhandler = (dotconf_errorhandler_t) dc_error_handler; | 452 | cf->errorhandler = (dotconf_errorhandler_t) dc_error_handler; |
452 | cf->contextchecker = (dotconf_contextchecker_t) dc_context_checker; | 453 | cf->contextchecker = (dotconf_contextchecker_t) dc_context_checker; |
453 | if(!dotconf_command_loop(cf)) | 454 | if(!dotconf_command_loop(cf)) |
454 | throw konforka::exception(CODEPOINT,"failed to dotconf_command_loop()"); | 455 | throw konforka::exception(CODEPOINT,"failed to dotconf_command_loop()"); |
455 | dotconf_cleanup(cf); | 456 | dotconf_cleanup(cf); |
456 | } | 457 | } |
457 | 458 | ||
458 | void loaded_options::parse(configuration *config,const string& cfile) { | 459 | void loaded_options::parse(configuration *config,const string& cfile) { |
459 | struct dc_context dcc; | 460 | struct dc_context dcc; |
460 | dcc.cf = config; | 461 | dcc.cf = config; |
461 | dcc.ctx = DCC_SCRC; | 462 | dcc.ctx = DCC_SCRC; |
462 | dcc.co.push_front(this); | 463 | dcc.co.push_front(this); |
463 | configfile_t *cf = dotconf_create((char*)cfile.c_str(),dc_options,(context_t*)&dcc,CASE_INSENSITIVE); | 464 | configfile_t *cf = dotconf_create((char*)cfile.c_str(),dc_options,(context_t*)&dcc,CASE_INSENSITIVE); |
464 | if(!cf) | 465 | if(!cf) |
465 | throw konforka::exception(CODEPOINT,"failed to dotconf_create()"); | 466 | throw konforka::exception(CODEPOINT,"failed to dotconf_create()"); |
466 | cf->errorhandler = (dotconf_errorhandler_t) dc_error_handler; | 467 | cf->errorhandler = (dotconf_errorhandler_t) dc_error_handler; |
467 | cf->contextchecker = (dotconf_contextchecker_t) dc_context_checker; | 468 | cf->contextchecker = (dotconf_contextchecker_t) dc_context_checker; |
468 | if(!dotconf_command_loop(cf)) | 469 | if(!dotconf_command_loop(cf)) |
469 | throw konforka::exception(CODEPOINT,"failed to dotconf_command_loop()"); | 470 | throw konforka::exception(CODEPOINT,"failed to dotconf_command_loop()"); |
470 | dotconf_cleanup(cf); | 471 | dotconf_cleanup(cf); |
471 | source_file = cfile; | 472 | source_file = cfile; |
472 | stat(cfile.c_str(),&st); // TODO: handle errors? | 473 | stat(cfile.c_str(),&st); // TODO: handle errors? |
473 | } | 474 | } |
474 | } | 475 | } |
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,642 +1,643 @@ | |||
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> |
9 | using namespace std; | 9 | using 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" |
12 | using namespace sitecing; | 13 | using 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 | %% |
34 | 35 | ||
35 | <INITIAL>{ | 36 | <INITIAL>{ |
36 | ^\%\%class{WHITESPACE}+{ | 37 | ^\%\%class{WHITESPACE}+{ |
37 | // TODO: signal error if we already have class name acquired from source. | 38 | // TODO: signal error if we already have class name acquired from source. |
38 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments|modus_operandi::flag_devour_whitespace)); | 39 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments|modus_operandi::flag_devour_whitespace)); |
39 | BEGIN(CLASSLINE); | 40 | BEGIN(CLASSLINE); |
40 | } | 41 | } |
41 | ^\%\%decl{WHITESPACE}+{ | 42 | ^\%\%decl{WHITESPACE}+{ |
42 | modi.push_front(modus_operandi(0)); | 43 | modi.push_front(modus_operandi(0)); |
43 | anchor(); | 44 | anchor(); |
44 | BEGIN(DECLLINE); | 45 | BEGIN(DECLLINE); |
45 | } | 46 | } |
46 | ^\%\%impl{WHITESPACE}+{ | 47 | ^\%\%impl{WHITESPACE}+{ |
47 | modi.push_front(modus_operandi(0)); | 48 | modi.push_front(modus_operandi(0)); |
48 | anchor(); | 49 | anchor(); |
49 | BEGIN(IMPLLINE); | 50 | BEGIN(IMPLLINE); |
50 | } | 51 | } |
51 | \<\%decl\> { | 52 | \<\%decl\> { |
52 | modi.push_front(modus_operandi(0)); | 53 | modi.push_front(modus_operandi(0)); |
53 | anchor(); | 54 | anchor(); |
54 | BEGIN(DECLBLOCK); | 55 | BEGIN(DECLBLOCK); |
55 | } | 56 | } |
56 | \<\%impl\> { | 57 | \<\%impl\> { |
57 | modi.push_front(modus_operandi(0)); | 58 | modi.push_front(modus_operandi(0)); |
58 | anchor(); | 59 | anchor(); |
59 | BEGIN(IMPLBLOCK); | 60 | BEGIN(IMPLBLOCK); |
60 | } | 61 | } |
61 | ^\%\%var{WHITESPACE}+{ | 62 | ^\%\%var{WHITESPACE}+{ |
62 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); | 63 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); |
63 | anchor(); | 64 | anchor(); |
64 | BEGIN(VARLINE); | 65 | BEGIN(VARLINE); |
65 | } | 66 | } |
66 | ^\%\%import{WHITESPACE}+{ | 67 | ^\%\%import{WHITESPACE}+{ |
67 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); | 68 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); |
68 | BEGIN(IMPORTLINE); | 69 | BEGIN(IMPORTLINE); |
69 | } | 70 | } |
70 | ^\%\%import_type{WHITESPACE}+ { | 71 | ^\%\%import_type{WHITESPACE}+ { |
71 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); | 72 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); |
72 | BEGIN(IMPORTTYPELINE); | 73 | BEGIN(IMPORTTYPELINE); |
73 | } | 74 | } |
74 | ^\%\%derive{WHITESPACE}+{ | 75 | ^\%\%derive{WHITESPACE}+{ |
75 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); | 76 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); |
76 | BEGIN(DERIVELINE); | 77 | BEGIN(DERIVELINE); |
77 | } | 78 | } |
78 | \<\%constructor\>{ | 79 | \<\%constructor\>{ |
79 | modi.push_front(modus_operandi()); | 80 | modi.push_front(modus_operandi()); |
80 | anchor(); | 81 | anchor(); |
81 | BEGIN(CONSTRUCTOR); | 82 | BEGIN(CONSTRUCTOR); |
82 | } | 83 | } |
83 | \<\%destructor\>{ | 84 | \<\%destructor\>{ |
84 | modi.push_front(modus_operandi()); | 85 | modi.push_front(modus_operandi()); |
85 | anchor(); | 86 | anchor(); |
86 | BEGIN(DESTRUCTOR); | 87 | BEGIN(DESTRUCTOR); |
87 | } | 88 | } |
88 | \<\%codemethod{WHITESPACE}+{ | 89 | \<\%codemethod{WHITESPACE}+{ |
89 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); | 90 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); |
90 | anchor(); | 91 | anchor(); |
91 | BEGIN(CODEMETHODLINE); | 92 | BEGIN(CODEMETHODLINE); |
92 | } | 93 | } |
93 | \<\%method{WHITESPACE}+ { | 94 | \<\%method{WHITESPACE}+ { |
94 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); | 95 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); |
95 | anchor(); | 96 | anchor(); |
96 | BEGIN(METHODLINE); | 97 | BEGIN(METHODLINE); |
97 | } | 98 | } |
98 | ^\%\%pragma{WHITESPACE}+{ | 99 | ^\%\%pragma{WHITESPACE}+{ |
99 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); | 100 | modi.push_front(modus_operandi(modus_operandi::flag_devour_comments)); |
100 | BEGIN(PRAGMALINE); | 101 | BEGIN(PRAGMALINE); |
101 | } | 102 | } |
102 | <<EOF>>{ | 103 | <<EOF>>{ |
103 | assert(modi.size()==1); | 104 | assert(modi.size()==1); |
104 | M().modify(modus_operandi::modus_preop); | 105 | M().modify(modus_operandi::modus_preop); |
105 | LexerOutput(";",1); | 106 | LexerOutput(";",1); |
106 | return 0; | 107 | return 0; |
107 | } | 108 | } |
108 | } | 109 | } |
109 | <<EOF>>throw preprocessor_error(CODEPOINT,"unexpected end of file",lineno()); | 110 | <<EOF>>throw preprocessor_error(CODEPOINT,"unexpected end of file",lineno()); |
110 | 111 | ||
111 | <CODEBLOCK,CODEMETHODBLOCK>{ | 112 | <CODEBLOCK,CODEMETHODBLOCK>{ |
112 | "<%output>"{ | 113 | "<%output>"{ |
113 | anchor(); | 114 | anchor(); |
114 | yy_push_state(OUTPUTBLOCK); | 115 | yy_push_state(OUTPUTBLOCK); |
115 | } | 116 | } |
116 | } | 117 | } |
117 | 118 | ||
118 | <PRAGMALINE>{ | 119 | <PRAGMALINE>{ |
119 | {WHITESPACE}+{ | 120 | {WHITESPACE}+{ |
120 | modus_operandi& m = M(); | 121 | modus_operandi& m = M(); |
121 | if(!m.output.empty()) { | 122 | if(!m.output.empty()) { |
122 | string::size_type eq = m.output.find('='); | 123 | string::size_type eq = m.output.find('='); |
123 | if(eq==string::npos) { | 124 | if(eq==string::npos) { |
124 | pragmas[m.output]=m.output; | 125 | pragmas[m.output]=m.output; |
125 | }else{ | 126 | }else{ |
126 | pragmas[m.output.substr(0,eq)] = m.output.substr(eq+1); | 127 | pragmas[m.output.substr(0,eq)] = m.output.substr(eq+1); |
127 | } | 128 | } |
128 | m.output.erase(); | 129 | m.output.erase(); |
129 | } | 130 | } |
130 | } | 131 | } |
131 | \n { | 132 | \n { |
132 | modus_operandi& m = M(); | 133 | modus_operandi& m = M(); |
133 | if(!m.output.empty()) { | 134 | if(!m.output.empty()) { |
134 | string::size_type eq = m.output.find('='); | 135 | string::size_type eq = m.output.find('='); |
135 | if(eq==string::npos) { | 136 | if(eq==string::npos) { |
136 | pragmas[m.output]=m.output; | 137 | pragmas[m.output]=m.output; |
137 | }else{ | 138 | }else{ |
138 | pragmas[m.output.substr(0,eq)] = m.output.substr(eq+1); | 139 | pragmas[m.output.substr(0,eq)] = m.output.substr(eq+1); |
139 | } | 140 | } |
140 | m.output.erase(); | 141 | m.output.erase(); |
141 | } | 142 | } |
142 | modi.pop_front(); | 143 | modi.pop_front(); |
143 | BEGIN(INITIAL); | 144 | BEGIN(INITIAL); |
144 | anchor(); | 145 | anchor(); |
145 | } | 146 | } |
146 | } | 147 | } |
147 | 148 | ||
148 | <METHODLINE>{ | 149 | <METHODLINE>{ |
149 | {WHITESPACE}+{ | 150 | {WHITESPACE}+{ |
150 | modus_operandi& m = M(); | 151 | modus_operandi& m = M(); |
151 | if(!m.output.empty()) { | 152 | if(!m.output.empty()) { |
152 | if(!m._lastid.empty()) { | 153 | if(!m._lastid.empty()) { |
153 | if(!m._type.empty()) m._type += ' '; | 154 | if(!m._type.empty()) m._type += ' '; |
154 | m._type += m._lastid; | 155 | m._type += m._lastid; |
155 | } | 156 | } |
156 | m._lastid = m.output; | 157 | m._lastid = m.output; |
157 | m.output.clear(); | 158 | m.output.clear(); |
158 | } | 159 | } |
159 | } | 160 | } |
160 | \*{ | 161 | \*{ |
161 | modus_operandi& m = M(); | 162 | modus_operandi& m = M(); |
162 | ECHO; | 163 | ECHO; |
163 | if(!m._lastid.empty()) { | 164 | if(!m._lastid.empty()) { |
164 | if(!m._type.empty()) m._type += ' '; | 165 | if(!m._type.empty()) m._type += ' '; |
165 | m._type += m._lastid; | 166 | m._type += m._lastid; |
166 | } | 167 | } |
167 | m._lastid = m.output; | 168 | m._lastid = m.output; |
168 | m.output.clear(); | 169 | m.output.clear(); |
169 | } | 170 | } |
170 | \({ | 171 | \({ |
171 | modus_operandi& m = M(); | 172 | modus_operandi& m = M(); |
172 | if(m.output.empty()) { | 173 | if(m.output.empty()) { |
173 | m._name=m._lastid; | 174 | m._name=m._lastid; |
174 | }else{ | 175 | }else{ |
175 | if(!m._lastid.empty()) { // XXX: lastid, I believe should never be emtpy... | 176 | if(!m._lastid.empty()) { // XXX: lastid, I believe should never be emtpy... |
176 | if(!m._type.empty()) m._type += ' '; | 177 | if(!m._type.empty()) m._type += ' '; |
177 | m._type += m._lastid; | 178 | m._type += m._lastid; |
178 | } | 179 | } |
179 | m._name = m.output; | 180 | m._name = m.output; |
180 | m.output.clear(); | 181 | m.output.clear(); |
181 | } | 182 | } |
182 | ECHO; | 183 | ECHO; |
183 | BEGIN(METHODARGS); | 184 | BEGIN(METHODARGS); |
184 | } | 185 | } |
185 | } | 186 | } |
186 | <METHODARGS>{ | 187 | <METHODARGS>{ |
187 | \%\>{ | 188 | \%\>{ |
188 | modus_operandi& m = M(); | 189 | modus_operandi& m = M(); |
189 | m._args = m.output; | 190 | m._args = m.output; |
190 | m.output.clear(); | 191 | m.output.clear(); |
191 | anchor(); | 192 | anchor(); |
192 | BEGIN(METHODBLOCK); | 193 | BEGIN(METHODBLOCK); |
193 | } | 194 | } |
194 | } | 195 | } |
195 | 196 | ||
196 | <INITIAL,METHODBLOCK,OUTPUTBLOCK>{ | 197 | <INITIAL,METHODBLOCK,OUTPUTBLOCK>{ |
197 | \<\%{WHITESPACE}+{ | 198 | \<\%{WHITESPACE}+{ |
198 | M().modify(modus_operandi::modus_postop); | 199 | M().modify(modus_operandi::modus_postop); |
199 | anchor(); | 200 | anchor(); |
200 | LexerOutput("(",1); | 201 | LexerOutput("(",1); |
201 | yy_push_state(INLINE); | 202 | yy_push_state(INLINE); |
202 | } | 203 | } |
203 | ^\%{WHITESPACE}{ | 204 | ^\%{WHITESPACE}{ |
204 | M().modify(modus_operandi::modus_code); | 205 | M().modify(modus_operandi::modus_code); |
205 | anchor(); | 206 | anchor(); |
206 | yy_push_state(CODELINE); | 207 | yy_push_state(CODELINE); |
207 | } | 208 | } |
208 | \<\%code\>{ | 209 | \<\%code\>{ |
209 | M().modify(modus_operandi::modus_code); | 210 | M().modify(modus_operandi::modus_code); |
210 | anchor(); | 211 | anchor(); |
211 | yy_push_state(CODEBLOCK); | 212 | yy_push_state(CODEBLOCK); |
212 | } | 213 | } |
213 | "</%output>" { | 214 | "</%output>" { |
214 | if(YY_START!=OUTPUTBLOCK) throw preprocessor_error(CODEPOINT,"unexpected tag",lineno()); | 215 | if(YY_START!=OUTPUTBLOCK) throw preprocessor_error(CODEPOINT,"unexpected tag",lineno()); |
215 | M().modify(modus_operandi::modus_code); | 216 | M().modify(modus_operandi::modus_code); |
216 | anchor(); | 217 | anchor(); |
217 | yy_pop_state(); | 218 | yy_pop_state(); |
218 | } | 219 | } |
219 | } | 220 | } |
220 | 221 | ||
221 | <INLINE>\%\>LexerOutput(")",1); M().modus=modus_operandi::modus_preop; yy_pop_state(); | 222 | <INLINE>\%\>LexerOutput(")",1); M().modus=modus_operandi::modus_preop; yy_pop_state(); |
222 | <CODELINE>\nyy_pop_state(); | 223 | <CODELINE>\nyy_pop_state(); |
223 | 224 | ||
224 | <CODEMETHODLINE>{ | 225 | <CODEMETHODLINE>{ |
225 | {WHITESPACE}+{ | 226 | {WHITESPACE}+{ |
226 | modus_operandi& m = M(); | 227 | modus_operandi& m = M(); |
227 | if(!m.output.empty()) { | 228 | if(!m.output.empty()) { |
228 | if(!m._lastid.empty()) { | 229 | if(!m._lastid.empty()) { |
229 | if(!m._type.empty()) m._type += ' '; | 230 | if(!m._type.empty()) m._type += ' '; |
230 | m._type += m._lastid; | 231 | m._type += m._lastid; |
231 | } | 232 | } |
232 | m._lastid = m.output; | 233 | m._lastid = m.output; |
233 | m.output.clear(); | 234 | m.output.clear(); |
234 | } | 235 | } |
235 | } | 236 | } |
236 | \*{ | 237 | \*{ |
237 | modus_operandi& m = M(); | 238 | modus_operandi& m = M(); |
238 | ECHO; | 239 | ECHO; |
239 | if(!m._lastid.empty()) { | 240 | if(!m._lastid.empty()) { |
240 | if(!m._type.empty()) m._type += ' '; | 241 | if(!m._type.empty()) m._type += ' '; |
241 | m._type += m._lastid; | 242 | m._type += m._lastid; |
242 | } | 243 | } |
243 | m._lastid = m.output; | 244 | m._lastid = m.output; |
244 | m.output.clear(); | 245 | m.output.clear(); |
245 | } | 246 | } |
246 | \({ | 247 | \({ |
247 | modus_operandi& m = M(); | 248 | modus_operandi& m = M(); |
248 | if(m.output.empty()) { | 249 | if(m.output.empty()) { |
249 | m._name=m._lastid; | 250 | m._name=m._lastid; |
250 | }else{ | 251 | }else{ |
251 | if(!m._lastid.empty()) { // XXX: lastid, I believe should never be emtpy... | 252 | if(!m._lastid.empty()) { // XXX: lastid, I believe should never be emtpy... |
252 | if(!m._type.empty()) m._type += ' '; | 253 | if(!m._type.empty()) m._type += ' '; |
253 | m._type += m._lastid; | 254 | m._type += m._lastid; |
254 | } | 255 | } |
255 | m._name = m.output; | 256 | m._name = m.output; |
256 | m.output.clear(); | 257 | m.output.clear(); |
257 | } | 258 | } |
258 | ECHO; | 259 | ECHO; |
259 | BEGIN(CODEMETHODARGS); | 260 | BEGIN(CODEMETHODARGS); |
260 | } | 261 | } |
261 | } | 262 | } |
262 | <CODEMETHODARGS>{ | 263 | <CODEMETHODARGS>{ |
263 | \%\>{ | 264 | \%\>{ |
264 | modus_operandi& m = M(); | 265 | modus_operandi& m = M(); |
265 | m._args = m.output; | 266 | m._args = m.output; |
266 | m.output.clear(); | 267 | m.output.clear(); |
267 | m.flags=0; | 268 | m.flags=0; |
268 | anchor(); | 269 | anchor(); |
269 | BEGIN(CODEMETHODBLOCK); | 270 | BEGIN(CODEMETHODBLOCK); |
270 | } | 271 | } |
271 | } | 272 | } |
272 | 273 | ||
273 | <IMPORTLINE>{ | 274 | <IMPORTLINE>{ |
274 | {WHITESPACE}+{ } | 275 | {WHITESPACE}+{ } |
275 | {ID}{ | 276 | {ID}{ |
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 | } |
394 | m._lastid = m.output; | 395 | m._lastid = m.output; |
395 | m.output.clear(); | 396 | m.output.clear(); |
396 | } | 397 | } |
397 | \;|\n|\={ | 398 | \;|\n|\={ |
398 | modus_operandi& m = M(); | 399 | modus_operandi& m = M(); |
399 | if(m.output.empty()) { | 400 | if(m.output.empty()) { |
400 | m._name=m._lastid; | 401 | m._name=m._lastid; |
401 | }else{ | 402 | }else{ |
402 | if(!m._lastid.empty()) { // XXX: lastid should never be emtpy, I believe? | 403 | if(!m._lastid.empty()) { // XXX: lastid should never be emtpy, I believe? |
403 | if(!m._type.empty()) m._type += ' '; | 404 | if(!m._type.empty()) m._type += ' '; |
404 | m._type += m._lastid; | 405 | m._type += m._lastid; |
405 | } | 406 | } |
406 | m._name=m.output; | 407 | m._name=m.output; |
407 | m.output.clear(); | 408 | m.output.clear(); |
408 | } | 409 | } |
409 | BEGIN(VARINIT); | 410 | BEGIN(VARINIT); |
410 | if(*yytext!='=') | 411 | if(*yytext!='=') |
411 | unput('\n'); | 412 | unput('\n'); |
412 | } | 413 | } |
413 | } | 414 | } |
414 | <VARINIT>{ | 415 | <VARINIT>{ |
415 | \n{ | 416 | \n{ |
416 | modus_operandi& m = M(); | 417 | modus_operandi& m = M(); |
417 | string::size_type t = m.output.find_first_not_of(" \t"); | 418 | string::size_type t = m.output.find_first_not_of(" \t"); |
418 | if(t!=string::npos) | 419 | if(t!=string::npos) |
419 | m.output.erase(0,t); | 420 | m.output.erase(0,t); |
420 | t = m.output.find_last_not_of(" \t;"); | 421 | t = m.output.find_last_not_of(" \t;"); |
421 | if(t!=string::npos) | 422 | if(t!=string::npos) |
422 | m.output.erase(t+1); | 423 | m.output.erase(t+1); |
423 | member_variables.push_back(member_variable(m._type,m._name,m.output)); | 424 | member_variables.push_back(member_variable(m._type,m._name,m.output)); |
424 | if(!m.output.empty()) | 425 | if(!m.output.empty()) |
425 | have_initializers=true; | 426 | have_initializers=true; |
426 | modi.pop_front(); | 427 | modi.pop_front(); |
427 | BEGIN(INITIAL); | 428 | BEGIN(INITIAL); |
428 | } | 429 | } |
429 | } | 430 | } |
430 | <DECLLINE>\n{ | 431 | <DECLLINE>\n{ |
431 | ECHO; | 432 | ECHO; |
432 | decl += M().output; | 433 | decl += M().output; |
433 | modi.pop_front(); | 434 | modi.pop_front(); |
434 | BEGIN(INITIAL); | 435 | BEGIN(INITIAL); |
435 | } | 436 | } |
436 | <IMPLLINE>\n{ | 437 | <IMPLLINE>\n{ |
437 | ECHO; | 438 | ECHO; |
438 | impl += M().output; | 439 | impl += M().output; |
439 | modi.pop_front(); | 440 | modi.pop_front(); |
440 | BEGIN(INITIAL); | 441 | BEGIN(INITIAL); |
441 | } | 442 | } |
442 | <CLASSLINE>\n{ | 443 | <CLASSLINE>\n{ |
443 | class_name = M().output; | 444 | class_name = M().output; |
444 | modi.pop_front(); | 445 | modi.pop_front(); |
445 | BEGIN(INITIAL); | 446 | BEGIN(INITIAL); |
446 | } | 447 | } |
447 | <CLASSLINE,DECLLINE,IMPLLINE,VARLINE,VARINIT,IMPORTLINE,IMPORTCOMPONENT,CODEMETHODLINE,CODEMETHODARGS,INLINE,METHODLINE,METHODARGS,DECLBLOCK,IMPLBLOCK,CONSTRUCTOR,DESTRUCTOR,CODEMETHODBLOCK,CODELINE,CODEBLOCK,PRAGMALINE,DERIVELINE,DERIVECOMPONENT>{ | 448 | <CLASSLINE,DECLLINE,IMPLLINE,VARLINE,VARINIT,IMPORTLINE,IMPORTCOMPONENT,CODEMETHODLINE,CODEMETHODARGS,INLINE,METHODLINE,METHODARGS,DECLBLOCK,IMPLBLOCK,CONSTRUCTOR,DESTRUCTOR,CODEMETHODBLOCK,CODELINE,CODEBLOCK,PRAGMALINE,DERIVELINE,DERIVECOMPONENT>{ |
448 | "/*"{ | 449 | "/*"{ |
449 | yy_push_state(SLASHSTAR_COMMENT); | 450 | yy_push_state(SLASHSTAR_COMMENT); |
450 | if(!M().devour_comments()) { | 451 | if(!M().devour_comments()) { |
451 | ECHO; | 452 | ECHO; |
452 | } | 453 | } |
453 | } | 454 | } |
454 | "//"{ | 455 | "//"{ |
455 | yy_push_state(SLASHSLASH_COMMENT); | 456 | yy_push_state(SLASHSLASH_COMMENT); |
456 | if(!M().devour_comments()) { | 457 | if(!M().devour_comments()) { |
457 | ECHO; | 458 | ECHO; |
458 | } | 459 | } |
459 | } | 460 | } |
460 | \" { | 461 | \" { |
461 | yy_push_state(STRING); | 462 | yy_push_state(STRING); |
462 | ECHO; | 463 | ECHO; |
463 | } | 464 | } |
464 | \'\\.\'{ | 465 | \'\\.\'{ |
465 | ECHO; | 466 | ECHO; |
466 | } | 467 | } |
467 | } | 468 | } |
468 | 469 | ||
469 | <INITIAL,METHODBLOCK,OUTPUTBLOCK>{ | 470 | <INITIAL,METHODBLOCK,OUTPUTBLOCK>{ |
470 | \"soft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\\"",2); | 471 | \"soft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\\"",2); |
471 | \nsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\n",2); | 472 | \nsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\n",2); |
472 | \rsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\r",2); | 473 | \rsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\r",2); |
473 | \tsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\t",2); | 474 | \tsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\t",2); |
474 | \bsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\b",2); | 475 | \bsoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\b",2); |
475 | \asoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\a",2); | 476 | \asoft_anchor(); M().modify(modus_operandi::modus_text); LexerOutput("\\a",2); |
476 | .soft_anchor(); M().modify(modus_operandi::modus_text); ECHO; | 477 | .soft_anchor(); M().modify(modus_operandi::modus_text); ECHO; |
477 | {WHITESPACE}+soft_anchor(); M().modify(modus_operandi::modus_text); ECHO; | 478 | {WHITESPACE}+soft_anchor(); M().modify(modus_operandi::modus_text); ECHO; |
478 | } | 479 | } |
479 | 480 | ||
480 | <DECLBLOCK,IMPLBLOCK,CONSTRUCTOR,DESTRUCTOR,CODEMETHODBLOCK,METHODBLOCK,CODEBLOCK>{ | 481 | <DECLBLOCK,IMPLBLOCK,CONSTRUCTOR,DESTRUCTOR,CODEMETHODBLOCK,METHODBLOCK,CODEBLOCK>{ |
481 | \<\/\%decl\>{ | 482 | \<\/\%decl\>{ |
482 | if(YY_START!=DECLBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); | 483 | if(YY_START!=DECLBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); |
483 | decl += M().output; | 484 | decl += M().output; |
484 | modi.pop_front(); | 485 | modi.pop_front(); |
485 | BEGIN(INITIAL); | 486 | BEGIN(INITIAL); |
486 | } | 487 | } |
487 | \<\/\%impl\>{ | 488 | \<\/\%impl\>{ |
488 | if(YY_START!=IMPLBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); | 489 | if(YY_START!=IMPLBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); |
489 | impl += M().output; | 490 | impl += M().output; |
490 | modi.pop_front(); | 491 | modi.pop_front(); |
491 | BEGIN(INITIAL); | 492 | BEGIN(INITIAL); |
492 | } | 493 | } |
493 | \<\/\%constructor\>{ | 494 | \<\/\%constructor\>{ |
494 | if(YY_START!=CONSTRUCTOR) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); | 495 | if(YY_START!=CONSTRUCTOR) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); |
495 | member_functions.push_back(member_function("","","",M().output)); | 496 | member_functions.push_back(member_function("","","",M().output)); |
496 | have_constructor = true; | 497 | have_constructor = true; |
497 | modi.pop_front(); | 498 | modi.pop_front(); |
498 | BEGIN(INITIAL); | 499 | BEGIN(INITIAL); |
499 | } | 500 | } |
500 | \<\/\%destructor\>{ | 501 | \<\/\%destructor\>{ |
501 | if(YY_START!=DESTRUCTOR) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); | 502 | if(YY_START!=DESTRUCTOR) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); |
502 | member_functions.push_back(member_function("","~","",M().output)); | 503 | member_functions.push_back(member_function("","~","",M().output)); |
503 | modi.pop_front(); | 504 | modi.pop_front(); |
504 | BEGIN(INITIAL); | 505 | BEGIN(INITIAL); |
505 | } | 506 | } |
506 | \<\/\%codemethod\>{ | 507 | \<\/\%codemethod\>{ |
507 | if(YY_START!=CODEMETHODBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); | 508 | if(YY_START!=CODEMETHODBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); |
508 | modus_operandi& m = M(); | 509 | modus_operandi& m = M(); |
509 | member_functions.push_back(member_function(m._type,m._name,m._args,m.output)); | 510 | member_functions.push_back(member_function(m._type,m._name,m._args,m.output)); |
510 | modi.pop_front(); | 511 | modi.pop_front(); |
511 | BEGIN(INITIAL); | 512 | BEGIN(INITIAL); |
512 | } | 513 | } |
513 | \<\/%method\> { | 514 | \<\/%method\> { |
514 | if(YY_START!=METHODBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); | 515 | if(YY_START!=METHODBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); |
515 | modus_operandi& m = M(); | 516 | modus_operandi& m = M(); |
516 | m.modify(modus_operandi::modus_code); | 517 | m.modify(modus_operandi::modus_code); |
517 | member_functions.push_back(member_function(m._type,m._name,m._args,m.output)); | 518 | member_functions.push_back(member_function(m._type,m._name,m._args,m.output)); |
518 | modi.pop_front(); | 519 | modi.pop_front(); |
519 | BEGIN(INITIAL); | 520 | BEGIN(INITIAL); |
520 | } | 521 | } |
521 | \<\/%code\> { | 522 | \<\/%code\> { |
522 | if(YY_START!=CODEBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); | 523 | if(YY_START!=CODEBLOCK) throw preprocessor_error(CODEPOINT,"tags mismatch",lineno()); |
523 | yy_pop_state(); | 524 | yy_pop_state(); |
524 | } | 525 | } |
525 | \n ECHO; | 526 | \n ECHO; |
526 | } | 527 | } |
527 | 528 | ||
528 | <SLASHSTAR_COMMENT>{ | 529 | <SLASHSTAR_COMMENT>{ |
529 | "*/"{ | 530 | "*/"{ |
530 | if(!M().devour_comments()) { | 531 | if(!M().devour_comments()) { |
531 | ECHO; | 532 | ECHO; |
532 | } | 533 | } |
533 | yy_pop_state(); | 534 | yy_pop_state(); |
534 | unput(' '); | 535 | unput(' '); |
535 | } | 536 | } |
536 | \n{ | 537 | \n{ |
537 | if(!M().devour_comments()) { | 538 | if(!M().devour_comments()) { |
538 | ECHO; | 539 | ECHO; |
539 | } | 540 | } |
540 | } | 541 | } |
541 | } | 542 | } |
542 | <SLASHSLASH_COMMENT>{ | 543 | <SLASHSLASH_COMMENT>{ |
543 | \n{ | 544 | \n{ |
544 | if(!M().devour_comments()) { | 545 | if(!M().devour_comments()) { |
545 | ECHO; | 546 | ECHO; |
546 | } | 547 | } |
547 | yy_pop_state(); | 548 | yy_pop_state(); |
548 | if(YY_START!=CODEBLOCK && YY_START!=CODEMETHODBLOCK && YY_START!=IMPLBLOCK && YY_START!=DECLBLOCK) | 549 | if(YY_START!=CODEBLOCK && YY_START!=CODEMETHODBLOCK && YY_START!=IMPLBLOCK && YY_START!=DECLBLOCK) |
549 | unput('\n'); | 550 | unput('\n'); |
550 | } | 551 | } |
551 | } | 552 | } |
552 | <SLASHSTAR_COMMENT,SLASHSLASH_COMMENT>.{ | 553 | <SLASHSTAR_COMMENT,SLASHSLASH_COMMENT>.{ |
553 | if(!M().devour_comments()) { | 554 | if(!M().devour_comments()) { |
554 | ECHO; | 555 | ECHO; |
555 | } | 556 | } |
556 | } | 557 | } |
557 | <STRING>{ | 558 | <STRING>{ |
558 | \\.ECHO; | 559 | \\.ECHO; |
559 | \"ECHO; yy_pop_state(); | 560 | \"ECHO; yy_pop_state(); |
560 | .ECHO; | 561 | .ECHO; |
561 | } | 562 | } |
562 | 563 | ||
563 | {WHITESPACE}+{ | 564 | {WHITESPACE}+{ |
564 | if(!(M().flags&modus_operandi::flag_devour_whitespace)) { | 565 | if(!(M().flags&modus_operandi::flag_devour_whitespace)) { |
565 | ECHO; | 566 | ECHO; |
566 | } | 567 | } |
567 | } | 568 | } |
568 | 569 | ||
569 | %% | 570 | %% |
570 | 571 | ||
571 | sitecing_parser::sitecing_parser(component_factory& f) | 572 | sitecing_parser::sitecing_parser(component_factory& f) |
572 | : factory(f), have_initializers(false), have_constructor(false), | 573 | : factory(f), have_initializers(false), have_constructor(false), |
573 | base_class("sitecing::cgi_component"), | 574 | base_class("sitecing::cgi_component"), |
574 | base_header("sitecing/cgi_component.h"), | 575 | base_header("sitecing/cgi_component.h"), |
575 | skeleton(__SC_DEFAULT_SKELETON) { | 576 | skeleton(__SC_DEFAULT_SKELETON) { |
576 | } | 577 | } |
577 | 578 | ||
578 | void sitecing_parser::preprocess(const string& in) { | 579 | void sitecing_parser::preprocess(const string& in) { |
579 | ifstream ifs(in.c_str(),ios::in); | 580 | ifstream ifs(in.c_str(),ios::in); |
580 | if(!ifs.good()) | 581 | if(!ifs.good()) |
581 | throw preprocessor_error(CODEPOINT,"failed to open input file"); | 582 | throw preprocessor_error(CODEPOINT,"failed to open input file"); |
582 | input_file = in; | 583 | input_file = in; |
583 | modi.push_front(modus_operandi(0)); | 584 | modi.push_front(modus_operandi(0)); |
584 | switch_streams(&ifs,NULL); | 585 | switch_streams(&ifs,NULL); |
585 | if(yylex()) | 586 | if(yylex()) |
586 | throw preprocessor_error(CODEPOINT,"unknown error"); | 587 | throw preprocessor_error(CODEPOINT,"unknown error"); |
587 | pragmas_t::const_iterator mp = pragmas.find("main"); | 588 | pragmas_t::const_iterator mp = pragmas.find("main"); |
588 | if(mp==pragmas.end()) { | 589 | if(mp==pragmas.end()) { |
589 | member_functions.push_back(member_function("void","main","(int _magic,va_list _args)",M().output)); | 590 | member_functions.push_back(member_function("void","main","(int _magic,va_list _args)",M().output)); |
590 | }else{ | 591 | }else{ |
591 | member_functions.push_back( | 592 | member_functions.push_back( |
592 | member_function( | 593 | member_function( |
593 | "void","main","(int _magic,va_list _args)", | 594 | "void","main","(int _magic,va_list _args)", |
594 | mp->second+"::main(_magic,_args);" | 595 | mp->second+"::main(_magic,_args);" |
595 | ) | 596 | ) |
596 | ); | 597 | ); |
597 | } | 598 | } |
598 | if(have_initializers && !have_constructor) | 599 | if(have_initializers && !have_constructor) |
599 | member_functions.push_back(member_function("","","","")); | 600 | member_functions.push_back(member_function("","","","")); |
600 | sitecing_enflesher enflesher(*this); | 601 | sitecing_enflesher enflesher(*this); |
601 | enflesher.enflesh(); | 602 | enflesher.enflesh(); |
602 | } | 603 | } |
603 | 604 | ||
604 | void sitecing_parser::LexerOutput(const char* buf,int size) { | 605 | void sitecing_parser::LexerOutput(const char* buf,int size) { |
605 | assert(modi.size()); | 606 | assert(modi.size()); |
606 | M().output.append(buf,size); | 607 | M().output.append(buf,size); |
607 | } | 608 | } |
608 | 609 | ||
609 | static const char *modus_transitions | 610 | static const char *modus_transitions |
610 | [sitecing_parser::modus_operandi::modi] | 611 | [sitecing_parser::modus_operandi::modi] |
611 | [sitecing_parser::modus_operandi::modi] = { | 612 | [sitecing_parser::modus_operandi::modi] = { |
612 | // To: | 613 | // To: |
613 | // code preop postop text From: | 614 | // code preop postop text From: |
614 | { "", "(*(__SCIF->out))", "(*(__SCIF->out))<<", "(*(__SCIF->out))<<\"" }, // code | 615 | { "", "(*(__SCIF->out))", "(*(__SCIF->out))<<", "(*(__SCIF->out))<<\"" }, // code |
615 | { ";", "", "<<", "<<\"" }, // preop | 616 | { ";", "", "<<", "<<\"" }, // preop |
616 | { NULL, NULL, "", "\"" }, // postop | 617 | { NULL, NULL, "", "\"" }, // postop |
617 | { "\";", "\"", "\"<<", "" } // text | 618 | { "\";", "\"", "\"<<", "" } // text |
618 | }; | 619 | }; |
619 | 620 | ||
620 | void sitecing_parser::modus_operandi::modify(modus_t m) { | 621 | void sitecing_parser::modus_operandi::modify(modus_t m) { |
621 | const char * x = modus_transitions[modus][m]; | 622 | const char * x = modus_transitions[modus][m]; |
622 | assert(x); | 623 | assert(x); |
623 | output += x; | 624 | output += x; |
624 | modus = m; | 625 | modus = m; |
625 | } | 626 | } |
626 | 627 | ||
627 | void sitecing_parser::soft_anchor() { | 628 | void sitecing_parser::soft_anchor() { |
628 | if(M().modus!=modus_operandi::modus_text) | 629 | if(M().modus!=modus_operandi::modus_text) |
629 | anchor(); | 630 | anchor(); |
630 | } | 631 | } |
631 | void sitecing_parser::anchor() { | 632 | void sitecing_parser::anchor() { |
632 | if(M().modus==modus_operandi::modus_text) | 633 | if(M().modus==modus_operandi::modus_text) |
633 | M().modify(modus_operandi::modus_preop); | 634 | M().modify(modus_operandi::modus_preop); |
634 | M().output += "\n#line "; | 635 | M().output += "\n#line "; |
635 | char tmp[7]; | 636 | char tmp[7]; |
636 | snprintf(tmp,sizeof(tmp),"%d",lineno()); | 637 | snprintf(tmp,sizeof(tmp),"%d",lineno()); |
637 | M().output += tmp; | 638 | M().output += tmp; |
638 | M().output += " \""; | 639 | M().output += " \""; |
639 | M().output += input_file; | 640 | M().output += input_file; |
640 | M().output += "\"\n"; | 641 | M().output += "\"\n"; |
641 | } | 642 | } |
642 | /* vim:set ft=lex: */ | 643 | /* vim:set ft=lex: */ |
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,279 +1,162 @@ | |||
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 | ||
17 | namespace sitecing { | 17 | namespace 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)) |
121 | return; | 59 | return; |
122 | sleep(8); | 60 | sleep(8); |
123 | } | 61 | } |
124 | throw konforka::exception(CODEPOINT,"failed to obtain file lock"); | 62 | throw konforka::exception(CODEPOINT,"failed to obtain file lock"); |
125 | } | 63 | } |
126 | void file_lock::unlock() { | 64 | void file_lock::unlock() { |
127 | if(fd<0) | 65 | if(fd<0) |
128 | return; | 66 | return; |
129 | struct flock fl; | 67 | struct flock fl; |
130 | fl.l_type = F_UNLCK; | 68 | fl.l_type = F_UNLCK; |
131 | fl.l_whence=SEEK_SET; | 69 | fl.l_whence=SEEK_SET; |
132 | fl.l_start=fl.l_len=0; | 70 | fl.l_start=fl.l_len=0; |
133 | int rv = fcntl(fd,F_SETLK,&fl); | 71 | int rv = fcntl(fd,F_SETLK,&fl); |
134 | close(fd); | 72 | close(fd); |
135 | fd=-1; | 73 | fd=-1; |
136 | if(rv) | 74 | if(rv) |
137 | throw konforka::exception(CODEPOINT,"failed to release file lock"); | 75 | throw konforka::exception(CODEPOINT,"failed to release file lock"); |
138 | } | 76 | } |
139 | 77 | ||
140 | void pid_file::set(const string& f,bool u) { | 78 | void pid_file::set(const string& f,bool u) { |
141 | ofstream of(f.c_str(),ios::trunc); | 79 | ofstream of(f.c_str(),ios::trunc); |
142 | if(!of) | 80 | if(!of) |
143 | throw konforka::exception(CODEPOINT,"failed to open file for writing pid"); | 81 | throw konforka::exception(CODEPOINT,"failed to open file for writing pid"); |
144 | of << getpid() << endl; | 82 | of << getpid() << endl; |
145 | of.close(); | 83 | of.close(); |
146 | file_name = f; | 84 | file_name = f; |
147 | unlink_pid = u; | 85 | unlink_pid = u; |
148 | } | 86 | } |
149 | void pid_file::unlink() { | 87 | void pid_file::unlink() { |
150 | if(!unlink_pid) | 88 | if(!unlink_pid) |
151 | return; | 89 | return; |
152 | ::unlink(file_name.c_str()); | 90 | ::unlink(file_name.c_str()); |
153 | } | 91 | } |
154 | 92 | ||
155 | void semaphore::init() { | 93 | void semaphore::init() { |
156 | deinit(); | 94 | deinit(); |
157 | semid = semget(IPC_PRIVATE,1,IPC_CREAT|0600); | 95 | semid = semget(IPC_PRIVATE,1,IPC_CREAT|0600); |
158 | if(semid<0) | 96 | if(semid<0) |
159 | throw konforka::exception(CODEPOINT,"failed to semget()"); | 97 | throw konforka::exception(CODEPOINT,"failed to semget()"); |
160 | if(semctl(semid,0,SETVAL,1)) | 98 | if(semctl(semid,0,SETVAL,1)) |
161 | throw konforka::exception(CODEPOINT,"failed to semctl()"); | 99 | throw konforka::exception(CODEPOINT,"failed to semctl()"); |
162 | } | 100 | } |
163 | void semaphore::deinit() { | 101 | void semaphore::deinit() { |
164 | if(semid<0) | 102 | if(semid<0) |
165 | return; | 103 | return; |
166 | semctl(semid,0,IPC_RMID,0); | 104 | semctl(semid,0,IPC_RMID,0); |
167 | } | 105 | } |
168 | void semaphore::on() { | 106 | void semaphore::on() { |
169 | assert(semid>=0); | 107 | assert(semid>=0); |
170 | struct sembuf sb; | 108 | struct sembuf sb; |
171 | sb.sem_num=0; | 109 | sb.sem_num=0; |
172 | sb.sem_op=-1; | 110 | sb.sem_op=-1; |
173 | sb.sem_flg = SEM_UNDO; | 111 | sb.sem_flg = SEM_UNDO; |
174 | while(semop(semid,&sb,1)<0) { | 112 | while(semop(semid,&sb,1)<0) { |
175 | if(errno!=EINTR) | 113 | if(errno!=EINTR) |
176 | throw konforka::exception(CODEPOINT,"failed to semop()"); | 114 | throw konforka::exception(CODEPOINT,"failed to semop()"); |
177 | } | 115 | } |
178 | } | 116 | } |
179 | void semaphore::off() { | 117 | void semaphore::off() { |
180 | assert(semid>=0); | 118 | assert(semid>=0); |
181 | struct sembuf sb; | 119 | struct sembuf sb; |
182 | sb.sem_num=0; | 120 | sb.sem_num=0; |
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,52 +1,53 @@ | |||
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 | ||
9 | namespace sitecing { | 10 | namespace 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); |
48 | } | 49 | } |
49 | } | 50 | } |
50 | } | 51 | } |
51 | 52 | ||
52 | } | 53 | } |
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,231 +1,232 @@ | |||
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> |
9 | using namespace std; | 9 | using 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" |
19 | using namespace sitecing; | 20 | using 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 | ||
25 | static sitespace* site_space = NULL; | 26 | static sitespace* site_space = NULL; |
26 | typedef pair<dev_t,ino_t> the_inode_t; | 27 | typedef pair<dev_t,ino_t> the_inode_t; |
27 | set<the_inode_t> built_inodes; | 28 | set<the_inode_t> built_inodes; |
28 | 29 | ||
29 | void build_component(const string& component) { | 30 | void 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"); |
34 | }catch(compile_error& ce) { | 35 | }catch(compile_error& ce) { |
35 | ce.see(CODEPOINT); | 36 | ce.see(CODEPOINT); |
36 | ifstream err((site_space->config.root_intermediate+ce.component_path+".stderr").c_str(),ios::in); | 37 | ifstream err((site_space->config.root_intermediate+ce.component_path+".stderr").c_str(),ios::in); |
37 | if(err) { | 38 | if(err) { |
38 | cerr << err.rdbuf(); | 39 | cerr << err.rdbuf(); |
39 | } | 40 | } |
40 | throw; | 41 | throw; |
41 | }catch(preprocessor_error& pe) { | 42 | }catch(preprocessor_error& pe) { |
42 | pe.see(CODEPOINT); | 43 | pe.see(CODEPOINT); |
43 | cerr << site_space->config.root_source << pe.component_name << ":" << pe.line_number << ":" << pe.what() << endl; | 44 | cerr << site_space->config.root_source << pe.component_name << ":" << pe.line_number << ":" << pe.what() << endl; |
44 | throw; | 45 | throw; |
45 | } | 46 | } |
46 | } | 47 | } |
47 | 48 | ||
48 | void build_imports(const string& component); | 49 | void build_imports(const string& component); |
49 | 50 | ||
50 | void build_with_imports(const string& component) { | 51 | void build_with_imports(const string& component) { |
51 | assert(site_space); | 52 | assert(site_space); |
52 | struct stat st; | 53 | struct stat st; |
53 | string cp = site_space->config.root_source+component; | 54 | string cp = site_space->config.root_source+component; |
54 | if(!lstat(cp.c_str(),&st)) { | 55 | if(!lstat(cp.c_str(),&st)) { |
55 | if(built_inodes.find(the_inode_t(st.st_dev,st.st_ino))!=built_inodes.end()) | 56 | if(built_inodes.find(the_inode_t(st.st_dev,st.st_ino))!=built_inodes.end()) |
56 | return; | 57 | return; |
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 | ||
63 | void build_imports(const string& component) { | 64 | void 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 | ||
77 | void build_http_status_handlers(const string& target) { | 78 | void 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('/'); |
106 | if(sl==string::npos) { | 107 | if(sl==string::npos) { |
107 | t.erase(); | 108 | t.erase(); |
108 | }else{ | 109 | }else{ |
109 | if(sl==(t.length()-1)) | 110 | if(sl==(t.length()-1)) |
110 | t.erase(sl); | 111 | t.erase(sl); |
111 | else | 112 | else |
112 | t.erase(sl+1); | 113 | t.erase(sl+1); |
113 | } | 114 | } |
114 | } | 115 | } |
115 | } | 116 | } |
116 | 117 | ||
117 | void build_target(const string& target) { | 118 | void build_target(const string& target) { |
118 | assert(site_space); | 119 | assert(site_space); |
119 | string action = target; | 120 | string action = target; |
120 | config_options::action_handler_t *ah = site_space->config.lookup_action_handler(target); | 121 | config_options::action_handler_t *ah = site_space->config.lookup_action_handler(target); |
121 | if(ah) | 122 | if(ah) |
122 | action = ah->action; | 123 | action = ah->action; |
123 | build_with_imports(action); | 124 | build_with_imports(action); |
124 | } | 125 | } |
125 | 126 | ||
126 | void build(const string& target) { | 127 | void 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 | ||
166 | int main(int argc,char **argv) { | 167 | int 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' }, |
175 | { "config", required_argument, 0, 'f' }, | 176 | { "config", required_argument, 0, 'f' }, |
176 | { NULL, 0, 0, 0 } | 177 | { NULL, 0, 0, 0 } |
177 | }; | 178 | }; |
178 | int c = getopt_long(argc,argv,"f:hVL",opts,NULL); | 179 | int c = getopt_long(argc,argv,"f:hVL",opts,NULL); |
179 | if(c==-1) | 180 | if(c==-1) |
180 | break; | 181 | break; |
181 | switch(c) { | 182 | switch(c) { |
182 | case 'h': | 183 | case 'h': |
183 | cerr << PHEADER << endl | 184 | cerr << PHEADER << endl |
184 | << PCOPY << endl << endl | 185 | << PCOPY << endl << endl |
185 | << " -h, --help" << endl | 186 | << " -h, --help" << endl |
186 | << " --usage display this text" << endl | 187 | << " --usage display this text" << endl |
187 | << " -V, --version display version number" << endl | 188 | << " -V, --version display version number" << endl |
188 | << " -L, --license show license" << endl | 189 | << " -L, --license show license" << endl |
189 | << " -f filename, --config=filename" << endl | 190 | << " -f filename, --config=filename" << endl |
190 | << " specify configuration file to use" << endl; | 191 | << " specify configuration file to use" << endl; |
191 | exit(0); | 192 | exit(0); |
192 | break; | 193 | break; |
193 | case 'V': | 194 | case 'V': |
194 | cerr << VERSION << endl; | 195 | cerr << VERSION << endl; |
195 | exit(0); | 196 | exit(0); |
196 | break; | 197 | break; |
197 | case 'L': | 198 | case 'L': |
198 | extern const char *COPYING; | 199 | extern const char *COPYING; |
199 | cerr << COPYING << endl; | 200 | cerr << COPYING << endl; |
200 | exit(0); | 201 | exit(0); |
201 | break; | 202 | break; |
202 | case 'f': | 203 | case 'f': |
203 | config_file = optarg; | 204 | config_file = optarg; |
204 | break; | 205 | break; |
205 | default: | 206 | default: |
206 | cerr << "Huh??" << endl; | 207 | cerr << "Huh??" << endl; |
207 | break; | 208 | break; |
208 | } | 209 | } |
209 | } | 210 | } |
210 | configuration config(config_file,true); | 211 | configuration config(config_file,true); |
211 | if(!(config.flags&configuration::flag_root_source)) | 212 | if(!(config.flags&configuration::flag_root_source)) |
212 | throw konforka::exception(CODEPOINT,"Unspecified root for sources"); | 213 | throw konforka::exception(CODEPOINT,"Unspecified root for sources"); |
213 | if(!(config.flags&configuration::flag_root_intermediate)) | 214 | if(!(config.flags&configuration::flag_root_intermediate)) |
214 | throw konforka::exception(CODEPOINT,"Unspecified root for intermediate files"); | 215 | throw konforka::exception(CODEPOINT,"Unspecified root for intermediate files"); |
215 | if(!(config.flags&configuration::flag_root_so)) | 216 | if(!(config.flags&configuration::flag_root_so)) |
216 | throw konforka::exception(CODEPOINT,"Unspecified root for shared objects"); | 217 | throw konforka::exception(CODEPOINT,"Unspecified root for shared objects"); |
217 | sitespace ss(config); | 218 | sitespace ss(config); |
218 | site_space = &ss; | 219 | site_space = &ss; |
219 | if(optind<argc) { | 220 | if(optind<argc) { |
220 | for(int narg=optind;narg<argc;narg++) { | 221 | for(int narg=optind;narg<argc;narg++) { |
221 | const char *arg = argv[narg]; | 222 | const char *arg = argv[narg]; |
222 | build(arg); | 223 | build(arg); |
223 | } | 224 | } |
224 | }else | 225 | }else |
225 | build("/"); | 226 | build("/"); |
226 | return 0; | 227 | return 0; |
227 | }catch(exception& e) { | 228 | }catch(exception& e) { |
228 | cerr << "Oops: " << e.what() << endl; | 229 | cerr << "Oops: " << e.what() << endl; |
229 | return 1; | 230 | return 1; |
230 | } | 231 | } |
231 | } | 232 | } |
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 | |||
@@ -1,328 +1,328 @@ | |||
1 | #include <sys/types.h> | 1 | #include <sys/types.h> |
2 | #include <unistd.h> | 2 | #include <unistd.h> |
3 | #include <signal.h> | 3 | #include <signal.h> |
4 | #include <getopt.h> | 4 | #include <getopt.h> |
5 | #include <pwd.h> | 5 | #include <pwd.h> |
6 | #include <grp.h> | 6 | #include <grp.h> |
7 | #include <errno.h> | 7 | #include <errno.h> |
8 | #include <syslog.h> | 8 | #include <syslog.h> |
9 | #include <iostream> | 9 | #include <iostream> |
10 | #include <memory> | 10 | #include <memory> |
11 | #include <typeinfo> | 11 | #include <typeinfo> |
12 | using namespace std; | 12 | using namespace std; |
13 | #include "kingate/fastcgi.h" | 13 | #include "kingate/fastcgi.h" |
14 | #include "kingate/cgi_gateway.h" | 14 | #include "kingate/cgi_gateway.h" |
15 | using namespace kingate; | 15 | using namespace kingate; |
16 | #include "sitecing/sitecing_util.h" | 16 | #include "sitecing/sitecing_util.h" |
17 | #include "sitecing/util.h" | 17 | #include "sitecing/util.h" |
18 | #include "sitecing/sitespace.h" | 18 | #include "sitecing/sitespace.h" |
19 | #include "sitecing/sitecing_interface_cgi.h" | 19 | #include "sitecing/sitecing_interface_cgi.h" |
20 | #include "sitecing/cgi_component.h" | 20 | #include "sitecing/cgi_component.h" |
21 | #include "sitecing/configuration.h" | 21 | #include "sitecing/configuration.h" |
22 | #include "sitecing/magic.h" | 22 | #include "sitecing/magic.h" |
23 | #include "sitecing/sitecing_exception.h" | 23 | #include "sitecing/sitecing_exception.h" |
24 | #include "sitecing/exception.h" | 24 | #include "sitecing/exception.h" |
25 | #include "sitecing/process_manager.h" | 25 | #include "sitecing/process_manager.h" |
26 | using namespace sitecing; | 26 | using namespace sitecing; |
27 | 27 | ||
28 | #include "config.h" | 28 | #include "config.h" |
29 | #define PHEADER PACKAGE " Version " VERSION | 29 | #define PHEADER PACKAGE " Version " VERSION |
30 | #define PCOPY "Copyright (c) 2004 Klever Group" | 30 | #define PCOPY "Copyright (c) 2004 Klever Group" |
31 | 31 | ||
32 | class cdummyClass : public acomponent { | 32 | class cdummyClass : public acomponent { |
33 | public: | 33 | public: |
34 | void main(int _magic,va_list _args) {} | 34 | void main(int _magic,va_list _args) {} |
35 | void *__the_most_derived_this() { return NULL; } | 35 | void *__the_most_derived_this() { return NULL; } |
36 | } cdummyInstance; | 36 | } cdummyInstance; |
37 | class adummyClass : public cgi_component { | 37 | class adummyClass : public cgi_component { |
38 | public: | 38 | public: |
39 | void main(int _magic,va_list _args) {} | 39 | void main(int _magic,va_list _args) {} |
40 | void *__the_most_derived_this() { return NULL; } | 40 | void *__the_most_derived_this() { return NULL; } |
41 | } adummyInstance; | 41 | } adummyInstance; |
42 | 42 | ||
43 | class sitecing_fastcgi_pm : public process_manager { | 43 | class sitecing_fastcgi_pm : public process_manager { |
44 | public: | 44 | public: |
45 | configuration config; | 45 | configuration config; |
46 | fcgi_socket *fss; | 46 | fcgi_socket *fss; |
47 | semaphore sem; | 47 | semaphore sem; |
48 | bool multi; | 48 | bool multi; |
49 | uid_t uid; | 49 | uid_t uid; |
50 | gid_t gid; | 50 | gid_t gid; |
51 | pid_file pidfile; | 51 | pid_file pidfile; |
52 | 52 | ||
53 | sitecing_fastcgi_pm(const string& config_file); | 53 | sitecing_fastcgi_pm(const string& config_file); |
54 | ~sitecing_fastcgi_pm(); | 54 | ~sitecing_fastcgi_pm(); |
55 | 55 | ||
56 | void process(int slot); | 56 | void process(int slot); |
57 | 57 | ||
58 | void run(); | 58 | void run(); |
59 | void give_up_privs(); | 59 | void give_up_privs(); |
60 | }; | 60 | }; |
61 | 61 | ||
62 | sitecing_fastcgi_pm::sitecing_fastcgi_pm(const string& config_file) | 62 | sitecing_fastcgi_pm::sitecing_fastcgi_pm(const string& config_file) |
63 | : config(config_file), multi(false) { | 63 | : config(config_file), multi(false) { |
64 | if(( (config.flags&configuration::flag_user) || (config.flags&configuration::flag_group) || (config.flags&configuration::flag_chroot) ) && geteuid() ) | 64 | if(( (config.flags&configuration::flag_user) || (config.flags&configuration::flag_group) || (config.flags&configuration::flag_chroot) ) && geteuid() ) |
65 | throw konforka::exception(CODEPOINT,"can't use User, Group or Chroot when started without root privileges"); | 65 | throw konforka::exception(CODEPOINT,"can't use User, Group or Chroot when started without root privileges"); |
66 | if(config.flags&configuration::flag_user) { | 66 | if(config.flags&configuration::flag_user) { |
67 | struct passwd *ptmp = getpwnam(config.user.c_str()); | 67 | struct passwd *ptmp = getpwnam(config.user.c_str()); |
68 | if(ptmp) { | 68 | if(ptmp) { |
69 | uid = ptmp->pw_uid; | 69 | uid = ptmp->pw_uid; |
70 | }else{ | 70 | }else{ |
71 | errno=0; | 71 | errno=0; |
72 | uid = strtol(config.user.c_str(),NULL,0); | 72 | uid = strtol(config.user.c_str(),NULL,0); |
73 | if(errno) | 73 | if(errno) |
74 | throw konforka::exception(CODEPOINT,"failed to resolve User value to uid"); | 74 | throw konforka::exception(CODEPOINT,"failed to resolve User value to uid"); |
75 | } | 75 | } |
76 | } | 76 | } |
77 | if(config.flags&configuration::flag_group) { | 77 | if(config.flags&configuration::flag_group) { |
78 | struct group *gtmp = getgrnam(config.group.c_str()); | 78 | struct group *gtmp = getgrnam(config.group.c_str()); |
79 | if(gtmp) { | 79 | if(gtmp) { |
80 | gid = gtmp->gr_gid; | 80 | gid = gtmp->gr_gid; |
81 | }else{ | 81 | }else{ |
82 | errno=0; | 82 | errno=0; |
83 | gid = strtol(config.group.c_str(),NULL,0); | 83 | gid = strtol(config.group.c_str(),NULL,0); |
84 | if(errno) | 84 | if(errno) |
85 | throw konforka::exception(CODEPOINT,"failed to resolve Group value to gid"); | 85 | throw konforka::exception(CODEPOINT,"failed to resolve Group value to gid"); |
86 | } | 86 | } |
87 | } | 87 | } |
88 | if(!(config.flags&configuration::flag_root_source)) | 88 | if(!(config.flags&configuration::flag_root_source)) |
89 | throw konforka::exception(CODEPOINT,"unspecified root for sources"); | 89 | throw konforka::exception(CODEPOINT,"unspecified root for sources"); |
90 | if(!(config.flags&configuration::flag_root_intermediate)) | 90 | if(!(config.flags&configuration::flag_root_intermediate)) |
91 | throw konforka::exception(CODEPOINT,"unspecified root for intermediate files"); | 91 | throw konforka::exception(CODEPOINT,"unspecified root for intermediate files"); |
92 | if(!(config.flags&configuration::flag_root_so)) | 92 | if(!(config.flags&configuration::flag_root_so)) |
93 | throw konforka::exception(CODEPOINT,"unspecified root for shared objects"); | 93 | throw konforka::exception(CODEPOINT,"unspecified root for shared objects"); |
94 | if(config.flags&configuration::flag_min_children) | 94 | if(config.flags&configuration::flag_min_children) |
95 | min_children = config.min_children; | 95 | min_children = config.min_children; |
96 | if(config.flags&configuration::flag_max_children) | 96 | if(config.flags&configuration::flag_max_children) |
97 | max_children = config.max_children; | 97 | max_children = config.max_children; |
98 | if(config.flags&configuration::flag_min_spare_children) | 98 | if(config.flags&configuration::flag_min_spare_children) |
99 | min_spare_children = config.min_spare_children; | 99 | min_spare_children = config.min_spare_children; |
100 | if(config.flags&configuration::flag_max_spare_children) | 100 | if(config.flags&configuration::flag_max_spare_children) |
101 | max_spare_children = config.max_spare_children; | 101 | max_spare_children = config.max_spare_children; |
102 | if(max_children<min_spare_children) | 102 | if(max_children<min_spare_children) |
103 | throw konforka::exception(CODEPOINT,"inconsistent numbers of MaxChildren and MinSpareChildren"); | 103 | throw konforka::exception(CODEPOINT,"inconsistent numbers of MaxChildren and MinSpareChildren"); |
104 | if(min_children>max_spare_children && max_spare_children>=0) | 104 | if(min_children>max_spare_children && max_spare_children>=0) |
105 | throw konforka::exception(CODEPOINT,"inconsistent numbers of MinChildren and MaxSpareChildren"); | 105 | throw konforka::exception(CODEPOINT,"inconsistent numbers of MinChildren and MaxSpareChildren"); |
106 | if(config.flags&configuration::flag_multi_process) { | 106 | if(config.flags&configuration::flag_multi_process) { |
107 | multi = config.multi_process; | 107 | multi = config.multi_process; |
108 | }else{ | 108 | }else{ |
109 | if(config.flags&configuration::flag_listen_socket) | 109 | if(config.flags&configuration::flag_listen_socket) |
110 | multi = true; | 110 | multi = true; |
111 | else | 111 | else |
112 | multi = false; | 112 | multi = false; |
113 | } | 113 | } |
114 | fss = (config.flags&configuration::flag_listen_socket)?new fcgi_socket(config.listen_socket.c_str(),5):new fcgi_socket(0); | 114 | fss = (config.flags&configuration::flag_listen_socket)?new fcgi_socket(config.listen_socket.c_str(),5):new fcgi_socket(0); |
115 | if(!fss) | 115 | if(!fss) |
116 | throw konforka::exception(CODEPOINT,"failed to establish listening socket"); | 116 | throw konforka::exception(CODEPOINT,"failed to establish listening socket"); |
117 | if(config.flags&configuration::flag_daemonize && config.daemonize) { | 117 | if(config.flags&configuration::flag_daemonize && config.daemonize) { |
118 | pid_t pf = fork(); | 118 | pid_t pf = fork(); |
119 | if(pf<0) | 119 | if(pf<0) |
120 | throw konforka::exception(CODEPOINT,"failed to fork()"); | 120 | throw konforka::exception(CODEPOINT,"failed to fork()"); |
121 | if(pf) { | 121 | if(pf) { |
122 | die_humbly=true; | 122 | die_humbly=true; |
123 | _exit(0); | 123 | _exit(0); |
124 | } | 124 | } |
125 | } | 125 | } |
126 | if(config.flags&configuration::flag_pid_file) { | 126 | if(config.flags&configuration::flag_pid_file) { |
127 | pidfile.set(config.pid_file); | 127 | pidfile.set(config.pid_file); |
128 | } | 128 | } |
129 | if(multi) | 129 | if(multi) |
130 | sem.init(); | 130 | sem.init(); |
131 | } | 131 | } |
132 | sitecing_fastcgi_pm::~sitecing_fastcgi_pm() { | 132 | sitecing_fastcgi_pm::~sitecing_fastcgi_pm() { |
133 | if(fss) | 133 | if(fss) |
134 | delete fss; | 134 | delete fss; |
135 | } | 135 | } |
136 | 136 | ||
137 | void sitecing_fastcgi_pm::process(int slot) { | 137 | void sitecing_fastcgi_pm::process(int slot) { |
138 | signal(SIGINT,SIG_DFL); | 138 | signal(SIGINT,SIG_DFL); |
139 | signal(SIGABRT,SIG_DFL); | 139 | signal(SIGABRT,SIG_DFL); |
140 | signal(SIGTERM,SIG_DFL); | 140 | signal(SIGTERM,SIG_DFL); |
141 | give_up_privs(); | 141 | give_up_privs(); |
142 | scoreboard_slot *sslot = sboard.get_slot(slot); | 142 | scoreboard_slot *sslot = sboard.get_slot(slot); |
143 | try { | 143 | try { |
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()); |
212 | }else{ | 212 | }else{ |
213 | ce.see(CODEPOINT); | 213 | ce.see(CODEPOINT); |
214 | throw; | 214 | throw; |
215 | } | 215 | } |
216 | }catch(preprocessor_error& pe) { | 216 | }catch(preprocessor_error& pe) { |
217 | config_options *co_exception_handler = config.lookup_config(component_path,config_options::flag_exception_handler); | 217 | config_options *co_exception_handler = config.lookup_config(component_path,config_options::flag_exception_handler); |
218 | if(co_exception_handler) { | 218 | if(co_exception_handler) { |
219 | so_component eh = ss.fetch(co_exception_handler->exception_handler,&scif); // TODO: handle error trying to handle error. | 219 | so_component eh = ss.fetch(co_exception_handler->exception_handler,&scif); // TODO: handle error trying to handle error. |
220 | eh.ac->run(__magic_preprocess_error,pe.what(),config.root_source.c_str(),config.root_intermediate.c_str(),config.root_so.c_str(),pe.component_name.c_str(),pe.line_number); | 220 | eh.ac->run(__magic_preprocess_error,pe.what(),config.root_source.c_str(),config.root_intermediate.c_str(),config.root_so.c_str(),pe.component_name.c_str(),pe.line_number); |
221 | }else{ | 221 | }else{ |
222 | pe.see(CODEPOINT); | 222 | pe.see(CODEPOINT); |
223 | throw; | 223 | throw; |
224 | } | 224 | } |
225 | }catch(exception& e) { | 225 | }catch(exception& e) { |
226 | config_options *co_exception_handler = config.lookup_config(component_path,config_options::flag_exception_handler); | 226 | config_options *co_exception_handler = config.lookup_config(component_path,config_options::flag_exception_handler); |
227 | if(co_exception_handler) { | 227 | if(co_exception_handler) { |
228 | so_component eh = ss.fetch(co_exception_handler->exception_handler,&scif); // TODO: handle error trying to handle error. | 228 | so_component eh = ss.fetch(co_exception_handler->exception_handler,&scif); // TODO: handle error trying to handle error. |
229 | eh.ac->run(__magic_generic_exception,e.what(),config.root_source.c_str(),config.root_intermediate.c_str(),config.root_so.c_str(),component_path.c_str(),&e); | 229 | eh.ac->run(__magic_generic_exception,e.what(),config.root_source.c_str(),config.root_intermediate.c_str(),config.root_so.c_str(),component_path.c_str(),&e); |
230 | } | 230 | } |
231 | } | 231 | } |
232 | scif.flush(); | 232 | scif.flush(); |
233 | } | 233 | } |
234 | }catch(exception& e) { | 234 | }catch(exception& e) { |
235 | cerr << "->Oops: " << e.what() << endl; | 235 | cerr << "->Oops: " << e.what() << endl; |
236 | } | 236 | } |
237 | } | 237 | } |
238 | 238 | ||
239 | void sitecing_fastcgi_pm::run() { | 239 | void sitecing_fastcgi_pm::run() { |
240 | if(multi) | 240 | if(multi) |
241 | manage(); | 241 | manage(); |
242 | else | 242 | else |
243 | process(0); | 243 | process(0); |
244 | } | 244 | } |
245 | 245 | ||
246 | void sitecing_fastcgi_pm::give_up_privs() { | 246 | void sitecing_fastcgi_pm::give_up_privs() { |
247 | if(config.flags&configuration::flag_chroot) { | 247 | if(config.flags&configuration::flag_chroot) { |
248 | if(chroot(config.chroot.c_str())) | 248 | if(chroot(config.chroot.c_str())) |
249 | throw konforka::exception(CODEPOINT,"failed to chroot()"); | 249 | throw konforka::exception(CODEPOINT,"failed to chroot()"); |
250 | } | 250 | } |
251 | if(config.flags&configuration::flag_group) { | 251 | if(config.flags&configuration::flag_group) { |
252 | if((getgid()!=gid) && setgid(gid)) | 252 | if((getgid()!=gid) && setgid(gid)) |
253 | throw konforka::exception(CODEPOINT,"failed to setgid()"); | 253 | throw konforka::exception(CODEPOINT,"failed to setgid()"); |
254 | } | 254 | } |
255 | if(config.flags&configuration::flag_user) { | 255 | if(config.flags&configuration::flag_user) { |
256 | if((getuid()!=uid) && setuid(uid)) | 256 | if((getuid()!=uid) && setuid(uid)) |
257 | throw konforka::exception(CODEPOINT,"failed to setuid()"); | 257 | throw konforka::exception(CODEPOINT,"failed to setuid()"); |
258 | } | 258 | } |
259 | } | 259 | } |
260 | 260 | ||
261 | static sitecing_fastcgi_pm* _process_manager = NULL; | 261 | static sitecing_fastcgi_pm* _process_manager = NULL; |
262 | 262 | ||
263 | static void lethal_signal_handler(int signum) { | 263 | static void lethal_signal_handler(int signum) { |
264 | _process_manager->finishing=true; | 264 | _process_manager->finishing=true; |
265 | } | 265 | } |
266 | 266 | ||
267 | int main(int argc,char **argv) { | 267 | int main(int argc,char **argv) { |
268 | const char* id = *argv; | 268 | const char* id = *argv; |
269 | const char* t; | 269 | const char* t; |
270 | while(t = index(id,'/')) { | 270 | while(t = index(id,'/')) { |
271 | id=t; id++; | 271 | id=t; id++; |
272 | } | 272 | } |
273 | openlog(id,LOG_PERROR|LOG_PID,LOG_USER); | 273 | openlog(id,LOG_PERROR|LOG_PID,LOG_USER); |
274 | try { | 274 | try { |
275 | string config_file = "sitecing.conf"; | 275 | string config_file = "sitecing.conf"; |
276 | while(true) { | 276 | while(true) { |
277 | static struct option opts[] = { | 277 | static struct option opts[] = { |
278 | { "help", no_argument, 0, 'h' }, | 278 | { "help", no_argument, 0, 'h' }, |
279 | { "usage", no_argument, 0, 'h' }, | 279 | { "usage", no_argument, 0, 'h' }, |
280 | { "version", no_argument, 0, 'V' }, | 280 | { "version", no_argument, 0, 'V' }, |
281 | { "license", no_argument, 0, 'L' }, | 281 | { "license", no_argument, 0, 'L' }, |
282 | { "config", required_argument, 0, 'f' }, | 282 | { "config", required_argument, 0, 'f' }, |
283 | { NULL, 0, 0, 0 } | 283 | { NULL, 0, 0, 0 } |
284 | }; | 284 | }; |
285 | int c = getopt_long(argc,argv,"f:hVL",opts,NULL); | 285 | int c = getopt_long(argc,argv,"f:hVL",opts,NULL); |
286 | if(c==-1) | 286 | if(c==-1) |
287 | break; | 287 | break; |
288 | switch(c) { | 288 | switch(c) { |
289 | case 'h': | 289 | case 'h': |
290 | cerr << PHEADER << endl | 290 | cerr << PHEADER << endl |
291 | << PCOPY << endl << endl | 291 | << PCOPY << endl << endl |
292 | << " -h, --help" << endl | 292 | << " -h, --help" << endl |
293 | << " --usage display this text" << endl | 293 | << " --usage display this text" << endl |
294 | << " -V, --version display version number" << endl | 294 | << " -V, --version display version number" << endl |
295 | << " -L, --license show license" << endl | 295 | << " -L, --license show license" << endl |
296 | << " -f filename, --config=filename" << endl | 296 | << " -f filename, --config=filename" << endl |
297 | << " specify configuration file to use" << endl; | 297 | << " specify configuration file to use" << endl; |
298 | exit(0); | 298 | exit(0); |
299 | break; | 299 | break; |
300 | case 'V': | 300 | case 'V': |
301 | cerr << VERSION << endl; | 301 | cerr << VERSION << endl; |
302 | exit(0); | 302 | exit(0); |
303 | break; | 303 | break; |
304 | case 'L': | 304 | case 'L': |
305 | extern const char *COPYING; | 305 | extern const char *COPYING; |
306 | cerr << COPYING << endl; | 306 | cerr << COPYING << endl; |
307 | exit(0); | 307 | exit(0); |
308 | break; | 308 | break; |
309 | case 'f': | 309 | case 'f': |
310 | config_file = optarg; | 310 | config_file = optarg; |
311 | break; | 311 | break; |
312 | default: | 312 | default: |
313 | cerr << "Huh??" << endl; | 313 | cerr << "Huh??" << endl; |
314 | break; | 314 | break; |
315 | } | 315 | } |
316 | } | 316 | } |
317 | sitecing_fastcgi_pm sfpm(config_file); | 317 | sitecing_fastcgi_pm sfpm(config_file); |
318 | _process_manager = &sfpm; | 318 | _process_manager = &sfpm; |
319 | signal(SIGINT,lethal_signal_handler); | 319 | signal(SIGINT,lethal_signal_handler); |
320 | signal(SIGABRT,lethal_signal_handler); | 320 | signal(SIGABRT,lethal_signal_handler); |
321 | signal(SIGTERM,lethal_signal_handler); | 321 | signal(SIGTERM,lethal_signal_handler); |
322 | sfpm.run(); | 322 | sfpm.run(); |
323 | }catch(exception& e) { | 323 | }catch(exception& e) { |
324 | /* cerr << "Oops: " << e.what() << endl; */ | 324 | /* cerr << "Oops: " << e.what() << endl; */ |
325 | syslog(LOG_ERR,"uncaught exception: %s",e.what()); | 325 | syslog(LOG_ERR,"uncaught exception: %s",e.what()); |
326 | } | 326 | } |
327 | closelog(); | 327 | closelog(); |
328 | } | 328 | } |
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 | |||
@@ -1,181 +1,181 @@ | |||
1 | #include <sys/types.h> | 1 | #include <sys/types.h> |
2 | #include <unistd.h> | 2 | #include <unistd.h> |
3 | #include <signal.h> | 3 | #include <signal.h> |
4 | #include <getopt.h> | 4 | #include <getopt.h> |
5 | #include <pwd.h> | 5 | #include <pwd.h> |
6 | #include <grp.h> | 6 | #include <grp.h> |
7 | #include <errno.h> | 7 | #include <errno.h> |
8 | #include <syslog.h> | 8 | #include <syslog.h> |
9 | #include <iostream> | 9 | #include <iostream> |
10 | #include <memory> | 10 | #include <memory> |
11 | #include <typeinfo> | 11 | #include <typeinfo> |
12 | using namespace std; | 12 | using namespace std; |
13 | #include "kingate/plaincgi.h" | 13 | #include "kingate/plaincgi.h" |
14 | #include "kingate/cgi_gateway.h" | 14 | #include "kingate/cgi_gateway.h" |
15 | using namespace kingate; | 15 | using namespace kingate; |
16 | #include "sitecing/sitecing_util.h" | 16 | #include "sitecing/sitecing_util.h" |
17 | #include "sitecing/util.h" | 17 | #include "sitecing/util.h" |
18 | #include "sitecing/sitespace.h" | 18 | #include "sitecing/sitespace.h" |
19 | #include "sitecing/sitecing_interface_cgi.h" | 19 | #include "sitecing/sitecing_interface_cgi.h" |
20 | #include "sitecing/cgi_component.h" | 20 | #include "sitecing/cgi_component.h" |
21 | #include "sitecing/configuration.h" | 21 | #include "sitecing/configuration.h" |
22 | #include "sitecing/magic.h" | 22 | #include "sitecing/magic.h" |
23 | #include "sitecing/sitecing_exception.h" | 23 | #include "sitecing/sitecing_exception.h" |
24 | #include "sitecing/exception.h" | 24 | #include "sitecing/exception.h" |
25 | using namespace sitecing; | 25 | using namespace sitecing; |
26 | 26 | ||
27 | #include "config.h" | 27 | #include "config.h" |
28 | #define PHEADER PACKAGE " Version " VERSION | 28 | #define PHEADER PACKAGE " Version " VERSION |
29 | #define PCOPY "Copyright (c) 2005 Klever Group" | 29 | #define PCOPY "Copyright (c) 2005 Klever Group" |
30 | 30 | ||
31 | class cdummyClass : public acomponent { | 31 | class 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; |
36 | class adummyClass : public cgi_component { | 36 | class 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 | ||
42 | void process_request(configuration& config) { | 42 | void 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()); |
97 | }else{ | 97 | }else{ |
98 | ce.see(CODEPOINT); | 98 | ce.see(CODEPOINT); |
99 | throw; | 99 | throw; |
100 | } | 100 | } |
101 | }catch(preprocessor_error& pe) { | 101 | }catch(preprocessor_error& pe) { |
102 | config_options *co_exception_handler = config.lookup_config(component_path,config_options::flag_exception_handler); | 102 | config_options *co_exception_handler = config.lookup_config(component_path,config_options::flag_exception_handler); |
103 | if(co_exception_handler) { | 103 | if(co_exception_handler) { |
104 | so_component eh = ss.fetch(co_exception_handler->exception_handler,&scif); // TODO: handle error trying to handle error. | 104 | so_component eh = ss.fetch(co_exception_handler->exception_handler,&scif); // TODO: handle error trying to handle error. |
105 | eh.ac->run(__magic_preprocess_error,pe.what(),config.root_source.c_str(),config.root_intermediate.c_str(),config.root_so.c_str(),pe.component_name.c_str(),pe.line_number); | 105 | eh.ac->run(__magic_preprocess_error,pe.what(),config.root_source.c_str(),config.root_intermediate.c_str(),config.root_so.c_str(),pe.component_name.c_str(),pe.line_number); |
106 | }else{ | 106 | }else{ |
107 | pe.see(CODEPOINT); | 107 | pe.see(CODEPOINT); |
108 | throw; | 108 | throw; |
109 | } | 109 | } |
110 | }catch(exception& e) { | 110 | }catch(exception& e) { |
111 | config_options *co_exception_handler = config.lookup_config(component_path,config_options::flag_exception_handler); | 111 | config_options *co_exception_handler = config.lookup_config(component_path,config_options::flag_exception_handler); |
112 | if(co_exception_handler) { | 112 | if(co_exception_handler) { |
113 | so_component eh = ss.fetch(co_exception_handler->exception_handler,&scif); // TODO: handle error trying to handle error. | 113 | so_component eh = ss.fetch(co_exception_handler->exception_handler,&scif); // TODO: handle error trying to handle error. |
114 | eh.ac->run(__magic_generic_exception,e.what(),config.root_source.c_str(),config.root_intermediate.c_str(),config.root_so.c_str(),component_path.c_str(),&e); | 114 | eh.ac->run(__magic_generic_exception,e.what(),config.root_source.c_str(),config.root_intermediate.c_str(),config.root_so.c_str(),component_path.c_str(),&e); |
115 | } | 115 | } |
116 | } | 116 | } |
117 | scif.flush(); | 117 | scif.flush(); |
118 | }catch(exception& e) { | 118 | }catch(exception& e) { |
119 | cerr << "->Oops: " << e.what() << endl; | 119 | cerr << "->Oops: " << e.what() << endl; |
120 | } | 120 | } |
121 | } | 121 | } |
122 | 122 | ||
123 | int main(int argc,char **argv) { | 123 | int main(int argc,char **argv) { |
124 | const char* id = *argv; | 124 | const char* id = *argv; |
125 | const char* t; | 125 | const char* t; |
126 | while(t = index(id,'/')) { | 126 | while(t = index(id,'/')) { |
127 | id=t; id++; | 127 | id=t; id++; |
128 | } | 128 | } |
129 | openlog(id,LOG_PERROR|LOG_PID,LOG_USER); | 129 | openlog(id,LOG_PERROR|LOG_PID,LOG_USER); |
130 | try { | 130 | try { |
131 | const char *esccf = getenv("SITECING_CONF"); | 131 | const char *esccf = getenv("SITECING_CONF"); |
132 | string config_file = esccf ? esccf : "sitecing.conf"; | 132 | string config_file = esccf ? esccf : "sitecing.conf"; |
133 | while(true) { | 133 | while(true) { |
134 | static struct option opts[] = { | 134 | static struct option opts[] = { |
135 | { "help", no_argument, 0, 'h' }, | 135 | { "help", no_argument, 0, 'h' }, |
136 | { "usage", no_argument, 0, 'h' }, | 136 | { "usage", no_argument, 0, 'h' }, |
137 | { "version", no_argument, 0, 'V' }, | 137 | { "version", no_argument, 0, 'V' }, |
138 | { "license", no_argument, 0, 'L' }, | 138 | { "license", no_argument, 0, 'L' }, |
139 | { "config", required_argument, 0, 'f' }, | 139 | { "config", required_argument, 0, 'f' }, |
140 | { NULL, 0, 0, 0 } | 140 | { NULL, 0, 0, 0 } |
141 | }; | 141 | }; |
142 | int c = getopt_long(argc,argv,"f:hVL",opts,NULL); | 142 | int c = getopt_long(argc,argv,"f:hVL",opts,NULL); |
143 | if(c==-1) | 143 | if(c==-1) |
144 | break; | 144 | break; |
145 | switch(c) { | 145 | switch(c) { |
146 | case 'h': | 146 | case 'h': |
147 | cerr << PHEADER << endl | 147 | cerr << PHEADER << endl |
148 | << PCOPY << endl << endl | 148 | << PCOPY << endl << endl |
149 | << " -h, --help" << endl | 149 | << " -h, --help" << endl |
150 | << " --usage display this text" << endl | 150 | << " --usage display this text" << endl |
151 | << " -V, --version display version number" << endl | 151 | << " -V, --version display version number" << endl |
152 | << " -L, --license show license" << endl | 152 | << " -L, --license show license" << endl |
153 | << " -f filename, --config=filename" << endl | 153 | << " -f filename, --config=filename" << endl |
154 | << " specify configuration file to use" << endl; | 154 | << " specify configuration file to use" << endl; |
155 | exit(0); | 155 | exit(0); |
156 | break; | 156 | break; |
157 | case 'V': | 157 | case 'V': |
158 | cerr << VERSION << endl; | 158 | cerr << VERSION << endl; |
159 | exit(0); | 159 | exit(0); |
160 | break; | 160 | break; |
161 | case 'L': | 161 | case 'L': |
162 | extern const char *COPYING; | 162 | extern const char *COPYING; |
163 | cerr << COPYING << endl; | 163 | cerr << COPYING << endl; |
164 | exit(0); | 164 | exit(0); |
165 | break; | 165 | break; |
166 | case 'f': | 166 | case 'f': |
167 | config_file = optarg; | 167 | config_file = optarg; |
168 | break; | 168 | break; |
169 | default: | 169 | default: |
170 | cerr << "Huh??" << endl; | 170 | cerr << "Huh??" << endl; |
171 | break; | 171 | break; |
172 | } | 172 | } |
173 | } | 173 | } |
174 | configuration config(config_file); | 174 | configuration config(config_file); |
175 | process_request(config); | 175 | process_request(config); |
176 | }catch(exception& e) { | 176 | }catch(exception& e) { |
177 | /* cerr << "Oops: " << e.what() << endl; */ | 177 | /* cerr << "Oops: " << e.what() << endl; */ |
178 | syslog(LOG_ERR,"uncaught exception: %s",e.what()); | 178 | syslog(LOG_ERR,"uncaught exception: %s",e.what()); |
179 | } | 179 | } |
180 | closelog(); | 180 | closelog(); |
181 | } | 181 | } |