-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 @@ +%%decl using namespace std; +<%impl> + #include <iostream> + #include <fstream> + #include <sstream> + #include <cassert> + #include <cstdarg> + #include <stdexcept> + #include <cxxabi.h> + #include <sitecing/sitecing_util.h> + #include <sitecing/util.h> + #include <sitecing/magic.h> + #include <konforka/exception.h> +</%impl> +%%var string message; +%%var string root_source; +%%var string root_intermediate; +%%var string root_so; +%%var string component; +%%var int line_number = -1; +%%var const exception* exception_caught; +<%code> + __SCIF->headers.clear(); + __SCIF->out->seekp(0); + int magic = _magic; + va_list va = _args; + switch(magic) { + case sitecing::__magic_compile_error: + message = va_arg(va,const char*); + root_source = va_arg(va,const char*); + root_intermediate = va_arg(va,const char*); + root_so = va_arg(va,const char*); + component = va_arg(va,const char*); + break; + case sitecing::__magic_preprocess_error: + message = va_arg(va,const char*); + root_source = va_arg(va,const char*); + root_intermediate = va_arg(va,const char*); + root_so = va_arg(va,const char*); + component = va_arg(va,const char*); + line_number = va_arg(va,int); + break; + case sitecing::__magic_generic_exception: + message = va_arg(va,const char*); + root_source = va_arg(va,const char*); + root_intermediate = va_arg(va,const char *); + root_so = va_arg(va,const char *); + component = va_arg(va,const char*); + exception_caught = va_arg(va,const exception*); + break; + default: + break; + } +</%code> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> + <head> + <title><% message %></title> + <style type="text/css"> + <!-- + body { + font-family: sans-serif; + font-size: 11pt; + } + + h1 { + font-family: serif; + font-size: 130%; + font-weight: bold; + text-align: center; + } + p { + text-indent: 2em; + text-align: justify; + } + + dl.exception-props { + margin: 1ex 1em; + padding: 0.5ex; + border: solid 1px gray; + background-color: #e0e0e0; + } + dl.exception-props dt { + font-weight: bold; + color: blue; + } + dl.exception-props dd { + color: gray; + } + + div.exception-codepoint-report { + border: solid 1px black; + margin: 0.5ex 1em 0.ex 3em; + } + div.exception-codepoint-report h3 { + display: block; + color: blue; + border-bottom: 3px double black; + padding: 0.3ex; margin: 0px; + background: #e0e0e0; + } + div.exception-codepoint-report ul { + padding: 0px; + margin: 0px; + background: #87fdff; + font-size: 70%; + } + div.exception-codepoint-report li { + font-family: monospace; + list-style-type: none; + white-space: nowrap; + overflow: hidden; + } + div.exception-codepoint-report li.focused { + color: red; + border-top: solid 1px red; border-bottom: solid 1px red; + } + div.exception-codepoint-report li .lineno { + padding-right: 0.5ex; + border-right: dotted black 1px; + } + div.exception-codepoint-report div.what { + border-top: double 3px black; + padding: 0.5ex 2em; + font-weight: bold; color: #4040c0; + overflow: auto; + } + div.backtrace div.exception-codepoint-report div.what { + color: gray; + } + + div.exception-compile div.what { + font-weight: normal; + color: red; + } + + div.powered { + margin: 2em 0px 0px 50%; + padding: 1ex 2ex; + text-align: right; + font-family: serif; + font-size: 140%; + font-weight: bold; + border-top: solid 2px black; + border-left: solid 1px gray; border-right: solid 1px gray; border-bottom: solid 1px gray; + background: #c0c0f0; + } + --> + </style> +% __SCIF->headers["Content-Type"]="text/html; charset=utf-8"; +% __SCIF->headers["Pragma"]="no-cache"; + </head> + <body> + <%code> + switch(magic) { + case sitecing::__magic_compile_error: + handle_compile_error(); + break; + case sitecing::__magic_preprocess_error: + handle_preprocess_error(); + break; + case sitecing::__magic_generic_exception: + handle_generic_exception(); + break; + default: + handle_unknown_error(); + break; + } + </%code> + <div class="powered">Powered by <a href="http://kin.klever.net/sitecing/" title="site-C-ing">site-C-ing</a>.</div> + </body> +</html> +<%method void handle_generic_exception() %> + <div class="exception-generic"> + <h1>exception caught while running component '<code><% component %></code>'</h1> + <dl class="exception-props"> + <dt><code>typeid(<em>e</em>).name()</code></dt> +% int destat; +% char *demangled = abi::__cxa_demangle(typeid(*exception_caught).name(),NULL,NULL,&destat); + <dd><code><% destat?typeid(*exception_caught).name():demangled %></code></dd> +% if(!destat) free(demangled); + <dt><code><em>e</em>.what()</code></dt> + <dd><% message %></dd> +% if(typeid(*exception_caught)==typeid(konforka::exception&)) { +% konforka::exception* ke = (konforka::exception*)exception_caught; + <dt><code><em>e</em>.where()</code></dt> + <dd><code> +% if(ke->_where.line<0) { + <% ke->where() %> +% }else{ + <% strip_roots(ke->_where.file) %>:<% ke->_where.line %> [<% ke->_where.function %>] +% } + </code></dd> +% } + </dl> +% if(typeid(*exception_caught)==typeid(konforka::exception&)) { +% konforka::exception* ke = (konforka::exception*)exception_caught; +% if(ke->_where.line>=0) { +% report_error(ke->_where.file,ke->_where.line,ke->what()); +% } +% if(!ke->_seen.empty()) { + <h2>seen at:</h2> + <div class="backtrace"> +% for(list<konforka::code_point>::const_iterator i=ke->_seen.begin();i!=ke->_seen.end();++i) { +% if(i->line>=0) { +% report_error(i->file,i->line,i->function); +% } +% } + </div> +% } +% } + </div> +</%method> +<%method void handle_preprocess_error() %> + <div class="exception-preprocess"> + <h1>error preprocessing component '<code><% component %></code>'</h1> +% report_error(root_source+component,line_number,message); + </div> +</%method> +<%method void handle_compile_error() %> + <div class="exception-compile"> + <h1>error compiling component '<code><% component %></code>'</h1> + <%code> + ifstream err((root_intermediate+component+".stderr").c_str(),ios::in); + if(err.bad()) { + <%output> + Failed to access compiler output + </%output> + }else{ + string cumulative; + string error_file; + long error_line = -1; + while(!err.eof()) { + string oef = error_file; + long oel = error_line; + string line; + getline(err,line); + if(line[0]!=' ') { + string::size_type c = line.find(':'); + if(c!=string::npos) { + string fn = line.substr(0,c); + string::size_type c1 = line.find(':',c+1); + if(c1!=string::npos) { + string ln = line.substr(c+1,c1-c-1); + string::size_type nd = ln.find_first_not_of("0123456789"); + if(nd==string::npos) { + try { + error_file = sitecing::strip_prefix(fn,"In file included from "); + }catch(sitecing::utility_no_prefix& unp) { + error_file = fn; + } + error_line = strtol(ln.c_str(),0,10); + } + } + } + if((oel>0 && !oef.empty()) && (oel!=error_line || oef!=error_file)) { + string ef = "/"+sitecing::combine_path(root_source+component,oef); + report_error(ef,oel,remove_roots(cumulative)); + cumulative.clear(); + } + } + if(!cumulative.empty()) + cumulative += '\n'; + cumulative += line; + } + if(!(cumulative.empty() || error_file.empty() || error_line<0)) { + error_file = "/"+sitecing::combine_path(root_source+component,error_file); + report_error(error_file,error_line,remove_roots(cumulative)); + } + } + </%code> + </div> +</%method> +<%method void handle_unknown_error() %> + <div class="exception-unknown"> + <h1>unknown error</h1> + </div> +</%method> +<%method void report_error(const string& file,long line,const string& message) %> + <div class="exception-codepoint-report"> + <h3><% sitecing::html_escape(strip_roots(file)) %></h3> + <%code> + if(line>=0) { + int firstline = line-5, lastline = line+5; + if(firstline<1) + firstline = 1; + ifstream ifs(file.c_str(),ios::in); + if(ifs.bad()) { + // TODO: + }else{ + for(int l=1;l<firstline && !ifs.eof();l++) { + ifs.ignore(65536,'\n'); + } + if(ifs.eof()) { + // TODO: no such line in file + }else{ + <%output><ul></%output> + for(int l=firstline;l<=lastline && !ifs.eof();l++) { + string str; + getline(ifs,str); + for(string::size_type t=str.find('\t');t!=string::npos;t=str.find('\t')) { + str.replace(t,1,8-(t%8),' '); + } + char tln[16]; + snprintf(tln,sizeof(tln),"%5d",l); + <%output> + <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> + </%output> + } + <%output></ul></%output> + } + } + } + </%code> + <div class="what"> + <% sitecing::html_escape(message,sitecing::html_escape_br) %> + </div> + </div> +</%method> +<%codemethod string strip_roots(const string& filename) %> + string np = sitecing::normalize_path(filename); + try{ + return sitecing::strip_prefix(np,root_source); + }catch(sitecing::utility_no_prefix& e){ } + try{ + return sitecing::strip_prefix(np,root_intermediate); + }catch(sitecing::utility_no_prefix& e){ } +</%codemethod> +<%codemethod string remove_roots(const string& str) %> + string rv = str; + string::size_type rp; + string::size_type rl = root_source.length(); + while((rp=rv.find(root_source))!=string::npos) { + rv.erase(rp,rl); + } + rl = root_intermediate.length(); + while((rp=rv.find(root_intermediate))!=string::npos) { + rv.erase(rp,rl); + } + rl = root_so.length(); + while((rp=rv.find(root_so))!=string::npos) { + rv.erase(rp,rl); + } + return rv; +</%codemethod> +% /* vim:set ft=sitecing: */ |