packaging: Initial packaging
[platform/upstream/cmake.git] / Source / cmCommandArgumentsHelper.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
13 #include "cmCommandArgumentsHelper.h"
14
15 cmCommandArgument::cmCommandArgument(cmCommandArgumentsHelper* args,
16                                      const char* key,
17                                      cmCommandArgumentGroup* group)
18 :Key(key)
19 ,Group(group)
20 ,WasActive(false)
21 ,ArgumentsBeforeEmpty(true)
22 ,CurrentIndex(0)
23 {
24   if (args!=0)
25     {
26     args->AddArgument(this);
27     }
28
29   if (this->Group!=0)
30     {
31     this->Group->ContainedArguments.push_back(this);
32     }
33 }
34
35 void cmCommandArgument::Reset()
36 {
37   this->WasActive =false;
38   this->CurrentIndex = 0;
39   this->DoReset();
40 }
41
42 void cmCommandArgument::Follows(const cmCommandArgument* arg)
43 {
44   this->ArgumentsBeforeEmpty = false;
45   this->ArgumentsBefore.insert(arg);
46 }
47
48 void cmCommandArgument::FollowsGroup(const cmCommandArgumentGroup* group)
49 {
50   if (group!=0)
51     {
52     this->ArgumentsBeforeEmpty = false;
53     for(std::vector<cmCommandArgument*>::const_iterator
54         argIt= group->ContainedArguments.begin();
55         argIt != group->ContainedArguments.end();
56         ++argIt)
57       {
58       this->ArgumentsBefore.insert(*argIt);
59       }
60     }
61 }
62
63 bool cmCommandArgument::MayFollow(const cmCommandArgument* current) const
64 {
65   if (this->ArgumentsBeforeEmpty)
66     {
67     return true;
68     }
69
70   std::set<const cmCommandArgument*>::const_iterator argIt
71                                          = this->ArgumentsBefore.find(current);
72   if (argIt != this->ArgumentsBefore.end())
73     {
74     return true;
75     }
76
77   return false;
78 }
79
80 bool cmCommandArgument::KeyMatches(const std::string& key) const
81 {
82   if ((this->Key==0) || (this->Key[0]=='\0'))
83     {
84     return true;
85     }
86   return (key==this->Key);
87 }
88
89 void cmCommandArgument::ApplyOwnGroup()
90 {
91   if (this->Group!=0)
92     {
93     for (std::vector<cmCommandArgument*>::const_iterator
94          it = this->Group->ContainedArguments.begin();
95          it != this->Group->ContainedArguments.end();
96          ++it)
97       {
98       if(*it != this)
99         {
100         this->ArgumentsBefore.insert(*it);
101         }
102       }
103     }
104 }
105
106 void cmCommandArgument::Activate()
107 {
108   this->WasActive = true;
109   this->CurrentIndex = 0;
110 }
111
112 bool cmCommandArgument::Consume(const std::string& arg)
113 {
114   bool res=this->DoConsume(arg, this->CurrentIndex);
115   this->CurrentIndex++;
116   return res;
117 }
118
119
120 cmCAStringVector::cmCAStringVector(cmCommandArgumentsHelper* args,
121                                    const char* key,
122                                    cmCommandArgumentGroup* group)
123 :cmCommandArgument(args, key, group)
124 ,Ignore(0)
125 {
126   if ((key==0) || (*key==0))
127     {
128     this->DataStart = 0;
129     }
130   else
131     {
132     this->DataStart = 1;
133     }
134 }
135
136 bool cmCAStringVector::DoConsume(const std::string& arg,unsigned int index)
137 {
138   if (index >= this->DataStart)
139     {
140     if ((this->Ignore==0) || (arg != this->Ignore))
141       {
142       this->Vector.push_back(arg);
143       }
144     }
145
146   return false;
147 }
148
149 void cmCAStringVector::DoReset()
150 {
151   this->Vector.clear();
152 }
153
154 cmCAString::cmCAString(cmCommandArgumentsHelper* args,
155                        const char* key,
156                        cmCommandArgumentGroup* group)
157 :cmCommandArgument(args, key, group)
158 {
159   if ((key==0) || (*key==0))
160     {
161     this->DataStart = 0;
162     }
163   else
164     {
165     this->DataStart = 1;
166     }
167 }
168
169 bool cmCAString::DoConsume(const std::string& arg, unsigned int index)
170 {
171   if (index == this->DataStart)
172     {
173     this->String = arg;
174     }
175
176   return index >= this->DataStart;
177 }
178
179 void cmCAString::DoReset()
180 {
181   this->String = "";
182 }
183
184 cmCAEnabler::cmCAEnabler(cmCommandArgumentsHelper* args,
185                          const char* key,
186                          cmCommandArgumentGroup* group)
187 :cmCommandArgument(args, key, group)
188 ,Enabled(false)
189 {}
190
191 bool cmCAEnabler::DoConsume(const std::string&, unsigned int index)
192 {
193   if (index==0)
194     {
195     this->Enabled = true;
196     }
197   return true;
198 }
199
200 void cmCAEnabler::DoReset()
201 {
202   this->Enabled = false;
203 }
204
205 cmCADisabler::cmCADisabler(cmCommandArgumentsHelper* args,
206                            const char* key,
207                            cmCommandArgumentGroup* group)
208 :cmCommandArgument(args, key, group)
209 ,Enabled(true)
210 {}
211
212 bool cmCADisabler::DoConsume(const std::string&, unsigned int index)
213 {
214   if (index==0)
215     {
216     this->Enabled = false;
217     }
218   return true;
219 }
220
221 void cmCADisabler::DoReset()
222 {
223   this->Enabled = true;
224 }
225
226 void cmCommandArgumentGroup::Follows(const cmCommandArgument* arg)
227 {
228   for(std::vector<cmCommandArgument*>::iterator
229       it = this->ContainedArguments.begin();
230       it != this->ContainedArguments.end();
231       ++it)
232     {
233     (*it)->Follows(arg);
234     }
235 }
236
237 void cmCommandArgumentGroup::FollowsGroup(const cmCommandArgumentGroup* group)
238 {
239   for(std::vector<cmCommandArgument*>::iterator
240       it = this->ContainedArguments.begin();
241       it != this->ContainedArguments.end();
242       ++it)
243     {
244     (*it)->FollowsGroup(group);
245     }
246 }
247
248 void cmCommandArgumentsHelper::Parse(const std::vector<std::string>* args,
249                                      std::vector<std::string>* unconsumedArgs)
250 {
251   if(args==0)
252     {
253     return;
254     }
255
256   for(std::vector<cmCommandArgument*>::iterator
257       argIt = this->Arguments.begin();
258       argIt != this->Arguments.end();
259       ++argIt)
260     {
261     (*argIt)->ApplyOwnGroup();
262     (*argIt)->Reset();
263     }
264
265   cmCommandArgument* activeArgument = 0;
266   const cmCommandArgument* previousArgument = 0;
267   for(std::vector<std::string>::const_iterator it = args->begin();
268       it != args->end();
269       ++it)
270     {
271     for(std::vector<cmCommandArgument*>::iterator
272         argIt = this->Arguments.begin();
273         argIt != this->Arguments.end();
274         ++argIt)
275       {
276       if ((*argIt)->KeyMatches(*it) && ((*argIt)->MayFollow(previousArgument)))
277         {
278         activeArgument = *argIt;
279         activeArgument->Activate();
280         break;
281         }
282       }
283
284     if (activeArgument)
285       {
286       bool argDone = activeArgument->Consume(*it);
287       previousArgument = activeArgument;
288       if (argDone)
289         {
290         activeArgument = 0;
291         }
292       }
293     else
294       {
295       if (unconsumedArgs!=0)
296         {
297         unconsumedArgs->push_back(*it);
298         }
299       }
300     }
301 }
302
303 void cmCommandArgumentsHelper::AddArgument(cmCommandArgument* arg)
304 {
305   this->Arguments.push_back(arg);
306 }
307