/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  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.
============================================================================*/

#include "cmCTestTestHandler.h"
#include "cmCTestMultiProcessHandler.h"
#include "cmCTestBatchTestHandler.h"
#include "cmCTest.h"
#include "cmCTestRunTest.h"
#include "cmake.h"
#include "cmGeneratedFileStream.h"
#include <cmsys/Process.h>
#include <cmsys/RegularExpression.hxx>
#include <cmsys/Base64.h>
#include <cmsys/Directory.hxx>
#include <cmsys/FStream.hxx>
#include "cmMakefile.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmCommand.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
#include "cm_utf8.h"

#include <stdlib.h>
#include <math.h>
#include <float.h>

#include <set>

//----------------------------------------------------------------------
class cmCTestSubdirCommand : public cmCommand
{
public:
  /**
   * This is a virtual constructor for the command.
   */
  virtual cmCommand* Clone()
    {
    cmCTestSubdirCommand* c = new cmCTestSubdirCommand;
    c->TestHandler = this->TestHandler;
    return c;
    }

  /**
   * This is called when the command is first encountered in
   * the CMakeLists.txt file.
   */
  virtual bool InitialPass(std::vector<std::string> const& args,
                           cmExecutionStatus &);

  /**
   * The name of the command as specified in CMakeList.txt.
   */
  virtual std::string GetName() const { return "subdirs";}

  cmTypeMacro(cmCTestSubdirCommand, cmCommand);

  cmCTestTestHandler* TestHandler;
};

//----------------------------------------------------------------------
bool cmCTestSubdirCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if(args.size() < 1 )
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }
  std::vector<std::string>::const_iterator it;
  std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  for ( it = args.begin(); it != args.end(); ++ it )
    {
    std::string fname;

    if(cmSystemTools::FileIsFullPath(it->c_str()))
      {
      fname = *it;
      }
    else
      {
      fname = cwd;
      fname += "/";
      fname += *it;
      }

    if ( !cmSystemTools::FileIsDirectory(fname) )
      {
      // No subdirectory? So what...
      continue;
      }
    cmSystemTools::ChangeDirectory(fname);
    const char* testFilename;
    if( cmSystemTools::FileExists("CTestTestfile.cmake") )
      {
      // does the CTestTestfile.cmake exist ?
      testFilename = "CTestTestfile.cmake";
      }
    else if( cmSystemTools::FileExists("DartTestfile.txt") )
      {
      // does the DartTestfile.txt exist ?
      testFilename = "DartTestfile.txt";
      }
    else
      {
      // No CTestTestfile? Who cares...
      continue;
      }
    fname += "/";
    fname += testFilename;
    bool readit = this->Makefile->ReadDependentFile(fname.c_str());
    cmSystemTools::ChangeDirectory(cwd);
    if(!readit)
      {
      std::string m = "Could not find include file: ";
      m += fname;
      this->SetError(m);
      return false;
      }
    }
  cmSystemTools::ChangeDirectory(cwd);
  return true;
}

//----------------------------------------------------------------------
class cmCTestAddSubdirectoryCommand : public cmCommand
{
public:
  /**
   * This is a virtual constructor for the command.
   */
  virtual cmCommand* Clone()
    {
    cmCTestAddSubdirectoryCommand* c = new cmCTestAddSubdirectoryCommand;
    c->TestHandler = this->TestHandler;
    return c;
    }

  /**
   * This is called when the command is first encountered in
   * the CMakeLists.txt file.
   */
  virtual bool InitialPass(std::vector<std::string> const& args,
                           cmExecutionStatus &);

  /**
   * The name of the command as specified in CMakeList.txt.
   */
  virtual std::string GetName() const { return "add_subdirectory";}

  cmTypeMacro(cmCTestAddSubdirectoryCommand, cmCommand);

  cmCTestTestHandler* TestHandler;
};

//----------------------------------------------------------------------
bool cmCTestAddSubdirectoryCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if(args.size() < 1 )
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }

  std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  cmSystemTools::ChangeDirectory(cwd);
  std::string fname = cwd;
  fname += "/";
  fname += args[0];

  if ( !cmSystemTools::FileExists(fname.c_str()) )
    {
    // No subdirectory? So what...
    return true;
    }
  cmSystemTools::ChangeDirectory(fname);
  const char* testFilename;
  if( cmSystemTools::FileExists("CTestTestfile.cmake") )
    {
    // does the CTestTestfile.cmake exist ?
    testFilename = "CTestTestfile.cmake";
    }
  else if( cmSystemTools::FileExists("DartTestfile.txt") )
    {
    // does the DartTestfile.txt exist ?
    testFilename = "DartTestfile.txt";
    }
  else
    {
    // No CTestTestfile? Who cares...
    cmSystemTools::ChangeDirectory(cwd);
    return true;
    }
  fname += "/";
  fname += testFilename;
  bool readit = this->Makefile->ReadDependentFile(fname.c_str());
  cmSystemTools::ChangeDirectory(cwd);
  if(!readit)
    {
    std::string m = "Could not find include file: ";
    m += fname;
    this->SetError(m);
    return false;
    }
  return true;
}

//----------------------------------------------------------------------
class cmCTestAddTestCommand : public cmCommand
{
public:
  /**
   * This is a virtual constructor for the command.
   */
  virtual cmCommand* Clone()
    {
    cmCTestAddTestCommand* c = new cmCTestAddTestCommand;
    c->TestHandler = this->TestHandler;
    return c;
    }

  /**
   * This is called when the command is first encountered in
   * the CMakeLists.txt file.
   */
  virtual bool InitialPass(std::vector<std::string> const&,
                           cmExecutionStatus &);

  /**
   * The name of the command as specified in CMakeList.txt.
   */
  virtual std::string GetName() const { return "add_test";}

  cmTypeMacro(cmCTestAddTestCommand, cmCommand);

  cmCTestTestHandler* TestHandler;
};

//----------------------------------------------------------------------
bool cmCTestAddTestCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if ( args.size() < 2 )
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }
  return this->TestHandler->AddTest(args);
}

//----------------------------------------------------------------------
class cmCTestSetTestsPropertiesCommand : public cmCommand
{
public:
  /**
   * This is a virtual constructor for the command.
   */
  virtual cmCommand* Clone()
    {
    cmCTestSetTestsPropertiesCommand* c
      = new cmCTestSetTestsPropertiesCommand;
    c->TestHandler = this->TestHandler;
    return c;
    }

  /**
   * This is called when the command is first encountered in
   * the CMakeLists.txt file.
  */
  virtual bool InitialPass(std::vector<std::string> const&,
                           cmExecutionStatus &);

  /**
   * The name of the command as specified in CMakeList.txt.
   */
  virtual std::string GetName() const { return "set_tests_properties";}

  cmTypeMacro(cmCTestSetTestsPropertiesCommand, cmCommand);

  cmCTestTestHandler* TestHandler;
};

//----------------------------------------------------------------------
bool cmCTestSetTestsPropertiesCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  return this->TestHandler->SetTestsProperties(args);
}

//----------------------------------------------------------------------
// get the next number in a string with numbers separated by ,
// pos is the start of the search and pos2 is the end of the search
// pos becomes pos2 after a call to GetNextNumber.
// -1 is returned at the end of the list.
inline int GetNextNumber(std::string const& in,
                         int& val,
                         std::string::size_type& pos,
                         std::string::size_type& pos2)
{
  pos2 = in.find(',', pos);
  if(pos2 != in.npos)
    {
    if(pos2-pos == 0)
      {
      val = -1;
      }
    else
      {
      val = atoi(in.substr(pos, pos2-pos).c_str());
      }
    pos = pos2+1;
    return 1;
    }
  else
    {
    if(in.size()-pos == 0)
      {
       val = -1;
      }
    else
      {
      val = atoi(in.substr(pos, in.size()-pos).c_str());
      }
    return 0;
    }
}

//----------------------------------------------------------------------
// get the next number in a string with numbers separated by ,
// pos is the start of the search and pos2 is the end of the search
// pos becomes pos2 after a call to GetNextNumber.
// -1 is returned at the end of the list.
inline int GetNextRealNumber(std::string const& in,
                             double& val,
                             std::string::size_type& pos,
                             std::string::size_type& pos2)
{
  pos2 = in.find(',', pos);
  if(pos2 != in.npos)
    {
    if(pos2-pos == 0)
      {
      val = -1;
      }
    else
      {
      val = atof(in.substr(pos, pos2-pos).c_str());
      }
    pos = pos2+1;
    return 1;
    }
  else
    {
    if(in.size()-pos == 0)
      {
       val = -1;
      }
    else
      {
      val = atof(in.substr(pos, in.size()-pos).c_str());
      }
    return 0;
    }
}


//----------------------------------------------------------------------
cmCTestTestHandler::cmCTestTestHandler()
{
  this->UseUnion = false;

  this->UseIncludeLabelRegExpFlag   = false;
  this->UseExcludeLabelRegExpFlag   = false;
  this->UseIncludeRegExpFlag   = false;
  this->UseExcludeRegExpFlag   = false;
  this->UseExcludeRegExpFirst  = false;

  this->CustomMaximumPassedTestOutputSize = 1 * 1024;
  this->CustomMaximumFailedTestOutputSize = 300 * 1024;

  this->MemCheck = false;

  this->LogFile = 0;

  // regex to detect <DartMeasurement>...</DartMeasurement>
  this->DartStuff.compile(
    "(<DartMeasurement.*/DartMeasurement[a-zA-Z]*>)");
  // regex to detect each individual <DartMeasurement>...</DartMeasurement>
  this->DartStuff1.compile(
    "(<DartMeasurement[^<]*</DartMeasurement[a-zA-Z]*>)");
}

//----------------------------------------------------------------------
void cmCTestTestHandler::Initialize()
{
  this->Superclass::Initialize();

  this->ElapsedTestingTime = -1;

  this->TestResults.clear();

  this->CustomTestsIgnore.clear();
  this->StartTest = "";
  this->EndTest = "";

  this->CustomPreTest.clear();
  this->CustomPostTest.clear();
  this->CustomMaximumPassedTestOutputSize = 1 * 1024;
  this->CustomMaximumFailedTestOutputSize = 300 * 1024;

  this->TestsToRun.clear();

  this->UseIncludeLabelRegExpFlag = false;
  this->UseExcludeLabelRegExpFlag = false;
  this->UseIncludeRegExpFlag = false;
  this->UseExcludeRegExpFlag = false;
  this->UseExcludeRegExpFirst = false;
  this->IncludeLabelRegularExpression = "";
  this->ExcludeLabelRegularExpression = "";
  this->IncludeRegExp = "";
  this->ExcludeRegExp = "";

  TestsToRunString = "";
  this->UseUnion = false;
  this->TestList.clear();
}

//----------------------------------------------------------------------
void cmCTestTestHandler::PopulateCustomVectors(cmMakefile *mf)
{
  this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_PRE_TEST",
                                this->CustomPreTest);
  this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_POST_TEST",
                                this->CustomPostTest);
  this->CTest->PopulateCustomVector(mf,
                             "CTEST_CUSTOM_TESTS_IGNORE",
                             this->CustomTestsIgnore);
  this->CTest->PopulateCustomInteger(mf,
                             "CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE",
                             this->CustomMaximumPassedTestOutputSize);
  this->CTest->PopulateCustomInteger(mf,
                             "CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE",
                             this->CustomMaximumFailedTestOutputSize);
}

//----------------------------------------------------------------------
int cmCTestTestHandler::PreProcessHandler()
{
  if ( !this->ExecuteCommands(this->CustomPreTest) )
    {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
      "Problem executing pre-test command(s)." << std::endl);
    return 0;
    }
  return 1;
}

//----------------------------------------------------------------------
int cmCTestTestHandler::PostProcessHandler()
{
  if ( !this->ExecuteCommands(this->CustomPostTest) )
    {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
      "Problem executing post-test command(s)." << std::endl);
    return 0;
    }
  return 1;
}

//----------------------------------------------------------------------
//clearly it would be nice if this were broken up into a few smaller
//functions and commented...
int cmCTestTestHandler::ProcessHandler()
{
  // Update internal data structure from generic one
  this->SetTestsToRunInformation(this->GetOption("TestsToRunInformation"));
  this->SetUseUnion(cmSystemTools::IsOn(this->GetOption("UseUnion")));
  if(cmSystemTools::IsOn(this->GetOption("ScheduleRandom")))
    {
    this->CTest->SetScheduleType("Random");
    }
  if(this->GetOption("ParallelLevel"))
    {
    this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel")));
    }

  const char* val;
  val = this->GetOption("LabelRegularExpression");
  if ( val )
    {
    this->UseIncludeLabelRegExpFlag = true;
    this->IncludeLabelRegExp = val;
    }
  val = this->GetOption("ExcludeLabelRegularExpression");
  if ( val )
    {
    this->UseExcludeLabelRegExpFlag = true;
    this->ExcludeLabelRegExp = val;
    }
  val = this->GetOption("IncludeRegularExpression");
  if ( val )
    {
    this->UseIncludeRegExp();
    this->SetIncludeRegExp(val);
    }
  val = this->GetOption("ExcludeRegularExpression");
  if ( val )
    {
    this->UseExcludeRegExp();
    this->SetExcludeRegExp(val);
    }
  this->SetRerunFailed(cmSystemTools::IsOn(this->GetOption("RerunFailed")));

  this->TestResults.clear();

  cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
             (this->MemCheck ? "Memory check" : "Test")
             << " project " << cmSystemTools::GetCurrentWorkingDirectory()
             << std::endl, this->Quiet);
  if ( ! this->PreProcessHandler() )
    {
    return -1;
    }

  cmGeneratedFileStream mLogFile;
  this->StartLogFile((this->MemCheck ? "DynamicAnalysis" : "Test"), mLogFile);
  this->LogFile = &mLogFile;

  std::vector<std::string> passed;
  std::vector<std::string> failed;
  int total;

  //start the real time clock
  double clock_start, clock_finish;
  clock_start = cmSystemTools::GetTime();

  this->ProcessDirectory(passed, failed);

  clock_finish = cmSystemTools::GetTime();

  total = int(passed.size()) + int(failed.size());

  if (total == 0)
    {
    if ( !this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels() )
      {
      cmCTestLog(this->CTest, ERROR_MESSAGE, "No tests were found!!!"
        << std::endl);
      }
    }
  else
    {
    if (this->HandlerVerbose && !passed.empty() &&
      (this->UseIncludeRegExpFlag || this->UseExcludeRegExpFlag))
      {
      cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl
        << "The following tests passed:" << std::endl, this->Quiet);
      for(std::vector<std::string>::iterator j = passed.begin();
          j != passed.end(); ++j)
        {
        cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "\t" << *j
          << std::endl, this->Quiet);
        }
      }

    float percent = float(passed.size()) * 100.0f / float(total);
    if (!failed.empty() && percent > 99)
      {
      percent = 99;
      }

    cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl
               << static_cast<int>(percent + .5) << "% tests passed, "
               << failed.size() << " tests failed out of "
               << total << std::endl);
    if(this->CTest->GetLabelSummary())
      {
      this->PrintLabelSummary();
      }
    char realBuf[1024];
    sprintf(realBuf, "%6.2f sec", (double)(clock_finish - clock_start));
    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
      "\nTotal Test time (real) = " << realBuf << "\n", this->Quiet );

    if (!failed.empty())
      {
      cmGeneratedFileStream ofs;
      cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl
                 << "The following tests FAILED:" << std::endl);
      this->StartLogFile("TestsFailed", ofs);

      typedef std::set<cmCTestTestHandler::cmCTestTestResult,
                       cmCTestTestResultLess> SetOfTests;
      SetOfTests resultsSet(this->TestResults.begin(),
                            this->TestResults.end());

      for(SetOfTests::iterator ftit = resultsSet.begin();
          ftit != resultsSet.end(); ++ftit)
        {
        if ( ftit->Status != cmCTestTestHandler::COMPLETED )
          {
          ofs << ftit->TestCount << ":" << ftit->Name << std::endl;
          cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\t" << std::setw(3)
                     << ftit->TestCount << " - "
                     << ftit->Name << " ("
                     << this->GetTestStatus(ftit->Status) << ")"
                     << std::endl, this->Quiet);
          }
        }
      }
    }

  if ( this->CTest->GetProduceXML() )
    {
    cmGeneratedFileStream xmlfile;
    if( !this->StartResultingXML(
          (this->MemCheck ? cmCTest::PartMemCheck : cmCTest::PartTest),
        (this->MemCheck ? "DynamicAnalysis" : "Test"), xmlfile) )
      {
      cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot create "
        << (this->MemCheck ? "memory check" : "testing")
        << " XML file" << std::endl);
      this->LogFile = 0;
      return 1;
      }
    cmXMLWriter xml(xmlfile);
    this->GenerateDartOutput(xml);
    }

  if ( ! this->PostProcessHandler() )
    {
    this->LogFile = 0;
    return -1;
    }

  if ( !failed.empty() )
    {
    this->LogFile = 0;
    return -1;
    }
  this->LogFile = 0;
  return 0;
}

//----------------------------------------------------------------------
void cmCTestTestHandler::PrintLabelSummary()
{
  cmCTestTestHandler::ListOfTests::iterator it = this->TestList.begin();
  std::map<std::string, double> labelTimes;
  std::map<std::string, int> labelCounts;
  std::set<std::string> labels;
  // initialize maps
  std::string::size_type maxlen = 0;
  for(; it != this->TestList.end(); ++it)
    {
    cmCTestTestProperties& p = *it;
    if(!p.Labels.empty())
      {
      for(std::vector<std::string>::iterator l = p.Labels.begin();
          l !=  p.Labels.end(); ++l)
        {
        if((*l).size() > maxlen)
          {
          maxlen = (*l).size();
          }
        labels.insert(*l);
        labelTimes[*l] = 0;
        labelCounts[*l] = 0;
        }
      }
    }
  cmCTestTestHandler::TestResultsVector::iterator ri =
      this->TestResults.begin();
  // fill maps
  for(; ri != this->TestResults.end(); ++ri)
    {
    cmCTestTestResult &result = *ri;
    cmCTestTestProperties& p = *result.Properties;
    if(!p.Labels.empty())
      {
      for(std::vector<std::string>::iterator l = p.Labels.begin();
          l !=  p.Labels.end(); ++l)
        {
        labelTimes[*l] += result.ExecutionTime;
        ++labelCounts[*l];
        }
      }
    }
  // now print times
  if(!labels.empty())
    {
    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\nLabel Time Summary:",
      this->Quiet);
    }
  for(std::set<std::string>::const_iterator i = labels.begin();
      i != labels.end(); ++i)
    {
    std::string label = *i;
    label.resize(maxlen +3, ' ');

    char buf[1024];
    sprintf(buf, "%6.2f sec", labelTimes[*i]);

    std::ostringstream labelCountStr;
    labelCountStr << "(" << labelCounts[*i] << " test";
    if (labelCounts[*i] > 1)
      {
      labelCountStr << "s";
      }
    labelCountStr << ")";

    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\n"
               << label << " = " << buf << " " << labelCountStr.str(),
               this->Quiet );
    if ( this->LogFile )
      {
      *this->LogFile << "\n" << *i << " = "
                     << buf << "\n";
      }
    }
  if(!labels.empty())
    {
    if(this->LogFile)
      {
      *this->LogFile << "\n";
      }
    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\n", this->Quiet);
    }

}

//----------------------------------------------------------------------
void cmCTestTestHandler::CheckLabelFilterInclude(cmCTestTestProperties& it)
{
  // if not using Labels to filter then return
  if (!this->UseIncludeLabelRegExpFlag )
    {
    return;
    }
  // if there are no labels and we are filtering by labels
  // then exclude the test as it does not have the label
  if(it.Labels.empty())
    {
    it.IsInBasedOnREOptions = false;
    return;
    }
  // check to see if the label regular expression matches
  bool found = false;  // assume it does not match
  // loop over all labels and look for match
  for(std::vector<std::string>::iterator l = it.Labels.begin();
      l !=  it.Labels.end(); ++l)
    {
    if(this->IncludeLabelRegularExpression.find(*l))
      {
      found = true;
      }
    }
  // if no match was found, exclude the test
  if(!found)
    {
    it.IsInBasedOnREOptions = false;
    }
}


//----------------------------------------------------------------------
void cmCTestTestHandler::CheckLabelFilterExclude(cmCTestTestProperties& it)
{
  // if not using Labels to filter then return
  if (!this->UseExcludeLabelRegExpFlag )
    {
    return;
    }
  // if there are no labels and we are excluding by labels
  // then do nothing as a no label can not be a match
  if(it.Labels.empty())
    {
    return;
    }
  // check to see if the label regular expression matches
  bool found = false;  // assume it does not match
  // loop over all labels and look for match
  for(std::vector<std::string>::iterator l = it.Labels.begin();
      l !=  it.Labels.end(); ++l)
    {
    if(this->ExcludeLabelRegularExpression.find(*l))
      {
      found = true;
      }
    }
  // if match was found, exclude the test
  if(found)
    {
    it.IsInBasedOnREOptions = false;
    }
}

//----------------------------------------------------------------------
void cmCTestTestHandler::CheckLabelFilter(cmCTestTestProperties& it)
{
  this->CheckLabelFilterInclude(it);
  this->CheckLabelFilterExclude(it);
}

//----------------------------------------------------------------------
void cmCTestTestHandler::ComputeTestList()
{
  this->TestList.clear(); // clear list of test
  this->GetListOfTests();

  if (this->RerunFailed)
    {
    this->ComputeTestListForRerunFailed();
    return;
    }

  cmCTestTestHandler::ListOfTests::size_type tmsize = this->TestList.size();
  // how many tests are in based on RegExp?
  int inREcnt = 0;
  cmCTestTestHandler::ListOfTests::iterator it;
  for ( it = this->TestList.begin(); it != this->TestList.end(); it ++ )
    {
    this->CheckLabelFilter(*it);
    if (it->IsInBasedOnREOptions)
      {
      inREcnt ++;
      }
    }
  // expand the test list based on the union flag
  if (this->UseUnion)
    {
    this->ExpandTestsToRunInformation((int)tmsize);
    }
  else
    {
    this->ExpandTestsToRunInformation(inREcnt);
    }
  // Now create a final list of tests to run
  int cnt = 0;
  inREcnt = 0;
  std::string last_directory = "";
  ListOfTests finalList;
  for ( it = this->TestList.begin(); it != this->TestList.end(); it ++ )
    {
    cnt ++;
    if (it->IsInBasedOnREOptions)
      {
      inREcnt++;
      }

    if (this->UseUnion)
      {
      // if it is not in the list and not in the regexp then skip
      if ((!this->TestsToRun.empty() &&
           std::find(this->TestsToRun.begin(), this->TestsToRun.end(), cnt)
           == this->TestsToRun.end()) && !it->IsInBasedOnREOptions)
        {
        continue;
        }
      }
    else
      {
      // is this test in the list of tests to run? If not then skip it
      if ((!this->TestsToRun.empty() &&
           std::find(this->TestsToRun.begin(),
                     this->TestsToRun.end(), inREcnt)
           == this->TestsToRun.end()) || !it->IsInBasedOnREOptions)
        {
        continue;
        }
      }
    it->Index = cnt;  // save the index into the test list for this test
    finalList.push_back(*it);
    }
  // Save the total number of tests before exclusions
  this->TotalNumberOfTests = this->TestList.size();
  // Set the TestList to the final list of all test
  this->TestList = finalList;

  this->UpdateMaxTestNameWidth();
}

void cmCTestTestHandler::ComputeTestListForRerunFailed()
{
  this->ExpandTestsToRunInformationForRerunFailed();

  cmCTestTestHandler::ListOfTests::iterator it;
  ListOfTests finalList;
  int cnt = 0;
  for ( it = this->TestList.begin(); it != this->TestList.end(); it ++ )
    {
    cnt ++;

    // if this test is not in our list of tests to run, then skip it.
    if ((!this->TestsToRun.empty() &&
         std::find(this->TestsToRun.begin(), this->TestsToRun.end(), cnt)
         == this->TestsToRun.end()))
      {
      continue;
      }

    it->Index = cnt;
    finalList.push_back(*it);
    }

  // Save the total number of tests before exclusions
  this->TotalNumberOfTests = this->TestList.size();

  // Set the TestList to the list of failed tests to rerun
  this->TestList = finalList;

  this->UpdateMaxTestNameWidth();
}

void cmCTestTestHandler::UpdateMaxTestNameWidth()
{
  std::string::size_type max = this->CTest->GetMaxTestNameWidth();
  for ( cmCTestTestHandler::ListOfTests::iterator it = this->TestList.begin();
        it != this->TestList.end(); it ++ )
    {
    cmCTestTestProperties& p = *it;
    if(max < p.Name.size())
      {
      max = p.Name.size();
      }
    }
  if(static_cast<std::string::size_type>(this->CTest->GetMaxTestNameWidth())
     != max)
    {
    this->CTest->SetMaxTestNameWidth(static_cast<int>(max));
    }
}

bool cmCTestTestHandler::GetValue(const char* tag,
                                  int& value,
                                  std::istream& fin)
{
  std::string line;
  bool ret = true;
  cmSystemTools::GetLineFromStream(fin, line);
  if(line == tag)
    {
    fin >> value;
    ret = cmSystemTools::GetLineFromStream(fin, line); // read blank line
    }
  else
    {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "parse error: missing tag: "
               << tag << " found [" << line << "]" << std::endl);
    ret = false;
    }
  return ret;
}

bool cmCTestTestHandler::GetValue(const char* tag,
                                  double& value,
                                  std::istream& fin)
{
  std::string line;
  cmSystemTools::GetLineFromStream(fin, line);
  bool ret = true;
  if(line == tag)
    {
    fin >> value;
    ret = cmSystemTools::GetLineFromStream(fin, line); // read blank line
    }
  else
    {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "parse error: missing tag: "
               << tag << " found [" << line << "]" << std::endl);
    ret = false;
    }
  return ret;
}

bool cmCTestTestHandler::GetValue(const char* tag,
                                  bool& value,
                                  std::istream& fin)
{
  std::string line;
  cmSystemTools::GetLineFromStream(fin, line);
  bool ret = true;
  if(line == tag)
    {
#ifdef __HAIKU__
    int tmp = 0;
    fin >> tmp;
    value = false;
    if(tmp)
      {
      value = true;
      }
#else
    fin >> value;
#endif
    ret = cmSystemTools::GetLineFromStream(fin, line); // read blank line
    }
  else
    {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "parse error: missing tag: "
               << tag << " found [" << line << "]" << std::endl);
    ret = false;
    }
  return ret;
}

bool cmCTestTestHandler::GetValue(const char* tag,
                                  size_t& value,
                                  std::istream& fin)
{
  std::string line;
  cmSystemTools::GetLineFromStream(fin, line);
  bool ret = true;
  if(line == tag)
    {
    fin >> value;
    ret = cmSystemTools::GetLineFromStream(fin, line); // read blank line
    }
  else
    {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "parse error: missing tag: "
               << tag << " found [" << line << "]" << std::endl);
    ret = false;
    }
  return ret;
}

bool cmCTestTestHandler::GetValue(const char* tag,
                                  std::string& value,
                                  std::istream& fin)
{
  std::string line;
  cmSystemTools::GetLineFromStream(fin, line);
  bool ret = true;
  if(line == tag)
    {
    ret =  cmSystemTools::GetLineFromStream(fin, value);
    }
  else
    {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "parse error: missing tag: "
               << tag << " found [" << line << "]" << std::endl);
    ret = false;
    }
  return ret;
}

//---------------------------------------------------------------------
void cmCTestTestHandler::ProcessDirectory(std::vector<std::string> &passed,
                                         std::vector<std::string> &failed)
{
  this->ComputeTestList();
  this->StartTest = this->CTest->CurrentTime();
  this->StartTestTime = static_cast<unsigned int>(cmSystemTools::GetTime());
  double elapsed_time_start = cmSystemTools::GetTime();

  cmCTestMultiProcessHandler* parallel = this->CTest->GetBatchJobs() ?
    new cmCTestBatchTestHandler : new cmCTestMultiProcessHandler;
  parallel->SetCTest(this->CTest);
  parallel->SetParallelLevel(this->CTest->GetParallelLevel());
  parallel->SetTestHandler(this);
  parallel->SetQuiet(this->Quiet);
  if(this->TestLoad > 0)
    {
    parallel->SetTestLoad(this->TestLoad);
    }
  else
    {
    parallel->SetTestLoad(this->CTest->GetTestLoad());
    }

  *this->LogFile << "Start testing: "
    << this->CTest->CurrentTime() << std::endl
    << "----------------------------------------------------------"
    << std::endl;

  cmCTestMultiProcessHandler::TestMap tests;
  cmCTestMultiProcessHandler::PropertiesMap properties;

  bool randomSchedule = this->CTest->GetScheduleType() == "Random";
  if(randomSchedule)
    {
    srand((unsigned)time(0));
    }

  for (ListOfTests::iterator it = this->TestList.begin();
       it != this->TestList.end(); ++it)
    {
    cmCTestTestProperties& p = *it;
    cmCTestMultiProcessHandler::TestSet depends;

    if(randomSchedule)
      {
      p.Cost = static_cast<float>(rand());
      }

    if(p.Timeout == 0 && this->CTest->GetGlobalTimeout() != 0)
      {
      p.Timeout = this->CTest->GetGlobalTimeout();
      }

    if(!p.Depends.empty())
      {
      for(std::vector<std::string>::iterator i = p.Depends.begin();
          i != p.Depends.end(); ++i)
        {
        for(ListOfTests::iterator it2 = this->TestList.begin();
            it2 != this->TestList.end(); ++it2)
          {
          if(it2->Name == *i)
            {
            depends.insert(it2->Index);
            break; // break out of test loop as name can only match 1
            }
          }
        }
      }
    tests[it->Index] = depends;
    properties[it->Index] = &*it;
    }
  parallel->SetTests(tests, properties);
  parallel->SetPassFailVectors(&passed, &failed);
  this->TestResults.clear();
  parallel->SetTestResults(&this->TestResults);

  if(this->CTest->ShouldPrintLabels())
    {
    parallel->PrintLabels();
    }
  else if(this->CTest->GetShowOnly())
    {
    parallel->PrintTestList();
    }
  else
    {
    parallel->RunTests();
    }
  delete parallel;
  this->EndTest = this->CTest->CurrentTime();
  this->EndTestTime = static_cast<unsigned int>(cmSystemTools::GetTime());
  this->ElapsedTestingTime = cmSystemTools::GetTime() - elapsed_time_start;
  *this->LogFile << "End testing: "
     << this->CTest->CurrentTime() << std::endl;
}

//----------------------------------------------------------------------
void cmCTestTestHandler::GenerateTestCommand(std::vector<std::string>&, int)
{
}

//----------------------------------------------------------------------
void cmCTestTestHandler::GenerateDartOutput(cmXMLWriter& xml)
{
  if ( !this->CTest->GetProduceXML() )
    {
    return;
    }

  this->CTest->StartXML(xml, this->AppendXML);
  xml.StartElement("Testing");
  xml.Element("StartDateTime", this->StartTest);
  xml.Element("StartTestTime", this->StartTestTime);
  xml.StartElement("TestList");
  cmCTestTestHandler::TestResultsVector::size_type cc;
  for ( cc = 0; cc < this->TestResults.size(); cc ++ )
    {
    cmCTestTestResult *result = &this->TestResults[cc];
    std::string testPath = result->Path + "/" + result->Name;
    xml.Element("Test", this->CTest->GetShortPathToFile(testPath.c_str()));
    }
  xml.EndElement(); // TestList
  for ( cc = 0; cc < this->TestResults.size(); cc ++ )
    {
    cmCTestTestResult *result = &this->TestResults[cc];
    this->WriteTestResultHeader(xml, result);
    xml.StartElement("Results");
    if ( result->Status != cmCTestTestHandler::NOT_RUN )
      {
      if ( result->Status != cmCTestTestHandler::COMPLETED ||
        result->ReturnValue )
        {
        xml.StartElement("NamedMeasurement");
        xml.Attribute("type", "text/string");
        xml.Attribute("name", "Exit Code");
        xml.Element("Value", this->GetTestStatus(result->Status));
        xml.EndElement(); // NamedMeasurement
        xml.StartElement("NamedMeasurement");
        xml.Attribute("type", "text/string");
        xml.Attribute("name", "Exit Value");
        xml.Element("Value", result->ReturnValue);
        xml.EndElement(); // NamedMeasurement
        }
      this->GenerateRegressionImages(xml, result->DartString);
      xml.StartElement("NamedMeasurement");
      xml.Attribute("type", "numeric/double");
      xml.Attribute("name", "Execution Time");
      xml.Element("Value", result->ExecutionTime);
      xml.EndElement(); // NamedMeasurement
      if(!result->Reason.empty())
        {
        const char* reasonType = "Pass Reason";
        if(result->Status != cmCTestTestHandler::COMPLETED &&
           result->Status != cmCTestTestHandler::NOT_RUN)
          {
          reasonType = "Fail Reason";
          }
        xml.StartElement("NamedMeasurement");
        xml.Attribute("type", "text/string");
        xml.Attribute("name", reasonType);
        xml.Element("Value", result->Reason);
        xml.EndElement(); // NamedMeasurement
        }
      xml.StartElement("NamedMeasurement");
      xml.Attribute("type", "text/string");
      xml.Attribute("name", "Completion Status");
      xml.Element("Value", result->CompletionStatus);
      xml.EndElement(); // NamedMeasurement
      }
    xml.StartElement("NamedMeasurement");
    xml.Attribute("type", "text/string");
    xml.Attribute("name", "Command Line");
    xml.Element("Value", result->FullCommandLine);
    xml.EndElement(); // NamedMeasurement
    std::map<std::string,std::string>::iterator measureIt;
    for ( measureIt = result->Properties->Measurements.begin();
      measureIt != result->Properties->Measurements.end();
      ++ measureIt )
      {
      xml.StartElement("NamedMeasurement");
      xml.Attribute("type", "text/string");
      xml.Attribute("name", measureIt->first);
      xml.Element("Value", measureIt->second);
      xml.EndElement(); // NamedMeasurement
      }
    xml.StartElement("Measurement");
    xml.StartElement("Value");
    if (result->CompressOutput)
      {
      xml.Attribute("encoding", "base64");
      xml.Attribute("compression", "gzip");
      }
    xml.Content(result->Output);
    xml.EndElement(); // Value
    xml.EndElement(); // Measurement
    xml.EndElement(); // Results

    this->AttachFiles(xml, result);
    this->WriteTestResultFooter(xml, result);
    }

  xml.Element("EndDateTime", this->EndTest);
  xml.Element("EndTestTime", this->EndTestTime);
  xml.Element("ElapsedMinutes",
    static_cast<int>(this->ElapsedTestingTime/6)/10.0);
  xml.EndElement(); // Testing
  this->CTest->EndXML(xml);
}

//----------------------------------------------------------------------------
void cmCTestTestHandler::WriteTestResultHeader(cmXMLWriter& xml,
                                               cmCTestTestResult* result)
{
  xml.StartElement("Test");
  if ( result->Status == cmCTestTestHandler::COMPLETED )
    {
    xml.Attribute("Status", "passed");
    }
  else if ( result->Status == cmCTestTestHandler::NOT_RUN )
    {
    xml.Attribute("Status", "notrun");
    }
  else
    {
    xml.Attribute("Status", "failed");
    }
  std::string testPath = result->Path + "/" + result->Name;
  xml.Element("Name", result->Name);
  xml.Element("Path", this->CTest->GetShortPathToFile(result->Path.c_str()));
  xml.Element("FullName", this->CTest->GetShortPathToFile(testPath.c_str()));
  xml.Element("FullCommandLine", result->FullCommandLine);
}

//----------------------------------------------------------------------------
void cmCTestTestHandler::WriteTestResultFooter(cmXMLWriter& xml,
                                               cmCTestTestResult* result)
{
  if(!result->Properties->Labels.empty())
    {
    xml.StartElement("Labels");
    std::vector<std::string> const& labels = result->Properties->Labels;
    for(std::vector<std::string>::const_iterator li = labels.begin();
        li != labels.end(); ++li)
      {
      xml.Element("Label", *li);
      }
    xml.EndElement(); // Labels
    }

  xml.EndElement(); // Test
}

//----------------------------------------------------------------------
void cmCTestTestHandler::AttachFiles(cmXMLWriter& xml,
                                     cmCTestTestResult* result)
{
  if(result->Status != cmCTestTestHandler::COMPLETED
     && result->Properties->AttachOnFail.size())
    {
    result->Properties->AttachedFiles.insert(
      result->Properties->AttachedFiles.end(),
      result->Properties->AttachOnFail.begin(),
      result->Properties->AttachOnFail.end());
    }
  for(std::vector<std::string>::const_iterator file =
      result->Properties->AttachedFiles.begin();
      file != result->Properties->AttachedFiles.end(); ++file)
    {
    const std::string &base64 = this->CTest->Base64GzipEncodeFile(*file);
    std::string fname = cmSystemTools::GetFilenameName(*file);
    xml.StartElement("NamedMeasurement");
    xml.Attribute("name", "Attached File");
    xml.Attribute("encoding", "base64");
    xml.Attribute("compression", "tar/gzip");
    xml.Attribute("filename", fname);
    xml.Attribute("type", "file");
    xml.Element("Value", base64);
    xml.EndElement(); // NamedMeasurement
    }
}

//----------------------------------------------------------------------
int cmCTestTestHandler::ExecuteCommands(std::vector<std::string>& vec)
{
  std::vector<std::string>::iterator it;
  for ( it = vec.begin(); it != vec.end(); ++it )
    {
    int retVal = 0;
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run command: " <<
      *it << std::endl, this->Quiet);
    if ( !cmSystemTools::RunSingleCommand(it->c_str(), 0, 0, &retVal, 0,
                                          cmSystemTools::OUTPUT_MERGE
        /*this->Verbose*/) || retVal != 0 )
      {
      cmCTestLog(this->CTest, ERROR_MESSAGE, "Problem running command: "
        << *it << std::endl);
      return 0;
      }
    }
  return 1;
}


//----------------------------------------------------------------------
// Find the appropriate executable to run for a test
std::string cmCTestTestHandler::FindTheExecutable(const char *exe)
{
  std::string resConfig;
  std::vector<std::string> extraPaths;
  std::vector<std::string> failedPaths;
  if(strcmp(exe, "NOT_AVAILABLE") == 0)
    {
    return exe;
    }
  return cmCTestTestHandler::FindExecutable(this->CTest,
                                            exe, resConfig,
                                            extraPaths,
                                            failedPaths);
}

// add additional configurations to the search path
void cmCTestTestHandler
::AddConfigurations(cmCTest *ctest,
                    std::vector<std::string> &attempted,
                    std::vector<std::string> &attemptedConfigs,
                    std::string filepath,
                    std::string &filename)
{
  std::string tempPath;

  if (!filepath.empty() &&
      filepath[filepath.size()-1] != '/')
    {
    filepath += "/";
    }
  tempPath = filepath + filename;
  attempted.push_back(tempPath);
  attemptedConfigs.push_back("");

  if(!ctest->GetConfigType().empty())
    {
    tempPath = filepath;
    tempPath += ctest->GetConfigType();
    tempPath += "/";
    tempPath += filename;
    attempted.push_back(tempPath);
    attemptedConfigs.push_back(ctest->GetConfigType());
    // If the file is an OSX bundle then the configtype
    // will be at the start of the path
    tempPath = ctest->GetConfigType();
    tempPath += "/";
    tempPath += filepath;
    tempPath += filename;
    attempted.push_back(tempPath);
    attemptedConfigs.push_back(ctest->GetConfigType());
    }
  else
    {
    // no config specified - try some options...
    tempPath = filepath;
    tempPath += "Release/";
    tempPath += filename;
    attempted.push_back(tempPath);
    attemptedConfigs.push_back("Release");
    tempPath = filepath;
    tempPath += "Debug/";
    tempPath += filename;
    attempted.push_back(tempPath);
    attemptedConfigs.push_back("Debug");
    tempPath = filepath;
    tempPath += "MinSizeRel/";
    tempPath += filename;
    attempted.push_back(tempPath);
    attemptedConfigs.push_back("MinSizeRel");
    tempPath = filepath;
    tempPath += "RelWithDebInfo/";
    tempPath += filename;
    attempted.push_back(tempPath);
    attemptedConfigs.push_back("RelWithDebInfo");
    tempPath = filepath;
    tempPath += "Deployment/";
    tempPath += filename;
    attempted.push_back(tempPath);
    attemptedConfigs.push_back("Deployment");
    tempPath = filepath;
    tempPath += "Development/";
    tempPath += filename;
    attempted.push_back(tempPath);
    attemptedConfigs.push_back("Deployment");
    }
}


//----------------------------------------------------------------------
// Find the appropriate executable to run for a test
std::string cmCTestTestHandler
::FindExecutable(cmCTest *ctest,
                 const char *testCommand,
                 std::string &resultingConfig,
                 std::vector<std::string> &extraPaths,
                 std::vector<std::string> &failed)
{
  // now run the compiled test if we can find it
  std::vector<std::string> attempted;
  std::vector<std::string> attemptedConfigs;
  std::string tempPath;
  std::string filepath =
    cmSystemTools::GetFilenamePath(testCommand);
  std::string filename =
    cmSystemTools::GetFilenameName(testCommand);

  cmCTestTestHandler::AddConfigurations(ctest, attempted,
                                        attemptedConfigs,
                                        filepath,filename);

  // even if a fullpath was specified also try it relative to the current
  // directory
  if (!filepath.empty() && filepath[0] == '/')
    {
    std::string localfilepath = filepath.substr(1,filepath.size()-1);
    cmCTestTestHandler::AddConfigurations(ctest, attempted,
                                          attemptedConfigs,
                                          localfilepath,filename);
    }


  // if extraPaths are provided and we were not passed a full path, try them,
  // try any extra paths
  if (filepath.empty())
    {
    for (unsigned int i = 0; i < extraPaths.size(); ++i)
      {
      std::string filepathExtra =
        cmSystemTools::GetFilenamePath(extraPaths[i]);
      std::string filenameExtra =
        cmSystemTools::GetFilenameName(extraPaths[i]);
      cmCTestTestHandler::AddConfigurations(ctest,attempted,
                                            attemptedConfigs,
                                            filepathExtra,
                                            filenameExtra);
      }
    }

  // store the final location in fullPath
  std::string fullPath;

  // now look in the paths we specified above
  for(unsigned int ai=0;
      ai < attempted.size() && fullPath.empty(); ++ai)
    {
    // first check without exe extension
    if(cmSystemTools::FileExists(attempted[ai].c_str())
       && !cmSystemTools::FileIsDirectory(attempted[ai]))
      {
      fullPath = cmSystemTools::CollapseFullPath(attempted[ai]);
      resultingConfig = attemptedConfigs[ai];
      }
    // then try with the exe extension
    else
      {
      failed.push_back(attempted[ai]);
      tempPath = attempted[ai];
      tempPath += cmSystemTools::GetExecutableExtension();
      if(cmSystemTools::FileExists(tempPath.c_str())
         && !cmSystemTools::FileIsDirectory(tempPath))
        {
        fullPath = cmSystemTools::CollapseFullPath(tempPath);
        resultingConfig = attemptedConfigs[ai];
        }
      else
        {
        failed.push_back(tempPath);
        }
      }
    }

  // if everything else failed, check the users path, but only if a full path
  // wasn't specified
  if (fullPath.empty() && filepath.empty())
    {
    std::string path = cmSystemTools::FindProgram(filename.c_str());
    if (path != "")
      {
      resultingConfig = "";
      return path;
      }
    }
  if(fullPath.empty())
    {
    cmCTestLog(ctest, HANDLER_OUTPUT,
               "Could not find executable " << testCommand << "\n"
               << "Looked in the following places:\n");
    for(std::vector<std::string>::iterator i = failed.begin();
        i != failed.end(); ++i)
      {
      cmCTestLog(ctest, HANDLER_OUTPUT, i->c_str() << "\n");
      }
    }

  return fullPath;
}


//----------------------------------------------------------------------
void cmCTestTestHandler::GetListOfTests()
{
  if ( !this->IncludeLabelRegExp.empty() )
    {
    this->IncludeLabelRegularExpression.
      compile(this->IncludeLabelRegExp.c_str());
    }
  if ( !this->ExcludeLabelRegExp.empty() )
    {
    this->ExcludeLabelRegularExpression.
      compile(this->ExcludeLabelRegExp.c_str());
    }
  if ( !this->IncludeRegExp.empty() )
    {
    this->IncludeTestsRegularExpression.compile(this->IncludeRegExp.c_str());
    }
  if ( !this->ExcludeRegExp.empty() )
    {
    this->ExcludeTestsRegularExpression.compile(this->ExcludeRegExp.c_str());
    }
  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
    "Constructing a list of tests" << std::endl, this->Quiet);
  cmake cm;
  cm.SetHomeDirectory("");
  cm.SetHomeOutputDirectory("");
  cmGlobalGenerator gg(&cm);
  cmsys::auto_ptr<cmMakefile> mf(new cmMakefile(&gg, cm.GetCurrentSnapshot()));
  cmsys::auto_ptr<cmLocalGenerator> lg(
        gg.CreateLocalGenerator(mf.get()));
  mf->AddDefinition("CTEST_CONFIGURATION_TYPE",
    this->CTest->GetConfigType().c_str());

  // Add handler for ADD_TEST
  cmCTestAddTestCommand* newCom1 = new cmCTestAddTestCommand;
  newCom1->TestHandler = this;
  cm.GetState()->AddCommand(newCom1);

  // Add handler for SUBDIRS
  cmCTestSubdirCommand* newCom2 =
    new cmCTestSubdirCommand;
  newCom2->TestHandler = this;
  cm.GetState()->AddCommand(newCom2);

  // Add handler for ADD_SUBDIRECTORY
  cmCTestAddSubdirectoryCommand* newCom3 =
    new cmCTestAddSubdirectoryCommand;
  newCom3->TestHandler = this;
  cm.GetState()->AddCommand(newCom3);

  // Add handler for SET_SOURCE_FILES_PROPERTIES
  cmCTestSetTestsPropertiesCommand* newCom4
    = new cmCTestSetTestsPropertiesCommand;
  newCom4->TestHandler = this;
  cm.GetState()->AddCommand(newCom4);

  const char* testFilename;
  if( cmSystemTools::FileExists("CTestTestfile.cmake") )
    {
    // does the CTestTestfile.cmake exist ?
    testFilename = "CTestTestfile.cmake";
    }
  else if( cmSystemTools::FileExists("DartTestfile.txt") )
    {
    // does the DartTestfile.txt exist ?
    testFilename = "DartTestfile.txt";
    }
  else
    {
    return;
    }

  if ( !mf->ReadListFile(testFilename) )
    {
    return;
    }
  if ( cmSystemTools::GetErrorOccuredFlag() )
    {
    return;
    }
  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
    "Done constructing a list of tests" << std::endl, this->Quiet);
}

//----------------------------------------------------------------------
void cmCTestTestHandler::UseIncludeRegExp()
{
  this->UseIncludeRegExpFlag = true;
}

//----------------------------------------------------------------------
void cmCTestTestHandler::UseExcludeRegExp()
{
  this->UseExcludeRegExpFlag = true;
  this->UseExcludeRegExpFirst = this->UseIncludeRegExpFlag ? false : true;
}

//----------------------------------------------------------------------
const char* cmCTestTestHandler::GetTestStatus(int status)
{
  static const char statuses[][100] = {
    "Not Run",
    "Timeout",
    "SEGFAULT",
    "ILLEGAL",
    "INTERRUPT",
    "NUMERICAL",
    "OTHER_FAULT",
    "Failed",
    "BAD_COMMAND",
    "Completed"
  };

  if ( status < cmCTestTestHandler::NOT_RUN ||
       status > cmCTestTestHandler::COMPLETED )
    {
    return "No Status";
    }
  return statuses[status];
}

//----------------------------------------------------------------------
void cmCTestTestHandler::ExpandTestsToRunInformation(size_t numTests)
{
  if (this->TestsToRunString.empty())
    {
    return;
    }

  int start;
  int end = -1;
  double stride = -1;
  std::string::size_type pos = 0;
  std::string::size_type pos2;
  // read start
  if(GetNextNumber(this->TestsToRunString, start, pos, pos2))
    {
    // read end
    if(GetNextNumber(this->TestsToRunString, end, pos, pos2))
      {
      // read stride
      if(GetNextRealNumber(this->TestsToRunString, stride, pos, pos2))
        {
        int val =0;
        // now read specific numbers
        while(GetNextNumber(this->TestsToRunString, val, pos, pos2))
          {
          this->TestsToRun.push_back(val);
          }
        this->TestsToRun.push_back(val);
        }
      }
    }

  // if start is not specified then we assume we start at 1
  if(start == -1)
    {
    start = 1;
    }

  // if end isnot specified then we assume we end with the last test
  if(end == -1)
    {
    end = static_cast<int>(numTests);
    }

  // if the stride wasn't specified then it defaults to 1
  if(stride == -1)
    {
    stride = 1;
    }

  // if we have a range then add it
  if(end != -1 && start != -1 && stride > 0)
    {
    int i = 0;
    while (i*stride + start <= end)
      {
      this->TestsToRun.push_back(static_cast<int>(i*stride+start));
      ++i;
      }
    }

  // sort the array
  std::sort(this->TestsToRun.begin(), this->TestsToRun.end(),
    std::less<int>());
  // remove duplicates
  std::vector<int>::iterator new_end =
    std::unique(this->TestsToRun.begin(), this->TestsToRun.end());
  this->TestsToRun.erase(new_end, this->TestsToRun.end());
}

void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed()
{

  std::string dirName = this->CTest->GetBinaryDir() + "/Testing/Temporary";

  cmsys::Directory directory;
  if (directory.Load(dirName) == 0)
    {
    cmCTestLog(this->CTest, ERROR_MESSAGE, "Unable to read the contents of "
      << dirName << std::endl);
    return;
    }

  int numFiles = static_cast<int>
    (cmsys::Directory::GetNumberOfFilesInDirectory(dirName));
  std::string pattern = "LastTestsFailed";
  std::string logName = "";

  for (int i = 0; i < numFiles; ++i)
    {
    std::string fileName = directory.GetFile(i);
    // bcc crashes if we attempt a normal substring comparison,
    // hence the following workaround
    std::string fileNameSubstring = fileName.substr(0, pattern.length());
    if (fileNameSubstring.compare(pattern) != 0)
      {
      continue;
      }
    if (logName == "")
      {
      logName = fileName;
      }
    else
      {
      // if multiple matching logs were found we use the most recently
      // modified one.
      int res;
      cmSystemTools::FileTimeCompare(logName, fileName, &res);
      if (res == -1)
        {
        logName = fileName;
        }
      }
    }

  std::string lastTestsFailedLog = this->CTest->GetBinaryDir()
    + "/Testing/Temporary/" + logName;

  if ( !cmSystemTools::FileExists(lastTestsFailedLog.c_str()) )
    {
    if ( !this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels() )
      {
      cmCTestLog(this->CTest, ERROR_MESSAGE, lastTestsFailedLog
        << " does not exist!" << std::endl);
      }
    return;
    }

  // parse the list of tests to rerun from LastTestsFailed.log
  cmsys::ifstream ifs(lastTestsFailedLog.c_str());
  if ( ifs )
    {
    std::string line;
    std::string::size_type pos;
    while ( cmSystemTools::GetLineFromStream(ifs, line) )
      {
      pos = line.find(':', 0);
      if (pos == line.npos)
        {
        continue;
        }

      int val = atoi(line.substr(0, pos).c_str());
      this->TestsToRun.push_back(val);
      }
    ifs.close();
    }
  else if ( !this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels() )
    {
    cmCTestLog(this->CTest, ERROR_MESSAGE, "Problem reading file: "
      << lastTestsFailedLog <<
      " while generating list of previously failed tests." << std::endl);
    }
}

//----------------------------------------------------------------------
// Just for convenience
#define SPACE_REGEX "[ \t\r\n]"
//----------------------------------------------------------------------
void cmCTestTestHandler::GenerateRegressionImages(
  cmXMLWriter& xml, const std::string& dart)
{
  cmsys::RegularExpression twoattributes(
    "<DartMeasurement"
    SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
    SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
    SPACE_REGEX "*>([^<]*)</DartMeasurement>");
  cmsys::RegularExpression threeattributes(
    "<DartMeasurement"
    SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
    SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
    SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
    SPACE_REGEX "*>([^<]*)</DartMeasurement>");
  cmsys::RegularExpression fourattributes(
    "<DartMeasurement"
    SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
    SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
    SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
    SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
    SPACE_REGEX "*>([^<]*)</DartMeasurement>");
  cmsys::RegularExpression cdatastart(
    "<DartMeasurement"
    SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
    SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
    SPACE_REGEX "*>"
    SPACE_REGEX "*<!\\[CDATA\\[");
  cmsys::RegularExpression cdataend(
    "]]>"
    SPACE_REGEX "*</DartMeasurement>");
  cmsys::RegularExpression measurementfile(
    "<DartMeasurementFile"
    SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
    SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
    SPACE_REGEX "*>([^<]*)</DartMeasurementFile>");

  bool done = false;
  std::string cxml = dart;
  while ( ! done )
    {
    if ( twoattributes.find(cxml) )
      {
      xml.StartElement("NamedMeasurement");
      xml.Attribute(twoattributes.match(1).c_str(),
                    twoattributes.match(2));
      xml.Attribute(twoattributes.match(3).c_str(),
                    twoattributes.match(4));
      xml.Element("Value", twoattributes.match(5));
      xml.EndElement();
      cxml.erase(twoattributes.start(),
        twoattributes.end() - twoattributes.start());
      }
    else if ( threeattributes.find(cxml) )
      {
      xml.StartElement("NamedMeasurement");
      xml.Attribute(threeattributes.match(1).c_str(),
                    threeattributes.match(2));
      xml.Attribute(threeattributes.match(3).c_str(),
                    threeattributes.match(4));
      xml.Attribute(threeattributes.match(5).c_str(),
                    threeattributes.match(6));
      xml.Element("Value", twoattributes.match(7));
      xml.EndElement();
      cxml.erase(threeattributes.start(),
        threeattributes.end() - threeattributes.start());
      }
    else if ( fourattributes.find(cxml) )
      {
      xml.StartElement("NamedMeasurement");
      xml.Attribute(fourattributes.match(1).c_str(),
                    fourattributes.match(2));
      xml.Attribute(fourattributes.match(3).c_str(),
                    fourattributes.match(4));
      xml.Attribute(fourattributes.match(5).c_str(),
                    fourattributes.match(6));
      xml.Attribute(fourattributes.match(7).c_str(),
                    fourattributes.match(8));
      xml.Element("Value", twoattributes.match(9));
      xml.EndElement();
      cxml.erase(fourattributes.start(),
        fourattributes.end() - fourattributes.start());
      }
    else if ( cdatastart.find(cxml) && cdataend.find(cxml) )
      {
      xml.StartElement("NamedMeasurement");
      xml.Attribute(cdatastart.match(1).c_str(), cdatastart.match(2));
      xml.Attribute(cdatastart.match(3).c_str(), cdatastart.match(4));
      xml.StartElement("Value");
      xml.CData(
          cxml.substr(cdatastart.end(), cdataend.start() - cdatastart.end()));
      xml.EndElement(); // Value
      xml.EndElement(); // NamedMeasurement
      cxml.erase(cdatastart.start(),
        cdataend.end() - cdatastart.start());
      }
    else if ( measurementfile.find(cxml) )
      {
      const std::string& filename =
        cmCTest::CleanString(measurementfile.match(5));
      if ( cmSystemTools::FileExists(filename.c_str()) )
        {
        long len = cmSystemTools::FileLength(filename);
        if ( len == 0 )
          {
          std::string k1 = measurementfile.match(1);
          std::string v1 = measurementfile.match(2);
          std::string k2 = measurementfile.match(3);
          std::string v2 = measurementfile.match(4);
          if ( cmSystemTools::LowerCase(k1) == "type" )
            {
            v1 = "text/string";
            }
          if ( cmSystemTools::LowerCase(k2) == "type" )
            {
            v2 = "text/string";
            }

          xml.StartElement("NamedMeasurement");
          xml.Attribute(k1.c_str(), v1);
          xml.Attribute(k2.c_str(), v2);
          xml.Attribute("encoding", "none");
          xml.Element("Value", "Image " + filename + " is empty");
          xml.EndElement();
          }
        else
          {
          cmsys::ifstream ifs(filename.c_str(), std::ios::in
#ifdef _WIN32
                            | std::ios::binary
#endif
            );
          unsigned char *file_buffer = new unsigned char [ len + 1 ];
          ifs.read(reinterpret_cast<char*>(file_buffer), len);
          unsigned char *encoded_buffer
            = new unsigned char [ static_cast<int>(
                static_cast<double>(len) * 1.5 + 5.0) ];

          size_t rlen
            = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);

          xml.StartElement("NamedMeasurement");
          xml.Attribute(measurementfile.match(1).c_str(),
                        measurementfile.match(2));
          xml.Attribute(measurementfile.match(3).c_str(),
                        measurementfile.match(4));
          xml.Attribute("encoding", "base64");
          std::stringstream ostr;
          for (size_t cc = 0; cc < rlen; cc ++ )
            {
            ostr << encoded_buffer[cc];
            if ( cc % 60 == 0 && cc )
              {
              ostr << std::endl;
              }
            }
          xml.Element("Value", ostr.str());
          xml.EndElement(); // NamedMeasurement
          delete [] file_buffer;
          delete [] encoded_buffer;
          }
        }
      else
        {
        int idx = 4;
        if ( measurementfile.match(1) == "name" )
          {
          idx = 2;
          }
        xml.StartElement("NamedMeasurement");
        xml.Attribute("name", measurementfile.match(idx));
        xml.Attribute("text", "text/string");
        xml.Element("Value", "File " + filename + " not found");
        xml.EndElement();
        cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "File \"" << filename
          << "\" not found." << std::endl, this->Quiet);
        }
      cxml.erase(measurementfile.start(),
        measurementfile.end() - measurementfile.start());
      }
    else
      {
      done = true;
      }
    }
}

//----------------------------------------------------------------------
void cmCTestTestHandler::SetIncludeRegExp(const char *arg)
{
  this->IncludeRegExp = arg;
}

//----------------------------------------------------------------------
void cmCTestTestHandler::SetExcludeRegExp(const char *arg)
{
  this->ExcludeRegExp = arg;
}

//----------------------------------------------------------------------
void cmCTestTestHandler::SetTestsToRunInformation(const char* in)
{
  if ( !in )
    {
    return;
    }
  this->TestsToRunString = in;
  // if the argument is a file, then read it and use the contents as the
  // string
  if(cmSystemTools::FileExists(in))
    {
    cmsys::ifstream fin(in);
    unsigned long filelen = cmSystemTools::FileLength(in);
    char* buff = new char[filelen+1];
    fin.getline(buff, filelen);
    buff[fin.gcount()] = 0;
    this->TestsToRunString = buff;
    delete [] buff;
    }
}

//----------------------------------------------------------------------------
bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
{
  if(!length || length >= output.size() ||
     output.find("CTEST_FULL_OUTPUT") != output.npos)
    {
    return true;
    }

  // Truncate at given length but do not break in the middle of a multi-byte
  // UTF-8 encoding.
  char const* const begin = output.c_str();
  char const* const end = begin + output.size();
  char const* const truncate = begin + length;
  char const* current = begin;
  while(current < truncate)
    {
    unsigned int ch;
    if(const char* next = cm_utf8_decode_character(current, end, &ch))
      {
      if(next > truncate)
        {
        break;
        }
      current = next;
      }
    else // Bad byte will be handled by cmXMLWriter.
      {
      ++current;
      }
    }
  output = output.substr(0, current - begin);

  // Append truncation message.
  std::ostringstream msg;
  msg << "...\n"
    "The rest of the test output was removed since it exceeds the threshold "
    "of " << length << " bytes.\n";
  output += msg.str();
  return true;
}

//----------------------------------------------------------------------
bool cmCTestTestHandler::SetTestsProperties(
  const std::vector<std::string>& args)
{
  std::vector<std::string>::const_iterator it;
  std::vector<std::string> tests;
  bool found = false;
  for ( it = args.begin(); it != args.end(); ++ it )
    {
    if ( *it == "PROPERTIES" )
      {
      found = true;
      break;
      }
    tests.push_back(*it);
    }
  if ( !found )
    {
    return false;
    }
  ++ it; // skip PROPERTIES
  for ( ; it != args.end(); ++ it )
    {
    std::string key = *it;
    ++ it;
    if ( it == args.end() )
      {
      break;
      }
    std::string val = *it;
    std::vector<std::string>::const_iterator tit;
    for ( tit = tests.begin(); tit != tests.end(); ++ tit )
      {
      cmCTestTestHandler::ListOfTests::iterator rtit;
      for ( rtit = this->TestList.begin();
        rtit != this->TestList.end();
        ++ rtit )
        {
        if ( *tit == rtit->Name )
          {
          if ( key == "WILL_FAIL" )
            {
            rtit->WillFail = cmSystemTools::IsOn(val.c_str());
            }
          if ( key == "ATTACHED_FILES" )
            {
            cmSystemTools::ExpandListArgument(val, rtit->AttachedFiles);
            }
          if ( key == "ATTACHED_FILES_ON_FAIL" )
            {
            cmSystemTools::ExpandListArgument(val, rtit->AttachOnFail);
            }
          if ( key == "RESOURCE_LOCK" )
            {
            std::vector<std::string> lval;
            cmSystemTools::ExpandListArgument(val, lval);

            rtit->LockedResources.insert(lval.begin(), lval.end());
            }
          if ( key == "TIMEOUT" )
            {
            rtit->Timeout = atof(val.c_str());
            rtit->ExplicitTimeout = true;
            }
          if ( key == "COST" )
            {
            rtit->Cost = static_cast<float>(atof(val.c_str()));
            }
          if ( key == "REQUIRED_FILES" )
            {
            cmSystemTools::ExpandListArgument(val, rtit->RequiredFiles);
            }
          if ( key == "RUN_SERIAL" )
            {
            rtit->RunSerial = cmSystemTools::IsOn(val.c_str());
            }
          if ( key == "FAIL_REGULAR_EXPRESSION" )
            {
            std::vector<std::string> lval;
            cmSystemTools::ExpandListArgument(val, lval);
            std::vector<std::string>::iterator crit;
            for ( crit = lval.begin(); crit != lval.end(); ++ crit )
              {
              rtit->ErrorRegularExpressions.push_back(
                std::pair<cmsys::RegularExpression, std::string>(
                  cmsys::RegularExpression(crit->c_str()),
                  std::string(*crit)));
              }
            }
          if ( key == "PROCESSORS" )
            {
            rtit->Processors = atoi(val.c_str());
            if(rtit->Processors < 1)
              {
              rtit->Processors = 1;
              }
            }
          if ( key == "SKIP_RETURN_CODE" )
            {
            rtit->SkipReturnCode = atoi(val.c_str());
            if(rtit->SkipReturnCode < 0 || rtit->SkipReturnCode > 255)
              {
              rtit->SkipReturnCode = -1;
              }
            }
          if ( key == "DEPENDS" )
            {
            cmSystemTools::ExpandListArgument(val, rtit->Depends);
            }
          if ( key == "ENVIRONMENT" )
            {
            cmSystemTools::ExpandListArgument(val, rtit->Environment);
            }
          if ( key == "LABELS" )
            {
            cmSystemTools::ExpandListArgument(val, rtit->Labels);
            }
          if ( key == "MEASUREMENT" )
            {
            size_t pos = val.find_first_of("=");
            if ( pos != val.npos )
              {
              std::string mKey = val.substr(0, pos);
              const char* mVal = val.c_str() + pos + 1;
              rtit->Measurements[mKey] = mVal;
              }
            else
              {
              rtit->Measurements[val] = "1";
              }
            }
          if ( key == "PASS_REGULAR_EXPRESSION" )
            {
            std::vector<std::string> lval;
            cmSystemTools::ExpandListArgument(val, lval);
            std::vector<std::string>::iterator crit;
            for ( crit = lval.begin(); crit != lval.end(); ++ crit )
              {
              rtit->RequiredRegularExpressions.push_back(
                std::pair<cmsys::RegularExpression, std::string>(
                  cmsys::RegularExpression(crit->c_str()),
                  std::string(*crit)));
              }
            }
          if ( key == "WORKING_DIRECTORY" )
            {
            rtit->Directory = val;
            }
          }
        }
      }
    }
  return true;
}

//----------------------------------------------------------------------
bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
{
  const std::string& testname = args[0];
  cmCTestOptionalLog(this->CTest, DEBUG, "Add test: " << args[0] << std::endl,
    this->Quiet);

  if (this->UseExcludeRegExpFlag &&
    this->UseExcludeRegExpFirst &&
    this->ExcludeTestsRegularExpression.find(testname.c_str()))
    {
    return true;
    }
  if ( this->MemCheck )
    {
    std::vector<std::string>::iterator it;
    bool found = false;
    for ( it = this->CustomTestsIgnore.begin();
      it != this->CustomTestsIgnore.end(); ++ it )
      {
      if ( *it == testname )
        {
        found = true;
        break;
        }
      }
    if ( found )
      {
      cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
        "Ignore memcheck: " << *it << std::endl, this->Quiet);
      return true;
      }
    }
  else
    {
    std::vector<std::string>::iterator it;
    bool found = false;
    for ( it = this->CustomTestsIgnore.begin();
      it != this->CustomTestsIgnore.end(); ++ it )
      {
      if ( *it == testname )
        {
        found = true;
        break;
        }
      }
    if ( found )
      {
      cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Ignore test: "
        << *it << std::endl, this->Quiet);
      return true;
      }
    }

  cmCTestTestProperties test;
  test.Name = testname;
  test.Args = args;
  test.Directory = cmSystemTools::GetCurrentWorkingDirectory();
  cmCTestOptionalLog(this->CTest, DEBUG, "Set test directory: "
    << test.Directory << std::endl, this->Quiet);

  test.IsInBasedOnREOptions = true;
  test.WillFail = false;
  test.RunSerial = false;
  test.Timeout = 0;
  test.ExplicitTimeout = false;
  test.Cost = 0;
  test.Processors = 1;
  test.SkipReturnCode = -1;
  test.PreviousRuns = 0;
  if (this->UseIncludeRegExpFlag &&
    !this->IncludeTestsRegularExpression.find(testname.c_str()))
    {
    test.IsInBasedOnREOptions = false;
    }
  else if (this->UseExcludeRegExpFlag &&
    !this->UseExcludeRegExpFirst &&
    this->ExcludeTestsRegularExpression.find(testname.c_str()))
    {
    test.IsInBasedOnREOptions = false;
    }
  this->TestList.push_back(test);
  return true;
}

