Imported Upstream version 2.8.12.2
[platform/upstream/cmake.git] / Source / cmWhileCommand.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the License for more information.
11 ============================================================================*/
12 #include "cmWhileCommand.h"
13 #include "cmIfCommand.h"
14
15 bool cmWhileFunctionBlocker::
16 IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
17                   cmExecutionStatus &inStatus)
18 {
19   // at end of for each execute recorded commands
20   if (!cmSystemTools::Strucmp(lff.Name.c_str(),"while"))
21     {
22     // record the number of while commands past this one
23     this->Depth++;
24     }
25   else if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endwhile"))
26     {
27     // if this is the endwhile for this while loop then execute
28     if (!this->Depth)
29       {
30       // Remove the function blocker for this scope or bail.
31       cmsys::auto_ptr<cmFunctionBlocker>
32         fb(mf.RemoveFunctionBlocker(this, lff));
33       if(!fb.get()) { return false; }
34
35       std::string errorString;
36
37       std::vector<std::string> expandedArguments;
38       mf.ExpandArguments(this->Args, expandedArguments);
39       cmake::MessageType messageType;
40       bool isTrue =
41         cmIfCommand::IsTrue(expandedArguments,errorString,
42                             &mf, messageType);
43
44       while (isTrue)
45         {
46         if (errorString.size())
47           {
48           std::string err = "had incorrect arguments: ";
49           unsigned int i;
50           for(i =0; i < this->Args.size(); ++i)
51             {
52             err += (this->Args[i].Delim?"\"":"");
53             err += this->Args[i].Value;
54             err += (this->Args[i].Delim?"\"":"");
55             err += " ";
56             }
57           err += "(";
58           err += errorString;
59           err += ").";
60           mf.IssueMessage(messageType, err);
61           if (messageType == cmake::FATAL_ERROR)
62             {
63             cmSystemTools::SetFatalErrorOccured();
64             return true;
65             }
66           }
67
68         // Invoke all the functions that were collected in the block.
69         for(unsigned int c = 0; c < this->Functions.size(); ++c)
70           {
71           cmExecutionStatus status;
72           mf.ExecuteCommand(this->Functions[c],status);
73           if (status.GetReturnInvoked())
74             {
75             inStatus.SetReturnInvoked(true);
76             return true;
77             }
78           if (status.GetBreakInvoked())
79             {
80             return true;
81             }
82           if(cmSystemTools::GetFatalErrorOccured() )
83             {
84             return true;
85             }
86           }
87         expandedArguments.clear();
88         mf.ExpandArguments(this->Args, expandedArguments);
89         isTrue =
90           cmIfCommand::IsTrue(expandedArguments,errorString,
91                               &mf, messageType);
92         }
93       return true;
94       }
95     else
96       {
97       // decrement for each nested while that ends
98       this->Depth--;
99       }
100     }
101
102   // record the command
103   this->Functions.push_back(lff);
104
105   // always return true
106   return true;
107 }
108
109 bool cmWhileFunctionBlocker::
110 ShouldRemove(const cmListFileFunction& lff, cmMakefile& )
111 {
112   if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endwhile"))
113     {
114     // if the endwhile has arguments, then make sure
115     // they match the arguments of the matching while
116     if (lff.Arguments.size() == 0 ||
117         lff.Arguments == this->Args)
118       {
119       return true;
120       }
121     }
122   return false;
123 }
124
125 bool cmWhileCommand
126 ::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
127                     cmExecutionStatus &)
128 {
129   if(args.size() < 1)
130     {
131     this->SetError("called with incorrect number of arguments");
132     return false;
133     }
134
135   // create a function blocker
136   cmWhileFunctionBlocker *f = new cmWhileFunctionBlocker();
137   f->Args = args;
138   this->Makefile->AddFunctionBlocker(f);
139
140   return true;
141 }
142