Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmSetPropertyCommand.cxx
blob069d51d8b047b0f7dfbf30786132f8b3f608dfc4
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmSetPropertyCommand.cxx,v $
5 Language: C++
6 <<<<<<< cmSetPropertyCommand.cxx
7 Date: $Date: 2008/02/15 16:22:23 $
8 Version: $Revision: 1.6 $
9 =======
10 Date: $Date: 2008-04-01 18:22:06 $
11 Version: $Revision: 1.7 $
12 >>>>>>> 1.7
14 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
15 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
17 This software is distributed WITHOUT ANY WARRANTY; without even
18 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 PURPOSE. See the above copyright notices for more information.
21 =========================================================================*/
22 #include "cmSetPropertyCommand.h"
23 #include "cmSetTargetPropertiesCommand.h"
24 #include "cmSetTestsPropertiesCommand.h"
25 #include "cmSetSourceFilesPropertiesCommand.h"
27 //----------------------------------------------------------------------------
28 cmSetPropertyCommand::cmSetPropertyCommand()
30 this->AppendMode = false;
31 this->Remove = true;
34 //----------------------------------------------------------------------------
35 bool cmSetPropertyCommand
36 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
38 if(args.size() < 2 )
40 this->SetError("called with incorrect number of arguments");
41 return false;
44 // Get the scope on which to set the property.
45 std::vector<std::string>::const_iterator arg = args.begin();
46 cmProperty::ScopeType scope;
47 if(*arg == "GLOBAL")
49 scope = cmProperty::GLOBAL;
51 else if(*arg == "DIRECTORY")
53 scope = cmProperty::DIRECTORY;
55 else if(*arg == "TARGET")
57 scope = cmProperty::TARGET;
59 else if(*arg == "SOURCE")
61 scope = cmProperty::SOURCE_FILE;
63 else if(*arg == "TEST")
65 scope = cmProperty::TEST;
67 else
69 cmOStringStream e;
70 e << "given invalid scope " << *arg << ". "
71 << "Valid scopes are GLOBAL, DIRECTORY, TARGET, SOURCE, TEST.";
72 this->SetError(e.str().c_str());
73 return false;
76 // Parse the rest of the arguments up to the values.
77 enum Doing { DoingNone, DoingNames, DoingProperty, DoingValues };
78 Doing doing = DoingNames;
79 const char* sep = "";
80 for(++arg; arg != args.end(); ++arg)
82 if(*arg == "PROPERTY")
84 doing = DoingProperty;
86 else if(*arg == "APPEND")
88 doing = DoingNone;
89 this->AppendMode = true;
91 else if(doing == DoingNames)
93 this->Names.insert(*arg);
95 else if(doing == DoingProperty)
97 this->PropertyName = *arg;
98 doing = DoingValues;
100 else if(doing == DoingValues)
102 this->PropertyValue += sep;
103 sep = ";";
104 this->PropertyValue += *arg;
105 this->Remove = false;
107 else
109 cmOStringStream e;
110 e << "given invalid argument \"" << *arg << "\".";
111 this->SetError(e.str().c_str());
112 return false;
116 // Make sure a property name was found.
117 if(this->PropertyName.empty())
119 this->SetError("not given a PROPERTY <name> argument.");
120 return false;
123 // Dispatch property setting.
124 switch(scope)
126 case cmProperty::GLOBAL: return this->HandleGlobalMode();
127 case cmProperty::DIRECTORY: return this->HandleDirectoryMode();
128 case cmProperty::TARGET: return this->HandleTargetMode();
129 case cmProperty::SOURCE_FILE: return this->HandleSourceMode();
130 case cmProperty::TEST: return this->HandleTestMode();
132 case cmProperty::VARIABLE:
133 case cmProperty::CACHED_VARIABLE:
134 break; // should never happen
136 return true;
139 //----------------------------------------------------------------------------
140 bool cmSetPropertyCommand::HandleGlobalMode()
142 if(!this->Names.empty())
144 this->SetError("given names for GLOBAL scope.");
145 return false;
148 // Set or append the property.
149 cmake* cm = this->Makefile->GetCMakeInstance();
150 const char* name = this->PropertyName.c_str();
151 const char *value = this->PropertyValue.c_str();
152 if (this->Remove)
154 value = 0;
156 if(this->AppendMode)
158 cm->AppendProperty(name, value);
160 else
162 cm->SetProperty(name, value);
165 return true;
168 //----------------------------------------------------------------------------
169 bool cmSetPropertyCommand::HandleDirectoryMode()
171 if(this->Names.size() > 1)
173 this->SetError("allows at most one name for DIRECTORY scope.");
174 return false;
177 // Default to the current directory.
178 cmMakefile* mf = this->Makefile;
180 // Lookup the directory if given.
181 if(!this->Names.empty())
183 // Construct the directory name. Interpret relative paths with
184 // respect to the current directory.
185 std::string dir = *this->Names.begin();
186 if(!cmSystemTools::FileIsFullPath(dir.c_str()))
188 dir = this->Makefile->GetCurrentDirectory();
189 dir += "/";
190 dir += *this->Names.begin();
193 // The local generators are associated with collapsed paths.
194 dir = cmSystemTools::CollapseFullPath(dir.c_str());
196 // Lookup the generator.
197 if(cmLocalGenerator* lg =
198 (this->Makefile->GetLocalGenerator()
199 ->GetGlobalGenerator()->FindLocalGenerator(dir.c_str())))
201 // Use the makefile for the directory found.
202 mf = lg->GetMakefile();
204 else
206 // Could not find the directory.
207 this->SetError
208 ("DIRECTORY scope provided but requested directory was not found. "
209 "This could be because the directory argument was invalid or, "
210 "it is valid but has not been processed yet.");
211 return false;
215 // Set or append the property.
216 const char* name = this->PropertyName.c_str();
217 const char *value = this->PropertyValue.c_str();
218 if (this->Remove)
220 value = 0;
222 if(this->AppendMode)
224 mf->AppendProperty(name, value);
226 else
228 mf->SetProperty(name, value);
231 return true;
234 //----------------------------------------------------------------------------
235 bool cmSetPropertyCommand::HandleTargetMode()
237 for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
238 ni != this->Names.end(); ++ni)
240 if(cmTarget* target = this->Makefile->FindTargetToUse(ni->c_str()))
242 // Handle the current target.
243 if(!this->HandleTarget(target))
245 return false;
248 else
250 cmOStringStream e;
251 e << "could not find TARGET " << *ni
252 << ". Perhaps it has not yet been created.";
253 this->SetError(e.str().c_str());
254 return false;
257 return true;
260 //----------------------------------------------------------------------------
261 bool cmSetPropertyCommand::HandleTarget(cmTarget* target)
263 // Set or append the property.
264 const char* name = this->PropertyName.c_str();
265 const char *value = this->PropertyValue.c_str();
266 if (this->Remove)
268 value = 0;
270 if(this->AppendMode)
272 target->AppendProperty(name, value);
274 else
276 target->SetProperty(name, value);
279 return true;
282 //----------------------------------------------------------------------------
283 bool cmSetPropertyCommand::HandleSourceMode()
285 for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
286 ni != this->Names.end(); ++ni)
288 // Get the source file.
289 if(cmSourceFile* sf = this->Makefile->GetOrCreateSource(ni->c_str()))
291 if(!this->HandleSource(sf))
293 return false;
296 else
298 cmOStringStream e;
299 e << "given SOURCE name that could not be found or created: " << *ni;
300 this->SetError(e.str().c_str());
301 return false;
304 return true;
307 //----------------------------------------------------------------------------
308 bool cmSetPropertyCommand::HandleSource(cmSourceFile* sf)
310 // Set or append the property.
311 const char* name = this->PropertyName.c_str();
312 const char *value = this->PropertyValue.c_str();
313 if (this->Remove)
315 value = 0;
318 if(this->AppendMode)
320 sf->AppendProperty(name, value);
322 else
324 sf->SetProperty(name, value);
326 return true;
329 //----------------------------------------------------------------------------
330 bool cmSetPropertyCommand::HandleTestMode()
332 // Loop over all tests looking for matching names.
333 std::vector<cmTest*> const& tests = *this->Makefile->GetTests();
334 for(std::vector<cmTest*>::const_iterator ti = tests.begin();
335 ti != tests.end(); ++ti)
337 cmTest* test = *ti;
338 std::set<cmStdString>::iterator ni =
339 this->Names.find(test->GetName());
340 if(ni != this->Names.end())
342 if(this->HandleTest(test))
344 this->Names.erase(ni);
346 else
348 return false;
353 // Names that are still left were not found.
354 if(!this->Names.empty())
356 cmOStringStream e;
357 e << "given TEST names that do not exist:\n";
358 for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
359 ni != this->Names.end(); ++ni)
361 e << " " << *ni << "\n";
363 this->SetError(e.str().c_str());
364 return false;
366 return true;
369 //----------------------------------------------------------------------------
370 bool cmSetPropertyCommand::HandleTest(cmTest* test)
372 // Set or append the property.
373 const char* name = this->PropertyName.c_str();
374 const char *value = this->PropertyValue.c_str();
375 if (this->Remove)
377 value = 0;
379 if(this->AppendMode)
381 test->AppendProperty(name, value);
383 else
385 test->SetProperty(name, value);
388 return true;