| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst or https://cmake.org/licensing for details. */ | |
| #pragma once | |
| #include "cmConfigure.h" // IWYU pragma: keep | |
| #include <array> | |
| #include <iosfwd> | |
| #include <map> | |
| #include <set> | |
| #include <string> | |
| #include <vector> | |
| #include "cmsys/RegularExpression.hxx" | |
| #include "cmCTestGenericHandler.h" | |
| class cmGeneratedFileStream; | |
| class cmXMLWriter; | |
| class cmCTest; | |
| class cmCTestCoverageHandlerContainer | |
| { | |
| public: | |
| int Error; | |
| std::string SourceDir; | |
| std::string BinaryDir; | |
| using SingleFileCoverageVector = std::vector<int>; | |
| using SingleFileBranchCoverageVector = std::vector<std::array<int, 2>>; | |
| using TotalCoverageMap = std::map<std::string, SingleFileCoverageVector>; | |
| using TotalBranchCoverageMap = | |
| std::map<std::string, SingleFileBranchCoverageVector>; | |
| TotalCoverageMap TotalCoverage; | |
| TotalBranchCoverageMap TotalBranchCoverage; | |
| std::ostream* OFS; | |
| bool Quiet; | |
| }; | |
| /** \class cmCTestCoverageHandler | |
| * \brief A class that handles coverage computation for ctest | |
| * | |
| */ | |
| class cmCTestCoverageHandler : public cmCTestGenericHandler | |
| { | |
| public: | |
| using Superclass = cmCTestGenericHandler; | |
| /* | |
| * The main entry point for this class | |
| */ | |
| int ProcessHandler() override; | |
| cmCTestCoverageHandler(cmCTest* ctest); | |
| /** | |
| * This method is called when reading CTest custom file | |
| */ | |
| void PopulateCustomVectors(cmMakefile* mf) override; | |
| /** Report coverage only for sources with these labels. */ | |
| void SetLabelFilter(std::set<std::string> const& labels); | |
| private: | |
| bool ShouldIDoCoverage(std::string const& file, std::string const& srcDir, | |
| std::string const& binDir); | |
| void CleanCoverageLogFiles(std::ostream& log); | |
| bool StartCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount); | |
| void EndCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount); | |
| void StartCoverageLogXML(cmXMLWriter& xml); | |
| void EndCoverageLogXML(cmXMLWriter& xml); | |
| //! Handle coverage using GCC's GCov | |
| int HandleGCovCoverage(cmCTestCoverageHandlerContainer* cont); | |
| void FindGCovFiles(std::vector<std::string>& files); | |
| //! Handle coverage using Intel's LCov | |
| int HandleLCovCoverage(cmCTestCoverageHandlerContainer* cont); | |
| bool FindLCovFiles(std::vector<std::string>& files); | |
| //! Handle coverage using xdebug php coverage | |
| int HandlePHPCoverage(cmCTestCoverageHandlerContainer* cont); | |
| //! Handle coverage for Clang with llvm function | |
| int HandleClangSourceCodeCoverage(cmCTestCoverageHandlerContainer* cont); | |
| void HandleClangSourceCodeCoverageFile(cmCTestCoverageHandlerContainer* cont, | |
| std::string output); | |
| //! Handle coverage for Python with coverage.py | |
| int HandleCoberturaCoverage(cmCTestCoverageHandlerContainer* cont); | |
| //! Handle coverage for mumps | |
| int HandleMumpsCoverage(cmCTestCoverageHandlerContainer* cont); | |
| //! Handle coverage for Jacoco | |
| int HandleJacocoCoverage(cmCTestCoverageHandlerContainer* cont); | |
| //! Handle coverage for Delphi (Pascal) | |
| int HandleDelphiCoverage(cmCTestCoverageHandlerContainer* cont); | |
| //! Handle coverage for Jacoco | |
| int HandleBlanketJSCoverage(cmCTestCoverageHandlerContainer* cont); | |
| //! Handle coverage using Bullseye | |
| int HandleBullseyeCoverage(cmCTestCoverageHandlerContainer* cont); | |
| int RunBullseyeSourceSummary(cmCTestCoverageHandlerContainer* cont); | |
| int RunBullseyeCoverageBranch(cmCTestCoverageHandlerContainer* cont, | |
| std::set<std::string>& coveredFileNames, | |
| std::vector<std::string>& files, | |
| std::vector<std::string>& filesFullPath); | |
| int RunBullseyeCommand(cmCTestCoverageHandlerContainer* cont, | |
| char const* cmd, char const* arg, | |
| std::string& outputFile); | |
| bool ParseBullsEyeCovsrcLine(std::string const& inputLine, | |
| std::string& sourceFile, int& functionsCalled, | |
| int& totalFunctions, int& percentFunction, | |
| int& branchCovered, int& totalBranches, | |
| int& percentBranch); | |
| bool GetNextInt(std::string const& inputLine, std::string::size_type& pos, | |
| int& value); | |
| //! Handle Python coverage using Python's Trace.py | |
| int HandleTracePyCoverage(cmCTestCoverageHandlerContainer* cont); | |
| // Find the source file based on the source and build tree. This is used for | |
| // Trace.py mode, since that one does not tell us where the source file is. | |
| std::string FindFile(cmCTestCoverageHandlerContainer* cont, | |
| std::string const& fileName); | |
| std::set<std::string> FindUncoveredFiles( | |
| cmCTestCoverageHandlerContainer* cont); | |
| std::vector<std::string> CustomCoverageExclude; | |
| std::vector<cmsys::RegularExpression> CustomCoverageExcludeRegex; | |
| std::vector<std::string> ExtraCoverageGlobs; | |
| // Map from source file to label ids. | |
| class LabelSet : public std::set<int> | |
| { | |
| }; | |
| using LabelMapType = std::map<std::string, LabelSet>; | |
| LabelMapType SourceLabels; | |
| LabelMapType TargetDirs; | |
| // Map from label name to label id. | |
| using LabelIdMapType = std::map<std::string, int>; | |
| LabelIdMapType LabelIdMap; | |
| std::vector<std::string> Labels; | |
| int GetLabelId(std::string const& label); | |
| // Label reading and writing methods. | |
| void LoadLabels(); | |
| void LoadLabels(char const* dir); | |
| void WriteXMLLabels(cmXMLWriter& xml, std::string const& source); | |
| // Label-based filtering. | |
| std::set<int> LabelFilter; | |
| bool IntersectsFilter(LabelSet const& labels); | |
| bool IsFilteredOut(std::string const& source); | |
| }; |