/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmCTestCoverageHandler.h"

#include <algorithm>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iterator>
#include <sstream>
#include <utility>

#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"

#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
#include "cmParseBlanketJSCoverage.h"
#include "cmParseCacheCoverage.h"
#include "cmParseCoberturaCoverage.h"
#include "cmParseDelphiCoverage.h"
#include "cmParseGTMCoverage.h"
#include "cmParseJacocoCoverage.h"
#include "cmParsePHPCoverage.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"
#include "cmXMLWriter.h"

class cmMakefile;

#define SAFEDIV(x, y) (((y) != 0) ? ((x) / (y)) : (0))

class cmCTestRunProcess
{
public:
  cmCTestRunProcess()
  {
    this->Process = cmsysProcess_New();
    this->PipeState = -1;
    this->TimeOut = cmDuration(-1);
  }
  ~cmCTestRunProcess()
  {
    if (!(this->PipeState == -1) &&
        !(this->PipeState == cmsysProcess_Pipe_None) &&
        !(this->PipeState == cmsysProcess_Pipe_Timeout)) {
      this->WaitForExit();
    }
    cmsysProcess_Delete(this->Process);
  }
  cmCTestRunProcess(const cmCTestRunProcess&) = delete;
  cmCTestRunProcess& operator=(const cmCTestRunProcess&) = delete;
  void SetCommand(const char* command)
  {
    this->CommandLineStrings.clear();
    this->CommandLineStrings.emplace_back(command);
  }
  void AddArgument(const char* arg)
  {
    if (arg) {
      this->CommandLineStrings.emplace_back(arg);
    }
  }
  void SetWorkingDirectory(const char* dir) { this->WorkingDirectory = dir; }
  void SetTimeout(cmDuration t) { this->TimeOut = t; }
  bool StartProcess()
  {
    std::vector<const char*> args;
    for (std::string const& cl : this->CommandLineStrings) {
      args.push_back(cl.c_str());
    }
    args.push_back(nullptr); // null terminate
    cmsysProcess_SetCommand(this->Process, args.data());
    if (!this->WorkingDirectory.empty()) {
      cmsysProcess_SetWorkingDirectory(this->Process,
                                       this->WorkingDirectory.c_str());
    }

    cmsysProcess_SetOption(this->Process, cmsysProcess_Option_HideWindow, 1);
    if (this->TimeOut >= cmDuration::zero()) {
      cmsysProcess_SetTimeout(this->Process, this->TimeOut.count());
    }
    cmsysProcess_Execute(this->Process);
    this->PipeState = cmsysProcess_GetState(this->Process);
    // if the process is running or exited return true
    return this->PipeState == cmsysProcess_State_Executing ||
      this->PipeState == cmsysProcess_State_Exited;
  }
  void SetStdoutFile(const char* fname)
  {
    cmsysProcess_SetPipeFile(this->Process, cmsysProcess_Pipe_STDOUT, fname);
  }
  void SetStderrFile(const char* fname)
  {
    cmsysProcess_SetPipeFile(this->Process, cmsysProcess_Pipe_STDERR, fname);
  }
  int WaitForExit(double* timeout = nullptr)
  {
    this->PipeState = cmsysProcess_WaitForExit(this->Process, timeout);
    return this->PipeState;
  }
  int GetProcessState() { return this->PipeState; }

private:
  int PipeState;
  cmsysProcess* Process;
  std::vector<std::string> CommandLineStrings;
  std::string WorkingDirectory;
  cmDuration TimeOut;
};

cmCTestCoverageHandler::cmCTestCoverageHandler() = default;

void cmCTestCoverageHandler::Initialize()
{
  this->Superclass::Initialize();
  this->CustomCoverageExclude.clear();
  this->SourceLabels.clear();
  this->TargetDirs.clear();
  this->LabelIdMap.clear();
  this->Labels.clear();
  this->LabelFilter.clear();
}

void cmCTestCoverageHandler::CleanCoverageLogFiles(std::ostream& log)
{
  std::string logGlob =
    cmStrCat(this->CTest->GetCTestConfiguration("BuildDirectory"), "/Testing/",
             this->CTest->GetCurrentTag(), "/CoverageLog*");
  cmsys::Glob gl;
  gl.FindFiles(logGlob);
  std::vector<std::string> const& files = gl.GetFiles();
  for (std::string const& f : files) {
    log << "Removing old coverage log: " << f << "\n";
    cmSystemTools::RemoveFile(f);
  }
}

bool cmCTestCoverageHandler::StartCoverageLogFile(
  cmGeneratedFileStream& covLogFile, int logFileCount)
{
  char covLogFilename[1024];
  sprintf(covLogFilename, "CoverageLog-%d", logFileCount);
  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     "Open file: " << covLogFilename << std::endl,
                     this->Quiet);
  if (!this->StartResultingXML(cmCTest::PartCoverage, covLogFilename,
                               covLogFile)) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Cannot open log file: " << covLogFilename << std::endl);
    return false;
  }
  return true;
}

void cmCTestCoverageHandler::EndCoverageLogFile(cmGeneratedFileStream& ostr,
                                                int logFileCount)
{
  char covLogFilename[1024];
  sprintf(covLogFilename, "CoverageLog-%d.xml", logFileCount);
  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     "Close file: " << covLogFilename << std::endl,
                     this->Quiet);
  ostr.Close();
}

void cmCTestCoverageHandler::StartCoverageLogXML(cmXMLWriter& xml)
{
  this->CTest->StartXML(xml, this->AppendXML);
  xml.StartElement("CoverageLog");
  xml.Element("StartDateTime", this->CTest->CurrentTime());
  xml.Element("StartTime", std::chrono::system_clock::now());
}

void cmCTestCoverageHandler::EndCoverageLogXML(cmXMLWriter& xml)
{
  xml.Element("EndDateTime", this->CTest->CurrentTime());
  xml.Element("EndTime", std::chrono::system_clock::now());
  xml.EndElement(); // CoverageLog
  this->CTest->EndXML(xml);
}

bool cmCTestCoverageHandler::ShouldIDoCoverage(std::string const& file,
                                               std::string const& srcDir,
                                               std::string const& binDir)
{
  if (this->IsFilteredOut(file)) {
    return false;
  }

  for (cmsys::RegularExpression& rx : this->CustomCoverageExcludeRegex) {
    if (rx.find(file)) {
      cmCTestOptionalLog(
        this->CTest, HANDLER_VERBOSE_OUTPUT,
        "  File " << file << " is excluded in CTestCustom.ctest" << std::endl;
        , this->Quiet);
      return false;
    }
  }

  std::string fSrcDir = cmSystemTools::CollapseFullPath(srcDir);
  std::string fBinDir = cmSystemTools::CollapseFullPath(binDir);
  std::string fFile = cmSystemTools::CollapseFullPath(file);
  bool sourceSubDir = cmSystemTools::IsSubDirectory(fFile, fSrcDir);
  bool buildSubDir = cmSystemTools::IsSubDirectory(fFile, fBinDir);
  // Always check parent directory of the file.
  std::string fileDir = cmSystemTools::GetFilenamePath(fFile);
  std::string checkDir;

  // We also need to check the binary/source directory pair.
  if (sourceSubDir && buildSubDir) {
    if (fSrcDir.size() > fBinDir.size()) {
      checkDir = fSrcDir;
    } else {
      checkDir = fBinDir;
    }
  } else if (sourceSubDir) {
    checkDir = fSrcDir;
  } else if (buildSubDir) {
    checkDir = fBinDir;
  }
  std::string ndc = cmSystemTools::FileExistsInParentDirectories(
    ".NoDartCoverage", fFile, checkDir);
  if (!ndc.empty()) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Found: " << ndc << " so skip coverage of " << file
                                 << std::endl,
                       this->Quiet);
    return false;
  }

  // By now checkDir should be set to parent directory of the file.
  // Get the relative path to the file an apply it to the opposite directory.
  // If it is the same as fileDir, then ignore, otherwise check.
  std::string relPath;
  if (!checkDir.empty()) {
    relPath = cmSystemTools::RelativePath(checkDir, fFile);
  } else {
    relPath = fFile;
  }
  if (checkDir == fSrcDir) {
    checkDir = fBinDir;
  } else {
    checkDir = fSrcDir;
  }
  fFile = checkDir + "/" + relPath;
  fFile = cmSystemTools::GetFilenamePath(fFile);

  if (fileDir == fFile) {
    // This is in-source build, so we trust the previous check.
    return true;
  }

  ndc = cmSystemTools::FileExistsInParentDirectories(".NoDartCoverage", fFile,
                                                     checkDir);
  if (!ndc.empty()) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Found: " << ndc << " so skip coverage of: " << file
                                 << std::endl,
                       this->Quiet);
    return false;
  }
  // Ok, nothing in source tree, nothing in binary tree
  return true;
}

// clearly it would be nice if this were broken up into a few smaller
// functions and commented...
int cmCTestCoverageHandler::ProcessHandler()
{
  this->CTest->ClearSubmitFiles(cmCTest::PartCoverage);
  int error = 0;
  // do we have time for this
  if (this->CTest->GetRemainingTimeAllowed() < std::chrono::minutes(2)) {
    return error;
  }

  std::string coverage_start_time = this->CTest->CurrentTime();
  auto coverage_start_time_time = std::chrono::system_clock::now();
  std::string sourceDir =
    this->CTest->GetCTestConfiguration("SourceDirectory");
  std::string binaryDir = this->CTest->GetCTestConfiguration("BuildDirectory");

  this->LoadLabels();

  cmGeneratedFileStream ofs;
  auto elapsed_time_start = std::chrono::steady_clock::now();
  if (!this->StartLogFile("Coverage", ofs)) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Cannot create LastCoverage.log file" << std::endl);
  }

  ofs << "Performing coverage: "
      << elapsed_time_start.time_since_epoch().count() << std::endl;
  this->CleanCoverageLogFiles(ofs);

  cmSystemTools::ConvertToUnixSlashes(sourceDir);
  cmSystemTools::ConvertToUnixSlashes(binaryDir);

  cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
                     "Performing coverage" << std::endl, this->Quiet);

  cmCTestCoverageHandlerContainer cont;
  cont.Error = error;
  cont.SourceDir = sourceDir;
  cont.BinaryDir = binaryDir;
  cont.OFS = &ofs;
  cont.Quiet = this->Quiet;

  // setup the regex exclude stuff
  this->CustomCoverageExcludeRegex.clear();
  for (std::string const& rex : this->CustomCoverageExclude) {
    this->CustomCoverageExcludeRegex.emplace_back(rex);
  }

  if (this->HandleBullseyeCoverage(&cont)) {
    return cont.Error;
  }
  int file_count = 0;
  file_count += this->HandleGCovCoverage(&cont);
  error = cont.Error;
  if (file_count < 0) {
    return error;
  }
  file_count += this->HandleLCovCoverage(&cont);
  error = cont.Error;
  if (file_count < 0) {
    return error;
  }
  file_count += this->HandleTracePyCoverage(&cont);
  error = cont.Error;
  if (file_count < 0) {
    return error;
  }
  file_count += this->HandlePHPCoverage(&cont);
  error = cont.Error;
  if (file_count < 0) {
    return error;
  }
  file_count += this->HandleCoberturaCoverage(&cont);
  error = cont.Error;
  if (file_count < 0) {
    return error;
  }

  file_count += this->HandleMumpsCoverage(&cont);
  error = cont.Error;
  if (file_count < 0) {
    return error;
  }

  file_count += this->HandleJacocoCoverage(&cont);
  error = cont.Error;
  if (file_count < 0) {
    return error;
  }

  file_count += this->HandleBlanketJSCoverage(&cont);
  error = cont.Error;
  if (file_count < 0) {
    return error;
  }

  file_count += this->HandleDelphiCoverage(&cont);
  error = cont.Error;
  if (file_count < 0) {
    return error;
  }
  std::set<std::string> uncovered = this->FindUncoveredFiles(&cont);

  if (file_count == 0 && this->ExtraCoverageGlobs.empty()) {
    cmCTestOptionalLog(
      this->CTest, WARNING,
      " Cannot find any coverage files. Ignoring Coverage request."
        << std::endl,
      this->Quiet);
    return error;
  }
  cmGeneratedFileStream covSumFile;
  cmGeneratedFileStream covLogFile;
  cmXMLWriter covSumXML(covSumFile);
  cmXMLWriter covLogXML(covLogFile);

  if (!this->StartResultingXML(cmCTest::PartCoverage, "Coverage",
                               covSumFile)) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Cannot open coverage summary file." << std::endl);
    return -1;
  }
  covSumFile.setf(std::ios::fixed, std::ios::floatfield);
  covSumFile.precision(2);

  this->CTest->StartXML(covSumXML, this->AppendXML);
  // Produce output xml files

  covSumXML.StartElement("Coverage");
  covSumXML.Element("StartDateTime", coverage_start_time);
  covSumXML.Element("StartTime", coverage_start_time_time);
  int logFileCount = 0;
  if (!this->StartCoverageLogFile(covLogFile, logFileCount)) {
    return -1;
  }
  this->StartCoverageLogXML(covLogXML);
  int cnt = 0;
  long total_tested = 0;
  long total_untested = 0;
  // std::string fullSourceDir = sourceDir + "/";
  // std::string fullBinaryDir = binaryDir + "/";
  cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, std::endl, this->Quiet);
  cmCTestOptionalLog(
    this->CTest, HANDLER_OUTPUT,
    "   Accumulating results (each . represents one file):" << std::endl,
    this->Quiet);
  cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "    ", this->Quiet);

  std::vector<std::string> errorsWhileAccumulating;

  file_count = 0;
  for (auto const& file : cont.TotalCoverage) {
    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "." << std::flush,
                       this->Quiet);
    file_count++;
    if (file_count % 50 == 0) {
      cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
                         " processed: " << file_count << " out of "
                                        << cont.TotalCoverage.size()
                                        << std::endl,
                         this->Quiet);
      cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "    ", this->Quiet);
    }

    const std::string fullFileName = file.first;
    bool shouldIDoCoverage =
      this->ShouldIDoCoverage(fullFileName, sourceDir, binaryDir);
    if (!shouldIDoCoverage) {
      cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                         ".NoDartCoverage found, so skip coverage check for: "
                           << fullFileName << std::endl,
                         this->Quiet);
      continue;
    }

    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Process file: " << fullFileName << std::endl,
                       this->Quiet);

    if (!cmSystemTools::FileExists(fullFileName)) {
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Cannot find file: " << fullFileName << std::endl);
      continue;
    }

    if (++cnt % 100 == 0) {
      this->EndCoverageLogXML(covLogXML);
      this->EndCoverageLogFile(covLogFile, logFileCount);
      logFileCount++;
      if (!this->StartCoverageLogFile(covLogFile, logFileCount)) {
        return -1;
      }
      this->StartCoverageLogXML(covLogXML);
    }

    const std::string fileName = cmSystemTools::GetFilenameName(fullFileName);
    std::string shortFileName =
      this->CTest->GetShortPathToFile(fullFileName.c_str());
    const cmCTestCoverageHandlerContainer::SingleFileCoverageVector& fcov =
      file.second;
    covLogXML.StartElement("File");
    covLogXML.Attribute("Name", fileName);
    covLogXML.Attribute("FullPath", shortFileName);
    covLogXML.StartElement("Report");

    cmsys::ifstream ifs(fullFileName.c_str());
    if (!ifs) {
      std::ostringstream ostr;
      ostr << "Cannot open source file: " << fullFileName;
      errorsWhileAccumulating.push_back(ostr.str());
      error++;
      continue;
    }

    int tested = 0;
    int untested = 0;

    cmCTestCoverageHandlerContainer::SingleFileCoverageVector::size_type cc;
    std::string line;
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Actually performing coverage for: " << fullFileName
                                                            << std::endl,
                       this->Quiet);
    for (cc = 0; cc < fcov.size(); cc++) {
      if (!cmSystemTools::GetLineFromStream(ifs, line) &&
          cc != fcov.size() - 1) {
        std::ostringstream ostr;
        ostr << "Problem reading source file: " << fullFileName
             << " line:" << cc << "  out total: " << fcov.size() - 1;
        errorsWhileAccumulating.push_back(ostr.str());
        error++;
        break;
      }
      covLogXML.StartElement("Line");
      covLogXML.Attribute("Number", cc);
      covLogXML.Attribute("Count", fcov[cc]);
      covLogXML.Content(line);
      covLogXML.EndElement(); // Line
      if (fcov[cc] == 0) {
        untested++;
      } else if (fcov[cc] > 0) {
        tested++;
      }
    }
    if (cmSystemTools::GetLineFromStream(ifs, line)) {
      std::ostringstream ostr;
      ostr << "Looks like there are more lines in the file: " << fullFileName;
      errorsWhileAccumulating.push_back(ostr.str());
    }
    float cper = 0;
    float cmet = 0;
    if (tested + untested > 0) {
      cper = (100 *
              SAFEDIV(static_cast<float>(tested),
                      static_cast<float>(tested + untested)));
      cmet = (SAFEDIV(static_cast<float>(tested + 10),
                      static_cast<float>(tested + untested + 10)));
    }
    total_tested += tested;
    total_untested += untested;
    covLogXML.EndElement(); // Report
    covLogXML.EndElement(); // File
    covSumXML.StartElement("File");
    covSumXML.Attribute("Name", fileName);
    covSumXML.Attribute("FullPath",
                        this->CTest->GetShortPathToFile(fullFileName.c_str()));
    covSumXML.Attribute("Covered", tested + untested > 0 ? "true" : "false");
    covSumXML.Element("LOCTested", tested);
    covSumXML.Element("LOCUnTested", untested);
    covSumXML.Element("PercentCoverage", cper);
    covSumXML.Element("CoverageMetric", cmet);
    this->WriteXMLLabels(covSumXML, shortFileName);
    covSumXML.EndElement(); // File
  }

  // Handle all the files in the extra coverage globs that have no cov data
  for (std::string const& u : uncovered) {
    std::string fileName = cmSystemTools::GetFilenameName(u);
    std::string fullPath = cont.SourceDir + "/" + u;

    covLogXML.StartElement("File");
    covLogXML.Attribute("Name", fileName);
    covLogXML.Attribute("FullPath", u);
    covLogXML.StartElement("Report");

    cmsys::ifstream ifs(fullPath.c_str());
    if (!ifs) {
      std::ostringstream ostr;
      ostr << "Cannot open source file: " << fullPath;
      errorsWhileAccumulating.push_back(ostr.str());
      error++;
      covLogXML.EndElement(); // Report
      covLogXML.EndElement(); // File
      continue;
    }
    int untested = 0;
    std::string line;
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Actually performing coverage for: " << u << std::endl,
                       this->Quiet);
    while (cmSystemTools::GetLineFromStream(ifs, line)) {
      covLogXML.StartElement("Line");
      covLogXML.Attribute("Number", untested);
      covLogXML.Attribute("Count", 0);
      covLogXML.Content(line);
      covLogXML.EndElement(); // Line
      untested++;
    }
    covLogXML.EndElement(); // Report
    covLogXML.EndElement(); // File

    total_untested += untested;
    covSumXML.StartElement("File");
    covSumXML.Attribute("Name", fileName);
    covSumXML.Attribute("FullPath", u);
    covSumXML.Attribute("Covered", "true");
    covSumXML.Element("LOCTested", 0);
    covSumXML.Element("LOCUnTested", untested);
    covSumXML.Element("PercentCoverage", 0);
    covSumXML.Element("CoverageMetric", 0);
    this->WriteXMLLabels(covSumXML, u);
    covSumXML.EndElement(); // File
  }

  this->EndCoverageLogXML(covLogXML);
  this->EndCoverageLogFile(covLogFile, logFileCount);

  if (!errorsWhileAccumulating.empty()) {
    cmCTestLog(this->CTest, ERROR_MESSAGE, std::endl);
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Error(s) while accumulating results:" << std::endl);
    for (std::string const& er : errorsWhileAccumulating) {
      cmCTestLog(this->CTest, ERROR_MESSAGE, "  " << er << std::endl);
    }
  }

  long total_lines = total_tested + total_untested;
  float percent_coverage = 100 *
    SAFEDIV(static_cast<float>(total_tested), static_cast<float>(total_lines));
  if (total_lines == 0) {
    percent_coverage = 0;
  }

  std::string end_time = this->CTest->CurrentTime();

  covSumXML.Element("LOCTested", total_tested);
  covSumXML.Element("LOCUntested", total_untested);
  covSumXML.Element("LOC", total_lines);
  covSumXML.Element("PercentCoverage", percent_coverage);
  covSumXML.Element("EndDateTime", end_time);
  covSumXML.Element("EndTime", std::chrono::system_clock::now());
  covSumXML.Element("ElapsedMinutes",
                    std::chrono::duration_cast<std::chrono::minutes>(
                      std::chrono::steady_clock::now() - elapsed_time_start)
                      .count());
  covSumXML.EndElement(); // Coverage
  this->CTest->EndXML(covSumXML);

  cmCTestLog(this->CTest, HANDLER_OUTPUT,
             "" << std::endl
                << "\tCovered LOC:         " << total_tested << std::endl
                << "\tNot covered LOC:     " << total_untested << std::endl
                << "\tTotal LOC:           " << total_lines << std::endl
                << "\tPercentage Coverage: "
                << std::setiosflags(std::ios::fixed) << std::setprecision(2)
                << (percent_coverage) << "%" << std::endl);

  ofs << "\tCovered LOC:         " << total_tested << std::endl
      << "\tNot covered LOC:     " << total_untested << std::endl
      << "\tTotal LOC:           " << total_lines << std::endl
      << "\tPercentage Coverage: " << std::setiosflags(std::ios::fixed)
      << std::setprecision(2) << (percent_coverage) << "%" << std::endl;

  if (error) {
    return -1;
  }
  return 0;
}

void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile* mf)
{
  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     " Add coverage exclude regular expressions." << std::endl,
                     this->Quiet);
  this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_COVERAGE_EXCLUDE",
                                    this->CustomCoverageExclude);
  this->CTest->PopulateCustomVector(mf, "CTEST_EXTRA_COVERAGE_GLOB",
                                    this->ExtraCoverageGlobs);
  for (std::string const& cce : this->CustomCoverageExclude) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       " Add coverage exclude: " << cce << std::endl,
                       this->Quiet);
  }
  for (std::string const& ecg : this->ExtraCoverageGlobs) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       " Add coverage glob: " << ecg << std::endl,
                       this->Quiet);
  }
}

// Fix for issue #4971 where the case of the drive letter component of
// the filenames might be different when analyzing gcov output.
//
// Compare file names: fnc(fn1) == fnc(fn2) // fnc == file name compare
//
#ifdef _WIN32
#  define fnc(s) cmSystemTools::LowerCase(s)
#else
#  define fnc(s) s
#endif

bool IsFileInDir(const std::string& infile, const std::string& indir)
{
  std::string file = cmSystemTools::CollapseFullPath(infile);
  std::string dir = cmSystemTools::CollapseFullPath(indir);

  return file.size() > dir.size() &&
    fnc(file.substr(0, dir.size())) == fnc(dir) && file[dir.size()] == '/';
}

int cmCTestCoverageHandler::HandlePHPCoverage(
  cmCTestCoverageHandlerContainer* cont)
{
  cmParsePHPCoverage cov(*cont, this->CTest);
  std::string coverageDir = this->CTest->GetBinaryDir() + "/xdebugCoverage";
  if (cmSystemTools::FileIsDirectory(coverageDir)) {
    cov.ReadPHPCoverageDirectory(coverageDir.c_str());
  }
  return static_cast<int>(cont->TotalCoverage.size());
}

int cmCTestCoverageHandler::HandleCoberturaCoverage(
  cmCTestCoverageHandlerContainer* cont)
{
  cmParseCoberturaCoverage cov(*cont, this->CTest);

  // Assume the coverage.xml is in the binary directory
  // check for the COBERTURADIR environment variable,
  // if it doesn't exist or is empty, assume the
  // binary directory is used.
  std::string coverageXMLFile;
  if (!cmSystemTools::GetEnv("COBERTURADIR", coverageXMLFile) ||
      coverageXMLFile.empty()) {
    coverageXMLFile = this->CTest->GetBinaryDir();
  }
  // build the find file string with the directory from above
  coverageXMLFile += "/coverage.xml";

  if (cmSystemTools::FileExists(coverageXMLFile)) {
    // If file exists, parse it
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Parsing Cobertura XML file: " << coverageXMLFile
                                                      << std::endl,
                       this->Quiet);
    cov.ReadCoverageXML(coverageXMLFile.c_str());
  } else {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       " Cannot find Cobertura XML file: " << coverageXMLFile
                                                           << std::endl,
                       this->Quiet);
  }
  return static_cast<int>(cont->TotalCoverage.size());
}

int cmCTestCoverageHandler::HandleMumpsCoverage(
  cmCTestCoverageHandlerContainer* cont)
{
  // try gtm coverage
  cmParseGTMCoverage cov(*cont, this->CTest);
  std::string coverageFile =
    this->CTest->GetBinaryDir() + "/gtm_coverage.mcov";
  if (cmSystemTools::FileExists(coverageFile)) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Parsing Cache Coverage: " << coverageFile << std::endl,
                       this->Quiet);
    cov.ReadCoverageFile(coverageFile.c_str());
    return static_cast<int>(cont->TotalCoverage.size());
  }
  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     " Cannot find GTM coverage file: " << coverageFile
                                                        << std::endl,
                     this->Quiet);
  cmParseCacheCoverage ccov(*cont, this->CTest);
  coverageFile = this->CTest->GetBinaryDir() + "/cache_coverage.cmcov";
  if (cmSystemTools::FileExists(coverageFile)) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Parsing Cache Coverage: " << coverageFile << std::endl,
                       this->Quiet);
    ccov.ReadCoverageFile(coverageFile.c_str());
  } else {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       " Cannot find Cache coverage file: " << coverageFile
                                                            << std::endl,
                       this->Quiet);
  }
  return static_cast<int>(cont->TotalCoverage.size());
}

struct cmCTestCoverageHandlerLocale
{
  cmCTestCoverageHandlerLocale()
  {
    std::string l;
    if (cmSystemTools::GetEnv("LC_ALL", l)) {
      lc_all = l;
    }
    if (lc_all != "C") {
      cmSystemTools::PutEnv("LC_ALL=C");
    }
  }
  ~cmCTestCoverageHandlerLocale()
  {
    if (!lc_all.empty()) {
      cmSystemTools::PutEnv("LC_ALL=" + lc_all);
    } else {
      cmSystemTools::UnsetEnv("LC_ALL");
    }
  }
  cmCTestCoverageHandlerLocale(const cmCTestCoverageHandlerLocale&) = delete;
  cmCTestCoverageHandlerLocale& operator=(
    const cmCTestCoverageHandlerLocale&) = delete;
  std::string lc_all;
};

int cmCTestCoverageHandler::HandleJacocoCoverage(
  cmCTestCoverageHandlerContainer* cont)
{
  cmParseJacocoCoverage cov = cmParseJacocoCoverage(*cont, this->CTest);

  // Search in the source directory.
  cmsys::Glob g1;
  std::vector<std::string> files;
  g1.SetRecurse(true);

  std::string SourceDir =
    this->CTest->GetCTestConfiguration("SourceDirectory");
  std::string coverageFile = SourceDir + "/*jacoco.xml";

  g1.FindFiles(coverageFile);
  files = g1.GetFiles();

  // ...and in the binary directory.
  cmsys::Glob g2;
  g2.SetRecurse(true);
  std::string binaryDir = this->CTest->GetCTestConfiguration("BuildDirectory");
  std::string binCoverageFile = binaryDir + "/*jacoco.xml";
  g2.FindFiles(binCoverageFile);
  cmAppend(files, g2.GetFiles());

  if (!files.empty()) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Found Jacoco Files, Performing Coverage" << std::endl,
                       this->Quiet);
    cov.LoadCoverageData(files);
  } else {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       " Cannot find Jacoco coverage files: " << coverageFile
                                                              << std::endl,
                       this->Quiet);
  }
  return static_cast<int>(cont->TotalCoverage.size());
}

int cmCTestCoverageHandler::HandleDelphiCoverage(
  cmCTestCoverageHandlerContainer* cont)
{
  cmParseDelphiCoverage cov = cmParseDelphiCoverage(*cont, this->CTest);
  cmsys::Glob g;
  std::vector<std::string> files;
  g.SetRecurse(true);

  std::string BinDir = this->CTest->GetBinaryDir();
  std::string coverageFile = BinDir + "/*(*.pas).html";

  g.FindFiles(coverageFile);
  files = g.GetFiles();
  if (!files.empty()) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Found Delphi HTML Files, Performing Coverage"
                         << std::endl,
                       this->Quiet);
    cov.LoadCoverageData(files);
  } else {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       " Cannot find Delphi coverage files: " << coverageFile
                                                              << std::endl,
                       this->Quiet);
  }
  return static_cast<int>(cont->TotalCoverage.size());
}

static std::string joinCommandLine(const std::vector<std::string>& args)
{
  std::string ret;

  for (std::string const& s : args) {
    if (s.find(' ') == std::string::npos) {
      ret += s + ' ';
    } else {
      ret += "\"" + s + "\" ";
    }
  }

  // drop trailing whitespace
  ret.erase(ret.size() - 1);

  return ret;
}

int cmCTestCoverageHandler::HandleBlanketJSCoverage(
  cmCTestCoverageHandlerContainer* cont)
{
  cmParseBlanketJSCoverage cov = cmParseBlanketJSCoverage(*cont, this->CTest);
  std::string SourceDir =
    this->CTest->GetCTestConfiguration("SourceDirectory");

  // Look for something other than output.json, still JSON extension.
  std::string coverageFile = SourceDir + "/*.json";
  cmsys::Glob g;
  std::vector<std::string> files;
  std::vector<std::string> blanketFiles;
  g.FindFiles(coverageFile);
  files = g.GetFiles();
  // Ensure that the JSON files found are the result of the
  // Blanket.js output. Check for the "node-jscoverage"
  // string on the second line
  std::string line;
  for (std::string const& fileEntry : files) {
    cmsys::ifstream in(fileEntry.c_str());
    cmSystemTools::GetLineFromStream(in, line);
    cmSystemTools::GetLineFromStream(in, line);
    if (line.find("node-jscoverage") != std::string::npos) {
      blanketFiles.push_back(fileEntry);
    }
  }
  //  Take all files with the node-jscoverage string and parse those
  if (!blanketFiles.empty()) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Found BlanketJS output JSON, Performing Coverage"
                         << std::endl,
                       this->Quiet);
    cov.LoadCoverageData(files);
  } else {
    cmCTestOptionalLog(
      this->CTest, HANDLER_VERBOSE_OUTPUT,
      " Cannot find BlanketJS coverage files: " << coverageFile << std::endl,
      this->Quiet);
  }
  return static_cast<int>(cont->TotalCoverage.size());
}
int cmCTestCoverageHandler::HandleGCovCoverage(
  cmCTestCoverageHandlerContainer* cont)
{
  std::string gcovCommand =
    this->CTest->GetCTestConfiguration("CoverageCommand");
  if (gcovCommand.empty()) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Could not find gcov." << std::endl, this->Quiet);
    return 0;
  }
  std::string gcovExtraFlags =
    this->CTest->GetCTestConfiguration("CoverageExtraFlags");

  // Immediately skip to next coverage option since codecov is only for Intel
  // compiler
  if (gcovCommand == "codecov") {
    return 0;
  }

  // Style 1
  std::string st1gcovOutputRex1 =
    "[0-9]+\\.[0-9]+% of [0-9]+ (source |)lines executed in file (.*)$";
  std::string st1gcovOutputRex2 = "^Creating (.*\\.gcov)\\.";
  cmsys::RegularExpression st1re1(st1gcovOutputRex1.c_str());
  cmsys::RegularExpression st1re2(st1gcovOutputRex2.c_str());

  // Style 2
  std::string st2gcovOutputRex1 = "^File *[`'](.*)'$";
  std::string st2gcovOutputRex2 =
    "Lines executed: *[0-9]+\\.[0-9]+% of [0-9]+$";
  std::string st2gcovOutputRex3 = "^(.*)reating [`'](.*\\.gcov)'";
  std::string st2gcovOutputRex4 = "^(.*):unexpected EOF *$";
  std::string st2gcovOutputRex5 = "^(.*):cannot open source file*$";
  std::string st2gcovOutputRex6 =
    "^(.*):source file is newer than graph file `(.*)'$";
  cmsys::RegularExpression st2re1(st2gcovOutputRex1.c_str());
  cmsys::RegularExpression st2re2(st2gcovOutputRex2.c_str());
  cmsys::RegularExpression st2re3(st2gcovOutputRex3.c_str());
  cmsys::RegularExpression st2re4(st2gcovOutputRex4.c_str());
  cmsys::RegularExpression st2re5(st2gcovOutputRex5.c_str());
  cmsys::RegularExpression st2re6(st2gcovOutputRex6.c_str());

  std::vector<std::string> files;
  this->FindGCovFiles(files);

  if (files.empty()) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       " Cannot find any GCov coverage files." << std::endl,
                       this->Quiet);
    // No coverage files is a valid thing, so the exit code is 0
    return 0;
  }

  std::string testingDir = this->CTest->GetBinaryDir() + "/Testing";
  std::string tempDir = testingDir + "/CoverageInfo";
  if (!cmSystemTools::MakeDirectory(tempDir)) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Unable to make directory: " << tempDir << std::endl);
    cont->Error++;
    return 0;
  }
  cmWorkingDirectory workdir(tempDir);

  int gcovStyle = 0;

  std::set<std::string> missingFiles;

  std::string actualSourceFile;
  cmCTestOptionalLog(
    this->CTest, HANDLER_OUTPUT,
    "   Processing coverage (each . represents one file):" << std::endl,
    this->Quiet);
  cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "    ", this->Quiet);
  int file_count = 0;

  // make sure output from gcov is in English!
  cmCTestCoverageHandlerLocale locale_C;
  static_cast<void>(locale_C);

  std::vector<std::string> basecovargs =
    cmSystemTools::ParseArguments(gcovExtraFlags);
  basecovargs.insert(basecovargs.begin(), gcovCommand);
  basecovargs.emplace_back("-o");

  // files is a list of *.da and *.gcda files with coverage data in them.
  // These are binary files that you give as input to gcov so that it will
  // give us text output we can analyze to summarize coverage.
  //
  for (std::string const& f : files) {
    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "." << std::flush,
                       this->Quiet);

    // Call gcov to get coverage data for this *.gcda file:
    //
    std::string fileDir = cmSystemTools::GetFilenamePath(f);
    std::vector<std::string> covargs = basecovargs;
    covargs.push_back(fileDir);
    covargs.push_back(f);
    const std::string command = joinCommandLine(covargs);

    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       command << std::endl, this->Quiet);

    std::string output;
    std::string errors;
    int retVal = 0;
    *cont->OFS << "* Run coverage for: " << fileDir << std::endl;
    *cont->OFS << "  Command: " << command << std::endl;
    int res = this->CTest->RunCommand(covargs, &output, &errors, &retVal,
                                      tempDir.c_str(),
                                      cmDuration::zero() /*this->TimeOut*/);

    *cont->OFS << "  Output: " << output << std::endl;
    *cont->OFS << "  Errors: " << errors << std::endl;
    if (!res) {
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Problem running coverage on file: " << f << std::endl);
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Command produced error: " << errors << std::endl);
      cont->Error++;
      continue;
    }
    if (retVal != 0) {
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Coverage command returned: "
                   << retVal << " while processing: " << f << std::endl);
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Command produced error: " << cont->Error << std::endl);
    }
    cmCTestOptionalLog(
      this->CTest, HANDLER_VERBOSE_OUTPUT,
      "--------------------------------------------------------------"
        << std::endl
        << output << std::endl
        << "--------------------------------------------------------------"
        << std::endl,
      this->Quiet);

    std::vector<std::string> lines;
    cmsys::SystemTools::Split(output, lines);

    for (std::string const& line : lines) {
      std::string sourceFile;
      std::string gcovFile;

      cmCTestOptionalLog(this->CTest, DEBUG,
                         "Line: [" << line << "]" << std::endl, this->Quiet);

      if (line.empty()) {
        // Ignore empty line; probably style 2
      } else if (st1re1.find(line)) {
        if (gcovStyle == 0) {
          gcovStyle = 1;
        }
        if (gcovStyle != 1) {
          cmCTestLog(this->CTest, ERROR_MESSAGE,
                     "Unknown gcov output style e1" << std::endl);
          cont->Error++;
          break;
        }

        actualSourceFile.clear();
        sourceFile = st1re1.match(2);
      } else if (st1re2.find(line)) {
        if (gcovStyle == 0) {
          gcovStyle = 1;
        }
        if (gcovStyle != 1) {
          cmCTestLog(this->CTest, ERROR_MESSAGE,
                     "Unknown gcov output style e2" << std::endl);
          cont->Error++;
          break;
        }

        gcovFile = st1re2.match(1);
      } else if (st2re1.find(line)) {
        if (gcovStyle == 0) {
          gcovStyle = 2;
        }
        if (gcovStyle != 2) {
          cmCTestLog(this->CTest, ERROR_MESSAGE,
                     "Unknown gcov output style e3" << std::endl);
          cont->Error++;
          break;
        }

        actualSourceFile.clear();
        sourceFile = st2re1.match(1);
      } else if (st2re2.find(line)) {
        if (gcovStyle == 0) {
          gcovStyle = 2;
        }
        if (gcovStyle != 2) {
          cmCTestLog(this->CTest, ERROR_MESSAGE,
                     "Unknown gcov output style e4" << std::endl);
          cont->Error++;
          break;
        }
      } else if (st2re3.find(line)) {
        if (gcovStyle == 0) {
          gcovStyle = 2;
        }
        if (gcovStyle != 2) {
          cmCTestLog(this->CTest, ERROR_MESSAGE,
                     "Unknown gcov output style e5" << std::endl);
          cont->Error++;
          break;
        }

        gcovFile = st2re3.match(2);
      } else if (st2re4.find(line)) {
        if (gcovStyle == 0) {
          gcovStyle = 2;
        }
        if (gcovStyle != 2) {
          cmCTestLog(this->CTest, ERROR_MESSAGE,
                     "Unknown gcov output style e6" << std::endl);
          cont->Error++;
          break;
        }

        cmCTestOptionalLog(this->CTest, WARNING,
                           "Warning: " << st2re4.match(1)
                                       << " had unexpected EOF" << std::endl,
                           this->Quiet);
      } else if (st2re5.find(line)) {
        if (gcovStyle == 0) {
          gcovStyle = 2;
        }
        if (gcovStyle != 2) {
          cmCTestLog(this->CTest, ERROR_MESSAGE,
                     "Unknown gcov output style e7" << std::endl);
          cont->Error++;
          break;
        }

        cmCTestOptionalLog(this->CTest, WARNING,
                           "Warning: Cannot open file: " << st2re5.match(1)
                                                         << std::endl,
                           this->Quiet);
      } else if (st2re6.find(line)) {
        if (gcovStyle == 0) {
          gcovStyle = 2;
        }
        if (gcovStyle != 2) {
          cmCTestLog(this->CTest, ERROR_MESSAGE,
                     "Unknown gcov output style e8" << std::endl);
          cont->Error++;
          break;
        }

        cmCTestOptionalLog(this->CTest, WARNING,
                           "Warning: File: " << st2re6.match(1)
                                             << " is newer than "
                                             << st2re6.match(2) << std::endl,
                           this->Quiet);
      } else {
        // gcov 4.7 can have output lines saying "No executable lines" and
        // "Removing 'filename.gcov'"... Don't log those as "errors."
        if (line != "No executable lines" &&
            !cmHasLiteralPrefix(line, "Removing ")) {
          cmCTestLog(this->CTest, ERROR_MESSAGE,
                     "Unknown gcov output line: [" << line << "]"
                                                   << std::endl);
          cont->Error++;
          // abort();
        }
      }

      // If the last line of gcov output gave us a valid value for gcovFile,
      // and we have an actualSourceFile, then insert a (or add to existing)
      // SingleFileCoverageVector for actualSourceFile:
      //
      if (!gcovFile.empty() && !actualSourceFile.empty()) {
        cmCTestCoverageHandlerContainer::SingleFileCoverageVector& vec =
          cont->TotalCoverage[actualSourceFile];

        cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                           "   in gcovFile: " << gcovFile << std::endl,
                           this->Quiet);

        cmsys::ifstream ifile(gcovFile.c_str());
        if (!ifile) {
          cmCTestLog(this->CTest, ERROR_MESSAGE,
                     "Cannot open file: " << gcovFile << std::endl);
        } else {
          long cnt = -1;
          std::string nl;
          while (cmSystemTools::GetLineFromStream(ifile, nl)) {
            cnt++;

            // TODO: Handle gcov 3.0 non-coverage lines

            // Skip empty lines
            if (nl.empty()) {
              continue;
            }

            // Skip unused lines
            if (nl.size() < 12) {
              continue;
            }

            // Read the coverage count from the beginning of the gcov output
            // line
            std::string prefix = nl.substr(0, 12);
            int cov = atoi(prefix.c_str());

            // Read the line number starting at the 10th character of the gcov
            // output line
            std::string lineNumber = nl.substr(10, 5);

            int lineIdx = atoi(lineNumber.c_str()) - 1;
            if (lineIdx >= 0) {
              while (vec.size() <= static_cast<size_t>(lineIdx)) {
                vec.push_back(-1);
              }

              // Initially all entries are -1 (not used). If we get coverage
              // information, increment it to 0 first.
              if (vec[lineIdx] < 0) {
                if (cov > 0 || prefix.find('#') != std::string::npos) {
                  vec[lineIdx] = 0;
                }
              }

              vec[lineIdx] += cov;
            }
          }
        }

        actualSourceFile.clear();
      }

      if (!sourceFile.empty() && actualSourceFile.empty()) {
        gcovFile.clear();

        // Is it in the source dir or the binary dir?
        //
        if (IsFileInDir(sourceFile, cont->SourceDir)) {
          cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                             "   produced s: " << sourceFile << std::endl,
                             this->Quiet);
          *cont->OFS << "  produced in source dir: " << sourceFile
                     << std::endl;
          actualSourceFile = cmSystemTools::CollapseFullPath(sourceFile);
        } else if (IsFileInDir(sourceFile, cont->BinaryDir)) {
          cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                             "   produced b: " << sourceFile << std::endl,
                             this->Quiet);
          *cont->OFS << "  produced in binary dir: " << sourceFile
                     << std::endl;
          actualSourceFile = cmSystemTools::CollapseFullPath(sourceFile);
        }

        if (actualSourceFile.empty()) {
          if (missingFiles.find(sourceFile) == missingFiles.end()) {
            cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                               "Something went wrong" << std::endl,
                               this->Quiet);
            cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                               "Cannot find file: [" << sourceFile << "]"
                                                     << std::endl,
                               this->Quiet);
            cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                               " in source dir: [" << cont->SourceDir << "]"
                                                   << std::endl,
                               this->Quiet);
            cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                               " or binary dir: [" << cont->BinaryDir.size()
                                                   << "]" << std::endl,
                               this->Quiet);
            *cont->OFS << "  Something went wrong. Cannot find file: "
                       << sourceFile << " in source dir: " << cont->SourceDir
                       << " or binary dir: " << cont->BinaryDir << std::endl;

            missingFiles.insert(sourceFile);
          }
        }
      }
    }

    file_count++;

    if (file_count % 50 == 0) {
      cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
                         " processed: " << file_count << " out of "
                                        << files.size() << std::endl,
                         this->Quiet);
      cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "    ", this->Quiet);
    }
  }

  return file_count;
}

int cmCTestCoverageHandler::HandleLCovCoverage(
  cmCTestCoverageHandlerContainer* cont)
{
  std::string lcovCommand =
    this->CTest->GetCTestConfiguration("CoverageCommand");
  std::string lcovExtraFlags =
    this->CTest->GetCTestConfiguration("CoverageExtraFlags");
  if (lcovCommand != "codecov") {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       " Not a valid Intel Coverage command." << std::endl,
                       this->Quiet);
    return 0;
  }
  // There is only percentage completed output from LCOV
  std::string st2lcovOutputRex3 = "[0-9]+%";
  cmsys::RegularExpression st2re3(st2lcovOutputRex3.c_str());

  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     " This is coverage command: " << lcovCommand << std::endl,
                     this->Quiet);

  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     " These are coverage command flags: " << lcovExtraFlags
                                                           << std::endl,
                     this->Quiet);

  std::vector<std::string> files;
  if (!this->FindLCovFiles(files)) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Error while finding LCov files.\n");
    return 0;
  }

  if (files.empty()) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       " Cannot find any LCov coverage files." << std::endl,
                       this->Quiet);
    // No coverage files is a valid thing, so the exit code is 0
    return 0;
  }
  std::string testingDir = this->CTest->GetBinaryDir();

  std::set<std::string> missingFiles;

  std::string actualSourceFile;
  cmCTestOptionalLog(
    this->CTest, HANDLER_OUTPUT,
    "   Processing coverage (each . represents one file):" << std::endl,
    this->Quiet);
  cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "    ", this->Quiet);
  int file_count = 0;

  // make sure output from lcov is in English!
  cmCTestCoverageHandlerLocale locale_C;
  static_cast<void>(locale_C);

  std::vector<std::string> covargs =
    cmSystemTools::ParseArguments(lcovExtraFlags);
  covargs.insert(covargs.begin(), lcovCommand);
  const std::string command = joinCommandLine(covargs);

  // In intel compiler we have to call codecov only once in each executable
  // directory. It collects all *.dyn files to generate .dpi file.
  for (std::string const& f : files) {
    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "." << std::flush,
                       this->Quiet);
    std::string fileDir = cmSystemTools::GetFilenamePath(f);
    cmWorkingDirectory workdir(fileDir);
    if (workdir.Failed()) {
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Unable to change working directory to "
                   << fileDir << " : "
                   << std::strerror(workdir.GetLastResult()) << std::endl);
      cont->Error++;
      continue;
    }

    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Current coverage dir: " << fileDir << std::endl,
                       this->Quiet);
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       command << std::endl, this->Quiet);

    std::string output;
    std::string errors;
    int retVal = 0;
    *cont->OFS << "* Run coverage for: " << fileDir << std::endl;
    *cont->OFS << "  Command: " << command << std::endl;
    int res = this->CTest->RunCommand(covargs, &output, &errors, &retVal,
                                      fileDir.c_str(),
                                      cmDuration::zero() /*this->TimeOut*/);

    *cont->OFS << "  Output: " << output << std::endl;
    *cont->OFS << "  Errors: " << errors << std::endl;
    if (!res) {
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Problem running coverage on file: " << f << std::endl);
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Command produced error: " << errors << std::endl);
      cont->Error++;
      continue;
    }
    if (retVal != 0) {
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Coverage command returned: "
                   << retVal << " while processing: " << f << std::endl);
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Command produced error: " << cont->Error << std::endl);
    }
    cmCTestOptionalLog(
      this->CTest, HANDLER_VERBOSE_OUTPUT,
      "--------------------------------------------------------------"
        << std::endl
        << output << std::endl
        << "--------------------------------------------------------------"
        << std::endl,
      this->Quiet);

    std::vector<std::string> lines;
    cmsys::SystemTools::Split(output, lines);

    for (std::string const& line : lines) {
      std::string sourceFile;
      std::string lcovFile;

      if (line.empty()) {
        // Ignore empty line
      }
      // Look for LCOV files in binary directory
      // Intel Compiler creates a CodeCoverage dir for each subfolder and
      // each subfolder has LCOV files
      cmsys::Glob gl;
      gl.RecurseOn();
      gl.RecurseThroughSymlinksOff();
      std::string dir;
      std::vector<std::string> lcovFiles;
      dir = this->CTest->GetBinaryDir();
      std::string daGlob;
      daGlob = cmStrCat(dir, "/*.LCOV");
      cmCTestOptionalLog(
        this->CTest, HANDLER_VERBOSE_OUTPUT,
        "   looking for LCOV files in: " << daGlob << std::endl, this->Quiet);
      gl.FindFiles(daGlob);
      // Keep a list of all LCOV files
      cmAppend(lcovFiles, gl.GetFiles());

      for (std::string const& file : lcovFiles) {
        lcovFile = file;
        cmsys::ifstream srcead(lcovFile.c_str());
        if (!srcead) {
          cmCTestLog(this->CTest, ERROR_MESSAGE,
                     "Cannot open file: " << lcovFile << std::endl);
        }
        std::string srcname;

        int success = cmSystemTools::GetLineFromStream(srcead, srcname);
        if (!success) {
          cmCTestLog(this->CTest, ERROR_MESSAGE,
                     "Error while parsing lcov file '"
                       << lcovFile << "':"
                       << " No source file name found!" << std::endl);
          return 0;
        }
        srcname = srcname.substr(18);
        // We can directly read found LCOV files to determine the source
        // files
        sourceFile = srcname;
        actualSourceFile = srcname;

        for (std::string const& t : lcovFiles) {
          cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                             "Found LCOV File: " << t << std::endl,
                             this->Quiet);
        }
        cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                           "SourceFile: " << sourceFile << std::endl,
                           this->Quiet);
        cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                           "lCovFile: " << lcovFile << std::endl, this->Quiet);

        // If we have some LCOV files to process
        if (!lcovFile.empty() && !actualSourceFile.empty()) {
          cmCTestCoverageHandlerContainer::SingleFileCoverageVector& vec =
            cont->TotalCoverage[actualSourceFile];

          cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                             "   in lcovFile: " << lcovFile << std::endl,
                             this->Quiet);

          cmsys::ifstream ifile(lcovFile.c_str());
          if (!ifile) {
            cmCTestLog(this->CTest, ERROR_MESSAGE,
                       "Cannot open file: " << lcovFile << std::endl);
          } else {
            long cnt = -1;
            std::string nl;

            // Skip the first line
            cmSystemTools::GetLineFromStream(ifile, nl);
            cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                               "File is ready, start reading." << std::endl,
                               this->Quiet);
            while (cmSystemTools::GetLineFromStream(ifile, nl)) {
              cnt++;

              // Skip empty lines
              if (nl.empty()) {
                continue;
              }

              // Skip unused lines
              if (nl.size() < 12) {
                continue;
              }

              // Read the coverage count from the beginning of the lcov
              // output line
              std::string prefix = nl.substr(0, 17);
              int cov = atoi(prefix.c_str());

              // Read the line number starting at the 17th character of the
              // lcov output line
              std::string lineNumber = nl.substr(17, 7);

              int lineIdx = atoi(lineNumber.c_str()) - 1;
              if (lineIdx >= 0) {
                while (vec.size() <= static_cast<size_t>(lineIdx)) {
                  vec.push_back(-1);
                }

                // Initially all entries are -1 (not used). If we get coverage
                // information, increment it to 0 first.
                if (vec[lineIdx] < 0) {
                  if (cov > 0 || prefix.find('#') != std::string::npos) {
                    vec[lineIdx] = 0;
                  }
                }

                vec[lineIdx] += cov;
              }
            }
          }

          actualSourceFile.clear();
        }
      }
    }

    file_count++;

    if (file_count % 50 == 0) {
      cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
                         " processed: " << file_count << " out of "
                                        << files.size() << std::endl,
                         this->Quiet);
      cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "    ", this->Quiet);
    }
  }

  return file_count;
}

void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files)
{
  cmsys::Glob gl;
  gl.RecurseOn();
  gl.RecurseThroughSymlinksOff();

  for (auto const& lm : this->TargetDirs) {
    // Skip targets containing no interesting labels.
    if (!this->IntersectsFilter(lm.second)) {
      continue;
    }

    // Coverage files appear next to their object files in the target
    // support directory.
    cmCTestOptionalLog(
      this->CTest, HANDLER_VERBOSE_OUTPUT,
      "   globbing for coverage in: " << lm.first << std::endl, this->Quiet);
    std::string daGlob = cmStrCat(lm.first, "/*.da");
    gl.FindFiles(daGlob);
    cmAppend(files, gl.GetFiles());
    daGlob = cmStrCat(lm.first, "/*.gcda");
    gl.FindFiles(daGlob);
    cmAppend(files, gl.GetFiles());
  }
}

bool cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
{
  cmsys::Glob gl;
  gl.RecurseOff(); // No need of recurse if -prof_dir${BUILD_DIR} flag is
                   // used while compiling.
  gl.RecurseThroughSymlinksOff();
  std::string buildDir = this->CTest->GetCTestConfiguration("BuildDirectory");
  cmWorkingDirectory workdir(buildDir);
  if (workdir.Failed()) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Unable to change working directory to " << buildDir
                                                        << std::endl);
    return false;
  }

  // Run profmerge to merge all *.dyn files into dpi files
  if (!cmSystemTools::RunSingleCommand("profmerge")) {
    cmCTestLog(this->CTest, ERROR_MESSAGE, "Error while running profmerge.\n");
    return false;
  }

  // DPI file should appear in build directory
  std::string daGlob;
  daGlob = cmStrCat(buildDir, "/*.dpi");
  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     "   looking for dpi files in: " << daGlob << std::endl,
                     this->Quiet);
  if (!gl.FindFiles(daGlob)) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Error while finding files matching " << daGlob << std::endl);
    return false;
  }
  cmAppend(files, gl.GetFiles());
  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     "Now searching in: " << daGlob << std::endl, this->Quiet);
  return true;
}

int cmCTestCoverageHandler::HandleTracePyCoverage(
  cmCTestCoverageHandlerContainer* cont)
{
  cmsys::Glob gl;
  gl.RecurseOn();
  gl.RecurseThroughSymlinksOff();
  std::string daGlob = cont->BinaryDir + "/*.cover";
  gl.FindFiles(daGlob);
  std::vector<std::string> files = gl.GetFiles();

  if (files.empty()) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       " Cannot find any Python Trace.py coverage files."
                         << std::endl,
                       this->Quiet);
    // No coverage files is a valid thing, so the exit code is 0
    return 0;
  }

  std::string testingDir = this->CTest->GetBinaryDir() + "/Testing";
  std::string tempDir = testingDir + "/CoverageInfo";
  cmSystemTools::MakeDirectory(tempDir);

  int file_count = 0;
  for (std::string const& file : files) {
    std::string fileName = this->FindFile(cont, file);
    if (fileName.empty()) {
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Cannot find source Python file corresponding to: "
                   << file << std::endl);
      continue;
    }

    std::string actualSourceFile = cmSystemTools::CollapseFullPath(fileName);
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "   Check coverage for file: " << actualSourceFile
                                                      << std::endl,
                       this->Quiet);
    cmCTestCoverageHandlerContainer::SingleFileCoverageVector* vec =
      &cont->TotalCoverage[actualSourceFile];
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "   in file: " << file << std::endl, this->Quiet);
    cmsys::ifstream ifile(file.c_str());
    if (!ifile) {
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Cannot open file: " << file << std::endl);
    } else {
      long cnt = -1;
      std::string nl;
      while (cmSystemTools::GetLineFromStream(ifile, nl)) {
        cnt++;

        // Skip empty lines
        if (nl.empty()) {
          continue;
        }

        // Skip unused lines
        if (nl.size() < 12) {
          continue;
        }

        // Read the coverage count from the beginning of the Trace.py output
        // line
        std::string prefix = nl.substr(0, 6);
        if (prefix[5] != ' ' && prefix[5] != ':') {
          // This is a hack. We should really do something more elaborate
          prefix = nl.substr(0, 7);
          if (prefix[6] != ' ' && prefix[6] != ':') {
            prefix = nl.substr(0, 8);
            if (prefix[7] != ' ' && prefix[7] != ':') {
              cmCTestLog(this->CTest, ERROR_MESSAGE,
                         "Currently the limit is maximum coverage of 999999"
                           << std::endl);
            }
          }
        }
        int cov = atoi(prefix.c_str());
        if (prefix[prefix.size() - 1] != ':') {
          // This line does not have ':' so no coverage here. That said,
          // Trace.py does not handle not covered lines versus comments etc.
          // So, this will be set to 0.
          cov = 0;
        }
        cmCTestOptionalLog(
          this->CTest, DEBUG,
          "Prefix: " << prefix << " cov: " << cov << std::endl, this->Quiet);
        // Read the line number starting at the 10th character of the gcov
        // output line
        long lineIdx = cnt;
        if (lineIdx >= 0) {
          while (vec->size() <= static_cast<size_t>(lineIdx)) {
            vec->push_back(-1);
          }
          // Initially all entries are -1 (not used). If we get coverage
          // information, increment it to 0 first.
          if ((*vec)[lineIdx] < 0) {
            if (cov >= 0) {
              (*vec)[lineIdx] = 0;
            }
          }
          (*vec)[lineIdx] += cov;
        }
      }
    }
    ++file_count;
  }
  return file_count;
}

std::string cmCTestCoverageHandler::FindFile(
  cmCTestCoverageHandlerContainer* cont, std::string const& fileName)
{
  std::string fileNameNoE =
    cmSystemTools::GetFilenameWithoutLastExtension(fileName);
  // First check in source and binary directory
  std::string fullName = cont->SourceDir + "/" + fileNameNoE + ".py";
  if (cmSystemTools::FileExists(fullName)) {
    return fullName;
  }
  fullName = cont->BinaryDir + "/" + fileNameNoE + ".py";
  if (cmSystemTools::FileExists(fullName)) {
    return fullName;
  }
  return "";
}

// This is a header put on each marked up source file
namespace {
const char* bullseyeHelp[] = {
  "    Coverage produced by bullseye covbr tool: ",
  "      www.bullseye.com/help/ref_covbr.html",
  "    * An arrow --> indicates incomplete coverage.",
  "    * An X indicates a function that was invoked, a switch label that ",
  "      was exercised, a try-block that finished, or an exception handler ",
  "      that was invoked.",
  "    * A T or F indicates a boolean decision that evaluated true or false,",
  "      respectively.",
  "    * A t or f indicates a boolean condition within a decision if the ",
  "      condition evaluated true or false, respectively.",
  "    * A k indicates a constant decision or condition.",
  "    * The slash / means this probe is excluded from summary results. ",
  nullptr
};
}

int cmCTestCoverageHandler::RunBullseyeCoverageBranch(
  cmCTestCoverageHandlerContainer* cont,
  std::set<std::string>& coveredFileNames, std::vector<std::string>& files,
  std::vector<std::string>& filesFullPath)
{
  if (files.size() != filesFullPath.size()) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Files and full path files not the same size?:\n");
    return 0;
  }
  // create the output stream for the CoverageLog-N.xml file
  cmGeneratedFileStream covLogFile;
  cmXMLWriter covLogXML(covLogFile);
  int logFileCount = 0;
  if (!this->StartCoverageLogFile(covLogFile, logFileCount)) {
    return -1;
  }
  this->StartCoverageLogXML(covLogXML);
  // for each file run covbr on that file to get the coverage
  // information for that file
  std::string outputFile;
  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     "run covbr: " << std::endl, this->Quiet);

  if (!this->RunBullseyeCommand(cont, "covbr", nullptr, outputFile)) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "error running covbr for."
                 << "\n");
    return -1;
  }
  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     "covbr output in  " << outputFile << std::endl,
                     this->Quiet);
  // open the output file
  cmsys::ifstream fin(outputFile.c_str());
  if (!fin) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Cannot open coverage file: " << outputFile << std::endl);
    return 0;
  }
  std::map<std::string, std::string> fileMap;
  auto fp = filesFullPath.begin();
  for (auto f = files.begin(); f != files.end(); ++f, ++fp) {
    fileMap[*f] = *fp;
  }

  int count = 0; // keep count of the number of files
  // Now parse each line from the bullseye cov log file
  std::string lineIn;
  bool valid = false; // are we in a valid output file
  int line = 0;       // line of the current file
  std::string file;
  while (cmSystemTools::GetLineFromStream(fin, lineIn)) {
    bool startFile = false;
    if (lineIn.size() > 1 && lineIn[lineIn.size() - 1] == ':') {
      file = lineIn.substr(0, lineIn.size() - 1);
      if (coveredFileNames.find(file) != coveredFileNames.end()) {
        startFile = true;
      }
    }
    if (startFile) {
      // if we are in a valid file close it because a new one started
      if (valid) {
        covLogXML.EndElement(); // Report
        covLogXML.EndElement(); // File
      }
      // only allow 100 files in each log file
      if (count != 0 && count % 100 == 0) {
        cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                           "start a new log file: " << count << std::endl,
                           this->Quiet);
        this->EndCoverageLogXML(covLogXML);
        this->EndCoverageLogFile(covLogFile, logFileCount);
        logFileCount++;
        if (!this->StartCoverageLogFile(covLogFile, logFileCount)) {
          return -1;
        }
        this->StartCoverageLogXML(covLogXML);
        count++; // move on one
      }
      auto i = fileMap.find(file);
      // if the file should be covered write out the header for that file
      if (i != fileMap.end()) {
        // we have a new file so count it in the output
        count++;
        cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                           "Produce coverage for file: " << file << " "
                                                         << count << std::endl,
                           this->Quiet);
        // start the file output
        covLogXML.StartElement("File");
        covLogXML.Attribute("Name", i->first);
        covLogXML.Attribute(
          "FullPath", this->CTest->GetShortPathToFile(i->second.c_str()));
        covLogXML.StartElement("Report");
        // write the bullseye header
        line = 0;
        for (int k = 0; bullseyeHelp[k] != nullptr; ++k) {
          covLogXML.StartElement("Line");
          covLogXML.Attribute("Number", line);
          covLogXML.Attribute("Count", -1);
          covLogXML.Content(bullseyeHelp[k]);
          covLogXML.EndElement(); // Line
          line++;
        }
        valid = true; // we are in a valid file section
      } else {
        // this is not a file that we want coverage for
        valid = false;
      }
    }
    // we are not at a start file, and we are in a valid file output the line
    else if (valid) {
      covLogXML.StartElement("Line");
      covLogXML.Attribute("Number", line);
      covLogXML.Attribute("Count", -1);
      covLogXML.Content(lineIn);
      covLogXML.EndElement(); // Line
      line++;
    }
  }
  // if we ran out of lines a valid file then close that file
  if (valid) {
    covLogXML.EndElement(); // Report
    covLogXML.EndElement(); // File
  }
  this->EndCoverageLogXML(covLogXML);
  this->EndCoverageLogFile(covLogFile, logFileCount);
  return 1;
}

int cmCTestCoverageHandler::RunBullseyeCommand(
  cmCTestCoverageHandlerContainer* cont, const char* cmd, const char* arg,
  std::string& outputFile)
{
  std::string program = cmSystemTools::FindProgram(cmd);
  if (program.empty()) {
    cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find :" << cmd << "\n");
    return 0;
  }
  if (arg) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Run : " << program << " " << arg << "\n", this->Quiet);
  } else {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Run : " << program << "\n", this->Quiet);
  }
  // create a process object and start it
  cmCTestRunProcess runCoverageSrc;
  runCoverageSrc.SetCommand(program.c_str());
  runCoverageSrc.AddArgument(arg);
  std::string stdoutFile =
    cmStrCat(cont->BinaryDir, "/Testing/Temporary/",
             this->GetCTestInstance()->GetCurrentTag(), '-', cmd);
  std::string stderrFile = stdoutFile;
  stdoutFile += ".stdout";
  stderrFile += ".stderr";
  runCoverageSrc.SetStdoutFile(stdoutFile.c_str());
  runCoverageSrc.SetStderrFile(stderrFile.c_str());
  if (!runCoverageSrc.StartProcess()) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Could not run : " << program << " " << arg << "\n"
                                  << "kwsys process state : "
                                  << runCoverageSrc.GetProcessState());
    return 0;
  }
  // since we set the output file names wait for it to end
  runCoverageSrc.WaitForExit();
  outputFile = stdoutFile;
  return 1;
}

int cmCTestCoverageHandler::RunBullseyeSourceSummary(
  cmCTestCoverageHandlerContainer* cont)
{
  // Run the covsrc command and create a temp outputfile
  std::string outputFile;
  if (!this->RunBullseyeCommand(cont, "covsrc", "-c", outputFile)) {
    cmCTestLog(this->CTest, ERROR_MESSAGE, "error running covsrc:\n");
    return 0;
  }

  std::ostream& tmpLog = *cont->OFS;
  // copen the Coverage.xml file in the Testing directory
  cmGeneratedFileStream covSumFile;
  cmXMLWriter xml(covSumFile);
  if (!this->StartResultingXML(cmCTest::PartCoverage, "Coverage",
                               covSumFile)) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Cannot open coverage summary file." << std::endl);
    return 0;
  }
  this->CTest->StartXML(xml, this->AppendXML);
  auto elapsed_time_start = std::chrono::steady_clock::now();
  std::string coverage_start_time = this->CTest->CurrentTime();
  xml.StartElement("Coverage");
  xml.Element("StartDateTime", coverage_start_time);
  xml.Element("StartTime", std::chrono::system_clock::now());
  std::string stdline;
  std::string errline;
  // expected output:
  // first line is:
  // "Source","Function Coverage","out of","%","C/D Coverage","out of","%"
  // after that data follows in that format
  std::string sourceFile;
  int functionsCalled = 0;
  int totalFunctions = 0;
  int percentFunction = 0;
  int branchCovered = 0;
  int totalBranches = 0;
  int percentBranch = 0;
  double total_tested = 0;
  double total_untested = 0;
  double total_functions = 0;
  double percent_coverage = 0;
  double number_files = 0;
  std::vector<std::string> coveredFiles;
  std::vector<std::string> coveredFilesFullPath;
  // Read and parse the summary output file
  cmsys::ifstream fin(outputFile.c_str());
  if (!fin) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Cannot open coverage summary file: " << outputFile
                                                     << std::endl);
    return 0;
  }
  std::set<std::string> coveredFileNames;
  while (cmSystemTools::GetLineFromStream(fin, stdline)) {
    // if we have a line of output from stdout
    if (!stdline.empty()) {
      // parse the comma separated output
      this->ParseBullsEyeCovsrcLine(
        stdline, sourceFile, functionsCalled, totalFunctions, percentFunction,
        branchCovered, totalBranches, percentBranch);
      // The first line is the header
      if (sourceFile == "Source" || sourceFile == "Total") {
        continue;
      }
      std::string file = sourceFile;
      coveredFileNames.insert(file);
      if (!cmSystemTools::FileIsFullPath(sourceFile)) {
        // file will be relative to the binary dir
        file = cmStrCat(cont->BinaryDir, '/', sourceFile);
      }
      file = cmSystemTools::CollapseFullPath(file);
      bool shouldIDoCoverage =
        this->ShouldIDoCoverage(file, cont->SourceDir, cont->BinaryDir);
      if (!shouldIDoCoverage) {
        cmCTestOptionalLog(
          this->CTest, HANDLER_VERBOSE_OUTPUT,
          ".NoDartCoverage found, so skip coverage check for: " << file
                                                                << std::endl,
          this->Quiet);
        continue;
      }

      cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                         "Doing coverage for: " << file << std::endl,
                         this->Quiet);

      coveredFiles.push_back(sourceFile);
      coveredFilesFullPath.push_back(file);

      number_files++;
      total_functions += totalFunctions;
      total_tested += functionsCalled;
      total_untested += (totalFunctions - functionsCalled);

      std::string fileName = cmSystemTools::GetFilenameName(file);
      std::string shortFileName =
        this->CTest->GetShortPathToFile(file.c_str());

      float cper = static_cast<float>(percentBranch + percentFunction);
      if (totalBranches > 0) {
        cper /= 2.0f;
      }
      percent_coverage += static_cast<double>(cper);
      float cmet = static_cast<float>(percentFunction + percentBranch);
      if (totalBranches > 0) {
        cmet /= 2.0f;
      }
      cmet /= 100.0f;
      tmpLog << stdline << "\n";
      tmpLog << fileName << "\n";
      tmpLog << "functionsCalled: " << functionsCalled / 100 << "\n";
      tmpLog << "totalFunctions: " << totalFunctions / 100 << "\n";
      tmpLog << "percentFunction: " << percentFunction << "\n";
      tmpLog << "branchCovered: " << branchCovered << "\n";
      tmpLog << "totalBranches: " << totalBranches << "\n";
      tmpLog << "percentBranch: " << percentBranch << "\n";
      tmpLog << "percentCoverage: " << percent_coverage << "\n";
      tmpLog << "coverage metric: " << cmet << "\n";
      xml.StartElement("File");
      xml.Attribute("Name", sourceFile);
      xml.Attribute("FullPath", shortFileName);
      xml.Attribute("Covered", cmet > 0 ? "true" : "false");
      xml.Element("BranchesTested", branchCovered);
      xml.Element("BranchesUnTested", totalBranches - branchCovered);
      xml.Element("FunctionsTested", functionsCalled);
      xml.Element("FunctionsUnTested", totalFunctions - functionsCalled);
      // Hack for conversion of function to loc assume a function
      // has 100 lines of code
      xml.Element("LOCTested", functionsCalled * 100);
      xml.Element("LOCUnTested", (totalFunctions - functionsCalled) * 100);
      xml.Element("PercentCoverage", cper);
      xml.Element("CoverageMetric", cmet);
      this->WriteXMLLabels(xml, shortFileName);
      xml.EndElement(); // File
    }
  }
  std::string end_time = this->CTest->CurrentTime();
  xml.Element("LOCTested", total_tested);
  xml.Element("LOCUntested", total_untested);
  xml.Element("LOC", total_functions);
  xml.Element("PercentCoverage", SAFEDIV(percent_coverage, number_files));
  xml.Element("EndDateTime", end_time);
  xml.Element("EndTime", std::chrono::system_clock::now());
  xml.Element("ElapsedMinutes",
              std::chrono::duration_cast<std::chrono::minutes>(
                std::chrono::steady_clock::now() - elapsed_time_start)
                .count());
  xml.EndElement(); // Coverage
  this->CTest->EndXML(xml);

  // Now create the coverage information for each file
  return this->RunBullseyeCoverageBranch(cont, coveredFileNames, coveredFiles,
                                         coveredFilesFullPath);
}

int cmCTestCoverageHandler::HandleBullseyeCoverage(
  cmCTestCoverageHandlerContainer* cont)
{
  std::string covfile;
  if (!cmSystemTools::GetEnv("COVFILE", covfile) || covfile.empty()) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       " COVFILE environment variable not found, not running "
                       " bullseye\n",
                       this->Quiet);
    return 0;
  }
  cmCTestOptionalLog(
    this->CTest, HANDLER_VERBOSE_OUTPUT,
    " run covsrc with COVFILE=[" << covfile << "]" << std::endl, this->Quiet);
  if (!this->RunBullseyeSourceSummary(cont)) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Error running bullseye summary.\n");
    return 0;
  }
  cmCTestOptionalLog(this->CTest, DEBUG,
                     "HandleBullseyeCoverage return 1 " << std::endl,
                     this->Quiet);
  return 1;
}

bool cmCTestCoverageHandler::GetNextInt(std::string const& inputLine,
                                        std::string::size_type& pos,
                                        int& value)
{
  std::string::size_type start = pos;
  pos = inputLine.find(',', start);
  value = atoi(inputLine.substr(start, pos).c_str());
  if (pos == std::string::npos) {
    return true;
  }
  pos++;
  return true;
}

bool cmCTestCoverageHandler::ParseBullsEyeCovsrcLine(
  std::string const& inputLine, std::string& sourceFile, int& functionsCalled,
  int& totalFunctions, int& percentFunction, int& branchCovered,
  int& totalBranches, int& percentBranch)
{
  // find the first comma
  std::string::size_type pos = inputLine.find(',');
  if (pos == std::string::npos) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Error parsing string : " << inputLine << "\n");
    return false;
  }
  // the source file has "" around it so extract out the file name
  sourceFile = inputLine.substr(1, pos - 2);
  pos++;
  if (!this->GetNextInt(inputLine, pos, functionsCalled)) {
    return false;
  }
  if (!this->GetNextInt(inputLine, pos, totalFunctions)) {
    return false;
  }
  if (!this->GetNextInt(inputLine, pos, percentFunction)) {
    return false;
  }
  if (!this->GetNextInt(inputLine, pos, branchCovered)) {
    return false;
  }
  if (!this->GetNextInt(inputLine, pos, totalBranches)) {
    return false;
  }
  if (!this->GetNextInt(inputLine, pos, percentBranch)) {
    return false;
  }
  // should be at the end now
  if (pos != std::string::npos) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Error parsing input : "
                 << inputLine << " last pos not npos =  " << pos << "\n");
  }
  return true;
}

int cmCTestCoverageHandler::GetLabelId(std::string const& label)
{
  auto i = this->LabelIdMap.find(label);
  if (i == this->LabelIdMap.end()) {
    int n = int(this->Labels.size());
    this->Labels.push_back(label);
    LabelIdMapType::value_type entry(label, n);
    i = this->LabelIdMap.insert(entry).first;
  }
  return i->second;
}

void cmCTestCoverageHandler::LoadLabels()
{
  std::string fileList =
    cmStrCat(this->CTest->GetBinaryDir(), "/CMakeFiles/TargetDirectories.txt");
  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     " target directory list [" << fileList << "]\n",
                     this->Quiet);
  cmsys::ifstream finList(fileList.c_str());
  std::string line;
  while (cmSystemTools::GetLineFromStream(finList, line)) {
    this->LoadLabels(line.c_str());
  }
}

void cmCTestCoverageHandler::LoadLabels(const char* dir)
{
  LabelSet& dirLabels = this->TargetDirs[dir];
  std::string fname = cmStrCat(dir, "/Labels.txt");
  cmsys::ifstream fin(fname.c_str());
  if (!fin) {
    return;
  }

  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     " loading labels from [" << fname << "]\n", this->Quiet);
  bool inTarget = true;
  std::string source;
  std::string line;
  std::vector<int> targetLabels;
  while (cmSystemTools::GetLineFromStream(fin, line)) {
    if (line.empty() || line[0] == '#') {
      // Ignore blank and comment lines.
      continue;
    }
    if (line[0] == ' ') {
      // Label lines appear indented by one space.
      std::string label = line.substr(1);
      int id = this->GetLabelId(label);
      dirLabels.insert(id);
      if (inTarget) {
        targetLabels.push_back(id);
      } else {
        this->SourceLabels[source].insert(id);
      }
    } else {
      // Non-indented lines specify a source file name.  The first one
      // is the end of the target-wide labels.
      inTarget = false;

      source = this->CTest->GetShortPathToFile(line.c_str());

      // Label the source with the target labels.
      LabelSet& labelSet = this->SourceLabels[source];
      labelSet.insert(targetLabels.begin(), targetLabels.end());
    }
  }
}

void cmCTestCoverageHandler::WriteXMLLabels(cmXMLWriter& xml,
                                            std::string const& source)
{
  auto li = this->SourceLabels.find(source);
  if (li != this->SourceLabels.end() && !li->second.empty()) {
    xml.StartElement("Labels");
    for (auto const& ls : li->second) {
      xml.Element("Label", this->Labels[ls]);
    }
    xml.EndElement(); // Labels
  }
}

void cmCTestCoverageHandler::SetLabelFilter(
  std::set<std::string> const& labels)
{
  this->LabelFilter.clear();
  for (std::string const& l : labels) {
    this->LabelFilter.insert(this->GetLabelId(l));
  }
}

bool cmCTestCoverageHandler::IntersectsFilter(LabelSet const& labels)
{
  // If there is no label filter then nothing is filtered out.
  if (this->LabelFilter.empty()) {
    return true;
  }

  std::vector<int> ids;
  std::set_intersection(labels.begin(), labels.end(),
                        this->LabelFilter.begin(), this->LabelFilter.end(),
                        std::back_inserter(ids));
  return !ids.empty();
}

bool cmCTestCoverageHandler::IsFilteredOut(std::string const& source)
{
  // If there is no label filter then nothing is filtered out.
  if (this->LabelFilter.empty()) {
    return false;
  }

  // The source is filtered out if it does not have any labels in
  // common with the filter set.
  std::string shortSrc = this->CTest->GetShortPathToFile(source.c_str());
  auto li = this->SourceLabels.find(shortSrc);
  if (li != this->SourceLabels.end()) {
    return !this->IntersectsFilter(li->second);
  }
  return true;
}

std::set<std::string> cmCTestCoverageHandler::FindUncoveredFiles(
  cmCTestCoverageHandlerContainer* cont)
{
  std::set<std::string> extraMatches;

  for (std::string const& ecg : this->ExtraCoverageGlobs) {
    cmsys::Glob gl;
    gl.RecurseOn();
    gl.RecurseThroughSymlinksOff();
    std::string glob = cont->SourceDir + "/" + ecg;
    gl.FindFiles(glob);
    std::vector<std::string> files = gl.GetFiles();
    for (std::string const& f : files) {
      if (this->ShouldIDoCoverage(f, cont->SourceDir, cont->BinaryDir)) {
        extraMatches.insert(this->CTest->GetShortPathToFile(f.c_str()));
      }
    }
  }

  if (!extraMatches.empty()) {
    for (auto const& i : cont->TotalCoverage) {
      std::string shortPath = this->CTest->GetShortPathToFile(i.first.c_str());
      extraMatches.erase(shortPath);
    }
  }
  return extraMatches;
}
