summaryrefslogtreecommitdiff
path: root/Source/cmWhileCommand.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmWhileCommand.cxx')
-rw-r--r--Source/cmWhileCommand.cxx142
1 files changed, 142 insertions, 0 deletions
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
new file mode 100644
index 000000000..400034582
--- /dev/null
+++ b/Source/cmWhileCommand.cxx
@@ -0,0 +1,142 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmWhileCommand.h"
+#include "cmIfCommand.h"
+
+bool cmWhileFunctionBlocker::
+IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
+ cmExecutionStatus &inStatus)
+{
+ // at end of for each execute recorded commands
+ if (!cmSystemTools::Strucmp(lff.Name.c_str(),"while"))
+ {
+ // record the number of while commands past this one
+ this->Depth++;
+ }
+ else if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endwhile"))
+ {
+ // if this is the endwhile for this while loop then execute
+ if (!this->Depth)
+ {
+ // Remove the function blocker for this scope or bail.
+ cmsys::auto_ptr<cmFunctionBlocker>
+ fb(mf.RemoveFunctionBlocker(this, lff));
+ if(!fb.get()) { return false; }
+
+ std::string errorString;
+
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(this->Args, expandedArguments);
+ cmake::MessageType messageType;
+ bool isTrue =
+ cmIfCommand::IsTrue(expandedArguments,errorString,
+ &mf, messageType);
+
+ while (isTrue)
+ {
+ if (errorString.size())
+ {
+ std::string err = "had incorrect arguments: ";
+ unsigned int i;
+ for(i =0; i < this->Args.size(); ++i)
+ {
+ err += (this->Args[i].Quoted?"\"":"");
+ err += this->Args[i].Value;
+ err += (this->Args[i].Quoted?"\"":"");
+ err += " ";
+ }
+ err += "(";
+ err += errorString;
+ err += ").";
+ mf.IssueMessage(messageType, err);
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+ }
+
+ // Invoke all the functions that were collected in the block.
+ for(unsigned int c = 0; c < this->Functions.size(); ++c)
+ {
+ cmExecutionStatus status;
+ mf.ExecuteCommand(this->Functions[c],status);
+ if (status.GetReturnInvoked())
+ {
+ inStatus.SetReturnInvoked(true);
+ return true;
+ }
+ if (status.GetBreakInvoked())
+ {
+ return true;
+ }
+ if(cmSystemTools::GetFatalErrorOccured() )
+ {
+ return true;
+ }
+ }
+ expandedArguments.clear();
+ mf.ExpandArguments(this->Args, expandedArguments);
+ isTrue =
+ cmIfCommand::IsTrue(expandedArguments,errorString,
+ &mf, messageType);
+ }
+ return true;
+ }
+ else
+ {
+ // decrement for each nested while that ends
+ this->Depth--;
+ }
+ }
+
+ // record the command
+ this->Functions.push_back(lff);
+
+ // always return true
+ return true;
+}
+
+bool cmWhileFunctionBlocker::
+ShouldRemove(const cmListFileFunction& lff, cmMakefile& )
+{
+ if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endwhile"))
+ {
+ // if the endwhile has arguments, then make sure
+ // they match the arguments of the matching while
+ if (lff.Arguments.size() == 0 ||
+ lff.Arguments == this->Args)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool cmWhileCommand
+::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus &)
+{
+ if(args.size() < 1)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // create a function blocker
+ cmWhileFunctionBlocker *f = new cmWhileFunctionBlocker();
+ f->Args = args;
+ this->Makefile->AddFunctionBlocker(f);
+
+ return true;
+}
+