/* 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 "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 "cmSystemTools.h"
#include "cmWorkingDirectory.h"
#include "cmXMLWriter.h"
#include "cmake.h"

#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
#include <algorithm>
#include <chrono>
#include <cstring>
#include <iomanip>
#include <iterator>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <utility>

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);
  }
  void SetCommand(const char* command)
  {
    this->CommandLineStrings.clear();
    this->CommandLineStrings.push_back(command);
    ;
  }
  void AddArgument(const char* arg)
  {
    if (arg) {
      this->CommandLineStrings.push_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.begin());
    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()
{
}

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 = this->CTest->GetCTestConfiguration("BuildDirectory");
  logGlob += "/Testing/";
  logGlob += this->CTest->GetCurrentTag();
  logGlob += "/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.c_str(), checkDir.c_str());
  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.c_str(), checkDir.c_str());
  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.push_back(
      cmsys::RegularExpression(rex.c_str()));
  }

  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");
    }
  }
  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;
  std::vector<std::string> binFiles;
  g2.SetRecurse(true);
  std::string binaryDir = this->CTest->GetCTestConfiguration("BuildDirectory");
  std::string binCoverageFile = binaryDir + "/*jacoco.xml";
  g2.FindFiles(binCoverageFile);
  binFiles = g2.GetFiles();
  if (!binFiles.empty()) {
    files.insert(files.end(), binFiles.begin(), binFiles.end());
  }

  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.c_str());
  basecovargs.insert(basecovargs.begin(), gcovCommand);
  basecovargs.push_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;

    cmSystemTools::Split(output.c_str(), 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" &&
            !cmSystemTools::StringStartsWith(line.c_str(), "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.c_str());
  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;

    cmSystemTools::Split(output.c_str(), 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 = dir;
      daGlob += "/*.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
      lcovFiles.insert(lcovFiles.end(), gl.GetFiles().begin(),
                       gl.GetFiles().end());

      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 = lm.first;
    daGlob += "/*.da";
    gl.FindFiles(daGlob);
    files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end());
    daGlob = lm.first;
    daGlob += "/*.gcda";
    gl.FindFiles(daGlob);
    files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end());
  }
}

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 = buildDir;
  daGlob += "/*.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;
  }
  files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end());
  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;
  std::vector<std::string>::iterator fp = filesFullPath.begin();
  for (std::vector<std::string>::iterator 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
      }
      std::map<std::string, std::string>::iterator 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 = cont->BinaryDir + "/Testing/Temporary/";
  stdoutFile += this->GetCTestInstance()->GetCurrentTag();
  stdoutFile += "-";
  stdoutFile += 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 = cont->BinaryDir;
        file += "/";
        file += 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)
{
  LabelIdMapType::iterator 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 = this->CTest->GetBinaryDir();
  fileList += cmake::GetCMakeFilesDirectory();
  fileList += "/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 = dir;
  fname += "/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)
{
  LabelMapType::const_iterator 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());
  LabelMapType::const_iterator 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;
}
