#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sstream>
#include <iomanip>
#include <rld.h>
#include <rtems-utils.h>
#include "ReportsHtml.h"
#include "CoverageRanges.h"
#include "DesiredSymbols.h"
#include "ObjdumpProcessor.h"
#if 0
#define TABLE_HEADER_CLASS \
" table-autopage:10 table-page-number:pagenum table-page-count:pages "
#define TABLE_FOOTER \
"<tfoot>\n" \
"<tr>\n" \
"<td class=\"table-page:previous\" " \
"style=\"cursor:pointer;\">< < Previous</td>\n" \
"<td colspan=\"4\" style=\"text-align:center;\">Page " \
"<span id=\"pagenum\"></span> of <span id=\"pages\"></span></td>\n" \
"<td class=\"table-page:next\" " \
"style=\"cursor:pointer;\">Next > ></td>\n" \
"</tr>\n" \
"</tfoot>\n"
#else
#define TABLE_HEADER_CLASS ""
#define TABLE_FOOTER ""
#endif
namespace Coverage {
ReportsHtml::ReportsHtml(
time_t timestamp,
const std::string& symbolSetName,
Coverage::Explanations& allExplanations,
const std::string& projectName,
const std::string& outputDirectory,
const Coverage::DesiredSymbols& symbolsToAnalyze,
bool branchInfoAvailable
): ReportsBase(
timestamp,
symbolSetName,
allExplanations,
projectName,
outputDirectory,
symbolsToAnalyze,
branchInfoAvailable
),
lastState_m( A_SOURCE )
{
reportExtension_m = ".html";
}
ReportsHtml::~ReportsHtml()
{
}
void ReportsHtml::WriteIndex( const std::string& fileName )
{
std::ofstream aFile;
#define PRINT_ITEM( _t, _n ) \
aFile << "<li>" \
<< _t << " (<a href=\"" \
<< _n << ".html\">html</a> or <a href=\"" \
<< _n << ".txt\">text</a>)</li>" << std::endl;
#define PRINT_TEXT_ITEM( _t, _n ) \
aFile << "<li>" \
<< _t << " (<a href=\"" \
<< _n << "\">text</a>)</li>" << std::endl;
// Open the file
OpenFile( fileName, aFile );
aFile << "<title>Index</title>" << std::endl
<< "<div class=\"heading-title\">";
if ( !projectName_m.empty() ) {
aFile << projectName_m << "<br>";
}
aFile << "Coverage Analysis Reports</div>" << std::endl
<< "<div class =\"datetime\">"
<< asctime( localtime( ×tamp_m ) ) << "</div>" << std::endl
<< "<ul>" << std::endl;
PRINT_TEXT_ITEM( "Summary", "summary.txt" );
PRINT_ITEM( "Coverage Report", "uncovered" );
PRINT_ITEM( "Branch Report", "branch" );
PRINT_ITEM( "Annotated Assembly", "annotated" );
PRINT_ITEM( "Symbol Summary", "symbolSummary" );
PRINT_ITEM( "Uncovered Range Size Report", "sizes" );
PRINT_TEXT_ITEM( "Explanations Not Found", "ExplanationsNotFound.txt" );
aFile << "</ul>" << std::endl
<< "<!-- INSERT PROJECT SPECIFIC ITEMS HERE -->" << std::endl
<< "</html>" << std::endl;
CloseFile( aFile );
#undef PRINT_ITEM
#undef PRINT_TEXT_ITEM
}
void ReportsHtml::OpenFile(
const std::string& fileName,
std::ofstream& aFile
)
{
// Open the file
ReportsBase::OpenFile(
fileName,
symbolSetName_m,
aFile,
outputDirectory_m
);
// Put Header information on the file
aFile << "<html>" << std::endl
<< "<meta http-equiv=\"Content-Language\" content=\"English\" >"
<< std::endl
<< "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=us-ascii\" >"
<< std::endl
<< "<link rel=\"stylesheet\" type=\"text/css\" href=\"../covoar.css\" media=\"screen\" >"
<< std::endl
<< "<script type=\"text/javascript\" src=\"../table.js\"></script>"
<< std::endl;
}
void ReportsHtml::OpenAnnotatedFile(
const std::string& fileName,
std::ofstream& aFile
)
{
// Open the file
OpenFile( fileName, aFile );
aFile << "<title>Annotated Report</title>" << std::endl
<< "<div class=\"heading-title\">";
if ( !projectName_m.empty() ) {
aFile << projectName_m << "<br>";
}
aFile << "Annotated Report</div>" << std::endl
<< "<div class =\"datetime\">"
<< asctime( localtime( ×tamp_m ) ) << "</div>" << std::endl
<< "<body>" << std::endl
<< "<pre class=\"code\">" << std::endl;
}
void ReportsHtml::OpenBranchFile(
const std::string& fileName,
bool hasBranches,
std::ofstream& aFile
)
{
// Open the file
OpenFile( fileName, aFile );
// Put header information into the file
aFile << "<title>Branch Report</title>" << std::endl
<< "<div class=\"heading-title\">";
if ( !projectName_m.empty() ) {
aFile << projectName_m << "<br>";
}
aFile << "Branch Report</div>" << std::endl
<< "<div class =\"datetime\">"
<< asctime( localtime( ×tamp_m ) ) << "</div>" << std::endl
<< "<body>" << std::endl
<< "<table class=\"covoar table-autosort:0 table-autofilter table-stripeclass:covoar-tr-odd"
<< TABLE_HEADER_CLASS << "\">" << std::endl
<< "<thead>" << std::endl
<< "<tr>" << std::endl
<< "<th class=\"table-sortable:default\" align=\"left\">Symbol</th>" << std::endl
<< "<th class=\"table-sortable:default\" align=\"left\">Line</th>"
<< std::endl
<< "<th class=\"table-filterable table-sortable:default\" align=\"left\">File</th>"
<< std::endl
<< "<th class=\"table-sortable:numeric\" align=\"left\">Size <br>Bytes</th>"
<< std::endl
<< "<th class=\"table-sortable:default\" align=\"left\">Reason</th>"
<< std::endl
<< "<th class=\"table-filterable table-sortable:default\" align=\"left\">Taken</th>"
<< std::endl
<< "<th class=\"table-filterable table-sortable:default\" align=\"left\">Not Taken</th>"
<< std::endl
<< "<th class=\"table-filterable table-sortable:default\" align=\"left\">Classification</th>"
<< std::endl
<< "<th class=\"table-sortable:default\" align=\"left\">Explanation</th>"
<< std::endl
<< "</tr>" << std::endl
<< "</thead>" << std::endl
<< "<tbody>" << std::endl;
}
void ReportsHtml::OpenCoverageFile(
const std::string& fileName,
std::ofstream& aFile
)
{
// Open the file
OpenFile( fileName, aFile );
// Put header information into the file
aFile << "<title>Coverage Report</title>" << std::endl
<< "<div class=\"heading-title\">";
if ( !projectName_m.empty() ) {
aFile << projectName_m << "<br>";
}
aFile << "Coverage Report</div>" << std::endl
<< "<div class =\"datetime\">"
<< asctime( localtime( ×tamp_m ) ) << "</div>" << std::endl
<< "<body>" << std::endl
<< "<table class=\"covoar table-autosort:0 table-autofilter table-stripeclass:covoar-tr-odd"
<< TABLE_HEADER_CLASS << "\">" << std::endl
<< "<thead>" << std::endl
<< "<tr>" << std::endl
<< "<th class=\"table-sortable:default\" align=\"left\">Symbol</th>"
<< std::endl
<< "<th class=\"table-sortable:default\" align=\"left\">Range</th>"
<< std::endl
<< "<th class=\"table-filterable table-sortable:default\" align=\"left\">File</th>"
<< std::endl
<< "<th class=\"table-sortable:numeric\" align=\"left\">Size <br>Bytes</th>"
<< std::endl
<< "<th class=\"table-sortable:numeric\" align=\"left\">Size <br>Instructions</th>"
<< std::endl
<< "<th class=\"table-filterable table-sortable:default\" align=\"left\">Classification</th>"
<< std::endl
<< "<th class=\"table-sortable:default\" align=\"left\">Explanation</th>"
<< std::endl
<< "</tr>" << std::endl
<< "</thead>" << std::endl
<< "<tbody>" << std::endl;
}
void ReportsHtml::OpenNoRangeFile(
const std::string& fileName,
std::ofstream& aFile
)
{
// Open the file
OpenFile( fileName, aFile );
// Put header information into the file
aFile << "<title> Report</title>" << std::endl
<< "<div class=\"heading-title\">";
if ( !projectName_m.empty() ) {
aFile << projectName_m << "<br>";
}
aFile << "No Range Report</div>" << std::endl
<< "<div class =\"datetime\">"
<< asctime( localtime( ×tamp_m ) ) << "</div>" << std::endl
<< "<body>" << std::endl
<< "<table class=\"covoar table-autosort:0 table-autofilter table-stripeclass:covoar-tr-odd"
<< TABLE_HEADER_CLASS << "\">" << std::endl
<< "<thead>" << std::endl
<< "<tr>" << std::endl
<< "<th class=\"table-sortable:default\" align=\"left\">Symbol</th>"
<< std::endl
<< "</tr>" << std::endl
<< "</thead>" << std::endl
<< "<tbody>" << std::endl;
}
void ReportsHtml::OpenSizeFile(
const std::string& fileName,
std::ofstream& aFile
)
{
// Open the file
OpenFile( fileName, aFile );
// Put header information into the file
aFile << "<title>Uncovered Range Size Report</title>" << std::endl
<< "<div class=\"heading-title\">";
if ( !projectName_m.empty() ) {
aFile << projectName_m << "<br>";
}
aFile << "Uncovered Range Size Report</div>" << std::endl
<< "<div class =\"datetime\">"
<< asctime( localtime( ×tamp_m ) ) << "</div>" << std::endl
<< "<body>" << std::endl
<< "<table class=\"covoar table-autosort:0 table-autofilter table-stripeclass:covoar-tr-odd"
<< TABLE_HEADER_CLASS << "\">" << std::endl
<< "<thead>" << std::endl
<< "<tr>" << std::endl
<< "<th class=\"table-sortable:numeric\" align=\"left\">Size</th>"
<< std::endl
<< "<th class=\"table-sortable:default\" align=\"left\">Symbol</th>"
<< std::endl
<< "<th class=\"table-sortable:default\" align=\"left\">Line</th>"
<< std::endl
<< "<th class=\"table-filterable table-sortable:default\" align=\"left\">File</th>"
<< std::endl
<< "</tr>" << std::endl
<< "</thead>" << std::endl
<< "<tbody>" << std::endl;
}
void ReportsHtml::OpenSymbolSummaryFile(
const std::string& fileName,
std::ofstream& aFile
)
{
// Open the file
OpenFile( fileName, aFile );
// Put header information into the file
aFile << "<title>Symbol Summary Report</title>" << std::endl
<< "<div class=\"heading-title\">";
if ( !projectName_m.empty() ) {
aFile << projectName_m << "<br>";
}
aFile << "Symbol Summary Report</div>" << std::endl
<< "<div class =\"datetime\">"
<< asctime( localtime( ×tamp_m ) ) << "</div>" << std::endl
<< "<body>" << std::endl
<< "<table class=\"covoar table-autosort:0 table-autofilter table-stripeclass:covoar-tr-odd"
<< TABLE_HEADER_CLASS << "\">" << std::endl
<< "<thead>" << std::endl
<< "<tr>" << std::endl
<< "<th class=\"table-sortable:default\" align=\"center\">Symbol</th>"
<< std::endl
<< "<th class=\"table-sortable:numeric\" align=\"center\">Total<br>Size<br>Bytes</th>"
<< std::endl
<< "<th class=\"table-sortable:numeric\" align=\"center\">Total<br>Size<br>Instr</th>"
<< std::endl
<< "<th class=\"table-sortable:numeric\" align=\"center\">#<br>Ranges</th>"
<< std::endl
<< "<th class=\"table-sortable:numeric\" align=\"center\">Uncovered<br>Size<br>Bytes</th>"
<< std::endl
<< "<th class=\"table-sortable:numeric\" align=\"center\">Uncovered<br>Size<br>Instr</th>"
<< std::endl
<< "<th class=\"table-sortable:numeric\" align=\"center\">#<br>Branches</th>"
<< std::endl
<< "<th class=\"table-sortable:numeric\" align=\"center\">#<br>Always<br>Taken</th>"
<< std::endl
<< "<th class=\"table-sortable:numeric\" align=\"center\">#<br>Never<br>Taken</th>"
<< std::endl
<< "<th class=\"table-sortable:numeric\" align=\"center\">Percent<br>Uncovered<br>Instructions</th>"
<< std::endl
<< "<th class=\"table-sortable:numeric\" align=\"center\">Percent<br>Uncovered<br>Bytes</th>"
<< std::endl
<< "</tr>" << std::endl
<< "</thead>" << std::endl
<< "<tbody>" << std::endl;
}
void ReportsHtml::AnnotatedStart( std::ofstream& aFile )
{
aFile << "<hr>" << std::endl;
}
void ReportsHtml::AnnotatedEnd( std::ofstream& aFile )
{
}
void ReportsHtml::PutAnnotatedLine(
std::ofstream& aFile,
AnnotatedLineState_t state,
const std::string& line,
uint32_t id
)
{
std::string stateText;
std::string number;
number = std::to_string( id );
// Set the stateText based upon the current state.
switch ( state ) {
case A_SOURCE:
stateText = "</pre>\n<pre class=\"code\">\n";
break;
case A_EXECUTED:
stateText = "</pre>\n<pre class=\"codeExecuted\">\n";
break;
case A_NEVER_EXECUTED:
stateText = "</pre>\n";
stateText += "<a name=\"range";
stateText += number;
stateText += "\"></a><pre class=\"codeNotExecuted\">\n";
break;
case A_BRANCH_TAKEN:
stateText = "</pre>\n";
stateText += "<a name=\"range";
stateText += number;
stateText += "\"></a><pre class=\"codeAlwaysTaken\">\n";
break;
case A_BRANCH_NOT_TAKEN:
stateText = "</pre>\n";
stateText += "<a name=\"range";
stateText += number;
stateText += "\"></a><pre class=\"codeNeverTaken\">\n";
break;
default:
throw rld::error( "Unknown state", "ReportsHtml::PutAnnotatedLine" );
break;
}
// If the state has not changed there is no need to change the text block
// format. If it has changed close out the old format and open up the
// new format.
if ( state != lastState_m ) {
aFile << stateText;
lastState_m = state;
}
// For all the characters in the line replace html reserved special
// characters and output the line. Note that for a /pre block this
// is only a '<' symbol.
for ( unsigned int i=0; i<line.size(); i++ ) {
if ( line[i] == '<' ) {
aFile << "<";
} else {
aFile << line[i];
}
}
aFile << std::endl;
}
bool ReportsHtml::PutNoBranchInfo( std::ofstream& report )
{
if (
branchInfoAvailable_m &&
symbolsToAnalyze_m.getNumberBranchesFound( symbolSetName_m ) != 0
) {
report << "All branch paths taken." << std::endl;
} else {
report << "No branch information found." << std::endl;
}
return true;
}
bool ReportsHtml::PutBranchEntry(
std::ofstream& report,
unsigned int count,
const std::string& symbolName,
const SymbolInformation& symbolInfo,
const CoverageRanges::coverageRange_t& range
)
{
const Coverage::Explanation* explanation;
std::string temp;
int i;
uint32_t bAddress = 0;
uint32_t lowAddress = 0;
Coverage::CoverageMapBase* theCoverageMap = NULL;
// Mark the background color different for odd and even lines.
if ( ( count % 2 ) != 0 ) {
report << "<tr class=\"covoar-tr-odd\">\n";
} else {
report << "<tr>" << std::endl;
}
// symbol
report << "<td class=\"covoar-td\" align=\"center\">"
<< symbolName << "</td>" << std::endl;
// line
report << "<td class=\"covoar-td\" align=\"center\"><a href =\"annotated.html#range"
<< range.id << "\">"
<< range.lowSourceLine << "</td>" << std::endl;
// File
i = range.lowSourceLine.find( ":" );
temp = range.lowSourceLine.substr( 0, i );
report << "<td class=\"covoar-td\" align=\"center\">"
<< temp << "</td>" << std::endl;
// Size in bytes
report << "<td class=\"covoar-td\" align=\"center\">"
<< range.highAddress - range.lowAddress + 1 << "</td>" << std::endl;
// Reason Branch was uncovered
if (
range.reason ==
Coverage::CoverageRanges::UNCOVERED_REASON_BRANCH_ALWAYS_TAKEN
) {
report << "<td class=\"covoar-td\" align=\"center\">Always Taken</td>"
<< std::endl;
} else if (
range.reason ==
Coverage::CoverageRanges::UNCOVERED_REASON_BRANCH_NEVER_TAKEN
) {
report << "<td class=\"covoar-td\" align=\"center\">Never Taken</td>"
<< std::endl;
}
// Taken / Not taken counts
lowAddress = range.lowAddress;
bAddress = symbolInfo.baseAddress;
theCoverageMap = symbolInfo.unifiedCoverageMap;
report << "<td class=\"covoar-td\" align=\"center\">"
<< theCoverageMap->getWasTaken( lowAddress - bAddress )
<< "</td>" << std::endl
<< "<td class=\"covoar-td\" align=\"center\">"
<< theCoverageMap->getWasNotTaken( lowAddress - bAddress )
<< "</td>" << std::endl;
// See if an explanation is available and write the Classification and
// the Explination Columns.
explanation = allExplanations_m.lookupExplanation( range.lowSourceLine );
if ( !explanation ) {
// Write Classificationditr->second.baseAddress
report << "<td class=\"covoar-td\" align=\"center\">NONE</td>"
<< std::endl
<< "<td class=\"covoar-td\" align=\"center\">No Explanation</td>"
<< std::endl;
} else {
std::stringstream explanationFile( "explanation" );
explanationFile << range.id << ".html";
report << "<td class=\"covoar-td\" align=\"center\">"
<< explanation->classification << "</td>" << std::endl
<< "<td class=\"covoar-td\" align=\"center\">"
<< "<a href=\"" << explanationFile.str()
<< "\">Explanation</a></td>" << std::endl;
WriteExplanationFile( explanationFile.str(), explanation );
}
report << "</tr>" << std::endl;
return true;
}
bool ReportsHtml::WriteExplanationFile(
const std::string& fileName,
const Coverage::Explanation* explanation
)
{
std::ofstream report;
OpenFile( fileName, report );
for ( unsigned int i=0 ; i < explanation->explanation.size(); i++ ) {
report << explanation->explanation[i] << std::endl;
}
CloseFile( report );
return true;
}
void ReportsHtml::putCoverageNoRange(
std::ofstream& report,
std::ofstream& noRangeFile,
unsigned int count,
const std::string& symbol
)
{
Coverage::Explanation explanation;
explanation.explanation.push_back(
"<html><p>\n"
"This symbol was never referenced by an analyzed executable. "
"Therefore there is no size or disassembly for this symbol. "
"This could be due to symbol misspelling or lack of a test for "
"this symbol."
"</p></html>\n"
);
// Mark the background color different for odd and even lines.
if ( ( count % 2 ) != 0 ) {
report << "<tr class=\"covoar-tr-odd\">" << std::endl;
noRangeFile << "<tr class=\"covoar-tr-odd\">" << std::endl;
} else {
report << "<tr>" << std::endl;
noRangeFile << "<tr>" << std::endl;
}
// symbol
report << "<td class=\"covoar-td\" align=\"center\">"
<< symbol << "</td>" << std::endl;
noRangeFile << "<td class=\"covoar-td\" align=\"center\">"
<< symbol << "</td>" << std::endl;
// starting line
report << "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl;
// file
report << "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl;
// Size in bytes
report << "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl;
// Size in instructions
report << "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl;
// See if an explanation is available
report << "<td class=\"covoar-td\" align=\"center\">Unknown</td>"
<< std::endl
<< "<td class=\"covoar-td\" align=\"center\">"
<< "<a href=\"NotReferenced.html\">No data</a></td>"
<< std::endl;
WriteExplanationFile( "NotReferenced.html", &explanation );
report << "</tr>" << std::endl;
noRangeFile << "</tr>" << std::endl;
}
bool ReportsHtml::PutCoverageLine(
std::ofstream& report,
unsigned int count,
const std::string& symbolName,
const SymbolInformation& symbolInfo,
const CoverageRanges::coverageRange_t& range
)
{
const Coverage::Explanation* explanation;
std::string temp;
int i;
// Mark the background color different for odd and even lines.
if ( ( count % 2) != 0 ) {
report << "<tr class=\"covoar-tr-odd\">" << std::endl;
} else {
report << "<tr>" << std::endl;
}
// symbol
report << "<td class=\"covoar-td\" align=\"center\">"
<< symbolName << "</td>" << std::endl;
// Range
report << "<td class=\"covoar-td\" align=\"center\"><a href =\"annotated.html#range"
<< range.id << "\">"
<< range.lowSourceLine << " <br>"
<< range.highSourceLine << "</td>" << std::endl;
// File
i = range.lowSourceLine.find( ":" );
temp = range.lowSourceLine.substr( 0, i );
report << "<td class=\"covoar-td\" align=\"center\">"
<< temp << "</td>" << std::endl;
// Size in bytes
report << "<td class=\"covoar-td\" align=\"center\">"
<< range.highAddress - range.lowAddress + 1 << "</td>" << std::endl;
// Size in instructions
report << "<td class=\"covoar-td\" align=\"center\">"
<< range.instructionCount << "</td>" << std::endl;
// See if an explanation is available
explanation = allExplanations_m.lookupExplanation( range.lowSourceLine );
if ( !explanation ) {
report << "<td class=\"covoar-td\" align=\"center\">NONE</td>"
<< std::endl
<< "<td class=\"covoar-td\" align=\"center\">No Explanation</td>"
<< std::endl;
} else {
std::stringstream explanationFile( "explanation" );
explanationFile << range.id << ".html";
report << "<td class=\"covoar-td\" align=\"center\">"
<< explanation->classification << "</td>" << std::endl
<< "<td class=\"covoar-td\" align=\"center\">"
<< "<a href=\""
<< explanationFile.str() << "\">Explanation</a></td>"
<< std::endl;
WriteExplanationFile( explanationFile.str(), explanation );
}
report << "</tr>" << std::endl;
return true;
}
bool ReportsHtml::PutSizeLine(
std::ofstream& report,
unsigned int count,
const std::string& symbolName,
const CoverageRanges::coverageRange_t& range
)
{
std::string temp;
int i;
// Mark the background color different for odd and even lines.
if ( ( count % 2 ) != 0 ) {
report << "<tr class=\"covoar-tr-odd\">" << std::endl;
} else {
report << "<tr>" << std::endl;
}
// size
report << "<td class=\"covoar-td\" align=\"center\">"
<< range.highAddress - range.lowAddress + 1 << "</td>" << std::endl;
// symbol
report << "<td class=\"covoar-td\" align=\"center\">"
<< symbolName << "</td>" << std::endl;
// line
report << "<td class=\"covoar-td\" align=\"center\"><a href =\"annotated.html#range"
<< range.id << "\">"
<< range.lowSourceLine << "</td>" << std::endl;
// File
i = range.lowSourceLine.find( ":" );
temp = range.lowSourceLine.substr( 0, i );
report << "<td class=\"covoar-td\" align=\"center\">"
<< temp << "</td>" << std::endl
<< "</tr>" << std::endl;
return true;
}
bool ReportsHtml::PutSymbolSummaryLine(
std::ofstream& report,
unsigned int count,
const std::string& symbolName,
const SymbolInformation& symbolInfo
)
{
rtems::utils::ostream_guard old_state( report );
// Mark the background color different for odd and even lines.
if ( ( count % 2 ) != 0 ) {
report << "<tr class=\"covoar-tr-odd\">" << std::endl;
} else {
report << "<tr>" << std::endl;
}
// symbol
report << "<td class=\"covoar-td\" align=\"center\">"
<< symbolName << "</td>" << std::endl;
if ( symbolInfo.stats.sizeInBytes == 0 ) {
// The symbol has never been seen. Write "unknown" for all columns.
report << "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl
<< "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl
<< "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl
<< "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl
<< "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl
<< "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl
<< "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl
<< "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl
<< "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl
<< "<td class=\"covoar-td\" align=\"center\">unknown</td>"
<< std::endl;
} else {
// Total Size in Bytes
report << "<td class=\"covoar-td\" align=\"center\">"
<< symbolInfo.stats.sizeInBytes << "</td>" << std::endl;
// Total Size in Instructions
report << "<td class=\"covoar-td\" align=\"center\">"
<< symbolInfo.stats.sizeInInstructions << "</td>" << std::endl;
// Total Uncovered Ranges
report << "<td class=\"covoar-td\" align=\"center\">"
<< symbolInfo.stats.uncoveredRanges << "</td>" << std::endl;
// Uncovered Size in Bytes
report << "<td class=\"covoar-td\" align=\"center\">"
<< symbolInfo.stats.uncoveredBytes << "</td>" << std::endl;
// Uncovered Size in Instructions
report << "<td class=\"covoar-td\" align=\"center\">"
<< symbolInfo.stats.uncoveredInstructions << "</td>" << std::endl;
// Total number of branches
report << "<td class=\"covoar-td\" align=\"center\">"
<< symbolInfo.stats.branchesNotExecuted +
symbolInfo.stats.branchesExecuted
<< "</td>" << std::endl;
// Total Always Taken
report << "<td class=\"covoar-td\" align=\"center\">"
<< symbolInfo.stats.branchesAlwaysTaken << "</td>" << std::endl;
// Total Never Taken
report << "<td class=\"covoar-td\" align=\"center\">"
<< symbolInfo.stats.branchesNeverTaken << "</td>" << std::endl;
// % Uncovered Instructions
if ( symbolInfo.stats.sizeInInstructions == 0 ) {
report << "<td class=\"covoar-td\" align=\"center\">100.00</td>"
<< std::endl;
} else {
report << "<td class=\"covoar-td\" align=\"center\">"
<< std::fixed << std::setprecision( 2 )
<< ( symbolInfo.stats.uncoveredInstructions * 100.0 ) /
symbolInfo.stats.sizeInInstructions
<< "</td>" << std::endl;
}
// % Uncovered Bytes
if ( symbolInfo.stats.sizeInBytes == 0 ) {
report << "<td class=\"covoar-td\" align=\"center\">100.00</td>"
<< std::endl;
} else {
report << "<td class=\"covoar-td\" align=\"center\">"
<< ( symbolInfo.stats.uncoveredBytes * 100.0 ) /
symbolInfo.stats.sizeInBytes
<< "</td>" << std::endl;
}
}
report << "</tr>" << std::endl;
return true;
}
void ReportsHtml::CloseAnnotatedFile( std::ofstream& aFile )
{
aFile << "</pre>" << std::endl
<< "</body>" << std::endl
<< "</html>" << std::endl;
CloseFile( aFile );
}
void ReportsHtml::CloseBranchFile( std::ofstream& aFile, bool hasBranches )
{
aFile << TABLE_FOOTER
<< "</tbody>" << std::endl
<< "</table>" << std::endl;
CloseFile( aFile );
}
void ReportsHtml::CloseCoverageFile( std::ofstream& aFile )
{
aFile << TABLE_FOOTER
<< "</tbody>" << std::endl
<< "</table>" << std::endl
<< "</pre>" << std::endl
<< "</body>" << std::endl
<< "</html>";
CloseFile( aFile );
}
void ReportsHtml::CloseNoRangeFile( std::ofstream& aFile )
{
aFile << TABLE_FOOTER
<< "</tbody>" << std::endl
<< "</table>" << std::endl
<< "</pre>" << std::endl
<< "</body>" << std::endl
<< "</html>";
CloseFile( aFile );
}
void ReportsHtml::CloseSizeFile( std::ofstream& aFile )
{
aFile << TABLE_FOOTER
<< "</tbody>" << std::endl
<< "</table>" << std::endl
<< "</pre>" << std::endl
<< "</body>" << std::endl
<< "</html>";
CloseFile( aFile );
}
void ReportsHtml::CloseSymbolSummaryFile( std::ofstream& aFile )
{
aFile << TABLE_FOOTER
<< "</tbody>" << std::endl
<< "</table>" << std::endl
<< "</pre>" << std::endl
<< "</body>" << std::endl
<< "</html>";
CloseFile( aFile );
}
}