summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2002-12-11 23:13:33 (GMT)
committerBrad King <brad.king@kitware.com>2002-12-11 23:13:33 (GMT)
commit4888c088ae0ca829862e8b2f9568abca12dc34d1 (patch)
tree2c0fb825f1d1adff97d98373b555f00b84da14f7
parent5a321605bcc15c7e559c8da5168eef00796148b1 (diff)
downloadCMake-4888c088ae0ca829862e8b2f9568abca12dc34d1.zip
CMake-4888c088ae0ca829862e8b2f9568abca12dc34d1.tar.gz
CMake-4888c088ae0ca829862e8b2f9568abca12dc34d1.tar.bz2
ENH: Moved ExpandListVariables out of individual commands. Argument evaluation rules are now very consistent. Double quotes can always be used to create exactly one argument, regardless of contents inside.
-rw-r--r--Source/cmAbstractFilesCommand.cxx6
-rw-r--r--Source/cmAddCustomCommandCommand.cxx6
-rw-r--r--Source/cmAddCustomTargetCommand.cxx6
-rw-r--r--Source/cmAddDefinitionsCommand.cxx6
-rw-r--r--Source/cmAddDependenciesCommand.cxx6
-rw-r--r--Source/cmAddExecutableCommand.cxx8
-rw-r--r--Source/cmAddLibraryCommand.cxx6
-rw-r--r--Source/cmAddTestCommand.cxx3
-rw-r--r--Source/cmCPluginAPI.cxx10
-rw-r--r--Source/cmCommand.h18
-rw-r--r--Source/cmCreateTestSourceList.cxx10
-rw-r--r--Source/cmEndForEachCommand.cxx7
-rw-r--r--Source/cmEndForEachCommand.h8
-rw-r--r--Source/cmFindFileCommand.cxx6
-rw-r--r--Source/cmFindLibraryCommand.cxx6
-rw-r--r--Source/cmFindPathCommand.cxx6
-rw-r--r--Source/cmFindProgramCommand.cxx7
-rw-r--r--Source/cmForEachCommand.cxx92
-rw-r--r--Source/cmForEachCommand.h13
-rw-r--r--Source/cmFunctionBlocker.h7
-rw-r--r--Source/cmITKWrapTclCommand.cxx6
-rw-r--r--Source/cmIfCommand.cxx51
-rw-r--r--Source/cmIfCommand.h16
-rw-r--r--Source/cmIncludeDirectoryCommand.cxx6
-rw-r--r--Source/cmInstallProgramsCommand.cxx6
-rw-r--r--Source/cmInstallTargetsCommand.cxx6
-rw-r--r--Source/cmLinkDirectoriesCommand.cxx6
-rw-r--r--Source/cmLinkLibrariesCommand.cxx6
-rw-r--r--Source/cmListFileCache.cxx189
-rw-r--r--Source/cmListFileCache.h35
-rw-r--r--Source/cmLoadCacheCommand.cxx6
-rw-r--r--Source/cmLoadCommandCommand.cxx10
-rw-r--r--Source/cmLocalUnixMakefileGenerator.cxx6
-rw-r--r--Source/cmMacroCommand.cxx69
-rw-r--r--Source/cmMacroCommand.h13
-rw-r--r--Source/cmMakefile.cxx116
-rw-r--r--Source/cmMakefile.h14
-rw-r--r--Source/cmMarkAsAdvancedCommand.cxx6
-rw-r--r--Source/cmMessageCommand.cxx6
-rw-r--r--Source/cmProjectCommand.cxx6
-rw-r--r--Source/cmRemoveCommand.cxx10
-rw-r--r--Source/cmSetSourceFilesPropertiesCommand.cxx6
-rw-r--r--Source/cmSourceFilesCommand.cxx6
-rw-r--r--Source/cmSourceFilesRemoveCommand.cxx10
-rw-r--r--Source/cmSubdirCommand.cxx6
-rw-r--r--Source/cmSystemTools.cxx297
-rw-r--r--Source/cmSystemTools.h26
-rw-r--r--Source/cmTarget.cxx4
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx8
-rw-r--r--Source/cmUtilitySourceCommand.cxx6
-rw-r--r--Source/cmVariableRequiresCommand.cxx2
-rw-r--r--Source/cmWriteFileCommand.cxx6
-rw-r--r--Source/ctest.cxx33
53 files changed, 607 insertions, 629 deletions
diff --git a/Source/cmAbstractFilesCommand.cxx b/Source/cmAbstractFilesCommand.cxx
index e74653e..e0601cb 100644
--- a/Source/cmAbstractFilesCommand.cxx
+++ b/Source/cmAbstractFilesCommand.cxx
@@ -19,7 +19,7 @@
#include "cmSourceFile.h"
// cmAbstractFilesCommand
-bool cmAbstractFilesCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmAbstractFilesCommand::InitialPass(std::vector<std::string> const& args)
{
const char* versionValue
= m_Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
@@ -29,13 +29,11 @@ bool cmAbstractFilesCommand::InitialPass(std::vector<std::string> const& argsIn)
return false;
}
- if(argsIn.size() < 1 )
+ if(args.size() < 1 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
bool ret = true;
std::string m = "could not find source file(s):\n";
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 6b1c09c..a0a017d 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -18,19 +18,17 @@
// cmAddCustomCommandCommand
-bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmAddCustomCommandCommand::InitialPass(std::vector<std::string> const& args)
{
/* Let's complain at the end of this function about the lack of a particular
arg. For the moment, let's say that COMMAND, TARGET are always
required.
*/
- if (argsIn.size() < 4)
+ if (args.size() < 4)
{
this->SetError("called with wrong number of arguments.");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
std::string source, command, target, comment;
std::vector<std::string> command_args, depends, outputs;
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index c14264d..77ab3ef 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -17,17 +17,15 @@
#include "cmAddCustomTargetCommand.h"
// cmAddCustomTargetCommand
-bool cmAddCustomTargetCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmAddCustomTargetCommand::InitialPass(std::vector<std::string> const& args)
{
bool all = false;
- if(argsIn.size() < 2 )
+ if(args.size() < 2 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
// all target option
std::string arguments;
diff --git a/Source/cmAddDefinitionsCommand.cxx b/Source/cmAddDefinitionsCommand.cxx
index 4cb42dd..5067e3f 100644
--- a/Source/cmAddDefinitionsCommand.cxx
+++ b/Source/cmAddDefinitionsCommand.cxx
@@ -17,15 +17,13 @@
#include "cmAddDefinitionsCommand.h"
// cmAddDefinitionsCommand
-bool cmAddDefinitionsCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmAddDefinitionsCommand::InitialPass(std::vector<std::string> const& args)
{
// it is OK to have no arguments
- if(argsIn.size() < 1 )
+ if(args.size() < 1 )
{
return true;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
for(std::vector<std::string>::const_iterator i = args.begin();
i != args.end(); ++i)
diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx
index 57034d4..cfae2ce 100644
--- a/Source/cmAddDependenciesCommand.cxx
+++ b/Source/cmAddDependenciesCommand.cxx
@@ -17,15 +17,13 @@
#include "cmAddDependenciesCommand.h"
// cmDependenciesCommand
-bool cmAddDependenciesCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmAddDependenciesCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 2 )
+ if(args.size() < 2 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
std::string target_name = args[0];
diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index cfae79f..09aae18 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -17,16 +17,14 @@
#include "cmAddExecutableCommand.h"
// cmExecutableCommand
-bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 2 )
+ if(args.size() < 2 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
- std::vector<std::string>::iterator s = args.begin();
+ std::vector<std::string>::const_iterator s = args.begin();
std::string exename = *s;
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index b61b6ac..cb7c2d7 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -17,15 +17,13 @@
#include "cmAddLibraryCommand.h"
// cmLibraryCommand
-bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 1 )
+ if(args.size() < 1 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
// Library type defaults to value of BUILD_SHARED_LIBS, if it exists,
// otherwise it defaults to static library.
int shared = !cmSystemTools::IsOff(m_Makefile->GetDefinition("BUILD_SHARED_LIBS"));
diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx
index 09417a1..5802779 100644
--- a/Source/cmAddTestCommand.cxx
+++ b/Source/cmAddTestCommand.cxx
@@ -32,8 +32,7 @@ bool cmAddTestCommand::InitialPass(std::vector<std::string> const& args)
// store the arguments for the final pass
// also expand any CMake variables
- m_Args.erase(m_Args.begin(), m_Args.end());
- cmSystemTools::ExpandListArguments(args, m_Args);
+ m_Args = args;
return true;
}
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 56da7d3..7116f4d 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -296,12 +296,14 @@ void cmExecuteCommand(void *arg, const char *name,
{
cmMakefile *mf = static_cast<cmMakefile *>(arg);
std::vector<std::string> args2;
- int i;
- for (i = 0; i < numArgs; ++i)
+ cmListFileFunction lff;
+ lff.m_Name = name;
+ for(int i = 0; i < numArgs; ++i)
{
- args2.push_back(args[i]);
+ // Assume all arguments are quoted.
+ lff.m_Arguments.push_back(cmListFileArgument(args[i], true));
}
- mf->ExecuteCommand(std::string(name), args2);
+ mf->ExecuteCommand(lff);
}
void cmExpandSourceListArguments(void *arg,
diff --git a/Source/cmCommand.h b/Source/cmCommand.h
index 66228da..44e95d2 100644
--- a/Source/cmCommand.h
+++ b/Source/cmCommand.h
@@ -18,7 +18,8 @@
#define cmCommand_h
#include "cmStandardIncludes.h"
-class cmMakefile;
+#include "cmListFileCache.h"
+#include "cmMakefile.h"
/** \class cmCommand
* \brief Superclass for all commands in CMake.
@@ -51,6 +52,18 @@ public:
{m_Makefile = m; }
/**
+ * This is called by the cmMakefile when the command is first
+ * encountered in the CMakeLists.txt file. It expands the command's
+ * arguments and then invokes the InitialPass.
+ */
+ virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args)
+ {
+ std::vector<std::string> expandedArguments;
+ m_Makefile->ExpandArguments(args, expandedArguments);
+ return this->InitialPass(expandedArguments);
+ }
+
+ /**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
@@ -159,13 +172,14 @@ private:
// All subclasses of cmCommand should invoke this macro.
#define cmTypeMacro(thisClass,superclass) \
+typedef superclass Superclass; \
static bool IsTypeOf(const char *type) \
{ \
if ( !strcmp(#thisClass,type) ) \
{ \
return true; \
} \
- return superclass::IsTypeOf(type); \
+ return Superclass::IsTypeOf(type); \
} \
virtual bool IsA(const char *type) \
{ \
diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx
index 5ed0f44..8de8865 100644
--- a/Source/cmCreateTestSourceList.cxx
+++ b/Source/cmCreateTestSourceList.cxx
@@ -18,18 +18,16 @@
#include "cmSourceFile.h"
// cmCreateTestSourceList
-bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& argsIn)
+bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& args)
{
- if (argsIn.size() < 3)
+ if (args.size() < 3)
{
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();
+ std::vector<std::string>::const_iterator i = args.begin();
std::string extraInclude;
std::string function;
std::vector<std::string> tests;
@@ -120,7 +118,7 @@ bool cmCreateTestSourceList::InitialPass(std::vector<std::string> const& argsIn)
"/* Forward declare test functions. */\n"
"\n";
- std::vector<std::string>::iterator testsBegin = i;
+ std::vector<std::string>::const_iterator testsBegin = i;
std::vector<std::string> tests_func_name;
// The rest of the arguments consist of a list of test source files.
diff --git a/Source/cmEndForEachCommand.cxx b/Source/cmEndForEachCommand.cxx
index 7a0dca9..f29feb9 100644
--- a/Source/cmEndForEachCommand.cxx
+++ b/Source/cmEndForEachCommand.cxx
@@ -16,7 +16,7 @@
=========================================================================*/
#include "cmEndForEachCommand.h"
-bool cmEndForEachCommand::InitialPass(std::vector<std::string> const& args)
+bool cmEndForEachCommand::InvokeInitialPass(std::vector<cmListFileArgument> const& args)
{
if(args.size() < 1 )
{
@@ -25,7 +25,10 @@ bool cmEndForEachCommand::InitialPass(std::vector<std::string> const& args)
}
// remove any function blockers for this define
- m_Makefile->RemoveFunctionBlocker("ENDFOREACH",args);
+ cmListFileFunction lff;
+ lff.m_Name = "ENDFOREACH";
+ lff.m_Arguments = args;
+ m_Makefile->RemoveFunctionBlocker(lff);
return true;
}
diff --git a/Source/cmEndForEachCommand.h b/Source/cmEndForEachCommand.h
index 101dcb3..e250177 100644
--- a/Source/cmEndForEachCommand.h
+++ b/Source/cmEndForEachCommand.h
@@ -37,10 +37,16 @@ public:
}
/**
+ * Override cmCommand::InvokeInitialPass to get arguments before
+ * expansion.
+ */
+ virtual bool InvokeInitialPass(std::vector<cmListFileArgument> const&);
+
+ /**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
- virtual bool InitialPass(std::vector<std::string> const& args);
+ virtual bool InitialPass(std::vector<std::string> const&) {}
/**
* This determines if the command gets propagated down
diff --git a/Source/cmFindFileCommand.cxx b/Source/cmFindFileCommand.cxx
index f04429e..54f4d27 100644
--- a/Source/cmFindFileCommand.cxx
+++ b/Source/cmFindFileCommand.cxx
@@ -31,12 +31,12 @@ bool cmFindFileCommand::InitialPass(std::vector<std::string> const& argsIn)
std::string helpString = "Where can the ";
helpString += argsIn[1] + " file be found";
size_t size = argsIn.size();
- std::vector<std::string> argst;
+ std::vector<std::string> args;
for(unsigned int j = 0; j < size; ++j)
{
if(argsIn[j] != "DOC")
{
- argst.push_back(argsIn[j]);
+ args.push_back(argsIn[j]);
}
else
{
@@ -47,8 +47,6 @@ bool cmFindFileCommand::InitialPass(std::vector<std::string> const& argsIn)
break;
}
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argst, args);
std::vector<std::string>::const_iterator i = args.begin();
// Use the first argument as the name of something to be defined
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index ff7bf44..70c97a4 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -27,12 +27,12 @@ bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
}
std::string helpString;
size_t size = argsIn.size();
- std::vector<std::string> argst;
+ std::vector<std::string> args;
for(unsigned int j = 0; j < size; ++j)
{
if(argsIn[j] != "DOC")
{
- argst.push_back(argsIn[j]);
+ args.push_back(argsIn[j]);
}
else
{
@@ -43,8 +43,6 @@ bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
break;
}
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argst, args);
std::vector<std::string> path;
std::vector<std::string> names;
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index e23ffad..dd7c870 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -30,13 +30,13 @@ bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
// already, if so use that value and don't look for the program
std::string helpString = "What is the path where the file ";
helpString += argsIn[1] + " can be found";
- std::vector<std::string> argst;
+ std::vector<std::string> args;
size_t size = argsIn.size();
for(unsigned int j = 0; j < size; ++j)
{
if(argsIn[j] != "DOC")
{
- argst.push_back(argsIn[j]);
+ args.push_back(argsIn[j]);
}
else
{
@@ -47,8 +47,6 @@ bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
break;
}
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argst, args);
const char* cacheValue
= m_Makefile->GetDefinition(args[0].c_str());
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 1ec03a9..84f7dab 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -30,12 +30,12 @@ bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
}
std::string doc = "Path to a program.";
size_t size = argsIn.size();
- std::vector<std::string> argst;
+ std::vector<std::string> args;
for(unsigned int j = 0; j < size; ++j)
{
if(argsIn[j] != "DOC")
{
- argst.push_back(argsIn[j]);
+ args.push_back(argsIn[j]);
}
else
{
@@ -46,9 +46,6 @@ bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
break;
}
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argst, args);
-
std::vector<std::string>::iterator i = args.begin();
// Use the first argument as the name of something to be defined
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 9c344e1..e8d1ac6 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -17,68 +17,71 @@
#include "cmForEachCommand.h"
bool cmForEachFunctionBlocker::
-IsFunctionBlocked(const char *name, const std::vector<std::string> &args,
- cmMakefile &mf)
+IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
{
- // prevent recusion and don't let this blobker blobk its own commands
+ // Prevent recusion and don't let this blobker block its own
+ // commands.
if (m_Executing)
{
return false;
}
// at end of for each execute recorded commands
- if (!strcmp(name,"ENDFOREACH") && args[0] == m_Args[0])
+ if (lff.m_Name == "ENDFOREACH")
{
- m_Executing = true;
- std::string variable = "${";
- variable += m_Args[0];
- variable += "}";
- std::vector<std::string>::const_iterator j = m_Args.begin();
- ++j;
-
- for( ; j != m_Args.end(); ++j)
- {
- // perform string replace
- for(unsigned int c = 0; c < m_Commands.size(); ++c)
- {
- std::vector<std::string> newArgs;
- for (std::vector<std::string>::const_iterator k =
- m_CommandArguments[c].begin();
- k != m_CommandArguments[c].end(); ++k)
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(lff.m_Arguments, expandedArguments);
+ if(!expandedArguments.empty() && (expandedArguments[0] == m_Args[0]))
+ {
+ m_Executing = true;
+ std::string variable = "${";
+ variable += m_Args[0];
+ variable += "}";
+ std::vector<std::string>::const_iterator j = m_Args.begin();
+ ++j;
+
+ for( ; j != m_Args.end(); ++j)
+ {
+ // Invoke all the functions that were collected in the block.
+ for(unsigned int c = 0; c < m_Functions.size(); ++c)
{
- std::string tmps = *k;
- cmSystemTools::ReplaceString(tmps, variable.c_str(),
- j->c_str());
- newArgs.push_back(tmps);
+ // Replace the loop variable and then invoke the command.
+ cmListFileFunction newLFF;
+ newLFF.m_Name = m_Functions[c].m_Name;
+ for (std::vector<cmListFileArgument>::const_iterator k =
+ m_Functions[c].m_Arguments.begin();
+ k != m_Functions[c].m_Arguments.end(); ++k)
+ {
+ std::string tmps = k->Value;
+ cmSystemTools::ReplaceString(tmps, variable.c_str(), j->c_str());
+ cmListFileArgument arg(tmps, k->Quoted);
+ newLFF.m_Arguments.push_back(arg);
+ }
+ mf.ExecuteCommand(newLFF);
}
- // execute command
- mf.ExecuteCommand(m_Commands[c],newArgs);
}
+ return false;
}
- return false;
}
// record the command
- m_Commands.push_back(name);
- std::vector<std::string> newArgs;
- for(std::vector<std::string>::const_iterator j = args.begin();
- j != args.end(); ++j)
- {
- newArgs.push_back(*j);
- }
- m_CommandArguments.push_back(newArgs);
+ m_Functions.push_back(lff);
// always return true
return true;
}
bool cmForEachFunctionBlocker::
-ShouldRemove(const char *name, const std::vector<std::string> &args,
- cmMakefile &)
+ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf)
{
- if (!strcmp(name,"ENDFOREACH") && args[0] == m_Args[0])
+ if(lff.m_Name == "ENDFOREACH")
{
- return true;
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(lff.m_Arguments, expandedArguments);
+ if(!expandedArguments.empty() && (expandedArguments[0] == m_Args[0]))
+ {
+ return true;
+ }
}
return false;
}
@@ -90,11 +93,8 @@ ScopeEnded(cmMakefile &mf)
mf.GetCurrentDirectory());
}
-bool cmForEachCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmForEachCommand::InitialPass(std::vector<std::string> const& args)
{
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
-
if(args.size() < 1)
{
this->SetError("called with incorrect number of arguments");
@@ -103,11 +103,7 @@ bool cmForEachCommand::InitialPass(std::vector<std::string> const& argsIn)
// create a function blocker
cmForEachFunctionBlocker *f = new cmForEachFunctionBlocker();
- for(std::vector<std::string>::const_iterator j = args.begin();
- j != args.end(); ++j)
- {
- f->m_Args.push_back(*j);
- }
+ f->m_Args = args;
m_Makefile->AddFunctionBlocker(f);
return true;
diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h
index 8e73d82..95911e6 100644
--- a/Source/cmForEachCommand.h
+++ b/Source/cmForEachCommand.h
@@ -20,6 +20,7 @@
#include "cmStandardIncludes.h"
#include "cmCommand.h"
#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
/** \class cmForEachFunctionBlocker
* \brief subclass of function blocker
@@ -31,19 +32,13 @@ class cmForEachFunctionBlocker : public cmFunctionBlocker
public:
cmForEachFunctionBlocker() {m_Executing = false;}
virtual ~cmForEachFunctionBlocker() {}
- virtual bool IsFunctionBlocked(const char *name,
- const std::vector<std::string> &args,
+ virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
cmMakefile &mf);
- virtual bool ShouldRemove(const char *name,
- const std::vector<std::string> &args,
- cmMakefile &mf);
+ virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf);
virtual void ScopeEnded(cmMakefile &mf);
- virtual int NeedExpandedVariables () { return 0; };
-
std::vector<std::string> m_Args;
- std::vector<std::string> m_Commands;
- std::vector<std::vector<std::string> > m_CommandArguments;
+ std::vector<cmListFileFunction> m_Functions;
bool m_Executing;
};
diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h
index 95ee945..09b80ca 100644
--- a/Source/cmFunctionBlocker.h
+++ b/Source/cmFunctionBlocker.h
@@ -31,15 +31,14 @@ public:
/**
* should a function be blocked
*/
- virtual bool IsFunctionBlocked(const char *name, const std::vector<std::string> &args,
+ virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
cmMakefile&mf) = 0;
/**
* should this function blocker be removed, useful when one function adds a
* blocker and another must remove it
*/
- virtual bool ShouldRemove(const char *,
- const std::vector<std::string>&,
+ virtual bool ShouldRemove(const cmListFileFunction& lff,
cmMakefile&) {return false;}
/**
@@ -50,8 +49,6 @@ public:
virtual void ScopeEnded(cmMakefile&) {}
virtual ~cmFunctionBlocker() {}
-
- virtual int NeedExpandedVariables () { return 1; };
};
#endif
diff --git a/Source/cmITKWrapTclCommand.cxx b/Source/cmITKWrapTclCommand.cxx
index e762ce5..c7a2cc8 100644
--- a/Source/cmITKWrapTclCommand.cxx
+++ b/Source/cmITKWrapTclCommand.cxx
@@ -59,15 +59,13 @@ cmITKWrapTclCommand::AddDependencies(cmDependInformation const *info,
}
// cmITKWrapTclCommand
-bool cmITKWrapTclCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmITKWrapTclCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 2 )
+ if(args.size() < 2 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
// keep the target name
m_TargetName = args[0];
m_Target = &m_Makefile->GetTargets()[m_TargetName.c_str()];
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 98491e9..df1b06c 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -17,9 +17,10 @@
#include "cmIfCommand.h"
bool cmIfFunctionBlocker::
-IsFunctionBlocked(const char *name, const std::vector<std::string> &args,
- cmMakefile &mf)
+IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
{
+ const char* name = lff.m_Name.c_str();
+ const std::vector<cmListFileArgument>& args = lff.m_Arguments;
// always let if statements through
if (!strcmp(name,"IF"))
{
@@ -40,7 +41,7 @@ IsFunctionBlocked(const char *name, const std::vector<std::string> &args,
}
// otherwise it must be an ENDIF statement, in that case remove the
// function blocker
- mf.RemoveFunctionBlocker("ENDIF",args);
+ mf.RemoveFunctionBlocker(lff);
return true;
}
else if(args.empty())
@@ -50,10 +51,12 @@ IsFunctionBlocked(const char *name, const std::vector<std::string> &args,
err += ". Did you mean ";
err += name;
err += "( ";
- for(std::vector<std::string>::const_iterator a = m_Args.begin();
+ for(std::vector<cmListFileArgument>::const_iterator a = m_Args.begin();
a != m_Args.end();++a)
{
- err += *a;
+ err += (a->Quoted?"\"":"");
+ err += a->Value;
+ err += (a->Quoted?"\"":"");
err += " ";
}
err += ")?";
@@ -63,13 +66,12 @@ IsFunctionBlocked(const char *name, const std::vector<std::string> &args,
return m_IsBlocking;
}
-bool cmIfFunctionBlocker::
-ShouldRemove(const char *name, const std::vector<std::string> &args,
- cmMakefile &)
+bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
+ cmMakefile&)
{
- if (!strcmp(name,"ENDIF"))
+ if (lff.m_Name == "ENDIF")
{
- if (args == m_Args)
+ if (lff.m_Arguments == m_Args)
{
return true;
}
@@ -90,19 +92,24 @@ ScopeEnded(cmMakefile &mf)
std::string errmsg = "The end of a CMakeLists file was reached with an IF statement that was not closed properly.\nWithin the directory: ";
errmsg += mf.GetCurrentDirectory();
errmsg += "\nThe arguments are: ";
- for(std::vector<std::string>::const_iterator j = m_Args.begin();
+ for(std::vector<cmListFileArgument>::const_iterator j = m_Args.begin();
j != m_Args.end(); ++j)
{
- errmsg += *j;
+ errmsg += (j->Quoted?"\"":"");
+ errmsg += j->Value;
+ errmsg += (j->Quoted?"\"":"");
errmsg += " ";
}
cmSystemTools::Error(errmsg.c_str());
}
-bool cmIfCommand::InitialPass(std::vector<std::string> const& args)
+bool cmIfCommand::InvokeInitialPass(const std::vector<cmListFileArgument>& args)
{
bool isValid;
- bool isTrue = cmIfCommand::IsTrue(args,isValid,m_Makefile);
+
+ std::vector<std::string> expandedArguments;
+ m_Makefile->ExpandArguments(args, expandedArguments);
+ bool isTrue = cmIfCommand::IsTrue(expandedArguments,isValid,m_Makefile);
if (!isValid)
{
@@ -110,7 +117,9 @@ bool cmIfCommand::InitialPass(std::vector<std::string> const& args)
unsigned int i;
for(i =0; i < args.size(); ++i)
{
- err += args[i];
+ err += (args[i].Quoted?"\"":"");
+ err += args[i].Value;
+ err += (args[i].Quoted?"\"":"");
err += " ";
}
this->SetError(err.c_str());
@@ -120,25 +129,21 @@ bool cmIfCommand::InitialPass(std::vector<std::string> const& args)
cmIfFunctionBlocker *f = new cmIfFunctionBlocker();
// if is isn't true block the commands
f->m_IsBlocking = !isTrue;
- for(std::vector<std::string>::const_iterator j = args.begin();
- j != args.end(); ++j)
- {
- f->m_Args.push_back(*j);
- }
+ f->m_Args = args;
m_Makefile->AddFunctionBlocker(f);
return true;
}
-bool cmIfCommand::IsTrue(const std::vector<std::string> &args, bool &isValid,
- const cmMakefile *makefile)
+bool cmIfCommand::IsTrue(const std::vector<std::string> &args,
+ bool &isValid, const cmMakefile *makefile)
{
// check for the different signatures
bool isTrue = true;
isValid = false;
const char *def;
const char *def2;
-
+
if(args.size() < 1 )
{
isValid = true;
diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h
index 3e30a4e..152fcc2 100644
--- a/Source/cmIfCommand.h
+++ b/Source/cmIfCommand.h
@@ -31,15 +31,13 @@ class cmIfFunctionBlocker : public cmFunctionBlocker
public:
cmIfFunctionBlocker() {}
virtual ~cmIfFunctionBlocker() {}
- virtual bool IsFunctionBlocked(const char *name,
- const std::vector<std::string> &args,
+ virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
cmMakefile &mf);
- virtual bool ShouldRemove(const char *name,
- const std::vector<std::string> &args,
+ virtual bool ShouldRemove(const cmListFileFunction& lff,
cmMakefile &mf);
virtual void ScopeEnded(cmMakefile &mf);
- std::vector<std::string> m_Args;
+ std::vector<cmListFileArgument> m_Args;
bool m_IsBlocking;
};
@@ -60,10 +58,16 @@ public:
}
/**
+ * This overrides the default InvokeInitialPass implementation.
+ * It records the arguments before expansion.
+ */
+ virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args);
+
+ /**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
- virtual bool InitialPass(std::vector<std::string> const& args);
+ virtual bool InitialPass(std::vector<std::string> const& args) { return false; }
/**
* The name of the command as specified in CMakeList.txt.
diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx
index 6d2d5d3..48bede4 100644
--- a/Source/cmIncludeDirectoryCommand.cxx
+++ b/Source/cmIncludeDirectoryCommand.cxx
@@ -17,14 +17,12 @@
#include "cmIncludeDirectoryCommand.h"
// cmIncludeDirectoryCommand
-bool cmIncludeDirectoryCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmIncludeDirectoryCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 1 )
+ if(args.size() < 1 )
{
return true;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
std::vector<std::string>::const_iterator i = args.begin();
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
index 396742d..00dffd2 100644
--- a/Source/cmInstallProgramsCommand.cxx
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -17,15 +17,13 @@
#include "cmInstallProgramsCommand.h"
// cmExecutableCommand
-bool cmInstallProgramsCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmInstallProgramsCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 2)
+ if(args.size() < 2)
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
// Create an INSTALL_PROGRAMS target specifically for this path.
m_TargetName = "INSTALL_PROGRAMS_"+args[0];
diff --git a/Source/cmInstallTargetsCommand.cxx b/Source/cmInstallTargetsCommand.cxx
index a01fd86..1553754 100644
--- a/Source/cmInstallTargetsCommand.cxx
+++ b/Source/cmInstallTargetsCommand.cxx
@@ -17,15 +17,13 @@
#include "cmInstallTargetsCommand.h"
// cmExecutableCommand
-bool cmInstallTargetsCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmInstallTargetsCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 2 )
+ if(args.size() < 2 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
cmTargets &tgts = m_Makefile->GetTargets();
std::vector<std::string>::const_iterator s = args.begin();
diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx
index 717c71f..67994f7 100644
--- a/Source/cmLinkDirectoriesCommand.cxx
+++ b/Source/cmLinkDirectoriesCommand.cxx
@@ -17,14 +17,12 @@
#include "cmLinkDirectoriesCommand.h"
// cmLinkDirectoriesCommand
-bool cmLinkDirectoriesCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmLinkDirectoriesCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 1 )
+ if(args.size() < 1 )
{
return true;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
for(std::vector<std::string>::const_iterator i = args.begin();
i != args.end(); ++i)
diff --git a/Source/cmLinkLibrariesCommand.cxx b/Source/cmLinkLibrariesCommand.cxx
index 35b1ec3..d45f246 100644
--- a/Source/cmLinkLibrariesCommand.cxx
+++ b/Source/cmLinkLibrariesCommand.cxx
@@ -17,14 +17,12 @@
#include "cmLinkLibrariesCommand.h"
// cmLinkLibrariesCommand
-bool cmLinkLibrariesCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmLinkLibrariesCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 1 )
+ if(args.size() < 1 )
{
return true;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
// add libraries, nothe that there is an optional prefix
// of debug and optimized than can be used
for(std::vector<std::string>::const_iterator i = args.begin();
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 0893cf6..fce13db 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -16,7 +16,7 @@
=========================================================================*/
#include "cmListFileCache.h"
#include "cmSystemTools.h"
-
+#include "cmRegularExpression.h"
cmListFileCache* cmListFileCache::Instance = 0;
@@ -89,17 +89,17 @@ bool cmListFileCache::CacheFile(const char* path, bool requireProjectCommand)
cmSystemTools::Error("cmListFileCache: error can not open file ", path);
return false;
}
+ long line=0;
cmListFile inFile;
inFile.m_ModifiedTime = cmSystemTools::ModifiedTime(path);
bool parseError;
while ( fin )
{
cmListFileFunction inFunction;
- if(cmSystemTools::ParseFunction(fin,
- inFunction.m_Name,
- inFunction.m_Arguments,
- path, parseError))
+ if(cmListFileCache::ParseFunction(fin, inFunction, path, parseError,
+ &line))
{
+ inFunction.m_FilePath = path;
inFile.m_Functions.push_back(inFunction);
}
if (parseError)
@@ -126,7 +126,8 @@ bool cmListFileCache::CacheFile(const char* path, bool requireProjectCommand)
{
cmListFileFunction project;
project.m_Name = "PROJECT";
- project.m_Arguments.push_back("Project");
+ cmListFileArgument prj("Project", false);
+ project.m_Arguments.push_back(prj);
inFile.m_Functions.insert(inFile.m_Functions.begin(),project);
}
}
@@ -143,3 +144,179 @@ void cmListFileCache::FlushCache(const char* path)
return;
}
}
+
+inline void RemoveComments(char* ptr)
+{
+ while(*ptr)
+ {
+ if(*ptr == '#')
+ {
+ *ptr = 0;
+ break;
+ }
+ ++ptr;
+ }
+}
+
+bool cmListFileCache::ParseFunction(std::ifstream& fin,
+ cmListFileFunction& function,
+ const char* filename,
+ bool& parseError,
+ long* line)
+{
+ parseError = false;
+ std::string& name = function.m_Name;
+ std::vector<cmListFileArgument>& arguments = function.m_Arguments;
+ name = "";
+ arguments = std::vector<cmListFileArgument>();
+ const int BUFFER_SIZE = 4096;
+ char inbuffer[BUFFER_SIZE];
+ if(!fin)
+ {
+ return false;
+ }
+ if(fin.getline(inbuffer, BUFFER_SIZE ) )
+ {
+ if(line) { ++*line; }
+ RemoveComments(inbuffer);
+ cmRegularExpression blankLine("^[ \t\r]*$");
+ cmRegularExpression oneLiner("^[ \t]*([A-Za-z_0-9]*)[ \t]*\\((.*)\\)[ \t\r]*$");
+ cmRegularExpression multiLine("^[ \t]*([A-Za-z_0-9]*)[ \t]*\\((.*)$");
+ cmRegularExpression lastLine("^(.*)\\)[ \t\r]*$");
+
+ // check for blank line or comment
+ if(blankLine.find(inbuffer) )
+ {
+ return false;
+ }
+ // look for a oneline fun(arg arg2)
+ else if(oneLiner.find(inbuffer))
+ {
+ // the arguments are the second match
+ std::string args = oneLiner.match(2);
+ name = oneLiner.match(1);
+ // break up the arguments
+ cmListFileCache::GetArguments(args, arguments);
+ if(line)
+ {
+ function.m_Line = *line;
+ }
+ return true;
+ }
+ // look for a start of a multiline with no trailing ")" fun(arg arg2
+ else if(multiLine.find(inbuffer))
+ {
+ name = multiLine.match(1);
+ std::string args = multiLine.match(2);
+ cmListFileCache::GetArguments(args, arguments);
+ if(line)
+ {
+ function.m_Line = *line;
+ }
+ // Read lines until the closing paren is hit
+ bool done = false;
+ while(!done)
+ {
+ // read lines until the end paren is found
+ if(fin.getline(inbuffer, BUFFER_SIZE ) )
+ {
+ ++line;
+ RemoveComments(inbuffer);
+ // Check for comment lines and ignore them.
+ if(blankLine.find(inbuffer))
+ { continue; }
+ // Is this the last line?
+ if(lastLine.find(inbuffer))
+ {
+ done = true;
+ std::string gargs = lastLine.match(1);
+ cmListFileCache::GetArguments(gargs, arguments);
+ }
+ else
+ {
+ std::string line = inbuffer;
+ cmListFileCache::GetArguments(line, arguments);
+ }
+ }
+ else
+ {
+ parseError = true;
+ cmSystemTools::Error("Parse error in read function missing end )\nIn File: ",
+ filename, "\nCurrent line:", inbuffer);
+ return false;
+ }
+ }
+ return true;
+ }
+ else
+ {
+ parseError = true;
+ cmSystemTools::Error("Parse error in read function\nIn file:",
+ filename, "\nCurrent line:", inbuffer);
+ return false;
+ }
+ }
+ return false;
+
+}
+
+void cmListFileCache::GetArguments(std::string& line,
+ std::vector<cmListFileArgument>& arguments)
+{
+ // Match a normal argument (not quoted, no spaces).
+ cmRegularExpression normalArgument("[ \t]*(([^ \t\r\\]|[\\].)+)[ \t\r]*");
+ // Match a quoted argument (surrounded by double quotes, spaces allowed).
+ cmRegularExpression quotedArgument("[ \t]*(\"([^\"\\]|[\\].)*\")[ \t\r]*");
+
+ bool done = false;
+ while(!done)
+ {
+ std::string arg;
+ std::string::size_type endpos=0;
+ bool quoted = false;
+ bool foundQuoted = quotedArgument.find(line.c_str());
+ bool foundNormal = normalArgument.find(line.c_str());
+
+ if(foundQuoted && foundNormal)
+ {
+ // Both matches were found. Take the earlier one.
+ // Favor double-quoted version if there is a tie.
+ if(normalArgument.start(1) < quotedArgument.start(1))
+ {
+ arg = normalArgument.match(1);
+ endpos = normalArgument.end(1);
+ }
+ else
+ {
+ arg = quotedArgument.match(1);
+ endpos = quotedArgument.end(1);
+ // Strip off the double quotes on the ends.
+ arg = arg.substr(1, arg.length()-2);
+ quoted = true;
+ }
+ }
+ else if(foundQuoted)
+ {
+ arg = quotedArgument.match(1);
+ endpos = quotedArgument.end(1);
+ // Strip off the double quotes on the ends.
+ arg = arg.substr(1, arg.length()-2);
+ quoted = true;
+ }
+ else if(foundNormal)
+ {
+ arg = normalArgument.match(1);
+ endpos = normalArgument.end(1);
+ }
+ else
+ {
+ done = true;
+ }
+ if(!done)
+ {
+ cmListFileArgument a(cmSystemTools::RemoveEscapes(arg.c_str()), quoted);
+ arguments.push_back(a);
+ line = line.substr(endpos, line.length() - endpos);
+ }
+ }
+}
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 2520eca..9dc8073 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -26,10 +26,25 @@
* cmake list files.
*/
+struct cmListFileArgument
+{
+ cmListFileArgument(): Value(), Quoted(false) {}
+ cmListFileArgument(const cmListFileArgument& r): Value(r.Value), Quoted(r.Quoted) {}
+ cmListFileArgument(const std::string& v, bool q): Value(v), Quoted(q) {}
+ bool operator == (const cmListFileArgument& r) const
+ {
+ return (this->Value == r.Value) && (this->Quoted == r.Quoted);
+ }
+ std::string Value;
+ bool Quoted;
+};
+
struct cmListFileFunction
{
std::string m_Name;
- std::vector<std::string> m_Arguments;
+ std::vector<cmListFileArgument> m_Arguments;
+ std::string m_FilePath;
+ long m_Line;
};
struct cmListFile
@@ -60,7 +75,25 @@ public:
//! Flush cache file out of cache.
void FlushCache(const char* path);
+
+ /**
+ * Read a CMake command (or function) from an input file. This
+ * returns the name of the function and a list of its
+ * arguments. The last argument is the name of the file that
+ * the ifstream points to, and is used for debug info only.
+ */
+ static bool ParseFunction(std::ifstream&, cmListFileFunction& function,
+ const char* filename, bool& parseError,
+ long* line = 0);
+ /**
+ * Extract white-space separated arguments from a string.
+ * Double quoted strings are accepted with spaces.
+ * This is called by ParseFunction.
+ */
+ static void GetArguments(std::string& line,
+ std::vector<cmListFileArgument>& arguments);
+
private:
// Cache the file
bool CacheFile(const char* path, bool requireProjectCommand);
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
index 0ec5cab..ef3fe26 100644
--- a/Source/cmLoadCacheCommand.cxx
+++ b/Source/cmLoadCacheCommand.cxx
@@ -18,14 +18,12 @@
// cmLoadCacheCommand
-bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& args)
{
- if (argsIn.size()< 1)
+ if (args.size()< 1)
{
this->SetError("called with wrong number of arguments.");
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
if(args.size() >= 2 && args[1] == "READ_WITH_PREFIX")
{
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index d5a2f3a..b307148 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -166,18 +166,16 @@ cmLoadedCommand::~cmLoadedCommand()
}
// cmLoadCommandCommand
-bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 1 )
+ if(args.size() < 1 )
{
return true;
}
// the file must exist
std::string fullPath = cmDynamicLoader::LibPrefix();
- fullPath += "cm" + argsIn[0] + cmDynamicLoader::LibExtension();
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
+ fullPath += "cm" + args[0] + cmDynamicLoader::LibExtension();
// search for the file
std::vector<std::string> path;
@@ -197,7 +195,7 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& argsIn)
{
fullPath = "Attempt to load command failed from file : ";
fullPath += cmDynamicLoader::LibPrefix();
- fullPath += "cm" + argsIn[0] + cmDynamicLoader::LibExtension();
+ fullPath += "cm" + args[0] + cmDynamicLoader::LibExtension();
this->SetError(fullPath.c_str());
return false;
}
diff --git a/Source/cmLocalUnixMakefileGenerator.cxx b/Source/cmLocalUnixMakefileGenerator.cxx
index 5e72e0f..5092045 100644
--- a/Source/cmLocalUnixMakefileGenerator.cxx
+++ b/Source/cmLocalUnixMakefileGenerator.cxx
@@ -812,7 +812,7 @@ void cmLocalUnixMakefileGenerator::OutputLibraryRule(std::ostream& fout,
// expand multi-command semi-colon separated lists
// of commands into separate commands
std::vector<std::string> commands;
- cmSystemTools::ExpandListArguments(rules, commands);
+ cmSystemTools::ExpandList(rules, commands);
// collect custom commands for this target and add them to the list
std::string customCommands = this->CreateTargetRules(t, name);
if(customCommands.size() > 0)
@@ -986,7 +986,7 @@ void cmLocalUnixMakefileGenerator::OutputExecutableRule(std::ostream& fout,
std::string comment = "executable";
std::vector<std::string> commands;
- cmSystemTools::ExpandListArguments(rules, commands);
+ cmSystemTools::ExpandList(rules, commands);
std::string customCommands = this->CreateTargetRules(t, name);
if(customCommands.size() > 0)
{
@@ -2339,7 +2339,7 @@ OutputBuildObjectFromSource(std::ostream& fout,
// expand multi-command semi-colon separated lists
// of commands into separate commands
std::vector<std::string> commands;
- cmSystemTools::ExpandListArguments(rules, commands);
+ cmSystemTools::ExpandList(rules, commands);
for(std::vector<std::string>::iterator i = commands.begin();
i != commands.end(); ++i)
{
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 2cdcb09..58871a2 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -17,66 +17,67 @@
#include "cmMacroCommand.h"
bool cmMacroFunctionBlocker::
-IsFunctionBlocked(const char *name, const std::vector<std::string> &args,
- cmMakefile &mf)
+IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
{
// record commands until we hit the ENDMACRO
// at the ENDMACRO call we shift gears and start looking for invocations
- if (!strcmp(name,"ENDMACRO") && args[0] == m_Args[0])
+ if(lff.m_Name == "ENDMACRO")
{
- m_Executing = true;
- return true;
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(lff.m_Arguments, expandedArguments);
+ if(!expandedArguments.empty() && (expandedArguments[0] == m_Args[0]))
+ {
+ m_Executing = true;
+ return true;
+ }
}
if (!m_Executing)
{
// if it wasn't an endmacro and we are not executing then we must be
// recording
- m_Commands.push_back(name);
- std::vector<std::string> newArgs;
- for(std::vector<std::string>::const_iterator j = args.begin();
- j != args.end(); ++j)
- {
- newArgs.push_back(*j);
- }
- m_CommandArguments.push_back(newArgs);
+ m_Functions.push_back(lff);
return true;
}
// otherwise the macro has been recorded and we are executing
// so we look for macro invocations
- if (!strcmp(name,m_Args[0].c_str()))
+ if(lff.m_Name == m_Args[0])
{
+ // Expand the argument list to the macro.
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(lff.m_Arguments, expandedArguments);
// make sure the number of arguments matches
- if (args.size() != m_Args.size() - 1)
+ if (expandedArguments.size() != m_Args.size() - 1)
{
cmSystemTools::Error("A macro was invoked without the correct number of arguments. The macro name was: ", m_Args[0].c_str());
}
- // for each recorded command
- for(unsigned int c = 0; c < m_Commands.size(); ++c)
+
+ // Invoke all the functions that were collected in the block.
+ for(unsigned int c = 0; c < m_Functions.size(); ++c)
{
- // perform argument replacement
- std::vector<std::string> newArgs;
- // for each argument of this command
- for (std::vector<std::string>::const_iterator k =
- m_CommandArguments[c].begin();
- k != m_CommandArguments[c].end(); ++k)
+ // Replace the formal arguments and then invoke the command.
+ cmListFileFunction newLFF;
+ newLFF.m_Name = m_Functions[c].m_Name;
+ for (std::vector<cmListFileArgument>::const_iterator k =
+ m_Functions[c].m_Arguments.begin();
+ k != m_Functions[c].m_Arguments.end(); ++k)
{
- // replace any matches with the formal arguments
- std::string tmps = *k;
- // for each formal macro argument
+ std::string tmps = k->Value;
for (unsigned int j = 1; j < m_Args.size(); ++j)
{
std::string variable = "${";
variable += m_Args[j];
variable += "}";
cmSystemTools::ReplaceString(tmps, variable.c_str(),
- args[j-1].c_str());
+ expandedArguments[j-1].c_str());
}
- newArgs.push_back(tmps);
+ cmListFileArgument arg(tmps, k->Quoted);
+ newLFF.m_Arguments.push_back(arg);
+ newLFF.m_FilePath = m_Functions[c].m_FilePath;
+ newLFF.m_Line = m_Functions[c].m_Line;
}
- // execute command
- mf.ExecuteCommand(m_Commands[c],newArgs);
+ mf.ExecuteCommand(newLFF);
}
return true;
}
@@ -86,8 +87,7 @@ IsFunctionBlocked(const char *name, const std::vector<std::string> &args,
}
bool cmMacroFunctionBlocker::
-ShouldRemove(const char *, const std::vector<std::string> &,
- cmMakefile &)
+ShouldRemove(const cmListFileFunction&, cmMakefile &)
{
return false;
}
@@ -98,11 +98,8 @@ ScopeEnded(cmMakefile &)
// macros never leave scope
}
-bool cmMacroCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmMacroCommand::InitialPass(std::vector<std::string> const& args)
{
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
-
if(args.size() < 1)
{
this->SetError("called with incorrect number of arguments");
diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h
index 0705be7..e090ec7 100644
--- a/Source/cmMacroCommand.h
+++ b/Source/cmMacroCommand.h
@@ -31,19 +31,12 @@ class cmMacroFunctionBlocker : public cmFunctionBlocker
public:
cmMacroFunctionBlocker() {m_Executing = false;}
virtual ~cmMacroFunctionBlocker() {}
- virtual bool IsFunctionBlocked(const char *name,
- const std::vector<std::string> &args,
- cmMakefile &mf);
- virtual bool ShouldRemove(const char *name,
- const std::vector<std::string> &args,
- cmMakefile &mf);
+ virtual bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile &mf);
+ virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf);
virtual void ScopeEnded(cmMakefile &mf);
- virtual int NeedExpandedVariables () { return 0; };
-
std::vector<std::string> m_Args;
- std::vector<std::string> m_Commands;
- std::vector<std::vector<std::string> > m_CommandArguments;
+ std::vector<cmListFileFunction> m_Functions;
bool m_Executing;
};
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 9c5dc9f..db4a1ba 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -157,14 +157,14 @@ bool cmMakefile::CommandExists(const char* name) const
return m_LocalGenerator->GetGlobalGenerator()->GetCMakeInstance()->CommandExists(name);
}
-void cmMakefile::ExecuteCommand(std::string const &name,
- std::vector<std::string> const& arguments)
+void cmMakefile::ExecuteCommand(const cmListFileFunction& lff)
{
// quick return if blocked
- if(this->IsFunctionBlocked(name.c_str(), arguments))
+ if(this->IsFunctionBlocked(lff))
{
return;
}
+ std::string name = lff.m_Name;
// execute the command
cmCommand *rm =
m_LocalGenerator->GetGlobalGenerator()->GetCMakeInstance()->GetCommand(name.c_str());
@@ -179,27 +179,13 @@ void cmMakefile::ExecuteCommand(std::string const &name,
// if the command is inherited then InitialPass it.
if(!m_Inheriting || usedCommand->IsInherited())
{
- std::vector<std::string> expandedArguments;
- for(std::vector<std::string>::const_iterator i = arguments.begin();
- i != arguments.end(); ++i)
+ if(!usedCommand->InvokeInitialPass(lff.m_Arguments))
{
- std::string tmps = *i;
- this->ExpandVariablesInString(tmps);
- if (tmps.find_first_not_of(" ") != std::string::npos)
- {
- // we found something in the args
- expandedArguments.push_back(tmps);
- }
- }
- if(!usedCommand->InitialPass(expandedArguments))
- {
- std::string error;
- error = usedCommand->GetName();
- error += ": Error : \n";
- error += usedCommand->GetError();
- error += " from CMakeLists.txt file in directory: ";
- error += m_cmCurrentDirectory;
- cmSystemTools::Error(error.c_str());
+ cmOStringStream error;
+ error << "Error in cmake code at\n"
+ << lff.m_FilePath << ":" << lff.m_Line << ":\n"
+ << usedCommand->GetError();
+ cmSystemTools::Error(error.str().c_str());
}
else
{
@@ -216,18 +202,13 @@ void cmMakefile::ExecuteCommand(std::string const &name,
delete usedCommand;
}
}
- else if((name == "CABLE_WRAP_TCL") || (name == "CABLE_CLASS_SET") ||
- (name == "CONFIGURE_GCCXML"))
- {
- cmSystemTools::Error("The command ", name.c_str(),
- " is not implemented in this version of CMake.\n"
- "Contact cable@public.kitware.com for more information.");
- }
else
{
- cmSystemTools::Error("unknown CMake command:", name.c_str(),
- "\nReading cmake file in directory:" ,
- m_cmCurrentDirectory.c_str());
+ cmOStringStream error;
+ error << "Error in cmake code at\n"
+ << lff.m_FilePath << ":" << lff.m_Line << ":\n"
+ << "Unknown CMake command \"" << lff.m_Name.c_str() << "\".";
+ cmSystemTools::Error(error.str().c_str());
}
}
@@ -335,9 +316,7 @@ bool cmMakefile::ReadListFile(const char* filename, const char* external)
const size_t numberFunctions = lf->m_Functions.size();
for(size_t i =0; i < numberFunctions; ++i)
{
- cmListFileFunction& curFunction = lf->m_Functions[i];
- this->ExecuteCommand(curFunction.m_Name,
- curFunction.m_Arguments);
+ this->ExecuteCommand(lf->m_Functions[i]);
}
// send scope ended to and funciton blockers
@@ -1161,8 +1140,7 @@ cmMakefile::FindSourceGroup(const char* source,
return groups.front();
}
-bool cmMakefile::IsFunctionBlocked(const char *name,
- std::vector<std::string> const&args)
+bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff)
{
// if there are no blockers get out of here
if (m_FunctionBlockers.begin() == m_FunctionBlockers.end())
@@ -1171,51 +1149,52 @@ bool cmMakefile::IsFunctionBlocked(const char *name,
}
// loop over all function blockers to see if any block this command
- std::vector<std::string> expandedArguments;
- for(std::vector<std::string>::const_iterator i = args.begin();
- i != args.end(); ++i)
- {
- std::string tmps = *i;
- this->ExpandVariablesInString(tmps);
- if (tmps.find_first_not_of(" ") != std::string::npos)
- {
- // we found something in the args
- expandedArguments.push_back(tmps);
- }
- }
// evaluate in reverse, this is critical for balanced IF statements etc
std::list<cmFunctionBlocker *>::reverse_iterator pos;
for (pos = m_FunctionBlockers.rbegin();
pos != m_FunctionBlockers.rend(); ++pos)
{
- if ((*pos)->NeedExpandedVariables())
+ if((*pos)->IsFunctionBlocked(lff, *this))
{
- if ((*pos)->IsFunctionBlocked(name, expandedArguments, *this))
- {
- return true;
- }
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void cmMakefile::ExpandArguments(
+ std::vector<cmListFileArgument> const& inArgs,
+ std::vector<std::string>& outArgs)
+{
+ std::vector<cmListFileArgument>::const_iterator i;
+ for(i = inArgs.begin(); i != inArgs.end(); ++i)
+ {
+ // Expand the variables in the argument.
+ std::string value = i->Value;
+ this->ExpandVariablesInString(value);
+
+ // If the argument is quoted, it should be one argument.
+ // Otherwise, it may be a list of arguments.
+ if(i->Quoted)
+ {
+ outArgs.push_back(value);
}
else
{
- if ((*pos)->IsFunctionBlocked(name, args, *this))
- {
- return true;
- }
+ cmSystemTools::ExpandListArgument(value, outArgs);
}
}
-
- return false;
}
-void cmMakefile::RemoveFunctionBlocker(const char *name,
- const std::vector<std::string> &args)
+void cmMakefile::RemoveFunctionBlocker(const cmListFileFunction& lff)
{
// loop over all function blockers to see if any block this command
std::list<cmFunctionBlocker *>::reverse_iterator pos;
for (pos = m_FunctionBlockers.rbegin();
pos != m_FunctionBlockers.rend(); ++pos)
{
- if ((*pos)->ShouldRemove(name, args, *this))
+ if ((*pos)->ShouldRemove(lff, *this))
{
cmFunctionBlocker* b = *pos;
m_FunctionBlockers.remove(b);
@@ -1348,7 +1327,6 @@ void cmMakefile::ExpandSourceListArguments(
}
// now expand the args
- std::vector<std::string> tmpArgs;
unsigned int i;
for(i = 0; i < arguments.size(); ++i)
{
@@ -1356,14 +1334,16 @@ void cmMakefile::ExpandSourceListArguments(
const char *def = this->GetDefinition(arguments[i].c_str());
if (def && oldVersion && i >= start)
{
- tmpArgs.push_back(def);
+ // Definition lookup could result in a list that needs to be
+ // expanded.
+ cmSystemTools::ExpandListArgument(def, newargs);
}
else
{
- tmpArgs.push_back(arguments[i]);
+ // List expansion will have been done already.
+ newargs.push_back(arguments[i]);
}
}
- cmSystemTools::ExpandListArguments(tmpArgs, newargs);
}
int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index dbb62af..de8e3eb 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -22,6 +22,7 @@
#include "cmSystemTools.h"
#include "cmSourceGroup.h"
#include "cmTarget.h"
+#include "cmListFileCache.h"
#include "cmCacheManager.h"
class cmFunctionBlocker;
@@ -77,7 +78,7 @@ public:
{ m_FunctionBlockers.push_back(fb);}
void RemoveFunctionBlocker(cmFunctionBlocker *fb)
{ m_FunctionBlockers.remove(fb);}
- void RemoveFunctionBlocker(const char *name, const std::vector<std::string> &args);
+ void RemoveFunctionBlocker(const cmListFileFunction& lff);
/**
* Try running cmake and building a file. This is used for dynalically
@@ -511,7 +512,7 @@ public:
/**
* execute a single CMake command
*/
- void ExecuteCommand(std::string const &name, std::vector<std::string> const& args);
+ void ExecuteCommand(const cmListFileFunction& lff);
/** Check if a command exists. */
bool CommandExists(const char* name) const;
@@ -535,6 +536,13 @@ public:
///! Display progress or status message.
void DisplayStatus(const char*, float);
+
+ /**
+ * Expand the given list file arguments into the full set after
+ * variable replacement and list expansion.
+ */
+ void ExpandArguments(std::vector<cmListFileArgument> const& inArgs,
+ std::vector<std::string>& outArgs);
protected:
// add link libraries and directories to the target
void AddGlobalLinkInformation(const char* name, cmTarget& target);
@@ -581,7 +589,7 @@ protected:
DefinitionMap m_Definitions;
std::vector<cmCommand*> m_UsedCommands;
cmLocalGenerator* m_LocalGenerator;
- bool IsFunctionBlocked(const char *name, std::vector<std::string> const& args);
+ bool IsFunctionBlocked(const cmListFileFunction& lff);
private:
/**
diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx
index b50202a..3195387 100644
--- a/Source/cmMarkAsAdvancedCommand.cxx
+++ b/Source/cmMarkAsAdvancedCommand.cxx
@@ -17,15 +17,13 @@
#include "cmMarkAsAdvancedCommand.h"
// cmMarkAsAdvancedCommand
-bool cmMarkAsAdvancedCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmMarkAsAdvancedCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 1 )
+ if(args.size() < 1 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
unsigned int i =0;
const char* value = "1";
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 45c6dc9..c6e8e16 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -17,15 +17,13 @@
#include "cmMessageCommand.h"
// cmLibraryCommand
-bool cmMessageCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmMessageCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 1 )
+ if(args.size() < 1 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
std::string message;
std::vector<std::string>::const_iterator i = args.begin();
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index a9ec7ba..8f48fd6 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -17,15 +17,13 @@
#include "cmProjectCommand.h"
// cmProjectCommand
-bool cmProjectCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmProjectCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 1 )
+ if(args.size() < 1 )
{
this->SetError("PROJECT called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
m_Makefile->SetProjectName(args[0].c_str());
std::string bindir = args[0];
diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx
index 136b973..44c33d4 100644
--- a/Source/cmRemoveCommand.cxx
+++ b/Source/cmRemoveCommand.cxx
@@ -37,19 +37,17 @@ bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args)
// expand the variable
std::vector<std::string> varArgsExpanded;
- std::vector<std::string> temp;
- temp.push_back(std::string(cacheValue));
- cmSystemTools::ExpandListArguments(temp, varArgsExpanded);
+ cmSystemTools::ExpandListArgument(cacheValue, varArgsExpanded);
// expand the args
// check for REMOVE(VAR v1 v2 ... vn)
std::vector<std::string> argsExpanded;
- std::vector<std::string> temp2;
+ std::vector<std::string> temp;
for(unsigned int j = 1; j < args.size(); ++j)
{
- temp2.push_back(args[j]);
+ temp.push_back(args[j]);
}
- cmSystemTools::ExpandListArguments(temp2, argsExpanded);
+ cmSystemTools::ExpandList(temp, argsExpanded);
// now create the new value
std::string value;
diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx
index 64f6a25..3933321 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.cxx
+++ b/Source/cmSetSourceFilesPropertiesCommand.cxx
@@ -18,15 +18,13 @@
// cmSetSourceFilesPropertiesCommand
bool cmSetSourceFilesPropertiesCommand::InitialPass(
- std::vector<std::string> const& argsIn)
+ std::vector<std::string> const& args)
{
- if(argsIn.size() < 2 )
+ if(args.size() < 2 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
// first collect up the list of files
std::vector<std::string> propertyPairs;
diff --git a/Source/cmSourceFilesCommand.cxx b/Source/cmSourceFilesCommand.cxx
index 8fe4e1c..fc1171c 100644
--- a/Source/cmSourceFilesCommand.cxx
+++ b/Source/cmSourceFilesCommand.cxx
@@ -17,7 +17,7 @@
#include "cmSourceFilesCommand.h"
// cmSourceFilesCommand
-bool cmSourceFilesCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmSourceFilesCommand::InitialPass(std::vector<std::string> const& args)
{
const char* versionValue
= m_Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
@@ -27,13 +27,11 @@ bool cmSourceFilesCommand::InitialPass(std::vector<std::string> const& argsIn)
return false;
}
- if(argsIn.size() < 1 )
+ if(args.size() < 1 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
std::string sourceListValue;
// was the list already populated
diff --git a/Source/cmSourceFilesRemoveCommand.cxx b/Source/cmSourceFilesRemoveCommand.cxx
index cff9ffb..7fb9b7a 100644
--- a/Source/cmSourceFilesRemoveCommand.cxx
+++ b/Source/cmSourceFilesRemoveCommand.cxx
@@ -40,19 +40,17 @@ bool cmSourceFilesRemoveCommand::InitialPass(std::vector<std::string> const& arg
// expand the variable
std::vector<std::string> varArgsExpanded;
- std::vector<std::string> temp;
- temp.push_back(std::string(cacheValue));
- cmSystemTools::ExpandListArguments(temp, varArgsExpanded);
+ cmSystemTools::ExpandListArgument(cacheValue, varArgsExpanded);
// expand the args
// check for REMOVE(VAR v1 v2 ... vn)
std::vector<std::string> argsExpanded;
- std::vector<std::string> temp2;
+ std::vector<std::string> temp;
for(unsigned int j = 1; j < args.size(); ++j)
{
- temp2.push_back(args[j]);
+ temp.push_back(args[j]);
}
- cmSystemTools::ExpandListArguments(temp2, argsExpanded);
+ cmSystemTools::ExpandList(temp, argsExpanded);
// now create the new value
std::string value;
diff --git a/Source/cmSubdirCommand.cxx b/Source/cmSubdirCommand.cxx
index 10bb916..7fcf814 100644
--- a/Source/cmSubdirCommand.cxx
+++ b/Source/cmSubdirCommand.cxx
@@ -17,15 +17,13 @@
#include "cmSubdirCommand.h"
// cmSubdirCommand
-bool cmSubdirCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmSubdirCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 1 )
+ if(args.size() < 1 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
bool res = true;
for(std::vector<std::string>::const_iterator i = args.begin();
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index ff27805..28163a8 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -843,168 +843,6 @@ std::string cmSystemTools::ConvertToWindowsOutputPath(const char* path)
return ret;
}
-inline void RemoveComments(char* ptr)
-{
- while(*ptr)
- {
- if(*ptr == '#')
- {
- *ptr = 0;
- break;
- }
- ++ptr;
- }
-}
-
-bool cmSystemTools::ParseFunction(std::ifstream& fin,
- std::string& name,
- std::vector<std::string>& arguments,
- const char* filename,
- bool& parseError)
-{
- parseError = false;
- name = "";
- arguments = std::vector<std::string>();
- const int BUFFER_SIZE = 4096;
- char inbuffer[BUFFER_SIZE];
- if(!fin)
- {
- return false;
- }
- if(fin.getline(inbuffer, BUFFER_SIZE ) )
- {
- RemoveComments(inbuffer);
- cmRegularExpression blankLine("^[ \t\r]*$");
-// cmRegularExpression comment("^[ \t]*#.*$");
- cmRegularExpression oneLiner("^[ \t]*([A-Za-z_0-9]*)[ \t]*\\((.*)\\)[ \t\r]*$");
- cmRegularExpression multiLine("^[ \t]*([A-Za-z_0-9]*)[ \t]*\\((.*)$");
- cmRegularExpression lastLine("^(.*)\\)[ \t\r]*$");
-
- // check for blank line or comment
- if(blankLine.find(inbuffer) )
- {
- return false;
- }
- // look for a oneline fun(arg arg2)
- else if(oneLiner.find(inbuffer))
- {
- // the arguments are the second match
- std::string args = oneLiner.match(2);
- name = oneLiner.match(1);
- // break up the arguments
- cmSystemTools::GetArguments(args, arguments);
- return true;
- }
- // look for a start of a multiline with no trailing ")" fun(arg arg2
- else if(multiLine.find(inbuffer))
- {
- name = multiLine.match(1);
- std::string args = multiLine.match(2);
- cmSystemTools::GetArguments(args, arguments);
- // Read lines until the closing paren is hit
- bool done = false;
- while(!done)
- {
- // read lines until the end paren is found
- if(fin.getline(inbuffer, BUFFER_SIZE ) )
- {
- RemoveComments(inbuffer);
- // Check for comment lines and ignore them.
- if(blankLine.find(inbuffer))
- { continue; }
- // Is this the last line?
- if(lastLine.find(inbuffer))
- {
- done = true;
- std::string gargs = lastLine.match(1);
- cmSystemTools::GetArguments(gargs, arguments);
- }
- else
- {
- std::string line = inbuffer;
- cmSystemTools::GetArguments(line, arguments);
- }
- }
- else
- {
- parseError = true;
- cmSystemTools::Error("Parse error in read function missing end )\nIn File: ",
- filename, "\nCurrent line:", inbuffer);
- return false;
- }
- }
- return true;
- }
- else
- {
- parseError = true;
- cmSystemTools::Error("Parse error in read function\nIn file:",
- filename, "\nCurrent line:", inbuffer);
- return false;
- }
- }
- return false;
-
-}
-
-void cmSystemTools::GetArguments(std::string& line,
- std::vector<std::string>& arguments)
-{
- // Match a normal argument (not quoted, no spaces).
- cmRegularExpression normalArgument("[ \t]*(([^ \t\r\\]|[\\].)+)[ \t\r]*");
- // Match a quoted argument (surrounded by double quotes, spaces allowed).
- cmRegularExpression quotedArgument("[ \t]*(\"([^\"\\]|[\\].)*\")[ \t\r]*");
-
- bool done = false;
- while(!done)
- {
- std::string arg;
- std::string::size_type endpos=0;
- bool foundQuoted = quotedArgument.find(line.c_str());
- bool foundNormal = normalArgument.find(line.c_str());
-
- if(foundQuoted && foundNormal)
- {
- // Both matches were found. Take the earlier one.
- // Favor double-quoted version if there is a tie.
- if(normalArgument.start(1) < quotedArgument.start(1))
- {
- arg = normalArgument.match(1);
- endpos = normalArgument.end(1);
- }
- else
- {
- arg = quotedArgument.match(1);
- endpos = quotedArgument.end(1);
- // Strip off the double quotes on the ends.
- arg = arg.substr(1, arg.length()-2);
- }
- }
- else if (foundQuoted)
- {
- arg = quotedArgument.match(1);
- endpos = quotedArgument.end(1);
- // Strip off the double quotes on the ends.
- arg = arg.substr(1, arg.length()-2);
- }
- else if(foundNormal)
- {
- arg = normalArgument.match(1);
- endpos = normalArgument.end(1);
- }
- else
- {
- done = true;
- }
- if(!done)
- {
- arguments.push_back(cmSystemTools::RemoveEscapes(arg.c_str()));
- line = line.substr(endpos, line.length() - endpos);
- }
- }
-}
-
-
std::string cmSystemTools::RemoveEscapes(const char* s)
{
std::string result = "";
@@ -2141,90 +1979,101 @@ void cmSystemTools::GlobDirs(const char *fullPath,
}
-void cmSystemTools::ExpandListArguments(std::vector<std::string> const& arguments,
- std::vector<std::string>& newargs)
+void cmSystemTools::ExpandList(std::vector<std::string> const& arguments,
+ std::vector<std::string>& newargs)
{
std::vector<std::string>::const_iterator i;
- std::string newarg;
for(i = arguments.begin();i != arguments.end(); ++i)
{
- // if there are no ; in the name then just copy the current string
- if(i->find(';') == std::string::npos)
- {
- newargs.push_back(*i);
- }
- else
+ cmSystemTools::ExpandListArgument(*i, newargs);
+ }
+}
+
+void cmSystemTools::ExpandListArgument(const std::string& arg,
+ std::vector<std::string>& newargs)
+{
+ std::string newarg;
+ // If argument is empty, it is an empty list.
+ if(arg.length() == 0)
+ {
+ return;
+ }
+ // if there are no ; in the name then just copy the current string
+ if(arg.find(';') == std::string::npos)
+ {
+ newargs.push_back(arg);
+ }
+ else
+ {
+ std::string::size_type start = 0;
+ std::string::size_type endpos = 0;
+ const std::string::size_type size = arg.size();
+ // break up ; separated sections of the string into separate strings
+ while(endpos != size)
{
- std::string::size_type start = 0;
- std::string::size_type endpos = 0;
- const std::string::size_type size = i->size();
- // break up ; separated sections of the string into separate strings
- while(endpos != size)
+ endpos = arg.find(';', start);
+ if(endpos == std::string::npos)
{
- endpos = i->find(';', start);
+ endpos = arg.size();
+ }
+ else
+ {
+ // skip right over escaped ; ( \; )
+ while((endpos != std::string::npos)
+ && (endpos > 0)
+ && ((arg)[endpos-1] == '\\') )
+ {
+ endpos = arg.find(';', endpos+1);
+ }
if(endpos == std::string::npos)
{
- endpos = i->size();
+ endpos = arg.size();
}
- else
+ }
+ std::string::size_type len = endpos - start;
+ if (len > 0)
+ {
+ // check for a closing ] after the start position
+ if(arg.find('[', start) == std::string::npos)
{
- // skip right over escaped ; ( \; )
- while((endpos != std::string::npos)
- && (endpos > 0)
- && ((*i)[endpos-1] == '\\') )
- {
- endpos = i->find(';', endpos+1);
- }
- if(endpos == std::string::npos)
- {
- endpos = i->size();
- }
+ // if there is no [ in the string then keep it
+ newarg = arg.substr(start, len);
}
- std::string::size_type len = endpos - start;
- if (len > 0)
+ else
{
- // check for a closing ] after the start position
- if(i->find('[', start) == std::string::npos)
+ int opencount = 0;
+ int closecount = 0;
+ for(std::string::size_type j = start; j < endpos; ++j)
{
- // if there is no [ in the string then keep it
- newarg = i->substr(start, len);
- }
- else
- {
- int opencount = 0;
- int closecount = 0;
- for(std::string::size_type j = start; j < endpos; ++j)
+ if(arg.at(j) == '[')
{
- if(i->at(j) == '[')
- {
- ++opencount;
- }
- else if (i->at(j) == ']')
- {
- ++closecount;
- }
+ ++opencount;
}
- if(opencount != closecount)
+ else if (arg.at(j) == ']')
{
- // skip this one
- endpos = i->find(';', endpos+1);
- if(endpos == std::string::npos)
- {
- endpos = i->size();
- }
- len = endpos - start;
+ ++closecount;
}
- newarg = i->substr(start, len);
}
- std::string::size_type pos = newarg.find("\\;");
- if(pos != std::string::npos)
+ if(opencount != closecount)
{
- newarg.erase(pos, 1);
+ // skip this one
+ endpos = arg.find(';', endpos+1);
+ if(endpos == std::string::npos)
+ {
+ endpos = arg.size();
+ }
+ len = endpos - start;
}
- newargs.push_back(newarg);
+ newarg = arg.substr(start, len);
}
- start = endpos+1;
+ std::string::size_type pos = newarg.find("\\;");
+ if(pos != std::string::npos)
+ {
+ newarg.erase(pos, 1);
+ }
+ newargs.push_back(newarg);
}
+ start = endpos+1;
}
}
}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 0e41691..f9ff94f 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -56,8 +56,10 @@ public:
* strings into multiple arguements. A new vector is created
* containing the expanded versions of all arguments in argsIn.
*/
- static void ExpandListArguments(std::vector<std::string> const& argsIn,
- std::vector<std::string>& argsOut);
+ static void ExpandList(std::vector<std::string> const& argsIn,
+ std::vector<std::string>& argsOut);
+ static void ExpandListArgument(const std::string& arg,
+ std::vector<std::string>& argsOut);
/**
* Read a registry value
@@ -117,25 +119,6 @@ public:
///! Return true if a file exists in the current directory.
static bool FileExists(const char* filename);
-
- /**
- * Read a CMake command (or function) from an input file. This
- * returns the name of the function and a list of its
- * arguments. The last argument is the name of the file that
- * the ifstream points to, and is used for debug info only.
- */
- static bool ParseFunction(std::ifstream&,
- std::string& name,
- std::vector<std::string>& arguments,
- const char* filename, bool& parseError);
-
- /**
- * Extract white-space separated arguments from a string.
- * Double quoted strings are accepted with spaces.
- * This is called by ParseFunction.
- */
- static void GetArguments(std::string& line,
- std::vector<std::string>& arguments);
/**
* Given a string, replace any escape sequences with the corresponding
@@ -389,5 +372,4 @@ private:
static std::string s_Windows9xComspecSubstitute;
};
-
#endif
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 92fd063..1e97557 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -75,10 +75,8 @@ void cmTarget::GenerateSourceFilesFromSourceLists( cmMakefile &mf)
// if the definition exists
if (varValue)
{
- std::vector<std::string> tval;
- tval.push_back(varValue);
std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(tval, args);
+ cmSystemTools::ExpandListArgument(varValue, args);
unsigned int i;
for (i = 0; i < args.size(); ++i)
{
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index aabbcf7..70ba944 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -17,21 +17,19 @@
#include "cmTargetLinkLibrariesCommand.h"
// cmTargetLinkLibrariesCommand
-bool cmTargetLinkLibrariesCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmTargetLinkLibrariesCommand::InitialPass(std::vector<std::string> const& args)
{
// must have one argument
- if(argsIn.size() < 1)
+ if(args.size() < 1)
{
this->SetError("called with incorrect number of arguments");
return false;
}
// but we might not have any libs after variable expansion
- if(argsIn.size() < 2)
+ if(args.size() < 2)
{
return true;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
// add libraries, nothe that there is an optional prefix
// of debug and optimized than can be used
std::vector<std::string>::const_iterator i = args.begin();
diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx
index 1a33762..10cefb8 100644
--- a/Source/cmUtilitySourceCommand.cxx
+++ b/Source/cmUtilitySourceCommand.cxx
@@ -17,15 +17,13 @@
#include "cmUtilitySourceCommand.h"
// cmUtilitySourceCommand
-bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 3)
+ if(args.size() < 3)
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
std::vector<std::string>::const_iterator arg = args.begin();
diff --git a/Source/cmVariableRequiresCommand.cxx b/Source/cmVariableRequiresCommand.cxx
index 2433ca2..81e1f86 100644
--- a/Source/cmVariableRequiresCommand.cxx
+++ b/Source/cmVariableRequiresCommand.cxx
@@ -25,7 +25,7 @@ bool cmVariableRequiresCommand::InitialPass(std::vector<std::string> const& args
this->SetError("called with incorrect number of arguments");
return false;
}
- cmSystemTools::ExpandListArguments(args, m_Arguments);
+ m_Arguments = args;
return true;
}
diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx
index ab7f957..79a8b46 100644
--- a/Source/cmWriteFileCommand.cxx
+++ b/Source/cmWriteFileCommand.cxx
@@ -17,15 +17,13 @@
#include "cmWriteFileCommand.h"
// cmLibraryCommand
-bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& argsIn)
+bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args)
{
- if(argsIn.size() < 2 )
+ if(args.size() < 2 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
- std::vector<std::string> args;
- cmSystemTools::ExpandListArguments(argsIn, args);
std::string message;
std::vector<std::string>::const_iterator i = args.begin();
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 4fba9b1..20a183e 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -17,6 +17,7 @@
#include "ctest.h"
#include "cmRegularExpression.h"
#include "cmSystemTools.h"
+#include "cmListFileCache.h"
#include <stdio.h>
#include <time.h>
@@ -1111,17 +1112,19 @@ void ctest::ProcessDirectory(std::vector<std::string> &passed,
bool parseError;
while ( fin )
{
- if(cmSystemTools::ParseFunction(fin, name, args, "DartTestfile.txt",
- parseError))
+ cmListFileFunction lff;
+ if(cmListFileCache::ParseFunction(fin, lff, "DartTestfile.txt", parseError))
{
+ const std::string& name = lff.m_Name;
+ const std::vector<cmListFileArgument>& args = lff.m_Arguments;
if (name == "SUBDIRS")
{
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- for(std::vector<std::string>::iterator j = args.begin();
+ for(std::vector<cmListFileArgument>::const_iterator j = args.begin();
j != args.end(); ++j)
{
std::string nwd = cwd + "/";
- nwd += *j;
+ nwd += j->Value;
if (cmSystemTools::FileIsDirectory(nwd.c_str()))
{
cmSystemTools::ChangeDirectory(nwd.c_str());
@@ -1136,17 +1139,17 @@ void ctest::ProcessDirectory(std::vector<std::string> &passed,
{
if (this->m_UseExcludeRegExp &&
this->m_UseExcludeRegExpFirst &&
- ereg.find(args[0].c_str()))
+ ereg.find(args[0].Value.c_str()))
{
continue;
}
- if (this->m_UseIncludeRegExp && !ireg.find(args[0].c_str()))
+ if (this->m_UseIncludeRegExp && !ireg.find(args[0].Value.c_str()))
{
continue;
}
if (this->m_UseExcludeRegExp &&
!this->m_UseExcludeRegExpFirst &&
- ereg.find(args[0].c_str()))
+ ereg.find(args[0].Value.c_str()))
{
continue;
}
@@ -1159,30 +1162,30 @@ void ctest::ProcessDirectory(std::vector<std::string> &passed,
std::cerr << "Changing directory into " << nwd.c_str() << "\n";
firstTest = 0;
}
- cres.m_Name = args[0];
- fprintf(stderr,"Testing %-30s ",args[0].c_str());
+ cres.m_Name = args[0].Value;
+ fprintf(stderr,"Testing %-30s ",args[0].Value.c_str());
fflush(stderr);
//std::cerr << "Testing " << args[0] << " ... ";
// find the test executable
- std::string testCommand = this->FindExecutable(args[1].c_str());
+ std::string testCommand = this->FindExecutable(args[1].Value.c_str());
testCommand = cmSystemTools::ConvertToOutputPath(testCommand.c_str());
// continue if we did not find the executable
if (testCommand == "")
{
std::cerr << "Unable to find executable: " <<
- args[1].c_str() << "\n";
+ args[1].Value.c_str() << "\n";
continue;
}
// add the arguments
- std::vector<std::string>::iterator j = args.begin();
+ std::vector<cmListFileArgument>::const_iterator j = args.begin();
++j;
++j;
for(;j != args.end(); ++j)
{
testCommand += " ";
- testCommand += cmSystemTools::EscapeSpaces(j->c_str());
+ testCommand += cmSystemTools::EscapeSpaces(j->Value.c_str());
}
/**
* Run an executable command and put the stdout in output.
@@ -1219,7 +1222,7 @@ void ctest::ProcessDirectory(std::vector<std::string> &passed,
std::cerr << output.c_str() << "\n";
}
}
- failed.push_back(args[0]);
+ failed.push_back(args[0].Value);
}
else
{
@@ -1236,7 +1239,7 @@ void ctest::ProcessDirectory(std::vector<std::string> &passed,
std::cerr << output.c_str() << "\n";
}
}
- passed.push_back(args[0]);
+ passed.push_back(args[0].Value);
}
cres.m_Output = output;
cres.m_ReturnValue = retVal;