| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- #include "cmStandardIncludes.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include "cmSystemTools.h"
- #include "cmXMLParser.h"
- #include "cmParseDelphiCoverage.h"
- #include <cmsys/Directory.hxx>
- #include <cmsys/Glob.hxx>
- #include <cmsys/FStream.hxx>
- class cmParseDelphiCoverage::HTMLParser
- {
- public:
- typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
- FileLinesType;
- HTMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
- : CTest(ctest), Coverage(cont)
- {
- }
- virtual ~HTMLParser()
- {
- }
- bool initializeDelphiFile(const std::string filename,
- cmParseDelphiCoverage::HTMLParser::FileLinesType &coverageVector)
- {
- std::string line;
- size_t comPos;
- size_t semiPos;
- bool blockComFlag= false;
- bool lineComFlag= false;
- std::vector<std::string> beginSet;
- cmsys::ifstream in(filename.c_str());
- if(!in)
- {
- return false;
- }
- while(cmSystemTools::GetLineFromStream(in, line))
- {
- lineComFlag=false;
- // Unique cases found in lines.
- size_t beginPos = line.find("begin");
- //Check that the begin is the first non-space string on the line
- if( (beginPos == line.find_first_not_of(' ')) && beginPos != line.npos )
- {
- beginSet.push_back("begin");
- coverageVector.push_back(-1);
- continue;
- }
- else if(line.find('{') != line.npos)
- {
- blockComFlag=true;
- }
- else if(line.find('}') != line.npos)
- {
- blockComFlag=false;
- coverageVector.push_back(-1);
- continue;
- }
- else if((line.find("end;") != line.npos)
- && !beginSet.empty())
- {
- beginSet.pop_back();
- coverageVector.push_back(-1);
- continue;
- }
- // This checks for comments after lines of code, finding the
- // comment symbol after the ending semicolon.
- comPos = line.find("//");
- if(comPos != line.npos)
- {
- semiPos= line.find(';');
- if(comPos < semiPos)
- {
- lineComFlag=true;
- }
- }
- //Based up what was found, add a line to the coverageVector
- if(!beginSet.empty() && line != "" && !blockComFlag
- && !lineComFlag)
- {
- coverageVector.push_back(0);
- }
- else
- {
- coverageVector.push_back(-1);
- }
- }
- return true;
- }
- bool ParseFile(const char* file)
- {
- std::string line=file;
- std::string lineresult;
- std::string lastroutine;
- std::string filename;
- std::string filelineoffset;
- size_t afterLineNum = 0;
- size_t lastoffset = 0;
- size_t endcovpos = 0;
- size_t endnamepos = 0;
- size_t pos = 0;
- /*
- * This first 'while' section goes through the found HTML
- * file name and attempts to capture the source file name
- * which is set as part of the HTML file name: the name of
- * the file is found in parenthesis '()'
- *
- * See test HTML file name: UTCovTest(UTCovTest.pas).html.
- *
- * Find the text inside each pair of parenthesis and check
- * to see if it ends in '.pas'. If it can't be found,
- * exit the function.
- */
- while(true)
- {
- lastoffset = line.find('(',pos);
- if(lastoffset==line.npos)
- {
- cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
- endnamepos << "File not found " << lastoffset << std::endl);
- return false;
- }
- endnamepos = line.find(')',lastoffset);
- filename = line.substr(lastoffset+1,
- (endnamepos-1)-lastoffset);
- if(filename.find(".pas") != filename.npos)
- {
- cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
- "Coverage found for file: " << filename << std::endl);
- break;
- }
- pos = lastoffset+1;
- }
- /*
- * Glob through the source directory for the
- * file found above
- */
- cmsys::Glob gl;
- gl.RecurseOn();
- gl.RecurseThroughSymlinksOff();
- std::string glob = Coverage.SourceDir + "*/" + filename;
- gl.FindFiles(glob);
- std::vector<std::string> const& files = gl.GetFiles();
- if(files.size() == 0)
- {
- /*
- * If that doesn't find any matching files
- * return a failure.
- */
- cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
- "Unable to find file matching" << glob << std::endl);
- return false;
- }
- FileLinesType& coverageVector =
- this->Coverage.TotalCoverage[files[0]];
- /*
- * Initialize the file to have all code between 'begin' and
- * 'end' tags marked as executable
- */
- this->initializeDelphiFile(files[0],coverageVector);
- cmsys::ifstream in(file);
- if(!in)
- {
- return false;
- }
- /*
- * Now read the HTML file, looking for the lines that have an
- * "inline" in it. Then parse out the "class" value of that
- * line to determine if the line is executed or not.
- *
- * Sample HTML line:
- *
- * <tr class="covered"><td>47</td><td><pre style="display:inline;">
- * CheckEquals(1,2-1);</pre></td></tr>
- *
- */
- while( cmSystemTools::GetLineFromStream(in, line))
- {
- if(line.find("inline") == line.npos)
- {
- continue;
- }
- lastoffset = line.find("class=");
- endcovpos = line.find(">",lastoffset);
- lineresult = line.substr(lastoffset+7,(endcovpos-8)-lastoffset);
- if(lineresult == "covered")
- {
- afterLineNum = line.find('<',endcovpos+5);
- filelineoffset= line.substr(endcovpos+5,
- afterLineNum-(endcovpos+5));
- coverageVector[atoi(filelineoffset.c_str())-1] = 1;
- }
- }
- return true;
- }
- private:
- cmCTest* CTest;
- cmCTestCoverageHandlerContainer& Coverage;
- };
- cmParseDelphiCoverage::cmParseDelphiCoverage(
- cmCTestCoverageHandlerContainer& cont, cmCTest* ctest)
- :Coverage(cont), CTest(ctest)
- {
- }
- bool cmParseDelphiCoverage::LoadCoverageData(
- const std::vector<std::string> files)
- {
- size_t i;
- std::string path;
- size_t numf = files.size();
- for (i = 0; i < numf; i++)
- {
- path = files[i];
- cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
- "Reading HTML File " << path << std::endl);
- if(cmSystemTools::GetFilenameLastExtension(path) == ".html")
- {
- if(!this->ReadDelphiHTML(path.c_str()))
- {
- return false;
- }
- }
- }
- return true;
- }
- bool cmParseDelphiCoverage::ReadDelphiHTML(const char* file)
- {
- cmParseDelphiCoverage::HTMLParser
- parser(this->CTest, this->Coverage);
- parser.ParseFile(file);
- return true;
- }
|