#include <stdio.h>
#include <string.h>
#include <iomanip>
#include "ReportsText.h"
#include "app_common.h"
#include "CoverageRanges.h"
#include "DesiredSymbols.h"
#include "Explanations.h"
#include "ObjdumpProcessor.h"
namespace Coverage {
ReportsText::ReportsText( time_t timestamp, const std::string& symbolSetName ):
ReportsBase( timestamp, symbolSetName )
{
reportExtension_m = ".txt";
}
ReportsText::~ReportsText()
{
}
void ReportsText::AnnotatedStart( std::ofstream& aFile )
{
aFile << "========================================"
<< "=======================================" << std::endl;
}
void ReportsText::AnnotatedEnd( std::ofstream& aFile )
{
}
void ReportsText::PutAnnotatedLine(
std::ofstream& aFile,
AnnotatedLineState_t state,
const std::string& line,
uint32_t id
)
{
aFile << line << std::endl;
}
bool ReportsText::PutNoBranchInfo( std::ofstream& report )
{
if (
BranchInfoAvailable &&
SymbolsToAnalyze->getNumberBranchesFound( symbolSetName_m ) != 0
) {
report << "All branch paths taken." << std::endl;
} else {
report << "No branch information found." << std::endl;
}
return true;
}
bool ReportsText::PutBranchEntry(
std::ofstream& report,
unsigned int number,
const std::string& symbolName,
const SymbolInformation& symbolInfo,
const CoverageRanges::coverageRange_t& range
)
{
const Coverage::Explanation* explanation;
// Add an entry to the report
report << "============================================" << std::endl
<< "Symbol : " << symbolName
<< std::hex << " (0x" << symbolInfo.baseAddress << ")" << std::endl
<< "Line : " << range.lowSourceLine
<< " (0x" << range.lowAddress << ")" << std::endl
<< "Size in Bytes : " << range.highAddress - range.lowAddress + 1
<< std::dec << std::endl;
if (
range.reason ==
Coverage::CoverageRanges::UNCOVERED_REASON_BRANCH_ALWAYS_TAKEN
) {
report << "Reason : ALWAYS TAKEN"
<< std::endl << std::endl;
} else if (
range.reason ==
Coverage::CoverageRanges::UNCOVERED_REASON_BRANCH_NEVER_TAKEN
) {
report << "Reason : NEVER TAKEN"
<< std::endl << std::endl;
}
// See if an explanation is available
explanation = AllExplanations->lookupExplanation( range.lowSourceLine );
if ( !explanation ) {
report << "Classification: NONE" << std::endl << std::endl
<< "Explanation:" << std::endl
<< "No Explanation" << std::endl;
} else {
report << "Classification: " << explanation->classification
<< std::endl << std::endl
<< "Explanation:" << std::endl;
for ( unsigned int i=0; i < explanation->explanation.size(); i++ ) {
report << explanation->explanation[i] << std::endl;
}
}
report << "============================================" << std::endl;
return true;
}
void ReportsText::putCoverageNoRange(
std::ofstream& report,
std::ofstream& noRangeFile,
unsigned int number,
const std::string& symbol
)
{
report << "============================================" << std::endl
<< "Symbol : " << symbol << std::endl << std::endl
<< " *** NEVER REFERENCED ***" << std::endl << std::endl
<< "This symbol was never referenced by an analyzed executable."
<< std::endl
<< "Therefore there is no size or disassembly for this symbol."
<< std::endl
<< "This could be due to symbol misspelling or lack of a test for"
<< std::endl
<< "this symbol." << std::endl
<< "============================================" << std::endl;
noRangeFile << symbol << std::endl;
}
bool ReportsText::PutCoverageLine(
std::ofstream& report,
unsigned int number,
const std::string& symbolName,
const SymbolInformation& symbolInfo,
const CoverageRanges::coverageRange_t& range
)
{
const Coverage::Explanation* explanation;
report << "============================================" << std::endl
<< "Index : " << range.id << std::endl
<< "Symbol : " << symbolName
<< std::hex << " (0x" << symbolInfo.baseAddress << ")" << std::endl
<< "Starting Line : " << range.lowSourceLine
<< " (0x" << range.lowAddress << ")" << std::endl
<< "Ending Line : " << range.highSourceLine
<< " (0x" << range.highAddress << ")" << std::endl
<< std::dec
<< "Size in Bytes : "
<< range.highAddress - range.lowAddress + 1 << std::endl
<< "Size in Instructions : " << range.instructionCount
<< std::endl << std::endl;
explanation = AllExplanations->lookupExplanation( range.lowSourceLine );
if ( !explanation ) {
report << "Classification: NONE" << std::endl << std::endl
<< "Explanation:" << std::endl
<< "No Explanation" << std::endl;
} else {
report << "Classification: " << explanation->classification << std::endl
<< std::endl
<< "Explanation:" << std::endl;
for ( unsigned int i=0; i < explanation->explanation.size(); i++) {
report << explanation->explanation[i] << std::endl;
}
}
report << "============================================" << std::endl;
return true;
}
bool ReportsText::PutSizeLine(
std::ofstream& report,
unsigned int number,
const std::string& symbolName,
const CoverageRanges::coverageRange_t& range
)
{
report << range.highAddress - range.lowAddress + 1 << '\t'
<< symbolName << '\t'
<< range.lowSourceLine << std::endl;
return true;
}
bool ReportsText::PutSymbolSummaryLine(
std::ofstream& report,
unsigned int number,
const std::string& symbolName,
const SymbolInformation& symbolInfo
)
{
float uncoveredBytes;
float uncoveredInstructions;
if ( symbolInfo.stats.sizeInBytes == 0 ) {
report << "============================================" << std::endl
<< "Symbol : " << symbolName << std::endl
<< " *** NEVER REFERENCED ***"
<< std::endl << std::endl
<< "This symbol was never referenced by an analyzed executable."
<< std::endl
<< "Therefore there is no size or disassembly for this symbol."
<< std::endl
<< "This could be due to symbol misspelling or lack of a test for"
<< std::endl
<< "this symbol." << std::endl
<< "============================================" << std::endl;
} else {
if ( symbolInfo.stats.sizeInInstructions == 0 ) {
uncoveredInstructions = 0;
} else {
uncoveredInstructions =
( symbolInfo.stats.uncoveredInstructions * 100.0 ) /
symbolInfo.stats.sizeInInstructions;
}
if ( symbolInfo.stats.sizeInBytes == 0 ) {
uncoveredBytes = 0;
} else {
uncoveredBytes = ( symbolInfo.stats.uncoveredBytes * 100.0 ) /
symbolInfo.stats.sizeInBytes;
}
report << "============================================" << std::endl
<< "Symbol : "
<< symbolName << std::endl
<< "Total Size in Bytes : "
<< symbolInfo.stats.sizeInBytes << std::endl
<< "Total Size in Instructions : "
<< symbolInfo.stats.sizeInInstructions << std::endl
<< "Total number Branches : "
<< symbolInfo.stats.branchesNotExecuted +
symbolInfo.stats.branchesExecuted
<< std::endl
<< "Total Always Taken : "
<< symbolInfo.stats.branchesAlwaysTaken << std::endl
<< "Total Never Taken : "
<< symbolInfo.stats.branchesNeverTaken << std::endl
<< std::fixed << std::setprecision( 2 )
<< "Percentage Uncovered Instructions : "
<< uncoveredInstructions << std::endl
<< "Percentage Uncovered Bytes : "
<< uncoveredBytes << std::endl;
report << "============================================" << std::endl;
}
return true;
}
}