summaryrefslogtreecommitdiffabout
path: root/include
Unidiff
Diffstat (limited to 'include') (more/less context) (show whitespace changes)
-rw-r--r--include/.gitignore2
-rw-r--r--include/Makefile.am18
-rw-r--r--include/sitecing/acomponent.h78
-rw-r--r--include/sitecing/cgi_component.h54
-rw-r--r--include/sitecing/component_factory.h84
-rw-r--r--include/sitecing/component_so.h159
-rw-r--r--include/sitecing/configuration.h459
-rw-r--r--include/sitecing/exception.h542
-rw-r--r--include/sitecing/file_factory.h64
-rw-r--r--include/sitecing/magic.h63
-rw-r--r--include/sitecing/process_manager.h89
-rw-r--r--include/sitecing/scoreboard.h102
-rw-r--r--include/sitecing/sitecing_enflesher.h65
-rw-r--r--include/sitecing/sitecing_exception.h103
-rw-r--r--include/sitecing/sitecing_interface.h40
-rw-r--r--include/sitecing/sitecing_interface_cgi.h62
-rw-r--r--include/sitecing/sitecing_parser.h326
-rw-r--r--include/sitecing/sitecing_util.h341
-rw-r--r--include/sitecing/sitespace.h76
-rw-r--r--include/sitecing/util.h148
20 files changed, 2875 insertions, 0 deletions
diff --git a/include/.gitignore b/include/.gitignore
new file mode 100644
index 0000000..3dda729
--- a/dev/null
+++ b/include/.gitignore
@@ -0,0 +1,2 @@
1Makefile.in
2Makefile
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100644
index 0000000..88148d5
--- a/dev/null
+++ b/include/Makefile.am
@@ -0,0 +1,18 @@
1 #TODO: separate installable headers from internals
2 # but to make it sensible one need to elimitate
3 # abnoxious sitecing_interface_cgi.h inclusion of
4 # sitespace.h
5nobase_include_HEADERS = \
6 sitecing/acomponent.h sitecing/cgi_component.h \
7 sitecing/component_so.h \
8 sitecing/file_factory.h sitecing/component_factory.h \
9 sitecing/sitecing_interface.h sitecing/sitecing_interface_cgi.h \
10 sitecing/sitecing_parser.h sitecing/sitecing_enflesher.h \
11 sitecing/sitespace.h \
12 sitecing/configuration.h \
13 sitecing/magic.h sitecing/util.h \
14 sitecing/exception.h sitecing/sitecing_exception.h \
15 sitecing/sitecing_util.h \
16 sitecing/process_manager.h \
17 sitecing/scoreboard.h
18
diff --git a/include/sitecing/acomponent.h b/include/sitecing/acomponent.h
new file mode 100644
index 0000000..160e854
--- a/dev/null
+++ b/include/sitecing/acomponent.h
@@ -0,0 +1,78 @@
1#ifndef __SITECING_ACOMPONENT_H
2#define __SITECING_ACOMPONENT_H
3
4#include "sitecing/sitecing_interface.h"
5
6/**
7 * @file
8 * @brief The acomponent class declaration.
9 */
10
11namespace sitecing {
12
13 /**
14 * An abstract base class for sitecing components.
15 */
16 class acomponent {
17 public:
18 /**
19 * Pointer to the interface object, used to communicate with the
20 * site-C-ing core.
21 */
22 sitecing_interface *__SCIF;
23
24 acomponent();
25 virtual ~acomponent();
26
27 /**
28 * Set the interface to core pointer.
29 * @param scif the pointer to the interface object.
30 */
31 virtual void __set_interface(sitecing_interface *scif=0);
32 /**
33 * Invoked if the interface to the core has changed.
34 * @param oscif pointer to the old interface object.
35 */
36 virtual void __on_change_interface(sitecing_interface *oscif);
37
38 /**
39 * do import components.
40 */
41 virtual void __do_imports();
42 /**
43 * invoked on components imports.
44 */
45 virtual void __on_imports();
46 /**
47 * fetch the pointer to the most derived component.
48 * @returns pointer to the most derived object.
49 */
50 virtual void *__the_most_derived_this() = 0;
51
52 /**
53 * Do the job.
54 * @param __magic the magic number used as a key to decipher the
55 * rest of parameters.
56 * @param __args the parameters.
57 */
58 virtual void main(int __magic,va_list __args) = 0;
59
60 /**
61 * Run the component. Convenience helper for calling main().
62 * @param __magic the magic number.
63 * @param ... the rest of parameters.
64 * @see main();
65 */
66 void run(int __magic,...);
67
68 /**
69 * Helper function (which doesn't necessarily belongs here!) for
70 * reading the file and passing it to the output stream.
71 * @param fn the file name.
72 */
73 void pass_file_through(const char *fn);
74 };
75
76}
77
78#endif /* __SITECING_ACOMPONENT_H */
diff --git a/include/sitecing/cgi_component.h b/include/sitecing/cgi_component.h
new file mode 100644
index 0000000..91df689
--- a/dev/null
+++ b/include/sitecing/cgi_component.h
@@ -0,0 +1,54 @@
1#ifndef __SITECING_CGI_COMPONENT_H
2#define __SITECING_CGI_COMPONENT_H
3
4#include <map>
5#include "kingate/cgi_gateway.h"
6#include "sitecing/acomponent.h"
7#include "sitecing/sitecing_interface_cgi.h"
8
9/**
10 * @file
11 * @brief The cgi_component class declaration.
12 */
13
14namespace sitecing {
15 using namespace std;
16
17 /**
18 * The CGI-oriented component class.
19 */
20 class cgi_component : virtual public acomponent {
21 public:
22 /**
23 * The interface to site-C-ing core.
24 */
25 sitecing_interface_cgi* __SCIF;
26 /**
27 * The interface to the CGI gateway.
28 */
29 kingate::cgi_gateway* __CGI;
30
31 cgi_component();
32 virtual ~cgi_component();
33
34 /**
35 * @overload acomponent::__set_interface()
36 */
37 void __set_interface(sitecing_interface* scif);
38 /**
39 * @overload acomponent::__on_change_interface()
40 */
41 void __on_change_interface(sitecing_interface *o);
42 /**
43 * Invoked on the change of the interface to the CGI.
44 */
45 virtual void __on_change_CGI(kingate::cgi_gateway *o);
46 /**
47 * @overload acomponent::__on_imports()
48 */
49 virtual void __on_imports();
50 };
51
52}
53
54#endif /* __SITECING_CGI_COMPONENT_H */
diff --git a/include/sitecing/component_factory.h b/include/sitecing/component_factory.h
new file mode 100644
index 0000000..a208ed1
--- a/dev/null
+++ b/include/sitecing/component_factory.h
@@ -0,0 +1,84 @@
1#ifndef __SITECING_COMPONENT_FACTORY_H
2#define __SITECING_COMPONENT_FACTORY_H
3
4#include <string>
5#include <list>
6#include <stdexcept>
7#include "sitecing/file_factory.h"
8#include "sitecing/configuration.h"
9
10/**
11 * @file
12 * @brief The component_factory class declaration.
13 */
14
15namespace sitecing {
16 using namespace std;
17
18 /**
19 * @brief The components builder.
20 */
21 class component_factory : public file_factory {
22 public:
23 /**
24 * Path to the source files root.
25 */
26 string root_source;
27 /**
28 * Path to the root of the intermediate files storage.
29 */
30 string root_intermediate;
31 /**
32 * Output path for .so components.
33 */
34 string root_so;
35 /**
36 * Reference to the configuration container.
37 */
38 configuration& config;
39
40 /**
41 * @param c reference to the configuration container.
42 */
43 component_factory(configuration& c);
44
45 /**
46 * @overload file_factory::get_dependencies()
47 */
48 virtual void get_dependencies(const string& dst,file_list_t& deps);
49 /**
50 * @overload file_factory::is_uptodate()
51 */
52 virtual bool is_uptodate(const string& dst,file_list_t *deps=NULL);
53 /**
54 * @overload file_factory::build()
55 */
56 virtual void build(const string& dst);
57
58 /**
59 * Helper function for executing external command.
60 * @param cmd the command to execute.
61 * @param args the command line arguments.
62 * @param stdo stdout for the child process.
63 * @param stde stderr for the child process.
64 * @return exit code.
65 */
66 int execute(const string& cmd,const list<string>& args,int stdo,int stde);
67 /**
68 * Fetch the class name of the component.
69 * @param component the component.
70 * @return the class name.
71 */
72 string get_classname(const string& component);
73 /**
74 * Get the components from which the target component has been
75 * derived.
76 * @param component the target component
77 * @param rv where to store the list of ancestors.
78 */
79 void get_ancestors(const string& component,file_list_t &rv);
80 };
81
82}
83
84#endif /* __SITECING_COMPONENT_FACTORY_H */
diff --git a/include/sitecing/component_so.h b/include/sitecing/component_so.h
new file mode 100644
index 0000000..3239d4a
--- a/dev/null
+++ b/include/sitecing/component_so.h
@@ -0,0 +1,159 @@
1#ifndef __SITECING_COMPONENT_SO_H
2#define __SITECING_COMPONENT_SO_H
3
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <string>
7#include <map>
8#include <list>
9#include "sitecing/acomponent.h"
10
11/**
12 * @file
13 * @brief Classes related to the .so components handling.
14 */
15
16namespace sitecing {
17 using namespace std;
18
19 /**
20 * The 'class' component object.
21 */
22 class component_so {
23 public:
24 /**
25 * The type of the component instantiating function.
26 */
27 typedef acomponent *(*egg_t)();
28 /**
29 * Type for storing the list of instances and the reference counts.
30 */
31 typedef map<acomponent*,int> used_chickens_t;
32 /**
33 * The type for storing the list of unused instances.
34 */
35 typedef list<acomponent*> free_chickens_t;
36
37 /**
38 * The .so file name.
39 */
40 string sofile;
41 /**
42 * The stat structure for the .so loaded.
43 */
44 struct stat stso;
45 /**
46 * The dloaded .so handle.
47 */
48 void *dl;
49 /**
50 * Pointer to the instatiator function.
51 */
52 egg_t egg;
53 /**
54 * The list of instances in use.
55 */
56 used_chickens_t chickens_used;
57 /**
58 * The list of unused instances.
59 */
60 free_chickens_t chickens_free;
61
62 /**
63 * @param soname the .so file name
64 */
65 component_so(const string& soname);
66 ~component_so();
67 /**
68 * Check whether the loaded .so is in sync with the disk file.
69 */
70 bool is_uptodate() const;
71
72 /**
73 * @todo TODO: wish I could remember -- document me.
74 */
75 acomponent* allocate_chicken();
76 /**
77 * @todo TODO: wish I could remember -- document me.
78 */
79 void allocate_chicken(acomponent *ac);
80 /**
81 * @todo TODO: wish I could remember -- document me.
82 */
83 void deallocate_chicken(acomponent *ac);
84 };
85
86 /**
87 * The component instance container.
88 */
89 class so_component {
90 public:
91 /**
92 * Pointer to the component 'class'.
93 */
94 component_so *hen;
95 /**
96 * The instance in question.
97 */
98 acomponent* ac;
99
100 so_component()
101 : hen(0), ac(0) { }
102 /**
103 * @param h the 'class' object.
104 * @param scif pointer to the interface to the site-C-ing core.
105 */
106 so_component(component_so *h,sitecing_interface *scif);
107 /**
108 * Copy constructor
109 * @param s source instance.
110 */
111 so_component(const so_component& s)
112 : hen(0), ac(0) { attach(s); }
113 ~so_component() { detach(); }
114
115 /**
116 * Assignment operator.
117 * @param s source instance.
118 */
119 so_component& operator=(const so_component& s) {
120 attach(s); return *this;
121 }
122
123 /**
124 * @todo TODO: wish I could remember the details -- document me.
125 * @param h the 'class' object.
126 * @param a the instance to be attached.
127 */
128 void attach(component_so *h,acomponent *a);
129 /**
130 * @todo TODO: wish I could remember the details -- document me.
131 * @param s the source instance.
132 */
133 void attach(const so_component& s) { attach(s.hen,s.ac); }
134 /**
135 * @todo TODO: wish I could remember the details -- document me.
136 */
137 void detach();
138 };
139
140 /**
141 * The typed component instance container template.
142 * @param CT the component class.
143 */
144 template<typename CT>
145 class so_component_t : public sitecing::so_component {
146 public:
147 /**
148 * @param s The untyped instance container.
149 */
150 so_component_t(const so_component& s)
151 : so_component(s) { }
152 CT* operator->() {
153 return static_cast<CT*>(ac->__the_most_derived_this());
154 }
155 };
156
157}
158
159#endif /* __SITECING_COMPONENT_SO_H */
diff --git a/include/sitecing/configuration.h b/include/sitecing/configuration.h
new file mode 100644
index 0000000..330a5a6
--- a/dev/null
+++ b/include/sitecing/configuration.h
@@ -0,0 +1,459 @@
1#ifndef __SITECING_CONFIGURATION_H
2#define __SITECING_CONFIGURATION_H
3
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <string>
7#include <list>
8#include <map>
9#include <pcre++.h>
10
11/**
12 * @file
13 * @brief Classes related to configuration.
14 */
15
16namespace sitecing {
17 using namespace std;
18
19 class configuration;
20
21 /**
22 * The config options container class.
23 */
24 class config_options {
25 public:
26 /**
27 * The flags enumeration.
28 */
29 enum _flags {
30 /**
31 * Skeleton has been specified in the context.
32 * @see skeleton
33 */
34 flag_skeleton = 0x0001,
35 /**
36 * CPPFLAGS have been specified in the context
37 * @see cpp_flags
38 */
39 flag_cpp_flags = 0x0002,
40 /**
41 * LDFLAGS have been specified in the context.
42 * @see ld_flags
43 */
44 flag_ld_flags = 0x0004,
45 /**
46 * Enforced intermediate dependencies have been specified in the
47 * context.
48 * @see internediate_deps
49 */
50 flag_intermediate_deps = 0x0008,
51 /**
52 * Enforced .so dependencies have been specified in the context.
53 * @see so_deps
54 */
55 flag_so_deps = 0x0010,
56 /**
57 * Whether components should be built specified in the context.
58 * @see build
59 */
60 flag_build = 0x0020,
61 /**
62 * Whether to track down cpp dependencies has been specified in
63 * the context.
64 * @see cpp_deps
65 */
66 flag_cpp_deps = 0x0040,
67 /**
68 * The exception handler has been specified in the context.
69 * @see exception_handler
70 */
71 flag_exception_handler = 0x0080,
72 /**
73 * Action handlers have been specified in the context.
74 * @see action_handlers
75 */
76 flag_action_handlers = 0x0100,
77 /**
78 * HTTP status handerls have been specified in the context.
79 * @see http_status_handlers
80 */
81 flag_http_status_handlers = 0x0200,
82 /**
83 * The files to be built are specified in the context.
84 * @see auto_build_files
85 */
86 flag_auto_build_files = 0x0400
87 };
88 /**
89 * The flags specifying what parts of configuration have been
90 * specified for the context.
91 */
92 int flags;
93
94 /**
95 * The skeleton for building components.
96 */
97 string skeleton;
98 /**
99 * The flags to pass to compiler.
100 */
101 list<string> cpp_flags;
102 /**
103 * The flags to pass to linker.
104 */
105 list<string> ld_flags;
106 /**
107 * Whether to build inexstent and outdated components.
108 */
109 bool build;
110 /**
111 * Whether to track cpp dependencies.
112 */
113 bool cpp_deps;
114 /**
115 * The component handling caught exceptions.
116 */
117 string exception_handler;
118 /**
119 * Enforced intermediate dependencies.
120 */
121 list<string> intermediate_deps;
122 /**
123 * Enforced depencies for .so objects.
124 */
125 list<string> so_deps;
126 /**
127 * The action handler type.
128 */
129 struct action_handler_t {
130 /**
131 * The regexp to check request against.
132 */
133 string s_regex;
134 /**
135 * Precompiled regex.
136 */
137 pcrepp::Pcre regex;
138 /**
139 * The action handler component.
140 */
141 string action;
142 /**
143 * Arguments for the action hander coponent.
144 */
145 list<string> args;
146
147 action_handler_t(const string& s,const string& a)
148 : s_regex(s), regex(s), action(a) { }
149 action_handler_t(const action_handler_t& s)
150 : s_regex(s.s_regex), regex(s.regex), action (s.action), args(s.args) { }
151 };
152 /**
153 * Type for the list of action handlers.
154 */
155 typedef list<action_handler_t> action_handlers_t;
156 /**
157 * The list of action handlers.
158 */
159 action_handlers_t action_handlers;
160 /**
161 * Type for the map of HTTP status handler components.
162 */
163 typedef map<string,string> http_status_handlers_t;
164 /**
165 * The map of HTTP status handler components.
166 */
167 http_status_handlers_t http_status_handlers;
168 /**
169 * Files to be built automatically.
170 */
171 list<string> auto_build_files;
172
173 config_options()
174 : flags(0) { }
175
176 /**
177 * Look up if there is an action handler for the target defined.
178 * @param target the target component.
179 * @return the pointer to handler or zero.
180 */
181 action_handler_t *lookup_action_handler(const string& target);
182 /**
183 * Look up if there is a handler defined for the HTTP status.
184 * @param status HTTP status
185 * @return the handler component.
186 */
187 string lookup_http_status_handler(const string& status);
188 /**
189 * Check whether the file should be build automatically.
190 * @param fn file name.
191 * @param rv reference to the boolean where the answer should go.
192 * @return true if we know the answer.
193 */
194 bool match_autobuild_files(const char *fn,bool &rv);
195 };
196
197 /**
198 * Configuration data container for the configuration loaded from disk file.
199 */
200 class loaded_options : public config_options {
201 public:
202 /**
203 * The file where configuration originates from.
204 */
205 string source_file;
206 /**
207 * The stat structure for the source file as it was when we have
208 * loaded it.
209 */
210 struct stat st;
211
212 /**
213 * See if the data is still valid.
214 * @return true if yes.
215 */
216 bool is_valid();
217
218 /**
219 * Load the configuration file.
220 * @param config the main configuration container.
221 * @param the configuration file.
222 */
223 void parse(configuration *config,const string& cfile);
224 };
225
226 /**
227 * The main configuration container.
228 */
229 class configuration {
230 public:
231 /**
232 * @todo TODO:: document me.
233 */
234 bool autobuild;
235 /**
236 * The flags enumeration.
237 */
238 enum _flags {
239 /**
240 * Was the source root specified?
241 * @see root_source
242 */
243 flag_root_source = 0x00000001,
244 /**
245 * Was the root for intermediate files specified?
246 * @see root_intermediate
247 */
248 flag_root_intermediate = 0x00000002,
249 /**
250 * Was the root for the resulting .so files specified?
251 * @see root_so
252 */
253 flag_root_so = 0x00000004,
254 /**
255 * Was the socket to listen to specified?
256 * @see listen_socket
257 */
258 flag_listen_socket = 0x00000008,
259 /**
260 * Was the per-dir config file name specified.
261 * @see rc_file_name
262 */
263 flag_rc_file_name = 0x00000010,
264 /**
265 * Was the minimum number of child processes specified?
266 * @see min_children
267 */
268 flag_min_children = 0x00000020,
269 /**
270 * Was the maximum number of child processes specified?
271 * @see max_children
272 */
273 flag_max_children = 0x00000040,
274 /**
275 * Was the minimum number of spare child processes specified?
276 * @see min_spare_children
277 */
278 flag_min_spare_children = 0x00000080,
279 /**
280 * Was he maximum number of spare child processes specified?
281 * @see max_spare_children
282 */
283 flag_max_spare_children = 0x00000100,
284 /**
285 * Was the number of requests to handle per child process
286 * specified?
287 * @see requests_per_child
288 */
289 flag_requests_per_child = 0x00000200,
290 /**
291 * Was the multiprocess node (or it's absences) specified?
292 * @see multi_process
293 */
294 flag_multi_process = 0x00000400,
295 /**
296 * Was the user specified?
297 * @see user
298 */
299 flag_user = 0x00000800,
300 /**
301 * @Was the group specified?
302 * @see group
303 */
304 flag_group = 0x00001000,
305 /**
306 * Was the root to change to specified?
307 * @see chroot
308 */
309 flag_chroot = 0x00002000,
310 /**
311 * Was the file for storing PID specified?
312 * @see pidfile
313 */
314 flag_pid_file = 0x00004000,
315 /**
316 * Was it specified wether we should daemonize the process?
317 * @see daemonize
318 */
319 flag_daemonize = 0x00008000
320 };
321 /**
322 * The flags specifying what parts of the configuration has been
323 * loaded into the object.
324 */
325 long flags;
326
327 /**
328 * The root for the components source code.
329 */
330 string root_source;
331 /**
332 * The root for intermediate files.
333 */
334 string root_intermediate;
335 /**
336 * The root for .so files.
337 */
338 string root_so;
339 /**
340 * Socket to bind to
341 */
342 string listen_socket;
343 /**
344 * per-dir config file name.
345 */
346 string rc_file_name;
347 /**
348 * The minimum number of child processes in multiprocess mode.
349 */
350 int min_children;
351 /**
352 * The maxium number of child processes in multiprocess mode.
353 */
354 int max_children;
355 /**
356 * The minimum number of spare chidren in multiprocess mode.
357 */
358 int min_spare_children;
359 /**
360 * The maximum number of spare children in multiprocess mode.
361 */
362 int max_spare_children;
363 /**
364 * The number of requests the child process should handle before
365 * exiting.
366 */
367 int requests_per_child;
368 /**
369 * Whether we should run in multiprocess mode or not.
370 */
371 bool multi_process;
372 /**
373 * User to change to.
374 */
375 string user;
376 /**
377 * Group to set to.
378 */
379 string group;
380 /**
381 * Directory to change root to.
382 */
383 string chroot;
384 /**
385 * The file to store PID into.
386 */
387 string pid_file;
388 /**
389 * Whether we should fork into background.
390 */
391 bool daemonize;
392
393 typedef map<string,config_options> specs_t;
394 /**
395 * The local config options map.
396 */
397 specs_t specs;
398 typedef map<string,loaded_options> loaded_specs_t;
399 /**
400 * The local config options as specified in per-dir config files
401 * map.
402 */
403 loaded_specs_t loaded_specs;
404
405 configuration();
406 /**
407 * @param cfile the configuration file.
408 * @param ab @todo TODO:: document me
409 */
410 configuration(const string& cfile,bool ab=false);
411
412 /**
413 * Parse the configuration file.
414 * @param cfile the configuration file.
415 */
416 void parse(const string& cfile);
417
418 /**
419 * Fetch the reference to options for the very root.
420 */
421 config_options& root_options() { return specs[""]; }
422 /**
423 * Lookup where the certain config option for the target lies in.
424 * @param target the target component.
425 * @param flag the flag specifying the option we're looking for.
426 * @return the destination options continer or zero.
427 */
428 config_options* lookup_config(const string& target,int flag);
429 /**
430 * Lookup the action handler for the target.
431 * @param target the target request.
432 * @return the action handler or zero.
433 */
434 config_options::action_handler_t *lookup_action_handler(const string& target);
435 /**
436 * Lookup the HTPP status handler for the target.
437 * @param target the target.
438 * @param status the HTTP status.
439 * @return the handler component.
440 */
441 string lookup_http_status_handler(const string& target,const string& status);
442 /**
443 * Lookup the options loaded from per-dir config for the target
444 * @param target the target.
445 * @return options container or zero.
446 */
447 loaded_options* lookup_loaded_options(const string& target);
448 /**
449 * Check whether the components for the target should be prebuilt.
450 * @param target the target.
451 * @param fn file name.
452 * @return true if yes.
453 */
454 bool match_autobuild_files(const string& target,const char *fn);
455 };
456
457}
458
459#endif /* __SITECING_CONFIGURATION_H */
diff --git a/include/sitecing/exception.h b/include/sitecing/exception.h
new file mode 100644
index 0000000..985fc6d
--- a/dev/null
+++ b/include/sitecing/exception.h
@@ -0,0 +1,542 @@
1#ifndef __SITECING_EXCEPTION_H
2#define __SITECING_EXCEPTION_H
3
4/**
5 * @file
6 * @brief The site-C-ing specific exceptions.
7 */
8
9/**
10 * @brief The main site-C-ing namespace.
11 */
12namespace sitecing {
13
14 // TODO: status specifics
15
16 /**
17 * The http status to return.
18 */
19 class http_status {
20 public:
21 /**
22 * The status string.
23 */
24 string status;
25 /**
26 * The message to follow the status string.
27 */
28 string message;
29
30 /**
31 * @param s HTTP status.
32 * @param m HTTP status message.
33 */
34 http_status(const string& s,const string& m)
35 : status(s), message(m) { }
36 virtual ~http_status() throw() { }
37 };
38
39 // per RFC 2616
40
41 /**
42 * Informational.
43 */
44 class http_status_1xx : public http_status {
45 public:
46 explicit http_status_1xx(const string &s,const string& m)
47 : http_status(s,m) { }
48 };
49 /**
50 * Continue.
51 */
52 class http_status_100 : public http_status_1xx {
53 public:
54 explicit http_status_100(const string& m)
55 : http_status_1xx("100",m) { }
56 explicit http_status_100()
57 : http_status_1xx("100","Continue") { }
58 };
59 /**
60 * Switching protocols.
61 */
62 class http_status_101 : public http_status_1xx {
63 public:
64 explicit http_status_101(const string& m)
65 : http_status_1xx("101",m) { }
66 explicit http_status_101()
67 : http_status_1xx("101","Switching protocols") { }
68 };
69
70 /**
71 * Successful.
72 */
73 class http_status_2xx : public http_status {
74 public:
75 explicit http_status_2xx(const string& s,const string& m)
76 : http_status(s,m) { }
77 };
78 /**
79 * OK.
80 */
81 class http_status_200 : public http_status_2xx {
82 public:
83 explicit http_status_200(const string& m)
84 : http_status_2xx("200",m) { }
85 explicit http_status_200()
86 : http_status_2xx("200","OK") { }
87 };
88 /**
89 * Created.
90 */
91 class http_status_201 : public http_status_2xx {
92 public:
93 explicit http_status_201(const string& m)
94 : http_status_2xx("201",m) { }
95 explicit http_status_201()
96 : http_status_2xx("201","Created") { }
97 };
98 /**
99 * Accepted.
100 */
101 class http_status_202 : public http_status_2xx {
102 public:
103 explicit http_status_202(const string& m)
104 : http_status_2xx("202",m) { }
105 explicit http_status_202()
106 : http_status_2xx("202","Accepted") { }
107 };
108 /**
109 * Non-authoritative infortmation.
110 */
111 class http_status_203 : public http_status_2xx {
112 public:
113 explicit http_status_203(const string& m)
114 : http_status_2xx("203",m) { }
115 explicit http_status_203()
116 : http_status_2xx("203","Non-authoritative information") { }
117 };
118 /**
119 * No content.
120 */
121 class http_status_204 : public http_status_2xx {
122 public:
123 explicit http_status_204(const string& m)
124 : http_status_2xx("204",m) { }
125 explicit http_status_204()
126 : http_status_2xx("204","No content") { }
127 };
128 /**
129 * Reset content.
130 */
131 class http_status_205 : public http_status_2xx {
132 public:
133 explicit http_status_205(const string& m)
134 : http_status_2xx("205",m) { }
135 explicit http_status_205()
136 : http_status_2xx("205","Reset content") { }
137 };
138 /**
139 * Partial content.
140 */
141 class http_status_206 : public http_status_2xx {
142 public:
143 explicit http_status_206(const string& m)
144 : http_status_2xx("206",m) { }
145 explicit http_status_206()
146 : http_status_2xx("206","Partial content") { }
147 };
148
149 /**
150 * Redirection.
151 */
152 class http_status_3xx : public http_status {
153 public:
154 explicit http_status_3xx(const string& s,const string& m)
155 : http_status(s,m) { }
156 };
157 /**
158 * Multiple choices.
159 */
160 class http_status_300 : public http_status_3xx {
161 public:
162 explicit http_status_300(const string& m)
163 : http_status_3xx("300",m) { }
164 explicit http_status_300()
165 : http_status_3xx("300","Multiple choices") { }
166 };
167 /**
168 * Moved permanently.
169 */
170 class http_status_301 : public http_status_3xx {
171 public:
172 explicit http_status_301(const string& m)
173 : http_status_3xx("301",m) { }
174 explicit http_status_301()
175 : http_status_3xx("301","Moved permanently") { }
176 };
177 /**
178 * Found.
179 */
180 class http_status_302 : public http_status_3xx {
181 public:
182 explicit http_status_302(const string& m)
183 : http_status_3xx("302",m) { }
184 explicit http_status_302()
185 : http_status_3xx("302","Found") { }
186 };
187 /**
188 * See other.
189 */
190 class http_status_303 : public http_status_3xx {
191 public:
192 explicit http_status_303(const string& m)
193 : http_status_3xx("303",m) { }
194 explicit http_status_303()
195 : http_status_3xx("303","See other") { }
196 };
197 /**
198 * Not modified.
199 */
200 class http_status_304 : public http_status_3xx {
201 public:
202 explicit http_status_304(const string& m)
203 : http_status_3xx("304",m) { }
204 explicit http_status_304()
205 : http_status_3xx("304","Not modified") { }
206 };
207 /**
208 * Use proxy.
209 */
210 class http_status_305 : public http_status_3xx {
211 public:
212 explicit http_status_305(const string& m)
213 : http_status_3xx("305",m) { }
214 explicit http_status_305()
215 : http_status_3xx("305","Use proxy") { }
216 };
217 // 306 is unused and reserved
218 /**
219 * Temporary redirect.
220 */
221 class http_status_307 : public http_status_3xx {
222 public:
223 explicit http_status_307(const string& m)
224 : http_status_3xx("307",m) { }
225 explicit http_status_307()
226 : http_status_3xx("307","Temporary redirect") { }
227 };
228
229 /**
230 * Error.
231 */
232 class http_status_4xx : public http_status {
233 public:
234 explicit http_status_4xx(const string& s,const string& m)
235 : http_status(s,m) { }
236 };
237 /**
238 * Bad request.
239 */
240 class http_status_400 : public http_status_4xx {
241 public:
242 explicit http_status_400(const string& m)
243 : http_status_4xx("400",m) { }
244 explicit http_status_400()
245 : http_status_4xx("400","Bad request") { }
246 };
247 /**
248 * Unauthorized.
249 */
250 class http_status_401 : public http_status_4xx {
251 public:
252 explicit http_status_401(const string& m)
253 : http_status_4xx("401",m) { }
254 explicit http_status_401()
255 : http_status_4xx("401","Unauthorized") { }
256 };
257 /**
258 * Payment required.
259 */
260 class http_status_402 : public http_status_4xx {
261 public:
262 explicit http_status_402(const string& m)
263 : http_status_4xx("402",m) { }
264 explicit http_status_402()
265 : http_status_4xx("402","Payment required") { }
266 };
267 /**
268 * Forbidden.
269 */
270 class http_status_403 : public http_status_4xx {
271 public:
272 explicit http_status_403(const string& m)
273 : http_status_4xx("403",m) { }
274 explicit http_status_403()
275 : http_status_4xx("403","Forbidden") { }
276 };
277 /**
278 * Not found.
279 */
280 class http_status_404 : public http_status_4xx {
281 public:
282 explicit http_status_404(const string& m)
283 : http_status_4xx("404",m) { }
284 explicit http_status_404()
285 : http_status_4xx("404","Not found") { }
286 };
287 /**
288 * Method not allowed.
289 */
290 class http_status_405 : public http_status_4xx {
291 public:
292 explicit http_status_405(const string& m)
293 : http_status_4xx("405",m) { }
294 explicit http_status_405()
295 : http_status_4xx("405","Method not allowed") { }
296 };
297 /**
298 * Not acceptable.
299 */
300 class http_status_406 : public http_status_4xx {
301 public:
302 explicit http_status_406(const string& m)
303 : http_status_4xx("406",m) { }
304 explicit http_status_406()
305 : http_status_4xx("406","Not acceptable") { }
306 };
307 /**
308 * Proxy authentication required.
309 */
310 class http_status_407 : public http_status_4xx {
311 public:
312 explicit http_status_407(const string& m)
313 : http_status_4xx("407",m) { }
314 explicit http_status_407()
315 : http_status_4xx("407","Proxy authentication required") { }
316 };
317 /**
318 * Request timeout.
319 */
320 class http_status_408 : public http_status_4xx {
321 public:
322 explicit http_status_408(const string& m)
323 : http_status_4xx("408",m) { }
324 explicit http_status_408()
325 : http_status_4xx("408","Request timeout") { }
326 };
327 /**
328 * Conflict.
329 */
330 class http_status_409 : public http_status_4xx {
331 public:
332 explicit http_status_409(const string& m)
333 : http_status_4xx("409",m) { }
334 explicit http_status_409()
335 : http_status_4xx("409","Conflict") { }
336 };
337 /**
338 * Gone.
339 */
340 class http_status_410 : public http_status_4xx {
341 public:
342 explicit http_status_410(const string& m)
343 : http_status_4xx("410",m) { }
344 explicit http_status_410()
345 : http_status_4xx("410","Gone") { }
346 };
347 /**
348 * Length required.
349 */
350 class http_status_411 : public http_status_4xx {
351 public:
352 explicit http_status_411(const string& m)
353 : http_status_4xx("411",m) { }
354 explicit http_status_411()
355 : http_status_4xx("411","Length required") { }
356 };
357 /**
358 * Precondition failed.
359 */
360 class http_status_412 : public http_status_4xx {
361 public:
362 explicit http_status_412(const string& m)
363 : http_status_4xx("412",m) { }
364 explicit http_status_412()
365 : http_status_4xx("412","Precondition failed") { }
366 };
367 /**
368 * Request entity too large.
369 */
370 class http_status_413 : public http_status_4xx {
371 public:
372 explicit http_status_413(const string& m)
373 : http_status_4xx("413",m) { }
374 explicit http_status_413()
375 : http_status_4xx("413","Request entity too large") { }
376 };
377 /**
378 * Request URI too long.
379 */
380 class http_status_414 : public http_status_4xx {
381 public:
382 explicit http_status_414(const string& m)
383 : http_status_4xx("414",m) { }
384 explicit http_status_414()
385 : http_status_4xx("414","Request URI too long") { }
386 };
387 /**
388 * Unsupported media type.
389 */
390 class http_status_415 : public http_status_4xx {
391 public:
392 explicit http_status_415(const string& m)
393 : http_status_4xx("415",m) { }
394 explicit http_status_415()
395 : http_status_4xx("415","Unsupported media type") { }
396 };
397 /**
398 * Requested range not satisfiable.
399 */
400 class http_status_416 : public http_status_4xx {
401 public:
402 explicit http_status_416(const string& m)
403 : http_status_4xx("416",m) { }
404 explicit http_status_416()
405 : http_status_4xx("416","Requested range not satisfiable") { }
406 };
407 /**
408 * Expectation failed.
409 */
410 class http_status_417 : public http_status_4xx {
411 public:
412 explicit http_status_417(const string& m)
413 : http_status_4xx("417",m) { }
414 explicit http_status_417()
415 : http_status_4xx("417","Expectation failed") { }
416 };
417
418 /**
419 * Server error.
420 */
421 class http_status_5xx : public http_status {
422 public:
423 explicit http_status_5xx(const string& s,const string& m)
424 : http_status(s,m) { }
425 };
426 /**
427 * Internal server error.
428 */
429 class http_status_500 : public http_status_5xx {
430 public:
431 explicit http_status_500(const string& m)
432 : http_status_5xx("500",m) { }
433 explicit http_status_500()
434 : http_status_5xx("500","Internal server error") { }
435 };
436 /**
437 * Not implemented.
438 */
439 class http_status_501 : public http_status_5xx {
440 public:
441 explicit http_status_501(const string& m)
442 : http_status_5xx("501",m) { }
443 explicit http_status_501()
444 : http_status_5xx("501","Not implemented") { }
445 };
446 /**
447 * Bad gateway.
448 */
449 class http_status_502 : public http_status_5xx {
450 public:
451 explicit http_status_502(const string& m)
452 : http_status_5xx("502",m) { }
453 explicit http_status_502()
454 : http_status_5xx("502","Bad gateway") { }
455 };
456 /**
457 * Service unavailable.
458 */
459 class http_status_503 : public http_status_5xx {
460 public:
461 explicit http_status_503(const string& m)
462 : http_status_5xx("503",m) { }
463 explicit http_status_503()
464 : http_status_5xx("503","Service unavailable") { }
465 };
466 /**
467 * Gateway timeout.
468 */
469 class http_status_504 : public http_status_5xx {
470 public:
471 explicit http_status_504(const string& m)
472 : http_status_5xx("504",m) { }
473 explicit http_status_504()
474 : http_status_5xx("504","Gateway timeout") { }
475 };
476 /**
477 * HTTP version not supported.
478 */
479 class http_status_505 : public http_status_5xx {
480 public:
481 explicit http_status_505(const string& m)
482 : http_status_5xx("505",m) { }
483 explicit http_status_505()
484 : http_status_5xx("505","HTTP version not supported") { }
485 };
486
487 // Aliases
488
489 typedef http_status_1xx http_status_informational;
490 typedef http_status_100 http_status_continue;
491 typedef http_status_101 http_status_switching_protocols;
492
493 typedef http_status_2xx http_status_sucessful;
494 typedef http_status_200 http_status_ok;
495 typedef http_status_201 http_status_created;
496 typedef http_status_202 http_status_accepted;
497 typedef http_status_203 http_status_non_authoritative_information;
498 typedef http_status_204 http_status_no_content;
499 typedef http_status_205 http_status_reset_content;
500 typedef http_status_206 http_status_partial_content;
501
502 typedef http_status_3xx http_status_redirection;
503 typedef http_status_300 http_status_multiple_choices;
504 typedef http_status_301 http_status_moved_permanently;
505 typedef http_status_302 http_status_found;
506 typedef http_status_303 http_status_see_other;
507 typedef http_status_304 http_status_not_modified;
508 typedef http_status_305 http_status_use_proxy;
509 // 306 is unused and reserved
510 typedef http_status_307 http_status_temporary_redirect;
511
512 typedef http_status_4xx http_status_client_error;
513 typedef http_status_400 http_status_bad_request;
514 typedef http_status_401 http_status_unauthorized;
515 typedef http_status_402 http_status_payment_required;
516 typedef http_status_403 http_status_forbidden;
517 typedef http_status_404 http_status_not_found;
518 typedef http_status_405 http_status_method_not_allowed;
519 typedef http_status_406 http_status_not_acceptable;
520 typedef http_status_407 http_status_proxy_authentication_required;
521 typedef http_status_408 http_status_request_timeout;
522 typedef http_status_409 http_status_conflict;
523 typedef http_status_410 http_status_gone;
524 typedef http_status_411 http_status_length_required;
525 typedef http_status_412 http_status_precondition_failed;
526 typedef http_status_413 http_status_request_entity_too_large;
527 typedef http_status_414 http_status_requrest_uri_too_long;
528 typedef http_status_415 http_status_unsupported_media_type;
529 typedef http_status_416 http_status_required_range_not_satisfiable;
530 typedef http_status_417 http_status_expectation_failed;
531
532 typedef http_status_5xx http_status_server_error;
533 typedef http_status_500 http_status_internal_server_error;
534 typedef http_status_501 http_status_not_implemented;
535 typedef http_status_502 http_status_bad_gateway;
536 typedef http_status_503 http_status_service_unavailable;
537 typedef http_status_504 http_status_gateway_timeout;
538 typedef http_status_505 http_status_http_version_not_supported;
539
540}
541
542#endif /* __SITECING_EXCEPTION_H */
diff --git a/include/sitecing/file_factory.h b/include/sitecing/file_factory.h
new file mode 100644
index 0000000..7ec82da
--- a/dev/null
+++ b/include/sitecing/file_factory.h
@@ -0,0 +1,64 @@
1#ifndef __SITECING_FILE_FACTORY_H
2#define __SITECING_FILE_FACTORY_H
3
4#include <string>
5#include <list>
6
7/**
8 * @file
9 * @brief the file_factory class declaration.
10 */
11
12namespace sitecing {
13 using namespace std;
14
15 /**
16 * The factory class. Does the job similar to that which is done by make
17 * utility.
18 */
19 class file_factory {
20 public:
21 /**
22 * The recursion depth.
23 */
24 int depth;
25 /**
26 * The list of files type. The list of strings, in fact.
27 */
28 typedef list<string> file_list_t;
29
30 file_factory()
31 : depth(0) { }
32
33 /**
34 * Fetch depndencies for the given file.
35 * @param dst destination file.
36 * @param deps where to put dependencies to.
37 */
38 virtual void get_dependencies(const string& dst,file_list_t& deps) = 0;
39 /**
40 * Check if the destination is up to day.
41 * @param the destination file.
42 * @param deps if the deps pointer is non there, the dependencies
43 * retrieved will be stored there.
44 * @return true if yes.
45 * @see get_dependencies()
46 */
47 virtual bool is_uptodate(const string& dst,file_list_t* deps=0);
48 /**
49 * Build the file requested.
50 * @param dst the file requested.
51 */
52 virtual void build(const string& dst) = 0;
53 /**
54 * Make the file requested, which means: build it, unless it's
55 * uptodate.
56 * @see is_uptodate()
57 * @see build()
58 */
59 virtual void make(const string& dst);
60 };
61
62}
63
64#endif /* __SITECING_FILE_FACTORY_H */
diff --git a/include/sitecing/magic.h b/include/sitecing/magic.h
new file mode 100644
index 0000000..4802fcc
--- a/dev/null
+++ b/include/sitecing/magic.h
@@ -0,0 +1,63 @@
1 #ifndef__SITECING_MAGIC_H
2#define __SITECING_MAGIC_H
3
4/**
5 * @file
6 * @brief The magic numbers globally defined.
7 */
8
9namespace sitecing {
10
11 /**
12 * The magic numbers enumeration.
13 */
14 enum {
15 /**
16 * There is no magic.
17 */
18 __magic_none = 0,
19 /**
20 * Here is where user-defined magic starts.
21 */
22 __user_magical_numbers_start = 1,
23 /**
24 * Here is where site-C-ing defined magic starts.
25 */
26 __sitecing_magical_numbers_start = 0x8000,
27 /**
28 * The compiler error occured. The parameters passed are:
29 *
30 * char *message, char *root_source, char *root_intermediate, char *root_so, char *component
31 */
32 __magic_compile_error,
33 /**
34 * The preprocessor error occured. The parameters passed are:
35 *
36 * char *message, char *root_source, char *root_intermediate, char *root_so, char *component,
37 * int line_number
38 */
39 __magic_preprocess_error,
40 /**
41 * Exception caught while executing the component. The parameters passed are:
42 *
43 * char *message, char *root_source, char *root_intermediate, char *root_so, char *component,
44 * const exception *exception_caught
45 */
46 __magic_generic_exception,
47 /**
48 * The component called as an action handler. The parameters passed are:
49 *
50 * char *root_source, char *root_intermediate, char *root_so, list<string>* args
51 */
52 __magic_action,
53 /**
54 * The component called as an HTTP status handler. The parameters passed are:
55 *
56 * char *root_source, char *root_intermediate, char *root_so, char *component,
57 * const http_status *http_status_caught
58 */
59 __magic_http_status
60 };
61}
62
63#endif /* __SITECING_MAGIC_H */
diff --git a/include/sitecing/process_manager.h b/include/sitecing/process_manager.h
new file mode 100644
index 0000000..73415d3
--- a/dev/null
+++ b/include/sitecing/process_manager.h
@@ -0,0 +1,89 @@
1#ifndef __SITECING_PROCESS_MANAGER_H
2#define __SITECING_PROCESS_MANAGER_H
3
4#include <sitecing/scoreboard.h>
5
6/**
7 * @file
8 * @brief the process manager.
9 */
10
11namespace sitecing {
12
13 /**
14 * The process manager.
15 */
16 class process_manager {
17 public:
18 /**
19 * Minimum number of child processes.
20 */
21 int min_children;
22 /**
23 * Maxinum number of child processes.
24 */
25 int max_children;
26 /**
27 * Minimum number of spare child processes.
28 */
29 int min_spare_children;
30 /**
31 * Maxiumum number of spare child processes.
32 */
33 int max_spare_children;
34 /**
35 * The scoreboard.
36 */
37 scoreboard sboard;
38 /**
39 * We're in the process of shutting down.
40 */
41 bool finishing;
42 /**
43 * @todo TODO: wish I could rememer -- document me.
44 */
45 bool die_humbly;
46
47 process_manager();
48 virtual ~process_manager();
49
50 /**
51 * The main loop.
52 */
53 void manage();
54
55 /**
56 * The worker function.
57 * @param the slot allocated for the process.
58 */
59 virtual void process(int slot) = 0;
60
61 /**
62 * @todo TODO: wish I could remember -- document me.
63 */
64 void manage_children();
65 /**
66 * @todo TODO: wish I could remember -- document me.
67 */
68 bool spawn_children();
69 /**
70 * @todo TODO: wish I could remember -- document me.
71 */
72 bool kill_children();
73 /**
74 * @todo TODO: wish I could remember -- document me.
75 */
76 void spawn_child();
77 /**
78 * @todo TODO: wish I could remember -- document me.
79 */
80 void wait_for_children(bool hang=false);
81 /**
82 * @todo TODO: wish I could remember -- document me.
83 */
84 void collect_dead_souls(bool actively=false);
85 };
86
87}
88
89#endif /* __SITECING_PROCESS_MANAGER_H */
diff --git a/include/sitecing/scoreboard.h b/include/sitecing/scoreboard.h
new file mode 100644
index 0000000..788f881
--- a/dev/null
+++ b/include/sitecing/scoreboard.h
@@ -0,0 +1,102 @@
1#ifndef __SITECING_SCOREBOARD_H
2#define __SITECING_SCOREBOARD_H
3
4#include <sys/types.h>
5
6/**
7 * @file
8 * @brief the scoreboard manager.
9 */
10
11/**
12 * @def MAX_SITECING_SCOREBOARD_SLOTS
13 * The maximum number of slots scoreboard can hold.
14 */
15 #define MAX_SITECING_SCOREBOARD_SLOTS512
16
17namespace sitecing {
18
19 /**
20 * The scoreboard slot.
21 */
22 struct scoreboard_slot {
23 /**
24 * The state enumeration.
25 */
26 enum _state {
27 /**
28 * The slot is free.
29 */
30 state_free = 0,
31 /**
32 * The slot is allocated.
33 */
34 state_allocated,
35 /**
36 * The process is idle.
37 */
38 state_idle,
39 /**
40 * The process is accepting connection.
41 */
42 state_accept,
43 /**
44 * The process is processing request.
45 */
46 state_processing
47 } state;
48 pid_t pid;
49 };
50
51 /**
52 * The scoreboard manager.
53 */
54 class scoreboard {
55 /**
56 * shared memory id.
57 */
58 int shmid;
59 public:
60 /**
61 * Pointer to the scoreboard slots.
62 */
63 scoreboard_slot *slots;
64
65 scoreboard();
66 ~scoreboard();
67
68 /**
69 * Allocate a scoreboard slot.
70 * @return the slot number.
71 */
72 int allocate_slot();
73 /**
74 * Free the slot allocated.
75 * @param slot the slot number.
76 */
77 void free_slot(int slot);
78
79 /**
80 * Get the pointer to the slot.
81 * @param slot the slot number.
82 * @return the pointer.
83 */
84 scoreboard_slot *get_slot(int slot);
85 /**
86 * Find the slot corresponding to the process ID.
87 * @param pid the process id.
88 * @return the slot number.
89 */
90 int get_slot_by_pid(pid_t pid);
91
92 /**
93 * Count the slots in the particular state.
94 * @param state the state.
95 * @return the number of slots found.
96 */
97 int count_slots(enum scoreboard_slot::_state state=scoreboard_slot::state_free);
98 };
99
100}
101
102#endif /* __SITECING_SCOREBOARD_H */
diff --git a/include/sitecing/sitecing_enflesher.h b/include/sitecing/sitecing_enflesher.h
new file mode 100644
index 0000000..ad57fb5
--- a/dev/null
+++ b/include/sitecing/sitecing_enflesher.h
@@ -0,0 +1,65 @@
1#ifndef __SITECING_SITECING_ENFLESHER_H
2#define __SITECING_SITECING_ENFLESHER_H
3
4#include <fstream>
5#include <string>
6using namespace std;
7
8/**
9 * @file
10 * @brief The preprocessed source builder.
11 */
12
13#ifndef sitecing_enflesher_flexlexer_once
14#define sitecing_enflesher_flexlexer_once
15#undef yyFlexLexer
16#define yyFlexLexer sitecing_enflesherFlexLexer
17#include <FlexLexer.h>
18#undef yyFlexLexerOnce
19#endif
20
21class sitecing_parser;
22/**
23 * The enfleshing of the skeleton file according to the in-memory parsed
24 * component source.
25 */
26class sitecing_enflesher : public sitecing_enflesherFlexLexer {
27 public:
28 /**
29 * It is time to anchor output with the #line directive.
30 */
31 bool anchor_time;
32 /**
33 * @todo TODO: wish I could remember -- document me.
34 */
35 bool anchoraged;
36 /**
37 * The reference to the parser object containg the parsed source.
38 */
39 sitecing_parser& parser;
40 /**
41 * The output stream.
42 */
43 ofstream outs;
44
45 /**
46 * @param p The parser object containing preparsed data.
47 */
48 sitecing_enflesher(sitecing_parser& p)
49 : parser(p), anchor_time(true) { }
50
51 /**
52 * Do the job.
53 */
54 void enflesh();
55
56 virtual void LexerOutput(const char *buf,int size);
57 virtual int yylex();
58
59 /**
60 * Put a #line anchor into output.
61 */
62 void anchor();
63};
64
65#endif /* __SITECING_SITECING_ENFLESHER_H */
diff --git a/include/sitecing/sitecing_exception.h b/include/sitecing/sitecing_exception.h
new file mode 100644
index 0000000..bf475ac
--- a/dev/null
+++ b/include/sitecing/sitecing_exception.h
@@ -0,0 +1,103 @@
1#ifndef __SITECING_SITECING_EXCEPTION_H
2#define __SITECING_SITECING_EXCEPTION_H
3
4#include <konforka/exception.h>
5
6/**
7 * @file
8 * @brief The site-C-ing specific exception.
9 */
10
11namespace sitecing {
12
13 /**
14 * The component failed to compile.
15 */
16 class compile_error : public konforka::exception {
17 public:
18 /**
19 * The component path
20 */
21 string component_path;
22
23 /**
24 * @param w the message.
25 * @param cp component path.
26 */
27 compile_error(const string& w,const string& cp)
28 : konforka::exception(NOCODEPOINT,w), component_path(cp) { }
29 /**
30 * @param whe point in code.
31 * @param wha the message.
32 * @param cp component path.
33 */
34 compile_error(const string &whe,const string& wha,const string& cp)
35 : konforka::exception(whe,wha), component_path(cp) { }
36 /**
37 * @param fi the file name where the exception is thrown from.
38 * @param fu the function name where the exception originates from.
39 * @param l the line number where the exception originates from.
40 * @param cp component path.
41 */
42 compile_error(const string &fi,const string& fu,int l,const string& w,const string& cp)
43 : konforka::exception(fi,fu,l,w), component_path(cp) { }
44 ~compile_error() throw() { }
45 };
46
47 /**
48 * Failed to preprocess component source.
49 */
50 class preprocessor_error : public konforka::exception {
51 public:
52 /**
53 * Component name.
54 */
55 string component_name;
56 /**
57 * The line number of the source code where the error occured.
58 */
59 int line_number;
60
61 /**
62 * @param fi file name where the exception originates from.
63 * @param fu the function name where the exception originates from.
64 * @param l the line number where the exception originate from.
65 * @param w the error message.
66 * @param cn the component name.
67 * @param ln the line of the component source where the error occured.
68 */
69 preprocessor_error(const string& fi,const string& fu,int l,const string& w,const string& cn,int ln)
70 : konforka::exception(fi,fu,l,w), component_name(cn), line_number(ln) { }
71 /**
72 * @param fi file name where the exception originates from.
73 * @param fu the function name where the exception originates from.
74 * @param l the line number where the exception originate from.
75 * @param w the error message.
76 * @param cn the component name.
77 */
78 preprocessor_error(const string& fi,const string& fu,int l,const string& w,const string& cn)
79 : konforka::exception(fi,fu,l,w), component_name(cn), line_number(-1) { }
80 /**
81 * @param fi file name where the exception originates from.
82 * @param fu the function name where the exception originates from.
83 * @param l the line number where the exception originate from.
84 * @param w the error message.
85 * @param ln the line of the component source where the error occured.
86 */
87 preprocessor_error(const string& fi,const string& fu,int l,const string& w,int ln)
88 : konforka::exception(fi,fu,l,w), line_number(ln) { }
89 /**
90 * @param fi file name where the exception originates from.
91 * @param fu the function name where the exception originates from.
92 * @param l the line number where the exception originate from.
93 * @param w the error message.
94 */
95 preprocessor_error(const string& fi,const string& fu,int l,const string& w)
96 : konforka::exception(fi,fu,l,w), line_number(-1) { }
97
98 ~preprocessor_error() throw() {}
99 };
100
101}
102
103#endif /* __SITECING_SITECING_EXCEPTION_H */
diff --git a/include/sitecing/sitecing_interface.h b/include/sitecing/sitecing_interface.h
new file mode 100644
index 0000000..0cba2bb
--- a/dev/null
+++ b/include/sitecing/sitecing_interface.h
@@ -0,0 +1,40 @@
1#ifndef __SITECING_SITECING_INTERFACE_H
2#define __SITECING_SITECING_INTERFACE_H
3
4#include <ostream>
5
6/**
7 * @file
8 * @brief The sitecing_interface call declaration.
9 */
10
11namespace sitecing {
12 using namespace std;
13
14 /**
15 * @brief the interface to site-C-ing.
16 *
17 * The basic class used to convey communications between the component and
18 * the sitecing core.
19 */
20 class sitecing_interface {
21 public:
22 /**
23 * Pointer to the output stream.
24 */
25 ostream *out;
26
27 /**
28 * The default constructor doesn't do much.
29 */
30 sitecing_interface() : out(0) {}
31 /**
32 * The constructor initializes the output stream pointer.
33 * @param o the value to initialize the output stream pointer with.
34 */
35 sitecing_interface(ostream* o) : out(o) {}
36 };
37
38}
39
40#endif /* __SITECING_SITECING_INTERFACE_H */
diff --git a/include/sitecing/sitecing_interface_cgi.h b/include/sitecing/sitecing_interface_cgi.h
new file mode 100644
index 0000000..cab947c
--- a/dev/null
+++ b/include/sitecing/sitecing_interface_cgi.h
@@ -0,0 +1,62 @@
1#ifndef __SITECING_SITECING_INTERFACE_CGI_H
2#define __SITECING_SITECING_INTERFACE_CGI_H
3
4#include <sstream>
5#include <string>
6#include <map>
7#include "kingate/cgi_gateway.h"
8#include "sitecing/sitecing_interface.h"
9#include "sitecing/sitespace.h"
10
11/**
12 * @file
13 * @brief The sitecing_interface_cgi class declaration.
14 */
15
16namespace sitecing {
17 using namespace std;
18
19 /**
20 * The interface to site-C-ing core for the CGI component.
21 */
22 class sitecing_interface_cgi : public sitecing_interface {
23 public:
24 /**
25 * Pointer to the CGI gateway interface.
26 */
27 kingate::cgi_gateway* cgigw;
28 /**
29 * Type for the map of headers to spit out.
30 */
31 typedef map<string,string> headers_t;
32 /**
33 * The list of headers to spit out.
34 */
35 headers_t headers;
36 /**
37 * Here is where we prebuffer output.
38 */
39 ostringstream prebuffer;
40 /**
41 * Pointer to the sitespace object.
42 */
43 sitespace *ss; // XXX: or does it belong to the generic interface? or should this 'generic' interface exist at all?
44
45 /**
46 * @param s Pointer to the sitespace object.
47 */
48 sitecing_interface_cgi(sitespace *s);
49
50 /**
51 * @todo TODO: wish I could remember -- document me.
52 */
53 void prepare(kingate::cgi_gateway *cg);
54 /**
55 * @todo TODO: wish I could remember -- document me.
56 */
57 void flush();
58
59 };
60}
61
62#endif /* __SITECING_SITECING_INTERFACE_CGI_H */
diff --git a/include/sitecing/sitecing_parser.h b/include/sitecing/sitecing_parser.h
new file mode 100644
index 0000000..22d716f
--- a/dev/null
+++ b/include/sitecing/sitecing_parser.h
@@ -0,0 +1,326 @@
1#ifndef __SITECING_SITECING_PARSER_H
2#define __SITECING_SITECING_PARSER_H
3
4#include <string>
5#include <list>
6#include <map>
7#include <stdexcept>
8using namespace std;
9
10#include "sitecing/component_factory.h"
11using namespace sitecing;
12
13/**
14 * @file
15 * @brief The component source parser.
16 */
17
18#ifndef sitecing_parser_flexlexer_once
19#define sitecing_parser_flexlexer_once
20#undef yyFlexLexer
21#define yyFlexLexer sitecing_parserFlexLexer
22#include <FlexLexer.h>
23#undef yyFlexLexerOnce
24#endif
25
26/**
27 * The component source parser.
28 */
29class sitecing_parser : public sitecing_parserFlexLexer {
30 public:
31 /**
32 * The ancestor class definition.
33 */
34 class ancestor_class {
35 public:
36 /**
37 * The class name.
38 */
39 string name;
40 /**
41 * The source component path.
42 */
43 string path;
44
45 /**
46 * @param n the class name.
47 * @param p the component path.
48 */
49 ancestor_class(const string& n,const string& p)
50 : name(n), path(p) { }
51 };
52 /**
53 * The list of ancestor classes.
54 */
55 typedef list<ancestor_class> ancestor_classes_t;
56 /**
57 * The ancestor classes.
58 */
59 ancestor_classes_t ancestor_classes;
60 /**
61 * The member variable definition.
62 */
63 class member_variable {
64 public:
65 /**
66 * The member variable type.
67 */
68 string type;
69 /**
70 * The member variable name.
71 */
72 string name;
73 /**
74 * The member variable is a component.
75 */
76 bool bComponent;
77 /**
78 * The variable initializer.
79 */
80 string initializer;
81 /**
82 * @todo TODO: wish I could remember -- document me.
83 */
84 bool bTypeOnly;
85
86 /**
87 * @param t type.
88 * @param n name.
89 * @param i initializer.
90 * @param bc whether it is a component.
91 * @param bto @todo TODO: @see bTypeOnly.
92 */
93 member_variable(const string& t,const string& n,const string& i,bool bc = false,bool bto = false)
94 : type(t), name(n), initializer(i), bComponent(bc), bTypeOnly(bto) { }
95 };
96 /**
97 * The list of member variables.
98 */
99 typedef list<member_variable> member_variables_t;
100 /**
101 * Member variables.
102 */
103 member_variables_t member_variables;
104 /**
105 * @todo TODO: wish I could remember the details -- document me.
106 */
107 bool have_initializers;
108 /**
109 * Whether the component has a constructor defined.
110 */
111 bool have_constructor;
112 /**
113 * Member function definition.
114 */
115 class member_function {
116 public:
117 /**
118 * Return type.
119 */
120 string type;
121 /**
122 * Function name.
123 */
124 string name;
125 /**
126 * Arguments declaration.
127 */
128 string args;
129 /**
130 * Function body.
131 */
132 string body;
133
134 /**
135 * @param t type.
136 * @param n name.
137 * @param a arguments.
138 * @param b body.
139 */
140 member_function(const string& t,const string& n,const string& a,const string& b)
141 : type(t), name(n), args(a), body(b) { }
142 };
143 /**
144 * The list of member functions.
145 */
146 typedef list<member_function> member_functions_t;
147 /**
148 * Member functions.
149 */
150 member_functions_t member_functions;
151 /**
152 * Current mode of operation.
153 */
154 class modus_operandi {
155 public:
156 /**
157 * The state enumeration.
158 */
159 enum modus_t {
160 /**
161 * Building the code.
162 */
163 modus_code = 0,
164 /**
165 * Ready to do the '<<' thing.
166 */
167 modus_preop,
168 /**
169 * Just made a '<<'.
170 */
171 modus_postop,
172 /**
173 * Outputting raw output data.
174 */
175 modus_text,
176 /**
177 * The number of modes.
178 */
179 modi
180 };
181 /**
182 * Processing flags enumeration.
183 */
184 enum {
185 /**
186 * Eat the comments.
187 */
188 flag_devour_comments = 0x0001,
189 /**
190 * Eat whitespace.
191 */
192 flag_devour_whitespace = 0x0002
193 };
194 /**
195 * The processing mode.
196 */
197 modus_t modus;
198 /**
199 * The processing flags.
200 */
201 int flags;
202 /**
203 * Output being built.
204 */
205 string output;
206 /**
207 * The type for compound modes.
208 */
209 string _type;
210 /**
211 * The last id encountered.
212 */
213 string _lastid;
214 /**
215 * The name for compound modes.
216 */
217 string _name;
218 /**
219 * The argument declaration. Obviously for member functions.
220 */
221 string _args;
222
223 /**
224 * @param flags.
225 * @see flags
226 */
227 modus_operandi(int f = 0)
228 : modus(modus_code), flags(f) { }
229
230 /**
231 * Change the processing mode.
232 */
233 void modify(modus_t m);
234
235 /**
236 * See if we're eating up whitespaces.
237 */
238 bool devour_whitespace() { return flags&flag_devour_whitespace; }
239 /**
240 * See if we're eating up the comments.
241 */
242 bool devour_comments() { return flags&flag_devour_comments; }
243 };
244 /**
245 * The modes stack type.
246 */
247 typedef list<modus_operandi> modi_operandi;
248 /**
249 * The modes stack.
250 */
251 modi_operandi modi;
252 /**
253 * Input file name.
254 */
255 string input_file;
256 /**
257 * Base class name.
258 */
259 string base_class;
260 /**
261 * Base class header.
262 */
263 string base_header;
264 /**
265 * Component's basename.
266 * @todo TODO: wish I could remember the details -- document me.
267 */
268 string component_basename;
269 /**
270 * The skeleton file name.
271 */
272 string skeleton;
273 /**
274 * The component class name.
275 */
276 string class_name;
277 /**
278 * Output basename.
279 * @todo TODO: wish I could remember the details -- document me.
280 */
281 string output_basename;
282 /**
283 * Verbatim declaration part.
284 */
285 string decl;
286 /**
287 * Verbatim implementation part.
288 */
289 string impl;
290 /**
291 * The reference to the component factory object.
292 */
293 component_factory& factory;
294
295 /**
296 * @param f the component factory.
297 */
298 sitecing_parser(component_factory& f);
299
300 /**
301 * Preprocess file.
302 * @param in input file name.
303 */
304 void preprocess(const string& in);
305
306 virtual void LexerOutput(const char *buf,int size);
307 virtual int yylex();
308
309 /**
310 * Retrieve reference to the to of the modes stack.
311 * @return the reference in question.
312 */
313 modus_operandi& M() {
314 return modi.front();
315 }
316 /**
317 * Anchor the output with the #line, if we're not in the text output mode.
318 */
319 void soft_anchor();
320 /**
321 * Anchor the output with the #line directive, changing to the appropriate output mode if needed.
322 */
323 void anchor();
324};
325
326#endif /* __SITECING_SITECING_PARSER_H */
diff --git a/include/sitecing/sitecing_util.h b/include/sitecing/sitecing_util.h
new file mode 100644
index 0000000..d1a6c4a
--- a/dev/null
+++ b/include/sitecing/sitecing_util.h
@@ -0,0 +1,341 @@
1#ifndef __SITECING_SITECING_UTIL_H
2#define __SITECING_SITECING_UTIL_H
3
4#include <sys/types.h>
5#include <string>
6#include <konforka/exception.h>
7
8/**
9 * @file
10 * @brief utility classes and functions.
11 */
12
13namespace sitecing {
14 using namespace std;
15
16 /**
17 * Base class for utility exceptions.
18 */
19 class utility_error : public konforka::exception {
20 public:
21 utility_error(const string& fi,const string& fu,int l,const string& w)
22 : konforka::exception(fi,fu,l,w) { }
23 };
24 /**
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 /**
33 * No prefix or suffix found to strip out.
34 */
35 class utility_no_affix : public utility_error {
36 public:
37 utility_no_affix(const string& fi,const string& fu,int l,const string& w)
38 : utility_error(fi,fu,l,w) { }
39 };
40 /**
41 * No prefix to strip found.
42 */
43 class utility_no_prefix : public utility_no_affix {
44 public:
45 utility_no_prefix(const string& fi,const string& fu,int l,const string& w)
46 : utility_no_affix(fi,fu,l,w) { }
47 };
48 /**
49 * No suffix to strip found.
50 */
51 class utility_no_suffix : public utility_no_affix {
52 public:
53 utility_no_suffix(const string& fi,const string& fu,int l,const string& w)
54 : utility_no_affix(fi,fu,l,w) { }
55 };
56
57 /**
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.
69 */
70 class file_lock {
71 public:
72 /**
73 * The file descriptor.
74 */
75 int fd;
76
77 file_lock()
78 : fd(-1) { }
79 /**
80 * @param f file name.
81 */
82 file_lock(const string& f)
83 : fd(-1) { lock(f); }
84 ~file_lock() { unlock(); }
85
86 /**
87 * Do lock.
88 * @param f file name.
89 */
90 void lock(const string& f);
91 /**
92 * @todo TODO: wish I could remember the details -- document me.
93 */
94 void lock();
95 /**
96 * Release the lock obtained.
97 */
98 void unlock();
99 };
100
101 /**
102 * The pid file. Removed at object destruction.
103 */
104 class pid_file {
105 public:
106 /**
107 * The file name.
108 */
109 string file_name;
110 /**
111 * Do we unlink the file after we're done?
112 */
113 bool unlink_pid;
114
115 pid_file()
116 : unlink_pid(false) { }
117 ~pid_file() { unlink(); }
118
119 /**
120 * @param f file name.
121 * @param u whether we want to unlink the file.
122 */
123 void set(const string& f,bool u=true);
124 /**
125 * Unlink the file if we wanted to in the first place.
126 */
127 void unlink();
128 };
129
130 /**
131 * The semaphore object.
132 */
133 class semaphore {
134 public:
135 /**
136 * The semaphore id.
137 */
138 int semid;
139
140 semaphore()
141 : semid(-1) { }
142 /**
143 * @param sid semaphore id.
144 */
145 semaphore(int sid)
146 : semid(sid) { }
147 ~semaphore() {
148 deinit();
149 }
150
151 /**
152 * Init semaphore.
153 */
154 void init();
155 /**
156 * Undo the init.
157 */
158 void deinit();
159
160 /**
161 * Semaphore on.
162 */
163 void on();
164 /**
165 * Semaphore off.
166 */
167 void off();
168 };
169
170 /**
171 * The semaphor lock object, released at object destruction.
172 */
173 class semaphore_lock {
174 public:
175 /**
176 * Pointer to the semaphore we're operating on.
177 */
178 semaphore* sem;
179 /**
180 * Whether it is locked.
181 */
182 bool locked;
183
184 semaphore_lock()
185 : sem(NULL), locked(false) {}
186 /**
187 * @param s pointer to the semaphore.
188 * @param l lock at creation?
189 */
190 semaphore_lock(semaphore* s,bool l=true)
191 : sem(s), locked(false) {
192 if(l) lock();
193 }
194 /**
195 * @param s reference to the semaphore.
196 * @param l lock at creation?
197 */
198 semaphore_lock(semaphore& s,bool l=true)
199 : sem(&s), locked(false) {
200 if(l) lock();
201 }
202
203 ~semaphore_lock() {
204 unlock();
205 }
206
207 /**
208 * Lock it.
209 */
210 void lock();
211 /**
212 * Unlock it.
213 */
214 void unlock();
215 };
216
217 /**
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.
261 * @param str the string.
262 * @param prefix prefix to strip.
263 * @return the string without prefix.
264 * @todo TODO: document exceptions.
265 */
266 string strip_prefix(const string& str,const string& prefix);
267 /**
268 * Strip suffix from the string.
269 * @param str the string.
270 * @param suffix suffix to strip.
271 * @return the string without suffix.
272 * @todo TODO: document exceptions.
273 */
274 string strip_suffix(const string& str,const string& suffix);
275 /**
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 /**
300 * Change to the directory and pop back at object's destruction (e.g. when
301 * the object goes out of scope).
302 */
303 class auto_chdir {
304 public:
305 /**
306 * Saved working directory.
307 */
308 string saved_pwd;
309 /**
310 * Whether we want to change back automatically.
311 */
312 bool autopop;
313
314 auto_chdir()
315 : autopop(false) { }
316 /**
317 * @param td destination path.
318 * @param ap automatically come back?
319 */
320 auto_chdir(const string& td,bool ap=true)
321 : autopop(false) { pushdir(td,ap); }
322 ~auto_chdir() {
323 if(autopop)
324 popdir();
325 }
326
327 /**
328 * Change into directory.
329 * @param td the directory.
330 * @param ap automaticall pop back?
331 */
332 void pushdir(const string& td,bool ap=true);
333 /**
334 * Change to the saved directory.
335 */
336 void popdir();
337 };
338
339}
340
341#endif /* __SITECING_SITECING_UTIL_H */
diff --git a/include/sitecing/sitespace.h b/include/sitecing/sitespace.h
new file mode 100644
index 0000000..38fafe4
--- a/dev/null
+++ b/include/sitecing/sitespace.h
@@ -0,0 +1,76 @@
1#ifndef __SITECING_SITESPACE_H
2#define __SITECING_SITESPACE_H
3
4#include <string>
5#include <map>
6#include <list>
7#include "sitecing/component_factory.h"
8#include "sitecing/component_so.h"
9#include "sitecing/configuration.h"
10
11/**
12 * @file
13 * @brief The sitespace class declaration.
14 */
15
16namespace sitecing {
17 using namespace std;
18
19 /**
20 * The class responsible for handling the whole environment (as far as I can
21 * remember).
22 */
23 class sitespace {
24 public:
25 /**
26 * The type for the map of components from the component name/path
27 * to the loaded component objects.
28 */
29 typedef map<string,component_so*> components_t;
30 /**
31 * The type for listing the components.
32 */
33 typedef list<component_so*> sentenced_t;
34 /**
35 * The main configuration object.
36 */
37 configuration& config;
38 /**
39 * The components producing factory.
40 */
41 component_factory factory;
42 /**
43 * The components loaded.
44 */
45 components_t components;
46 /**
47 * The list of components sentenced to death.
48 */
49 sentenced_t sentenced;
50
51 /**
52 * Create an object in accordance with the configuration parsed.
53 * @param c the coniguration container.
54 */
55 sitespace(configuration& c);
56 ~sitespace();
57
58 /**
59 * Fetch the component, providing it with the interface object
60 * pointer.
61 * @param c the component name.
62 * @param scif the interface object.
63 * @return the component fetches.
64 */
65 so_component fetch(const string& c,sitecing_interface* scif);
66
67 private:
68 /**
69 * Execute the death sentence as much as we can.
70 */
71 void execute_sentenced();
72 };
73
74}
75
76#endif /* __SITECING_SITESPACE_H */
diff --git a/include/sitecing/util.h b/include/sitecing/util.h
new file mode 100644
index 0000000..5750ab6
--- a/dev/null
+++ b/include/sitecing/util.h
@@ -0,0 +1,148 @@
1#ifndef __SITECING_UTIL_H
2#define __SITECING_UTIL_H
3
4#include <ostream>
5#include <string>
6#include "sitecing/acomponent.h"
7
8/**
9 * @file
10 * @brief more or less non-internal utility classes and functions.
11 */
12
13namespace sitecing {
14 using namespace std;
15
16 /**
17 * the html_escape options enumeration.
18 */
19 enum html_escape_options {
20 /**
21 * Turn spaces into &nbsp;
22 */
23 html_escape_nbsp = 0x0001,
24 /**
25 * Turn newlines into <br/> or <br>.
26 */
27 html_escape_br = 0x0002,
28 /**
29 * Turn quotes to &quot;
30 */
31 html_escape_quot = 0x0004,
32 /**
33 * Do not put '/' into <br/> consruct.
34 */
35 html_escape_br_noslash = 0x0008
36 };
37 /**
38 * Escape string suitable for html output.
39 * @param str the string.
40 * @param flags options.
41 * @return the string escaped.
42 * @see html_escape_options
43 */
44 string html_escape(const string& str,int flags=html_escape_br);
45
46 /**
47 * The output string checkpoint object, letting one to rollback output.
48 */
49 class checkpoint {
50 public:
51 /**
52 * The object's death will enumeration.
53 */
54 enum will_t {
55 /**
56 * The stream is to be rolled back at object destruction.
57 */
58 will_rollback,
59 /**
60 * The stream is not to be rolled back at object destruction.
61 */
62 will_commit,
63 /**
64 * The object will die intestate. What's the point then?
65 */
66 will_intestate
67 };
68 /**
69 * The output stream in question.
70 */
71 ostream* stream;
72 /**
73 * The point at which objhect was created.
74 */
75 ostream::pos_type point;
76 /**
77 * The last will.
78 */
79 will_t last_will;
80
81 /**
82 * @param s reference to the stream.
83 * @param lw the last will.
84 */
85 checkpoint(ostream& s, will_t lw=will_rollback)
86 : stream(&s), last_will(lw) { set(); }
87 /**
88 * @param s pointer to the stream.
89 * @param lw the last will.
90 */
91 checkpoint(ostream* s, will_t lw=will_rollback)
92 : stream(s), last_will(lw) { set(); }
93 /**
94 * @param s reference to the sitecing interface where to get output
95 * stream from.
96 * @param lw the last will.
97 */
98 checkpoint(sitecing_interface& s, will_t lw=will_rollback)
99 : stream(s.out), last_will(lw) { set(); }
100 /**
101 * @param s pointer to the sitecing interface where to get output
102 * stream from.
103 * @param lw the last will.
104 */
105 checkpoint(sitecing_interface* s, will_t lw=will_rollback)
106 : stream(s->out), last_will(lw) { set(); }
107 /**
108 * @param c reference to the component from which the output stream
109 * is obtained.
110 * @param lw the last will.
111 */
112 checkpoint(acomponent& c, will_t lw=will_rollback)
113 : stream(c.__SCIF->out), last_will(lw) { set(); }
114 /**
115 * @param c pointer to the component from which the output stream is
116 * obtained.
117 * @param lw the last will.
118 */
119 checkpoint(acomponent* c, will_t lw=will_rollback)
120 : stream(c->__SCIF->out), last_will(lw) { set(); }
121 ~checkpoint() {
122 if(last_will==will_rollback)
123 rollback();
124 }
125
126 /**
127 * Set the possible rolback point to the current position in stream.
128 */
129 void set();
130 /**
131 * Make or change will.
132 */
133 void make_will(will_t lw);
134 /**
135 * Rollback the output made so far. In case of rollback will
136 * change to intestate.
137 */
138 void rollback();
139 /**
140 * Commit output so far. In case of rollback will, change to
141 * intestate.
142 */
143 void commit();
144 };
145
146}
147
148#endif /* __SITECING_UTIL_H */