summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2002-12-11 18:13:33 -0500
committerBrad King <brad.king@kitware.com>2002-12-11 18:13:33 -0500
commit4888c088ae0ca829862e8b2f9568abca12dc34d1 (patch)
tree2c0fb825f1d1adff97d98373b555f00b84da14f7 /Source
parent5a321605bcc15c7e559c8da5168eef00796148b1 (diff)
downloadcmake-4888c088ae0ca829862e8b2f9568abca12dc34d1.tar.gz
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.
Diffstat (limited to 'Source')
-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 e74653ef86..e0601cbdb9 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 6b1c09c8f6..a0a017dfda 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 c14264da1a..77ab3ef0ec 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 4cb42dd7e5..5067e3f790 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 57034d44bb..cfae2ceed9 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 cfae79f684..09aae189eb 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 b61b6acf60..cb7c2d7caa 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 09417a18fc..5802779956 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 56da7d39e5..7116f4d1ae 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 66228da7b3..44e95d2968 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 5ed0f4475e..8de88656c7 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 7a0dca9515..f29feb908d 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 101dcb35ef..e2501778cc 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 f04429e274..54f4d27eb0 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 ff7bf449ed..70c97a46e8 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 e23ffad88a..dd7c870ccd 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 1ec03a9b02..84f7dab2ac 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 9c344e1788..e8d1ac61e7 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 8e73d82b67..95911e6ce9 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 95ee945bc8..09b80cacae 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 e762ce598c..c7a2cc82c3 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 98491e9111..df1b06cba4 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 3e30a4ea53..152fcc2981 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 6d2d5d36ed..48bede4e89 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 396742dd7c..00dffd2d3d 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 a01fd864f9..155375490f 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 717c71f16d..67994f7e34 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 35b1ec37f5..d45f24667e 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 0893cf65ed..fce13db34b 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 2520eca1d4..9dc8073eb7 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 0ec5cab3e9..ef3fe26209 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 d5a2f3afe2..b307148ab5 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 5e72e0f9a7..5092045cc3 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 2cdcb09e8d..58871a23c3 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 0705be7eab..e090ec723d 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 9c5dc9f546..db4a1baa4b 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 dbb62af489..de8e3eb85e 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 b50202aea1..3195387553 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 45c6dc9df7..c6e8e16037 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 a9ec7babfd..8f48fd61d5 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 136b973005..44c33d4b2a 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 64f6a25494..3933321141 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 8fe4e1cd3e..fc1171cd33 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 cff9ffb7ff..7fb9b7af48 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 10bb916085..7fcf81417e 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 ff27805dd7..28163a8815 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 0e41691e77..f9ff94ff51 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 92fd063980..1e9755742c 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 aabbcf73c9..70ba944a0c 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 1a3376242d..10cefb86bb 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 2433ca22f9..81e1f860b0 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 ab7f957326..79a8b4698e 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 4fba9b15c0..20a183e1e1 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;