[Cmake-commits] CMake branch, next, updated. v2.8.8-2708-g283b8fe

Bill Hoffman bill.hoffman at kitware.com
Wed Apr 25 17:06:14 EDT 2012


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  283b8fe1ed285f15ee3b408ec070e8a98bb29413 (commit)
       via  e6412e084ed6ba77c17292e3e7c5b9d8e2450bab (commit)
      from  53c3ca3a59790e99b5fc94bc8d99dc20d0379c5b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=283b8fe1ed285f15ee3b408ec070e8a98bb29413
commit 283b8fe1ed285f15ee3b408ec070e8a98bb29413
Merge: 53c3ca3 e6412e0
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Wed Apr 25 17:06:12 2012 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Wed Apr 25 17:06:12 2012 -0400

    Merge topic 'mumps_coverage' into next
    
    e6412e0 Add support to ctest for GTM mumps coverage.

diff --cc Source/CTest/cmCTestCoverageHandler.cxx
index ae06b0f,6c99928..23d2637
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@@ -751,34 -760,19 +760,46 @@@ int cmCTestCoverageHandler::HandlePHPCo
      }
    return static_cast<int>(cont->TotalCoverage.size());
  }
+ //----------------------------------------------------------------------
+ int cmCTestCoverageHandler::HandleGTMCoverage(
+   cmCTestCoverageHandlerContainer* cont)
+ {
+   cmParseGTMCoverage cov(*cont, this->CTest);
+   std::string coverageFile = this->CTest->GetBinaryDir() + "/gtm_coverage.mcov";
+   if(cmSystemTools::FileExists(coverageFile.c_str()))
+     {
+     cov.ReadGTMCoverage(coverageFile.c_str());
+     }
+   return static_cast<int>(cont->TotalCoverage.size());
+ }
  
 +struct cmCTestCoverageHandlerLocale
 +{
 +  cmCTestCoverageHandlerLocale()
 +    {
 +    if(const char* l = cmSystemTools::GetEnv("LC_ALL"))
 +      {
 +      lc_all = l;
 +      }
 +    if(lc_all != "C")
 +      {
 +      cmSystemTools::PutEnv("LC_ALL=C");
 +      }
 +    }
 +  ~cmCTestCoverageHandlerLocale()
 +    {
 +    if(!lc_all.empty())
 +      {
 +      cmSystemTools::PutEnv(("LC_ALL=" + lc_all).c_str());
 +      }
 +    else
 +      {
 +      cmSystemTools::UnsetEnv("LC_ALL");
 +      }
 +    }
 +  std::string lc_all;
 +};
 +
  //----------------------------------------------------------------------
  int cmCTestCoverageHandler::HandleGCovCoverage(
    cmCTestCoverageHandlerContainer* cont)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e6412e084ed6ba77c17292e3e7c5b9d8e2450bab
commit e6412e084ed6ba77c17292e3e7c5b9d8e2450bab
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Wed Apr 25 17:04:28 2012 -0400
Commit:     Bill Hoffman <bill.hoffman at kitware.com>
CommitDate: Wed Apr 25 17:04:28 2012 -0400

    Add support to ctest for GTM mumps coverage.

diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index f9d1c03..1ef67da 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -423,6 +423,7 @@ SET(CTEST_SRCS cmCTest.cxx
   CTest/cmCTestConfigureHandler.cxx
   CTest/cmCTestCoverageCommand.cxx
   CTest/cmCTestCoverageHandler.cxx
+  CTest/cmParseGTMCoverage.cxx
   CTest/cmParsePHPCoverage.cxx
   CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
   CTest/cmCTestGenericHandler.cxx
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 309abb1..6c99928 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -11,6 +11,7 @@
 ============================================================================*/
 #include "cmCTestCoverageHandler.h"
 #include "cmParsePHPCoverage.h"
+#include "cmParseGTMCoverage.h"
 #include "cmCTest.h"
 #include "cmake.h"
 #include "cmMakefile.h"
@@ -373,21 +374,29 @@ int cmCTestCoverageHandler::ProcessHandler()
     }
   int file_count = 0;
   file_count += this->HandleGCovCoverage(&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->HandleGTMCoverage(&cont);
   error = cont.Error;
+  if ( file_count < 0 )
+    {
+    return error;
+    }
 
   std::set<std::string> uncovered = this->FindUncoveredFiles(&cont);
 
@@ -751,6 +760,18 @@ int cmCTestCoverageHandler::HandlePHPCoverage(
     }
   return static_cast<int>(cont->TotalCoverage.size());
 }
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::HandleGTMCoverage(
+  cmCTestCoverageHandlerContainer* cont)
+{
+  cmParseGTMCoverage cov(*cont, this->CTest);
+  std::string coverageFile = this->CTest->GetBinaryDir() + "/gtm_coverage.mcov";
+  if(cmSystemTools::FileExists(coverageFile.c_str()))
+    {
+    cov.ReadGTMCoverage(coverageFile.c_str());
+    }
+  return static_cast<int>(cont->TotalCoverage.size());
+}
 
 //----------------------------------------------------------------------
 int cmCTestCoverageHandler::HandleGCovCoverage(
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
index d3e8503..f4c275f 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -70,6 +70,8 @@ private:
 
   //! Handle coverage using xdebug php coverage
   int HandlePHPCoverage(cmCTestCoverageHandlerContainer* cont);
+  //! Handle coverage using GTM
+  int HandleGTMCoverage(cmCTestCoverageHandlerContainer* cont);
 
   //! Handle coverage using Bullseye
   int HandleBullseyeCoverage(cmCTestCoverageHandlerContainer* cont);
diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx
new file mode 100644
index 0000000..16e0f61
--- /dev/null
+++ b/Source/CTest/cmParseGTMCoverage.cxx
@@ -0,0 +1,398 @@
+#include "cmStandardIncludes.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "cmSystemTools.h"
+#include "cmParseGTMCoverage.h"
+#include <cmsys/Directory.hxx>
+#include <cmsys/Glob.hxx>
+
+
+cmParseGTMCoverage::cmParseGTMCoverage(cmCTestCoverageHandlerContainer& cont,
+    cmCTest* ctest)
+    :Coverage(cont), CTest(ctest)
+{
+}
+
+bool cmParseGTMCoverage::ReadGTMCoverage(const char* file)
+{
+  // Read the gtm_coverage.mcov file, that has two lines of data:
+  // packages:/full/path/to/Vista/Packages
+  // coverage_dir:/full/path/to/dir/with/*.mcov
+  std::ifstream in(file);
+  if(!in)
+    {
+    return false;
+    }
+  std::string line;
+  cmSystemTools::GetLineFromStream(in, line);
+  std::string::size_type pos = line.find(':', 0);
+  std::string packages;
+  if(pos != std::string::npos)
+    {
+    packages = line.substr(pos+1);
+    }
+  cmSystemTools::GetLineFromStream(in, line);
+  pos = line.find(':', 0);
+  std::string coverage_dir;
+  if(pos != std::string::npos)
+    {
+    coverage_dir = line.substr(pos+1);
+    }
+  // load the mumps files from the packages directory
+  this->LoadPackages(packages.c_str());
+  // now load the *.mcov files from the coverage directory
+  this->LoadCoverageData(coverage_dir.c_str());
+  return true;
+}
+
+void cmParseGTMCoverage::InitializeFile(std::string& file)
+{
+  // initialize the coverage information for a given mumps file
+  std::ifstream in(file.c_str());
+  if(!in)
+    {
+    return;
+    }
+  std::string line;
+  cmCTestCoverageHandlerContainer::SingleFileCoverageVector&
+    coverageVector = this->Coverage.TotalCoverage[file];
+  if(!cmSystemTools::GetLineFromStream(in, line))
+    {
+    return;
+    }
+  // first line of a .m file can never be run
+  coverageVector.push_back(-1);
+  while( cmSystemTools::GetLineFromStream(in, line) )
+    {
+    // putting in a 0 for a line means it is executable code
+    // putting in a -1 for a line means it is not executable code
+    int val = -1; // assume line is not executable
+    bool found = false;
+    std::string::size_type i = 0;
+    // (1) Search for the first whitespace or semicolon character on a line.
+    //This will skip over labels if the line starts with one, or will simply
+    //be the first character on the line for non-label lines.
+    for(; i < line.size(); ++i)
+      {
+      if(line[i] == ' ' || line[i] == '\t' || line[i] == ';')
+        {
+        found = true;
+        break;
+        }
+      }
+    if(found)
+      {
+      // (2) If the first character found above is whitespace then continue the
+      // search for the first following non-whitespace character.
+      if(line[i] == ' ' || line[i] == '\t')
+        {
+        while(i < line.size() && (line[i] == ' ' || line[i] == '\t'))
+          {
+          i++;
+          }
+        }
+      // (3) If the character found is not a semicolon then the line counts for
+      // coverage.
+      if(i < line.size() && line[i] != ';')
+        {
+        val = 0;
+        }
+      }
+    coverageVector.push_back(val);
+    }
+}
+
+bool cmParseGTMCoverage::LoadPackages(const char* d)
+{
+  cmsys::Glob glob;
+  glob.RecurseOn();
+  std::string pat = d;
+  pat += "/*.m";
+  glob.FindFiles(pat.c_str());
+  std::vector<std::string>& files = glob.GetFiles();
+  std::vector<std::string>::iterator fileIt;
+  for ( fileIt = files.begin(); fileIt != files.end();
+        ++ fileIt )
+    {
+    std::string name = cmSystemTools::GetFilenameName(*fileIt);
+    this->RoutineToDirectory[name.substr(0, name.size()-2)] = *fileIt;
+    // initialze each file, this is left out until CDash is fixed
+    // to handle large numbers of files
+//    this->InitializeFile(*fileIt);
+    }
+  return true;
+}
+
+bool cmParseGTMCoverage::LoadCoverageData(const char* d)
+{
+  // load all the .mcov files in the specified directory
+  cmsys::Directory dir;
+  if(!dir.Load(d))
+    {
+    return false;
+    }
+  size_t numf;
+  unsigned int i;
+  numf = dir.GetNumberOfFiles();
+  for (i = 0; i < numf; i++)
+    {
+    std::string file = dir.GetFile(i);
+    if(file != "." && file != ".."
+       && !cmSystemTools::FileIsDirectory(file.c_str()))
+      {
+      std::string path = d;
+      path += "/";
+      path += file;
+      if(cmSystemTools::GetFilenameLastExtension(path) == ".mcov")
+        {
+        if(!this->ReadMCovFile(path.c_str()))
+          {
+          return false;
+          }
+        }
+      }
+    }
+  return true;
+}
+
+bool cmParseGTMCoverage::ParseFile(std::string& filepath,
+                                   std::string& function,
+                                   int& lineoffset)
+{
+  std::ifstream in(filepath.c_str());
+  if(!in)
+    {
+    return false;
+    }
+  std::string line;
+  int linenum = 0;
+  while(  cmSystemTools::GetLineFromStream(in, line))
+    {
+    std::string::size_type pos = line.find(function.c_str());
+    if(pos == 0)
+      {
+      char nextchar = line[function.size()];
+      if(nextchar == ' ' || nextchar == '(')
+        {
+        lineoffset = linenum;
+        return true;
+        }
+      }
+    if(pos == 1)
+      {
+      char prevchar = line[0];
+      char nextchar = line[function.size()+1];
+      if(prevchar == '%' && (nextchar == ' ' || nextchar == '('))
+        {
+        lineoffset = linenum;
+        return true;
+        }
+      }
+    linenum++; // move to next line count
+    }
+  lineoffset = 0;
+  cmCTestLog(this->CTest, ERROR_MESSAGE,
+             "Could not find entry point : "
+             << function << " in " << filepath << "\n");
+  return false;
+}
+
+bool cmParseGTMCoverage::ParseLine(std::string const& line,
+                                   std::string& routine,
+                                   std::string& function,
+                                   int& linenumber,
+                                   int& count)
+{
+  // this method parses lines from the .mcov file
+  // each line has ^COVERAGE(...) in it, and there
+  // are several varients of coverage lines:
+  //
+  // ^COVERAGE("DIC11","PR1",0)="2:0:0:0"
+  //          ( file  , entry, line ) = "number_executed:timing_info"
+  // ^COVERAGE("%RSEL","SRC")="1:0:0:0"
+  //          ( file  , entry ) = "number_executed:timing_info"
+  // ^COVERAGE("%RSEL","init",8,"FOR_LOOP",1)=1
+  //          ( file  , entry, line, IGNORE ) =number_executed
+  std::vector<cmStdString> args;
+  std::string::size_type pos = line.find('(', 0);
+  // if no ( is found, then return line has no coverage
+  if(pos == std::string::npos)
+    {
+    return false;
+    }
+  std::string arg;
+  bool done = false;
+  // separate out all of the comma separated arguments found
+  // in the COVERAGE(...) line
+  while(line[pos] && !done)
+    {
+    // save the char we are looking at
+    char cur = line[pos];
+    // , or ) means end of argument
+    if(cur == ',' || cur == ')')
+      {
+      // save the argument into the argument vector
+      args.push_back(arg);
+      // start on a new argument
+      arg = "";
+      // if we are at the end of the ), then finish while loop
+      if(cur == ')')
+        {
+        done = true;
+        }
+      }
+    else
+      {
+      // all chars except ", (, and % get stored in the arg string
+      if(cur != '\"' && cur != '(' && cur != '%')
+        {
+        arg.append(1, line[pos]);
+        }
+      }
+    // move to next char
+    pos++;
+    }
+  // now parse the right hand side of the =
+  pos = line.find('=');
+  // no = found, this is an error
+  if(pos == line.npos)
+    {
+    return false;
+    }
+  pos++; // move past =
+
+  // if the next positing is not a ", then this is a
+  // COVERAGE(..)=count line and turn the rest of the string
+  // past the = into an integer and set it to count
+  if(line[pos] != '\"')
+    {
+    count = atoi(line.substr(pos).c_str());
+    }
+  else
+    {
+    // this means line[pos] is a ", and we have a
+    // COVERAGE(...)="1:0:0:0" type of line
+    pos++; // move past "
+    // find the first : past the "
+    std::string::size_type pos2 = line.find(':', pos);
+    // turn the string between the " and the first : into an integer
+    // and set it to count
+    count = atoi(line.substr(pos, pos2-pos).c_str());
+    }
+  // less then two arguments is an error
+  if(args.size() < 2)
+    {
+    cmCTestLog(this->CTest, ERROR_MESSAGE,
+               "Error parsing mcov line: [" << line << "]\n");
+    return false;
+    }
+  routine = args[0]; // the routine is the first argument
+  function = args[1]; // the function in the routine is the second
+  // in the two argument only format
+  // ^COVERAGE("%RSEL","SRC"), the line offset is 0
+  if(args.size() == 2)
+    {
+    linenumber = 0;
+    }
+  else
+    {
+    // this is the format for this line
+    // ^COVERAGE("%RSEL","SRC",count)
+    linenumber = atoi(args[2].c_str());
+    }
+  return true;
+}
+
+bool cmParseGTMCoverage::ReadMCovFile(const char* file)
+{
+  std::ifstream in(file);
+  if(!in)
+    {
+    return false;
+    }
+  std::string line;
+  std::string lastfunction;
+  std::string lastroutine;
+  std::string lastpath;
+  int lastoffset = 0;
+  while(  cmSystemTools::GetLineFromStream(in, line))
+    {
+    // only look at lines that have coverage data
+    if(line.find("^COVERAGE") == line.npos)
+      {
+      continue;
+      }
+    std::string filepath;
+    std::string function;
+    std::string routine;
+    int linenumber = 0;
+    int count = 0;
+    this->ParseLine(line, routine, function, linenumber, count);
+    // skip this one
+    if(routine == "RSEL")
+      {
+      continue;
+      }
+    // no need to search the file if we just did it
+    if(function == lastfunction && lastroutine == routine)
+      {
+      this->Coverage.TotalCoverage[lastpath][lastoffset + linenumber] += count;
+      continue;
+      }
+    // Find the full path to the file
+    std::map<cmStdString, cmStdString>::iterator i =
+      this->RoutineToDirectory.find(routine);
+    bool found = false;
+    if(i != this->RoutineToDirectory.end())
+      {
+      filepath = i->second;
+      found = true;
+      }
+    else
+      {
+      // try some alternate names
+      char* tryname[] = {"GUX", "GTM", "ONT", 0};
+      for(int k=0; tryname[k] != 0; k++)
+        {
+        std::string routine2 = routine + tryname[k];
+        i = this->RoutineToDirectory.find(routine2);
+        if(i != this->RoutineToDirectory.end())
+          {
+          found = true;
+          filepath = i->second;
+          break; // break out of tryname loop if found
+          }
+        }
+      }
+    if(found)
+      {
+      int lineoffset;
+      if(this->ParseFile(filepath,
+                         function,
+                         lineoffset))
+        {
+        // hack, this should be done on every file, but for now
+        // just do it on the ones that have coverage at all
+        if( this->Coverage.TotalCoverage[filepath].size() == 0)
+          {
+          this->InitializeFile(filepath);
+          }
+        cmCTestCoverageHandlerContainer::SingleFileCoverageVector&
+          coverageVector = this->Coverage.TotalCoverage[filepath];
+        coverageVector[lineoffset + linenumber] += count;
+        }
+      lastoffset = lineoffset;
+      }
+    else
+      {
+      cmCTestLog(this->CTest, ERROR_MESSAGE,
+               "Can not find mumps file : "
+               << routine << "  referenced in this line of mcov data:\n"
+                 "[" << line << "]\n");
+      }
+    lastfunction = function;
+    lastroutine = routine;
+    lastpath = filepath;
+    }
+  return true;
+}
diff --git a/Source/CTest/cmParseGTMCoverage.h b/Source/CTest/cmParseGTMCoverage.h
new file mode 100644
index 0000000..d4e901d
--- /dev/null
+++ b/Source/CTest/cmParseGTMCoverage.h
@@ -0,0 +1,50 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2009 Kitware, Inc.
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+
+#ifndef cmParseGTMCoverage_h
+#define cmParseGTMCoverage_h
+
+#include "cmStandardIncludes.h"
+#include "cmCTestCoverageHandler.h"
+
+/** \class cmParseGTMCoverage
+ * \brief Parse GTM coverage information
+ *
+ * This class is used to parse GTM coverage information for
+ * mumps.
+ */
+class cmParseGTMCoverage
+{
+public:
+  cmParseGTMCoverage(cmCTestCoverageHandlerContainer& cont,
+    cmCTest* ctest);
+  bool ReadGTMCoverage(const char* file);
+private:
+  bool ParseFile(std::string& filepath,
+                 std::string& function,
+                 int& lineoffset);
+  bool ParseLine(std::string const& line,
+                 std::string& routine,
+                 std::string& function,
+                 int& linenumber,
+                 int& count);
+  bool LoadPackages(const char* dir);
+  bool LoadCoverageData(const char* dir);
+  bool ReadMCovFile(const char* f);
+  void InitializeFile(std::string& file);
+  std::map<cmStdString, cmStdString> RoutineToDirectory;
+  cmCTestCoverageHandlerContainer& Coverage;
+  cmCTest* CTest;
+};
+
+
+#endif
diff --git a/Source/CTest/cmParsePHPCoverage.h b/Source/CTest/cmParsePHPCoverage.h
index ce5741d..d50a83c 100644
--- a/Source/CTest/cmParsePHPCoverage.h
+++ b/Source/CTest/cmParsePHPCoverage.h
@@ -37,9 +37,6 @@ private:
   bool ReadInt(std::ifstream& in, int& v);
   bool ReadCoverageArray(std::ifstream& in, cmStdString const&);
   bool ReadUntil(std::ifstream& in, char until);
-  typedef std::map<int, int> FileLineCoverage;
-  std::map<cmStdString, FileLineCoverage> FileToCoverage;
-  std::map<int, int> FileCoverage;
   cmCTestCoverageHandlerContainer& Coverage;
   cmCTest* CTest;
 };

-----------------------------------------------------------------------

Summary of changes:
 Source/CMakeLists.txt                   |    1 +
 Source/CTest/cmCTestCoverageHandler.cxx |   21 ++
 Source/CTest/cmCTestCoverageHandler.h   |    2 +
 Source/CTest/cmParseGTMCoverage.cxx     |  398 +++++++++++++++++++++++++++++++
 Source/CTest/cmParseGTMCoverage.h       |   50 ++++
 Source/CTest/cmParsePHPCoverage.h       |    3 -
 6 files changed, 472 insertions(+), 3 deletions(-)
 create mode 100644 Source/CTest/cmParseGTMCoverage.cxx
 create mode 100644 Source/CTest/cmParseGTMCoverage.h


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list