ENH: add new command to create a test driver

This commit is contained in:
Bill Hoffman 2002-03-20 16:19:00 -05:00
parent 49bcc1ad51
commit 2f639d37b5
9 changed files with 282 additions and 3 deletions

View File

@ -131,6 +131,25 @@ IF(BUILD_TESTING)
wrapping
${CMake_BINARY_DIR}/Tests/Wrapping/bin)
ADD_TEST(testdriver1 ${CMake_BINARY_DIR}/Source/cmaketest
${CMake_SOURCE_DIR}/Tests/TestDriver
${CMake_BINARY_DIR}/Tests/TestDriver
TestDriverTest
${CMake_BINARY_DIR}/Tests/Wrapping/bin
TestDriverTest test1)
ADD_TEST(testdriver2 ${CMake_BINARY_DIR}/Source/cmaketest
${CMake_SOURCE_DIR}/Tests/TestDriver
${CMake_BINARY_DIR}/Tests/TestDriver
TestDriverTest
${CMake_BINARY_DIR}/Tests/Wrapping/bin
TestDriverTest test2)
ADD_TEST(testdriver3 ${CMake_BINARY_DIR}/Source/cmaketest
${CMake_SOURCE_DIR}/Tests/TestDriver
${CMake_BINARY_DIR}/Tests/TestDriver
TestDriverTest
${CMake_BINARY_DIR}/Tests/Wrapping/bin
TestDriverTest test3)
ENDIF (DART_ROOT)
ENDIF(BUILD_TESTING)

View File

@ -33,6 +33,7 @@
#include "cmCableWrapTclCommand.cxx"
#include "cmConfigureFileCommand.cxx"
#include "cmConfigureGccXmlCommand.cxx"
#include "cmCreateTestSourceList.cxx"
#include "cmElseCommand.cxx"
#include "cmEnableTestingCommand.cxx"
#include "cmEndForEachCommand.cxx"
@ -99,6 +100,7 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands)
commands.push_back(new cmCableWrapTclCommand);
commands.push_back(new cmConfigureFileCommand);
commands.push_back(new cmConfigureGccXmlCommand);
commands.push_back(new cmCreateTestSourceList);
commands.push_back(new cmElseCommand);
commands.push_back(new cmEnableTestingCommand);
commands.push_back(new cmEndForEachCommand);

View File

@ -0,0 +1,129 @@
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Insight Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "cmCreateTestSourceList.h"
// cmCreateTestSourceList
bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& argsIn)
{
if (argsIn.size() < 5)
{
this->SetError("called with wrong number of arguments.");
return false;
}
std::vector<std::string> args;
cmSystemTools::ExpandListArguments(argsIn, args);
std::vector<std::string>::iterator i = args.begin();
const char* sourceList = i->c_str();
++i;
std::string driver = m_Makefile->GetCurrentOutputDirectory();
driver += "/";
driver += *i;
driver += ".cxx";
++i;
std::vector<std::string>::iterator testsBegin = i;
std::ofstream fout(driver.c_str());
if(!fout)
{
std::string err = "Could not create file ";
err += driver;
err += " for cmCreateTestSourceList command.";
this->SetError(err.c_str());
return false;
}
// Create the test driver file
fout << "#include <stdio.h>\n";
fout << "#include <string.h>\n";
fout << "// forward declare test functions\n";
for(i = testsBegin; i != args.end(); ++i)
{
fout << "int " << *i << "(int, char**);\n";
}
fout << "// Create map \n";
fout << "typedef int (*MainFuncPointer)(int , char**);\n";
fout << "struct functionMapEntry\n"
<< "{\n"
<< "const char* name;\n"
<< "MainFuncPointer func;\n"
<< "};\n\n";
fout << "functionMapEntry cmakeGeneratedFunctionMapEntries[] = {\n";
int numTests = 0;
for(i = testsBegin; i != args.end(); ++i)
{
fout << "{\"" << *i << "\", " << *i << "},\n";
numTests++;
}
fout << "};\n";
fout << "int main(int ac, char** av)\n"
<< "{\n";
fout << " int NumTests = " << numTests << ";\n";
fout << " int i;\n";
fout << " if(ac < 2)\n";
fout << " {\n";
fout << " printf(\"Available tests:\\n\");\n";
fout << " for(i =0; i < NumTests; ++i)\n";
fout << " {\n";
fout << " printf(\"%d. %s\\n\", i, cmakeGeneratedFunctionMapEntries[i].name);\n";
fout << " }\n";
fout << " printf(\"To run a test, enter the test number: \");\n";
fout << " int testNum = 0;\n";
fout << " scanf(\"%d\", &testNum);\n";
fout << " if(testNum >= NumTests)\n";
fout << " {\n";
fout << " printf(\"%d is an invalid test number.\\n\", testNum);\n";
fout << " return -1;\n";
fout << " }\n";
fout << " return (*cmakeGeneratedFunctionMapEntries[testNum].func)(ac-1, av+1);\n";
fout << " }\n";
fout << " for(i =0; i < NumTests; ++i)\n";
fout << " {\n";
fout << " if(strcmp(cmakeGeneratedFunctionMapEntries[i].name, av[1]) == 0)\n";
fout << " {\n";
fout << " return (*cmakeGeneratedFunctionMapEntries[i].func)(ac-1, av+1);\n";
fout << " }\n";
fout << " }\n";
fout << " printf(\"Available tests:\\n\");\n";
fout << " for(i =0; i < NumTests; ++i)\n";
fout << " {\n";
fout << " printf(\"%d. %s\\n\", i, cmakeGeneratedFunctionMapEntries[i].name);\n";
fout << " }\n";
fout << " printf(\"Failed: %s is an invalid test name.\\n\", av[1]);\n";
fout << " return -1;\n";
fout << "}\n";
fout.close();
// create the source list
cmSourceFile cfile;
cfile.SetIsAnAbstractClass(false);
cfile.SetName(args[1].c_str(), m_Makefile->GetCurrentOutputDirectory(),
"cxx", false);
m_Makefile->AddSource(cfile, sourceList);
for(i = testsBegin; i != args.end(); ++i)
{
cmSourceFile cfile;
cfile.SetIsAnAbstractClass(false);
cfile.SetName(i->c_str(), m_Makefile->GetCurrentDirectory(),
"cxx", false);
m_Makefile->AddSource(cfile, sourceList);
}
return true;
}

View File

@ -0,0 +1,84 @@
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Insight Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef cmCreateTestSourceList_h
#define cmCreateTestSourceList_h
#include "cmStandardIncludes.h"
#include "cmCommand.h"
/** \class cmCreateTestSourceList
* \brief
*
*/
class cmCreateTestSourceList : public cmCommand
{
public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmCreateTestSourceList;
}
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool InitialPass(std::vector<std::string> const& args);
/**
* This determines if the command gets propagated down
* to makefiles located in subdirectories.
*/
virtual bool IsInherited() {return true;}
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() {return "CREATE_TEST_SOURCELIST";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Create a test driver and source list for building test programs.";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
"CREATE_TEST_SOURCELIST(SourceListName DriverName test1 test2 test3"
"The list of source files needed to build the testdriver will be in SourceListName.\n"
"DriverName.cxx is the name of the test driver program.\n"
"The rest of the arguments consist of a list of test source files, can be "
"; separated. Each test source file should have a function in it that "
"is the same name as the file with no extension (foo.cxx should have int foo();) "
"DriverName.cxx will be able to call each of the tests by name on the command line.";
}
cmTypeMacro(cmCreateTestSourceList, cmCommand);
};
#endif

View File

@ -87,11 +87,22 @@ int main (int argc, char *argv[])
generator += CMAKE_GENERATOR;
args.push_back(generator);
std::vector<std::string> progArgs;
if(argc > 6)
{
if(strcmp(argv[6] , "CMAKE_ARGS") == 0)
{
for (int j = 7; j < argc ; j++)
{
args.push_back(argv[j]);
}
}
else
{
for(int j = 6; j < argc; j++)
{
args.push_back(argv[j]);
progArgs.push_back(argv[j]);
}
}
}
@ -254,6 +265,12 @@ int main (int argc, char *argv[])
return 1;
}
fullPath = cmSystemTools::ConvertToOutputPath(fullPath.c_str());
for(std::vector<std::string>::iterator p = progArgs.begin();
p != progArgs.end(); ++p)
{
fullPath += " ";
fullPath += *p;
}
std::cout << "Running test executable: " << fullPath.c_str() << "\n";
int ret = 0;
if (!cmSystemTools::RunCommand(fullPath.c_str(), output, ret, 0, true))

View File

@ -0,0 +1,4 @@
PROJECT(TestDriverTest)
CREATE_TEST_SOURCELIST(testSrcs TestDriverTest test1 test2 test3)
ADD_EXECUTABLE(TestDriverTest testSrcs)

View File

@ -0,0 +1,8 @@
#include <stdio.h>
int test1(int ac, char** av)
{
printf("test1\n");
for(int i =0; i < ac; i++)
printf("arg %d is %s\n", ac, av[i]);
return 0;
}

View File

@ -0,0 +1,8 @@
#include <stdio.h>
int test2(int ac, char** av)
{
printf("test2\n");
for(int i =0; i < ac; i++)
printf("arg %d is %s\n", ac, av[i]);
return 0;
}

View File

@ -0,0 +1,8 @@
#include <stdio.h>
int test3(int ac, char** av)
{
printf("test3\n");
for(int i =0; i < ac; i++)
printf("arg %d is %s\n", ac, av[i]);
return 0;
}