Initial commit.
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmSetPropertyCommand.cxx
blobf296db25bbe8729364953318797f8f66d3020e33
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmSetPropertyCommand.cxx,v $
5 Language: C++
6 Date: $Date: 2008/01/28 13:38:36 $
7 Version: $Revision: 1.5 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmSetPropertyCommand.h"
18 #include "cmSetTargetPropertiesCommand.h"
19 #include "cmSetTestsPropertiesCommand.h"
20 #include "cmSetSourceFilesPropertiesCommand.h"
22 //----------------------------------------------------------------------------
23 cmSetPropertyCommand::cmSetPropertyCommand()
25 this->AppendMode = false;
28 //----------------------------------------------------------------------------
29 bool cmSetPropertyCommand
30 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
32 if(args.size() < 2 )
34 this->SetError("called with incorrect number of arguments");
35 return false;
38 // Get the scope on which to set the property.
39 std::vector<std::string>::const_iterator arg = args.begin();
40 cmProperty::ScopeType scope;
41 if(*arg == "GLOBAL")
43 scope = cmProperty::GLOBAL;
45 else if(*arg == "DIRECTORY")
47 scope = cmProperty::DIRECTORY;
49 else if(*arg == "TARGET")
51 scope = cmProperty::TARGET;
53 else if(*arg == "SOURCE")
55 scope = cmProperty::SOURCE_FILE;
57 else if(*arg == "TEST")
59 scope = cmProperty::TEST;
61 else
63 cmOStringStream e;
64 e << "given invalid scope " << *arg << ". "
65 << "Valid scopes are GLOBAL, DIRECTORY, TARGET, SOURCE, TEST.";
66 this->SetError(e.str().c_str());
67 return false;
70 // Parse the rest of the arguments up to the values.
71 enum Doing { DoingNone, DoingNames, DoingProperty, DoingValues };
72 Doing doing = DoingNames;
73 const char* sep = "";
74 for(++arg; arg != args.end(); ++arg)
76 if(*arg == "PROPERTY")
78 doing = DoingProperty;
80 else if(*arg == "APPEND")
82 doing = DoingNone;
83 this->AppendMode = true;
85 else if(doing == DoingNames)
87 this->Names.insert(*arg);
89 else if(doing == DoingProperty)
91 this->PropertyName = *arg;
92 doing = DoingValues;
94 else if(doing == DoingValues)
96 this->PropertyValue += sep;
97 sep = ";";
98 this->PropertyValue += *arg;
100 else
102 cmOStringStream e;
103 e << "given invalid argument \"" << *arg << "\".";
104 this->SetError(e.str().c_str());
105 return false;
109 // Make sure a property name was found.
110 if(this->PropertyName.empty())
112 this->SetError("not given a PROPERTY <name> argument.");
113 return false;
116 // Dispatch property setting.
117 switch(scope)
119 case cmProperty::GLOBAL: return this->HandleGlobalMode();
120 case cmProperty::DIRECTORY: return this->HandleDirectoryMode();
121 case cmProperty::TARGET: return this->HandleTargetMode();
122 case cmProperty::SOURCE_FILE: return this->HandleSourceMode();
123 case cmProperty::TEST: return this->HandleTestMode();
125 case cmProperty::VARIABLE:
126 case cmProperty::CACHED_VARIABLE:
127 break; // should never happen
129 return true;
132 //----------------------------------------------------------------------------
133 bool cmSetPropertyCommand::HandleGlobalMode()
135 if(!this->Names.empty())
137 this->SetError("given names for GLOBAL scope.");
138 return false;
141 // Set or append the property.
142 cmake* cm = this->Makefile->GetCMakeInstance();
143 const char* name = this->PropertyName.c_str();
144 if(this->AppendMode)
146 cm->AppendProperty(name, this->PropertyValue.c_str());
148 else
150 cm->SetProperty(name, this->PropertyValue.c_str());
153 return true;
156 //----------------------------------------------------------------------------
157 bool cmSetPropertyCommand::HandleDirectoryMode()
159 if(this->Names.size() > 1)
161 this->SetError("allows at most one name for DIRECTORY scope.");
162 return false;
165 // Default to the current directory.
166 cmMakefile* mf = this->Makefile;
168 // Lookup the directory if given.
169 if(!this->Names.empty())
171 // Construct the directory name. Interpret relative paths with
172 // respect to the current directory.
173 std::string dir = *this->Names.begin();
174 if(!cmSystemTools::FileIsFullPath(dir.c_str()))
176 dir = this->Makefile->GetCurrentDirectory();
177 dir += "/";
178 dir += *this->Names.begin();
181 // The local generators are associated with collapsed paths.
182 dir = cmSystemTools::CollapseFullPath(dir.c_str());
184 // Lookup the generator.
185 if(cmLocalGenerator* lg =
186 (this->Makefile->GetLocalGenerator()
187 ->GetGlobalGenerator()->FindLocalGenerator(dir.c_str())))
189 // Use the makefile for the directory found.
190 mf = lg->GetMakefile();
192 else
194 // Could not find the directory.
195 this->SetError
196 ("DIRECTORY scope provided but requested directory was not found. "
197 "This could be because the directory argument was invalid or, "
198 "it is valid but has not been processed yet.");
199 return false;
203 // Set or append the property.
204 const char* name = this->PropertyName.c_str();
205 if(this->AppendMode)
207 mf->AppendProperty(name, this->PropertyValue.c_str());
209 else
211 mf->SetProperty(name, this->PropertyValue.c_str());
214 return true;
217 //----------------------------------------------------------------------------
218 bool cmSetPropertyCommand::HandleTargetMode()
220 for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
221 ni != this->Names.end(); ++ni)
223 if(cmTarget* target = this->Makefile->FindTargetToUse(ni->c_str()))
225 // Handle the current target.
226 if(!this->HandleTarget(target))
228 return false;
231 else
233 cmOStringStream e;
234 e << "could not find TARGET " << *ni
235 << ". Perhaps it has not yet been created.";
236 this->SetError(e.str().c_str());
237 return false;
240 return true;
243 //----------------------------------------------------------------------------
244 bool cmSetPropertyCommand::HandleTarget(cmTarget* target)
246 // Set or append the property.
247 const char* name = this->PropertyName.c_str();
248 if(this->AppendMode)
250 target->AppendProperty(name, this->PropertyValue.c_str());
252 else
254 target->SetProperty(name, this->PropertyValue.c_str());
257 return true;
260 //----------------------------------------------------------------------------
261 bool cmSetPropertyCommand::HandleSourceMode()
263 for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
264 ni != this->Names.end(); ++ni)
266 // Get the source file.
267 if(cmSourceFile* sf = this->Makefile->GetOrCreateSource(ni->c_str()))
269 if(!this->HandleSource(sf))
271 return false;
274 else
276 cmOStringStream e;
277 e << "given SOURCE name that could not be found or created: " << *ni;
278 this->SetError(e.str().c_str());
279 return false;
282 return true;
285 //----------------------------------------------------------------------------
286 bool cmSetPropertyCommand::HandleSource(cmSourceFile* sf)
288 // Set or append the property.
289 const char* name = this->PropertyName.c_str();
290 if(this->AppendMode)
292 sf->AppendProperty(name, this->PropertyValue.c_str());
294 else
296 sf->SetProperty(name, this->PropertyValue.c_str());
299 // TODO: MACOSX_PACKAGE_LOCATION special case in
300 // cmSetSourceFilesPropertiesCommand
301 // The logic should be moved to cmSourceFile.
303 return true;
306 //----------------------------------------------------------------------------
307 bool cmSetPropertyCommand::HandleTestMode()
309 // Loop over all tests looking for matching names.
310 std::vector<cmTest*> const& tests = *this->Makefile->GetTests();
311 for(std::vector<cmTest*>::const_iterator ti = tests.begin();
312 ti != tests.end(); ++ti)
314 cmTest* test = *ti;
315 std::set<cmStdString>::iterator ni =
316 this->Names.find(test->GetName());
317 if(ni != this->Names.end())
319 if(this->HandleTest(test))
321 this->Names.erase(ni);
323 else
325 return false;
330 // Names that are still left were not found.
331 if(!this->Names.empty())
333 cmOStringStream e;
334 e << "given TEST names that do not exist:\n";
335 for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
336 ni != this->Names.end(); ++ni)
338 e << " " << *ni << "\n";
340 this->SetError(e.str().c_str());
341 return false;
343 return true;
346 //----------------------------------------------------------------------------
347 bool cmSetPropertyCommand::HandleTest(cmTest* test)
349 // Set or append the property.
350 const char* name = this->PropertyName.c_str();
351 if(this->AppendMode)
353 test->AppendProperty(name, this->PropertyValue.c_str());
355 else
357 test->SetProperty(name, this->PropertyValue.c_str());
360 return true;