ENH: added while command

This commit is contained in:
Ken Martin 2005-01-21 09:38:04 -05:00
parent 819c910ee3
commit 0c225eb5b9
5 changed files with 333 additions and 0 deletions

View File

@ -79,6 +79,7 @@
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include "cmAbstractFilesCommand.cxx"
#include "cmAuxSourceDirectoryCommand.cxx"
#include "cmEndWhileCommand.cxx"
#include "cmExportLibraryDependencies.cxx"
#include "cmEnableLanguageCommand.cxx"
#include "cmFLTKWrapUICommand.cxx"
@ -104,6 +105,7 @@
#include "cmQTWrapUICommand.cxx"
#include "cmUseMangledMesaCommand.cxx"
#include "cmUtilitySourceCommand.cxx"
#include "cmWhileCommand.cxx"
#include "cmWrapExcludeFilesCommand.cxx"
// This one must be last because it includes windows.h and
@ -173,6 +175,7 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands)
commands.push_back(new cmAbstractFilesCommand);
commands.push_back(new cmAuxSourceDirectoryCommand);
commands.push_back(new cmEnableLanguageCommand);
commands.push_back(new cmEndWhileCommand);
commands.push_back(new cmExportLibraryDependenciesCommand);
commands.push_back(new cmFLTKWrapUICommand);
commands.push_back(new cmGetCMakePropertyCommand);
@ -198,6 +201,7 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands)
commands.push_back(new cmQTWrapUICommand);
commands.push_back(new cmUseMangledMesaCommand);
commands.push_back(new cmUtilitySourceCommand);
commands.push_back(new cmWhileCommand);
commands.push_back(new cmWrapExcludeFilesCommand);
#endif
}

View File

@ -0,0 +1,24 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "cmEndWhileCommand.h"
bool cmEndWhileCommand::InvokeInitialPass(std::vector<cmListFileArgument> const&)
{
this->SetError("An ENDWHILE command was found outside of a proper WHILE ENDWHILE structure. Or its arguments did not match the opening WHILE command.");
return false;
}

View File

@ -0,0 +1,88 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef cmEndWhileCommand_h
#define cmEndWhileCommand_h
#include "cmCommand.h"
/** \class cmEndWhileCommand
* \brief ends an if block
*
* cmEndWhileCommand ends an if block
*/
class cmEndWhileCommand : public cmCommand
{
public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmEndWhileCommand;
}
/**
* 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&) {return false;}
/**
* This determines if the command gets propagated down
* to makefiles located in subdirectories.
*/
virtual bool IsInherited() {return true;}
/**
* This determines if the command is invoked when in script mode.
*/
virtual bool IsScriptable() { return true; }
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "ENDWHILE";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Ends a list of commands in a WHILE block.";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
" ENDWHILE(expression)\n"
"See WHILE command.";
}
cmTypeMacro(cmEndWhileCommand, cmCommand);
};
#endif

99
Source/cmWhileCommand.cxx Normal file
View File

@ -0,0 +1,99 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "cmWhileCommand.h"
bool cmWhileFunctionBlocker::
IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
{
// Prevent recusion and don't let this blocker block its own
// commands.
if (m_Executing)
{
return false;
}
// at end of for each execute recorded commands
if (lff.m_Name == "ENDWHILE")
{
char* errorString = 0;
std::vector<std::string> expandedArguments;
mf.ExpandArguments(m_Args, expandedArguments);
bool isTrue =
cmIfCommand::IsTrue(expandedArguments,&errorString,&mf);
m_Executing = true;
while (isTrue)
{
// Invoke all the functions that were collected in the block.
for(unsigned int c = 0; c < m_Functions.size(); ++c)
{
mf.ExecuteCommand(m_Functions[c]);
}
expandedArguments.clear();
mf.ExpandArguments(m_Args, expandedArguments);
isTrue =
cmIfCommand::IsTrue(expandedArguments,&errorString,&mf);
}
mf.RemoveFunctionBlocker(lff);
return true;
}
// record the command
m_Functions.push_back(lff);
// always return true
return true;
}
bool cmWhileFunctionBlocker::
ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf)
{
if(lff.m_Name == "ENDWHILE")
{
if (lff.m_Arguments == m_Args)
{
return true;
}
}
return false;
}
void cmWhileFunctionBlocker::
ScopeEnded(cmMakefile &mf)
{
cmSystemTools::Error("The end of a CMakeLists file was reached with a WHILE statement that was not closed properly. Within the directory: ",
mf.GetCurrentDirectory());
}
bool cmWhileCommand::InvokeInitialPass(
const std::vector<cmListFileArgument>& args)
{
if(args.size() < 1)
{
this->SetError("called with incorrect number of arguments");
return false;
}
// create a function blocker
cmWhileFunctionBlocker *f = new cmWhileFunctionBlocker();
f->m_Args = args;
m_Makefile->AddFunctionBlocker(f);
return true;
}

118
Source/cmWhileCommand.h Normal file
View File

@ -0,0 +1,118 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef cmWhileCommand_h
#define cmWhileCommand_h
#include "cmCommand.h"
#include "cmFunctionBlocker.h"
#include "cmListFileCache.h"
/** \class cmWhileFunctionBlocker
* \brief subclass of function blocker
*
*
*/
class cmWhileFunctionBlocker : public cmFunctionBlocker
{
public:
cmWhileFunctionBlocker() {m_Executing = false;}
virtual ~cmWhileFunctionBlocker() {}
virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
cmMakefile &mf);
virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf);
virtual void ScopeEnded(cmMakefile &mf);
std::vector<cmListFileArgument> m_Args;
std::vector<cmListFileFunction> m_Functions;
bool m_Executing;
};
/** \class cmWhileCommand
* \brief starts a while loop
*
* cmWhileCommand starts a while loop
*/
class cmWhileCommand : public cmCommand
{
public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmWhileCommand;
}
/**
* 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&) { return false; }
/**
* This determines if the command gets propagated down
* to makefiles located in subdirectories.
*/
virtual bool IsInherited() {return true;}
/**
* This determines if the command is invoked when in script mode.
*/
virtual bool IsScriptable() { return true; }
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "WHILE";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Evaluate a group of commands while a condition is true";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
" WHILE(condition)\n"
" COMMAND1(ARGS ...)\n"
" COMMAND2(ARGS ...)\n"
" ...\n"
" ENDWHILE(condition)\n"
"All commands between WHILE and the matching ENDWHILE are recorded "
"without being invoked. Once the ENDWHILE is evaluated, the "
"recorded list of commands is invoked as long as the condition "
"is true. The condition is evaulated using the same logic as the "
"FOR command.";
}
cmTypeMacro(cmWhileCommand, cmCommand);
};
#endif