void document_subgoals( const symex_target_equationt &equation, std::ostream &out) { typedef std::map<irept, doc_claimt> claim_sett; claim_sett claim_set; for(const auto &SSA_step : equation.SSA_steps) if(SSA_step.is_assert()) { locationt new_location; new_location.file(SSA_step.source.pc->location.file()); new_location.line(SSA_step.source.pc->location.line()); new_location.function(SSA_step.source.pc->location.function()); claim_set[new_location].comment_set.insert(SSA_step.comment); } for(claim_sett::const_iterator it = claim_set.begin(); it != claim_set.end(); it++) { std::string code; const irept &location = it->first; get_code(location, code); out << "\\claimlocation{File " << escape_latex(location.file().as_string(), false) << " function " << escape_latex(location.function().as_string(), false) << "}" << std::endl; out << std::endl; for(const auto &s_it : it->second.comment_set) out << "\\claim{" << escape_latex(s_it, false) << "}" << std::endl; out << std::endl; out << "\\begin{alltt}\\claimcode\n" << code << "\\end{alltt}\n"; out << std::endl; out << std::endl; } }
void document_propertiest::doit() { typedef std::map<source_locationt, doc_claimt> claim_sett; claim_sett claim_set; forall_goto_functions(f_it, goto_functions) { const goto_programt &goto_program=f_it->second.body; forall_goto_program_instructions(i_it, goto_program) { if(i_it->is_assert()) { source_locationt new_source_location; new_source_location.set_file(i_it->source_location.get_file()); new_source_location.set_line(i_it->source_location.get_line()); new_source_location.set_function(i_it->source_location.get_function()); claim_set[new_source_location].comment_set. insert(i_it->source_location.get_comment()); } } } for(claim_sett::const_iterator it=claim_set.begin(); it!=claim_set.end(); it++) { std::string code; const source_locationt &source_location=it->first; get_code(source_location, code); switch(format) { case LATEX: out << "\\claimlocation{File " << escape_latex(source_location.get_string("file"), false) << " function " << escape_latex(source_location.get_string("function"), false) << "}" << std::endl; out << std::endl; for(std::set<irep_idt>::const_iterator s_it=it->second.comment_set.begin(); s_it!=it->second.comment_set.end(); s_it++) out << "\\claim{" << escape_latex(id2string(*s_it), false) << "}" << std::endl; out << std::endl; out << "\\begin{alltt}\\claimcode\n" << code << "\\end{alltt}\n"; out << std::endl; out << std::endl; break; case HTML: out << "<div class=\"claim\">" << std::endl << "<div class=\"location\">File " << escape_html(source_location.get_string("file")) << " function " << escape_html(source_location.get_string("function")) << "</div>" << std::endl; out << std::endl; for(std::set<irep_idt>::const_iterator s_it=it->second.comment_set.begin(); s_it!=it->second.comment_set.end(); s_it++) out << "<div class=\"description\">" << std::endl << escape_html(id2string(*s_it)) << std::endl << "</div>" << std::endl; out << std::endl; out << "<div class=\"code\">\n" << code << "</div> <!-- code -->" << std::endl; out << "</div> <!-- claim -->" << std::endl; out << std::endl; break; } } }
void document_propertiest::get_code( const source_locationt &source_location, std::string &dest) { dest=""; const irep_idt &file=source_location.get_file(); const irep_idt &line=source_location.get_line(); if(file=="" || line=="") return; std::ifstream in(id2string(file)); if(!in) { dest+="ERROR: unable to open "; dest+=id2string(file); dest+="\n"; return; } int line_int=unsafe_string2int(id2string(line)); int line_start=line_int-3, line_end=line_int+3; if(line_start<=1) line_start=1; // skip line_start-1 lines for(int l=0; l<line_start-1; l++) { std::string tmp; std::getline(in, tmp); } // read till line_end std::list<linet> lines; for(int l=line_start; l<=line_end && in; l++) { lines.push_back(linet()); std::string &line=lines.back().text; std::getline(in, line); if(!line.empty() && line[line.size()-1]=='\r') line.resize(line.size()-1); lines.back().line_number=l; } // remove empty lines at the end and at the beginning for(std::list<linet>::iterator it=lines.begin(); it!=lines.end();) { if(is_empty(it->text)) it=lines.erase(it); else break; } for(std::list<linet>::iterator it=lines.end(); it!=lines.begin();) { it--; if(is_empty(it->text)) it=lines.erase(it); else break; } // strip space strip_space(lines); // build dest for(std::list<linet>::iterator it=lines.begin(); it!=lines.end(); it++) { std::string line_no=std::to_string(it->line_number); std::string tmp; switch(format) { case LATEX: while(line_no.size()<4) line_no=" "+line_no; line_no+" "; tmp+=escape_latex(it->text, true); if(it->line_number==line_int) tmp="{\\ttb{}"+tmp+"}"; break; case HTML: while(line_no.size()<4) line_no=" "+line_no; line_no+" "; tmp+=escape_html(it->text); if(it->line_number==line_int) tmp="<em>"+tmp+"</em>"; break; } dest+=tmp+"\n"; } }
void get_code(const irept &location, std::string &dest) { dest = ""; const irep_idt &file = location.file(); const irep_idt &line = location.line(); if(file == "" || line == "") return; std::ifstream in(file.c_str()); if(!in) return; int line_int = atoi(line.c_str()); int line_start = line_int - 3, line_end = line_int + 3; if(line_start <= 1) line_start = 1; // skip line_start-1 lines for(int l = 0; l < line_start - 1; l++) { std::string tmp; std::getline(in, tmp); } // read till line_end std::list<linet> lines; for(int l = line_start; l <= line_end && in; l++) { lines.emplace_back(); std::string &line = lines.back().text; std::getline(in, line); if(!line.empty() && line[line.size() - 1] == '\r') line.resize(line.size() - 1); lines.back().line_number = l; } // remove empty lines at the end and at the beginning for(std::list<linet>::iterator it = lines.begin(); it != lines.end();) { if(is_empty_str(it->text)) it = lines.erase(it); else break; } for(std::list<linet>::iterator it = lines.end(); it != lines.begin();) { it--; if(is_empty_str(it->text)) it = lines.erase(it); else break; } // strip space strip_space(lines); // build dest for(auto &line : lines) { std::string line_no = i2string(line.line_number); while(line_no.size() < 4) line_no = " " + line_no; std::string tmp = line_no + " " + escape_latex(line.text, true); if(line.line_number == line_int) tmp = emphasize(tmp); dest += tmp + "\n"; } }