Diffstat (limited to 'htdocs/handlers/exception_dev') (more/less context) (ignore whitespace changes)
-rw-r--r-- | htdocs/handlers/exception_dev | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/htdocs/handlers/exception_dev b/htdocs/handlers/exception_dev new file mode 100644 index 0000000..d8c84e1 --- a/dev/null +++ b/htdocs/handlers/exception_dev | |||
@@ -0,0 +1,346 @@ | |||
1 | %%decl using namespace std; | ||
2 | <%impl> | ||
3 | #include <iostream> | ||
4 | #include <fstream> | ||
5 | #include <sstream> | ||
6 | #include <cassert> | ||
7 | #include <cstdarg> | ||
8 | #include <stdexcept> | ||
9 | #include <cxxabi.h> | ||
10 | #include <sitecing/sitecing_util.h> | ||
11 | #include <sitecing/util.h> | ||
12 | #include <sitecing/magic.h> | ||
13 | #include <konforka/exception.h> | ||
14 | </%impl> | ||
15 | %%var string message; | ||
16 | %%var string root_source; | ||
17 | %%var string root_intermediate; | ||
18 | %%var string root_so; | ||
19 | %%var string component; | ||
20 | %%var int line_number = -1; | ||
21 | %%var const exception* exception_caught; | ||
22 | <%code> | ||
23 | __SCIF->headers.clear(); | ||
24 | __SCIF->out->seekp(0); | ||
25 | int magic = _magic; | ||
26 | va_list va = _args; | ||
27 | switch(magic) { | ||
28 | case sitecing::__magic_compile_error: | ||
29 | message = va_arg(va,const char*); | ||
30 | root_source = va_arg(va,const char*); | ||
31 | root_intermediate = va_arg(va,const char*); | ||
32 | root_so = va_arg(va,const char*); | ||
33 | component = va_arg(va,const char*); | ||
34 | break; | ||
35 | case sitecing::__magic_preprocess_error: | ||
36 | message = va_arg(va,const char*); | ||
37 | root_source = va_arg(va,const char*); | ||
38 | root_intermediate = va_arg(va,const char*); | ||
39 | root_so = va_arg(va,const char*); | ||
40 | component = va_arg(va,const char*); | ||
41 | line_number = va_arg(va,int); | ||
42 | break; | ||
43 | case sitecing::__magic_generic_exception: | ||
44 | message = va_arg(va,const char*); | ||
45 | root_source = va_arg(va,const char*); | ||
46 | root_intermediate = va_arg(va,const char *); | ||
47 | root_so = va_arg(va,const char *); | ||
48 | component = va_arg(va,const char*); | ||
49 | exception_caught = va_arg(va,const exception*); | ||
50 | break; | ||
51 | default: | ||
52 | break; | ||
53 | } | ||
54 | </%code> | ||
55 | <!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 | <head> | ||
58 | <title><% message %></title> | ||
59 | <style type="text/css"> | ||
60 | <!-- | ||
61 | body { | ||
62 | font-family: sans-serif; | ||
63 | font-size: 11pt; | ||
64 | } | ||
65 | |||
66 | h1 { | ||
67 | font-family: serif; | ||
68 | font-size: 130%; | ||
69 | font-weight: bold; | ||
70 | text-align: center; | ||
71 | } | ||
72 | p { | ||
73 | text-indent: 2em; | ||
74 | text-align: justify; | ||
75 | } | ||
76 | |||
77 | dl.exception-props { | ||
78 | margin: 1ex 1em; | ||
79 | padding: 0.5ex; | ||
80 | border: solid 1px gray; | ||
81 | background-color: #e0e0e0; | ||
82 | } | ||
83 | dl.exception-props dt { | ||
84 | font-weight: bold; | ||
85 | color: blue; | ||
86 | } | ||
87 | dl.exception-props dd { | ||
88 | color: gray; | ||
89 | } | ||
90 | |||
91 | div.exception-codepoint-report { | ||
92 | border: solid 1px black; | ||
93 | margin: 0.5ex 1em 0.ex 3em; | ||
94 | } | ||
95 | div.exception-codepoint-report h3 { | ||
96 | display: block; | ||
97 | color: blue; | ||
98 | border-bottom: 3px double black; | ||
99 | padding: 0.3ex; margin: 0px; | ||
100 | background: #e0e0e0; | ||
101 | } | ||
102 | div.exception-codepoint-report ul { | ||
103 | padding: 0px; | ||
104 | margin: 0px; | ||
105 | background: #87fdff; | ||
106 | font-size: 70%; | ||
107 | } | ||
108 | div.exception-codepoint-report li { | ||
109 | font-family: monospace; | ||
110 | list-style-type: none; | ||
111 | white-space: nowrap; | ||
112 | overflow: hidden; | ||
113 | } | ||
114 | div.exception-codepoint-report li.focused { | ||
115 | color: red; | ||
116 | border-top: solid 1px red; border-bottom: solid 1px red; | ||
117 | } | ||
118 | div.exception-codepoint-report li .lineno { | ||
119 | padding-right: 0.5ex; | ||
120 | border-right: dotted black 1px; | ||
121 | } | ||
122 | div.exception-codepoint-report div.what { | ||
123 | border-top: double 3px black; | ||
124 | padding: 0.5ex 2em; | ||
125 | font-weight: bold; color: #4040c0; | ||
126 | overflow: auto; | ||
127 | } | ||
128 | div.backtrace div.exception-codepoint-report div.what { | ||
129 | color: gray; | ||
130 | } | ||
131 | |||
132 | div.exception-compile div.what { | ||
133 | font-weight: normal; | ||
134 | color: red; | ||
135 | } | ||
136 | |||
137 | div.powered { | ||
138 | margin: 2em 0px 0px 50%; | ||
139 | padding: 1ex 2ex; | ||
140 | text-align: right; | ||
141 | font-family: serif; | ||
142 | font-size: 140%; | ||
143 | font-weight: bold; | ||
144 | border-top: solid 2px black; | ||
145 | border-left: solid 1px gray; border-right: solid 1px gray; border-bottom: solid 1px gray; | ||
146 | background: #c0c0f0; | ||
147 | } | ||
148 | --> | ||
149 | </style> | ||
150 | % __SCIF->headers["Content-Type"]="text/html; charset=utf-8"; | ||
151 | % __SCIF->headers["Pragma"]="no-cache"; | ||
152 | </head> | ||
153 | <body> | ||
154 | <%code> | ||
155 | switch(magic) { | ||
156 | case sitecing::__magic_compile_error: | ||
157 | handle_compile_error(); | ||
158 | break; | ||
159 | case sitecing::__magic_preprocess_error: | ||
160 | handle_preprocess_error(); | ||
161 | break; | ||
162 | case sitecing::__magic_generic_exception: | ||
163 | handle_generic_exception(); | ||
164 | break; | ||
165 | default: | ||
166 | handle_unknown_error(); | ||
167 | break; | ||
168 | } | ||
169 | </%code> | ||
170 | <div class="powered">Powered by <a href="http://kin.klever.net/sitecing/" title="site-C-ing">site-C-ing</a>.</div> | ||
171 | </body> | ||
172 | </html> | ||
173 | <%method void handle_generic_exception() %> | ||
174 | <div class="exception-generic"> | ||
175 | <h1>exception caught while running component '<code><% component %></code>'</h1> | ||
176 | <dl class="exception-props"> | ||
177 | <dt><code>typeid(<em>e</em>).name()</code></dt> | ||
178 | % int destat; | ||
179 | % char *demangled = abi::__cxa_demangle(typeid(*exception_caught).name(),NULL,NULL,&destat); | ||
180 | <dd><code><% destat?typeid(*exception_caught).name():demangled %></code></dd> | ||
181 | % if(!destat) free(demangled); | ||
182 | <dt><code><em>e</em>.what()</code></dt> | ||
183 | <dd><% message %></dd> | ||
184 | % if(typeid(*exception_caught)==typeid(konforka::exception&)) { | ||
185 | % konforka::exception* ke = (konforka::exception*)exception_caught; | ||
186 | <dt><code><em>e</em>.where()</code></dt> | ||
187 | <dd><code> | ||
188 | % if(ke->_where.line<0) { | ||
189 | <% ke->where() %> | ||
190 | % }else{ | ||
191 | <% strip_roots(ke->_where.file) %>:<% ke->_where.line %> [<% ke->_where.function %>] | ||
192 | % } | ||
193 | </code></dd> | ||
194 | % } | ||
195 | </dl> | ||
196 | % if(typeid(*exception_caught)==typeid(konforka::exception&)) { | ||
197 | % konforka::exception* ke = (konforka::exception*)exception_caught; | ||
198 | % if(ke->_where.line>=0) { | ||
199 | % report_error(ke->_where.file,ke->_where.line,ke->what()); | ||
200 | % } | ||
201 | % if(!ke->_seen.empty()) { | ||
202 | <h2>seen at:</h2> | ||
203 | <div class="backtrace"> | ||
204 | % for(list<konforka::code_point>::const_iterator i=ke->_seen.begin();i!=ke->_seen.end();++i) { | ||
205 | % if(i->line>=0) { | ||
206 | % report_error(i->file,i->line,i->function); | ||
207 | % } | ||
208 | % } | ||
209 | </div> | ||
210 | % } | ||
211 | % } | ||
212 | </div> | ||
213 | </%method> | ||
214 | <%method void handle_preprocess_error() %> | ||
215 | <div class="exception-preprocess"> | ||
216 | <h1>error preprocessing component '<code><% component %></code>'</h1> | ||
217 | % report_error(root_source+component,line_number,message); | ||
218 | </div> | ||
219 | </%method> | ||
220 | <%method void handle_compile_error() %> | ||
221 | <div class="exception-compile"> | ||
222 | <h1>error compiling component '<code><% component %></code>'</h1> | ||
223 | <%code> | ||
224 | ifstream err((root_intermediate+component+".stderr").c_str(),ios::in); | ||
225 | if(err.bad()) { | ||
226 | <%output> | ||
227 | Failed to access compiler output | ||
228 | </%output> | ||
229 | }else{ | ||
230 | string cumulative; | ||
231 | string error_file; | ||
232 | long error_line = -1; | ||
233 | while(!err.eof()) { | ||
234 | string oef = error_file; | ||
235 | long oel = error_line; | ||
236 | string line; | ||
237 | getline(err,line); | ||
238 | if(line[0]!=' ') { | ||
239 | string::size_type c = line.find(':'); | ||
240 | if(c!=string::npos) { | ||
241 | string fn = line.substr(0,c); | ||
242 | string::size_type c1 = line.find(':',c+1); | ||
243 | if(c1!=string::npos) { | ||
244 | string ln = line.substr(c+1,c1-c-1); | ||
245 | string::size_type nd = ln.find_first_not_of("0123456789"); | ||
246 | if(nd==string::npos) { | ||
247 | try { | ||
248 | error_file = sitecing::strip_prefix(fn,"In file included from "); | ||
249 | }catch(sitecing::utility_no_prefix& unp) { | ||
250 | error_file = fn; | ||
251 | } | ||
252 | error_line = strtol(ln.c_str(),0,10); | ||
253 | } | ||
254 | } | ||
255 | } | ||
256 | if((oel>0 && !oef.empty()) && (oel!=error_line || oef!=error_file)) { | ||
257 | string ef = "/"+sitecing::combine_path(root_source+component,oef); | ||
258 | report_error(ef,oel,remove_roots(cumulative)); | ||
259 | cumulative.clear(); | ||
260 | } | ||
261 | } | ||
262 | if(!cumulative.empty()) | ||
263 | cumulative += '\n'; | ||
264 | cumulative += line; | ||
265 | } | ||
266 | if(!(cumulative.empty() || error_file.empty() || error_line<0)) { | ||
267 | error_file = "/"+sitecing::combine_path(root_source+component,error_file); | ||
268 | report_error(error_file,error_line,remove_roots(cumulative)); | ||
269 | } | ||
270 | } | ||
271 | </%code> | ||
272 | </div> | ||
273 | </%method> | ||
274 | <%method void handle_unknown_error() %> | ||
275 | <div class="exception-unknown"> | ||
276 | <h1>unknown error</h1> | ||
277 | </div> | ||
278 | </%method> | ||
279 | <%method void report_error(const string& file,long line,const string& message) %> | ||
280 | <div class="exception-codepoint-report"> | ||
281 | <h3><% sitecing::html_escape(strip_roots(file)) %></h3> | ||
282 | <%code> | ||
283 | if(line>=0) { | ||
284 | int firstline = line-5, lastline = line+5; | ||
285 | if(firstline<1) | ||
286 | firstline = 1; | ||
287 | ifstream ifs(file.c_str(),ios::in); | ||
288 | if(ifs.bad()) { | ||
289 | // TODO: | ||
290 | }else{ | ||
291 | for(int l=1;l<firstline && !ifs.eof();l++) { | ||
292 | ifs.ignore(65536,'\n'); | ||
293 | } | ||
294 | if(ifs.eof()) { | ||
295 | // TODO: no such line in file | ||
296 | }else{ | ||
297 | <%output><ul></%output> | ||
298 | for(int l=firstline;l<=lastline && !ifs.eof();l++) { | ||
299 | string str; | ||
300 | getline(ifs,str); | ||
301 | for(string::size_type t=str.find('\t');t!=string::npos;t=str.find('\t')) { | ||
302 | str.replace(t,1,8-(t%8),' '); | ||
303 | } | ||
304 | char tln[16]; | ||
305 | snprintf(tln,sizeof(tln),"%5d",l); | ||
306 | <%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 | </%output> | ||
309 | } | ||
310 | <%output></ul></%output> | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | </%code> | ||
315 | <div class="what"> | ||
316 | <% sitecing::html_escape(message,sitecing::html_escape_br) %> | ||
317 | </div> | ||
318 | </div> | ||
319 | </%method> | ||
320 | <%codemethod string strip_roots(const string& filename) %> | ||
321 | string np = sitecing::normalize_path(filename); | ||
322 | try{ | ||
323 | return sitecing::strip_prefix(np,root_source); | ||
324 | }catch(sitecing::utility_no_prefix& e){ } | ||
325 | try{ | ||
326 | return sitecing::strip_prefix(np,root_intermediate); | ||
327 | }catch(sitecing::utility_no_prefix& e){ } | ||
328 | </%codemethod> | ||
329 | <%codemethod string remove_roots(const string& str) %> | ||
330 | string rv = str; | ||
331 | string::size_type rp; | ||
332 | string::size_type rl = root_source.length(); | ||
333 | while((rp=rv.find(root_source))!=string::npos) { | ||
334 | rv.erase(rp,rl); | ||
335 | } | ||
336 | rl = root_intermediate.length(); | ||
337 | while((rp=rv.find(root_intermediate))!=string::npos) { | ||
338 | rv.erase(rp,rl); | ||
339 | } | ||
340 | rl = root_so.length(); | ||
341 | while((rp=rv.find(root_so))!=string::npos) { | ||
342 | rv.erase(rp,rl); | ||
343 | } | ||
344 | return rv; | ||
345 | </%codemethod> | ||
346 | % /* vim:set ft=sitecing: */ | ||