Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmGetPropertyCommand.cxx
bloba0cae1ca3454da5caff15e0b8a729ce2805ddec5
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmGetPropertyCommand.cxx,v $
5 Language: C++
6 Date: $Date: 2009-03-10 15:10:59 $
7 Version: $Revision: 1.12 $
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 "cmGetPropertyCommand.h"
19 #include "cmake.h"
20 #include "cmTest.h"
21 #include "cmPropertyDefinition.h"
23 //----------------------------------------------------------------------------
24 cmGetPropertyCommand::cmGetPropertyCommand()
26 this->InfoType = OutValue;
29 //----------------------------------------------------------------------------
30 bool cmGetPropertyCommand
31 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
33 if(args.size() < 3 )
35 this->SetError("called with incorrect number of arguments");
36 return false;
39 // The cmake variable in which to store the result.
40 this->Variable = args[0];
42 // Get the scope from which to get the property.
43 cmProperty::ScopeType scope;
44 if(args[1] == "GLOBAL")
46 scope = cmProperty::GLOBAL;
48 else if(args[1] == "DIRECTORY")
50 scope = cmProperty::DIRECTORY;
52 else if(args[1] == "TARGET")
54 scope = cmProperty::TARGET;
56 else if(args[1] == "SOURCE")
58 scope = cmProperty::SOURCE_FILE;
60 else if(args[1] == "TEST")
62 scope = cmProperty::TEST;
64 else if(args[1] == "VARIABLE")
66 scope = cmProperty::VARIABLE;
68 else if(args[1] == "CACHE")
70 scope = cmProperty::CACHE;
72 else
74 cmOStringStream e;
75 e << "given invalid scope " << args[1] << ". "
76 << "Valid scopes are "
77 << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE.";
78 this->SetError(e.str().c_str());
79 return false;
82 // Parse remaining arguments.
83 enum Doing { DoingNone, DoingName, DoingProperty, DoingType };
84 Doing doing = DoingName;
85 for(unsigned int i=2; i < args.size(); ++i)
87 if(args[i] == "PROPERTY")
89 doing = DoingProperty;
91 else if(args[i] == "BRIEF_DOCS")
93 doing = DoingNone;
94 this->InfoType = OutBriefDoc;
96 else if(args[i] == "FULL_DOCS")
98 doing = DoingNone;
99 this->InfoType = OutFullDoc;
101 else if(args[i] == "SET")
103 doing = DoingNone;
104 this->InfoType = OutSet;
106 else if(args[i] == "DEFINED")
108 doing = DoingNone;
109 this->InfoType = OutDefined;
111 else if(doing == DoingName)
113 doing = DoingNone;
114 this->Name = args[i];
116 else if(doing == DoingProperty)
118 doing = DoingNone;
119 this->PropertyName = args[i];
121 else
123 cmOStringStream e;
124 e << "given invalid argument \"" << args[i] << "\".";
125 this->SetError(e.str().c_str());
126 return false;
130 // Make sure a property name was found.
131 if(this->PropertyName.empty())
133 this->SetError("not given a PROPERTY <name> argument.");
134 return false;
137 // Compute requested output.
138 if(this->InfoType == OutBriefDoc)
140 // Lookup brief documentation.
141 std::string output;
142 if(cmPropertyDefinition* def =
143 this->Makefile->GetCMakeInstance()->
144 GetPropertyDefinition(this->PropertyName.c_str(), scope))
146 output = def->GetShortDescription();
148 else
150 output = "NOTFOUND";
152 this->Makefile->AddDefinition(this->Variable.c_str(), output.c_str());
154 else if(this->InfoType == OutFullDoc)
156 // Lookup full documentation.
157 std::string output;
158 if(cmPropertyDefinition* def =
159 this->Makefile->GetCMakeInstance()->
160 GetPropertyDefinition(this->PropertyName.c_str(), scope))
162 output = def->GetFullDescription();
164 else
166 output = "NOTFOUND";
168 this->Makefile->AddDefinition(this->Variable.c_str(), output.c_str());
170 else if(this->InfoType == OutDefined)
172 // Lookup if the property is defined
173 if(this->Makefile->GetCMakeInstance()->
174 GetPropertyDefinition(this->PropertyName.c_str(), scope))
176 this->Makefile->AddDefinition(this->Variable.c_str(), "1");
178 else
180 this->Makefile->AddDefinition(this->Variable.c_str(), "0");
183 else
185 // Dispatch property getting.
186 switch(scope)
188 case cmProperty::GLOBAL: return this->HandleGlobalMode();
189 case cmProperty::DIRECTORY: return this->HandleDirectoryMode();
190 case cmProperty::TARGET: return this->HandleTargetMode();
191 case cmProperty::SOURCE_FILE: return this->HandleSourceMode();
192 case cmProperty::TEST: return this->HandleTestMode();
193 case cmProperty::VARIABLE: return this->HandleVariableMode();
194 case cmProperty::CACHE: return this->HandleCacheMode();
196 case cmProperty::CACHED_VARIABLE:
197 break; // should never happen
201 return true;
204 //----------------------------------------------------------------------------
205 bool cmGetPropertyCommand::StoreResult(const char* value)
207 if(this->InfoType == OutSet)
209 this->Makefile->AddDefinition(this->Variable.c_str(), value? "1":"0");
211 else // if(this->InfoType == OutValue)
213 if(value)
215 this->Makefile->AddDefinition(this->Variable.c_str(), value);
217 else
219 this->Makefile->RemoveDefinition(this->Variable.c_str());
222 return true;
225 //----------------------------------------------------------------------------
226 bool cmGetPropertyCommand::HandleGlobalMode()
228 if(!this->Name.empty())
230 this->SetError("given name for GLOBAL scope.");
231 return false;
234 // Get the property.
235 cmake* cm = this->Makefile->GetCMakeInstance();
236 return this->StoreResult(cm->GetProperty(this->PropertyName.c_str()));
239 //----------------------------------------------------------------------------
240 bool cmGetPropertyCommand::HandleDirectoryMode()
242 // Default to the current directory.
243 cmMakefile* mf = this->Makefile;
245 // Lookup the directory if given.
246 if(!this->Name.empty())
248 // Construct the directory name. Interpret relative paths with
249 // respect to the current directory.
250 std::string dir = this->Name;
251 if(!cmSystemTools::FileIsFullPath(dir.c_str()))
253 dir = this->Makefile->GetCurrentDirectory();
254 dir += "/";
255 dir += this->Name;
258 // The local generators are associated with collapsed paths.
259 dir = cmSystemTools::CollapseFullPath(dir.c_str());
261 // Lookup the generator.
262 if(cmLocalGenerator* lg =
263 (this->Makefile->GetLocalGenerator()
264 ->GetGlobalGenerator()->FindLocalGenerator(dir.c_str())))
266 // Use the makefile for the directory found.
267 mf = lg->GetMakefile();
269 else
271 // Could not find the directory.
272 this->SetError
273 ("DIRECTORY scope provided but requested directory was not found. "
274 "This could be because the directory argument was invalid or, "
275 "it is valid but has not been processed yet.");
276 return false;
280 // Get the property.
281 return this->StoreResult(mf->GetProperty(this->PropertyName.c_str()));
284 //----------------------------------------------------------------------------
285 bool cmGetPropertyCommand::HandleTargetMode()
287 if(this->Name.empty())
289 this->SetError("not given name for TARGET scope.");
290 return false;
293 if(cmTarget* target = this->Makefile->FindTargetToUse(this->Name.c_str()))
295 return this->StoreResult(target->GetProperty(this->PropertyName.c_str()));
297 else
299 cmOStringStream e;
300 e << "could not find TARGET " << this->Name
301 << ". Perhaps it has not yet been created.";
302 this->SetError(e.str().c_str());
303 return false;
307 //----------------------------------------------------------------------------
308 bool cmGetPropertyCommand::HandleSourceMode()
310 if(this->Name.empty())
312 this->SetError("not given name for SOURCE scope.");
313 return false;
316 // Get the source file.
317 if(cmSourceFile* sf =
318 this->Makefile->GetOrCreateSource(this->Name.c_str()))
320 return
321 this->StoreResult(sf->GetPropertyForUser(this->PropertyName.c_str()));
323 else
325 cmOStringStream e;
326 e << "given SOURCE name that could not be found or created: "
327 << this->Name;
328 this->SetError(e.str().c_str());
329 return false;
333 //----------------------------------------------------------------------------
334 bool cmGetPropertyCommand::HandleTestMode()
336 if(this->Name.empty())
338 this->SetError("not given name for TEST scope.");
339 return false;
342 // Loop over all tests looking for matching names.
343 if(cmTest* test = this->Makefile->GetTest(this->Name.c_str()))
345 return this->StoreResult(test->GetProperty(this->PropertyName.c_str()));
348 // If not found it is an error.
349 cmOStringStream e;
350 e << "given TEST name that does not exist: " << this->Name;
351 this->SetError(e.str().c_str());
352 return false;
355 //----------------------------------------------------------------------------
356 bool cmGetPropertyCommand::HandleVariableMode()
358 if(!this->Name.empty())
360 this->SetError("given name for VARIABLE scope.");
361 return false;
364 return this->StoreResult
365 (this->Makefile->GetDefinition(this->PropertyName.c_str()));
368 //----------------------------------------------------------------------------
369 bool cmGetPropertyCommand::HandleCacheMode()
371 if(this->Name.empty())
373 this->SetError("not given name for CACHE scope.");
374 return false;
377 const char* value = 0;
378 cmCacheManager::CacheIterator it =
379 this->Makefile->GetCacheManager()->GetCacheIterator(this->Name.c_str());
380 if(!it.IsAtEnd())
382 value = it.GetProperty(this->PropertyName.c_str());
384 this->StoreResult(value);
385 return true;