1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmGetPropertyCommand.cxx,v $
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"
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
&)
35 this->SetError("called with incorrect number of arguments");
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
;
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());
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")
94 this->InfoType
= OutBriefDoc
;
96 else if(args
[i
] == "FULL_DOCS")
99 this->InfoType
= OutFullDoc
;
101 else if(args
[i
] == "SET")
104 this->InfoType
= OutSet
;
106 else if(args
[i
] == "DEFINED")
109 this->InfoType
= OutDefined
;
111 else if(doing
== DoingName
)
114 this->Name
= args
[i
];
116 else if(doing
== DoingProperty
)
119 this->PropertyName
= args
[i
];
124 e
<< "given invalid argument \"" << args
[i
] << "\".";
125 this->SetError(e
.str().c_str());
130 // Make sure a property name was found.
131 if(this->PropertyName
.empty())
133 this->SetError("not given a PROPERTY <name> argument.");
137 // Compute requested output.
138 if(this->InfoType
== OutBriefDoc
)
140 // Lookup brief documentation.
142 if(cmPropertyDefinition
* def
=
143 this->Makefile
->GetCMakeInstance()->
144 GetPropertyDefinition(this->PropertyName
.c_str(), scope
))
146 output
= def
->GetShortDescription();
152 this->Makefile
->AddDefinition(this->Variable
.c_str(), output
.c_str());
154 else if(this->InfoType
== OutFullDoc
)
156 // Lookup full documentation.
158 if(cmPropertyDefinition
* def
=
159 this->Makefile
->GetCMakeInstance()->
160 GetPropertyDefinition(this->PropertyName
.c_str(), scope
))
162 output
= def
->GetFullDescription();
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");
180 this->Makefile
->AddDefinition(this->Variable
.c_str(), "0");
185 // Dispatch property getting.
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
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)
215 this->Makefile
->AddDefinition(this->Variable
.c_str(), value
);
219 this->Makefile
->RemoveDefinition(this->Variable
.c_str());
225 //----------------------------------------------------------------------------
226 bool cmGetPropertyCommand::HandleGlobalMode()
228 if(!this->Name
.empty())
230 this->SetError("given name for GLOBAL scope.");
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();
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();
271 // Could not find the directory.
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.");
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.");
293 if(cmTarget
* target
= this->Makefile
->FindTargetToUse(this->Name
.c_str()))
295 return this->StoreResult(target
->GetProperty(this->PropertyName
.c_str()));
300 e
<< "could not find TARGET " << this->Name
301 << ". Perhaps it has not yet been created.";
302 this->SetError(e
.str().c_str());
307 //----------------------------------------------------------------------------
308 bool cmGetPropertyCommand::HandleSourceMode()
310 if(this->Name
.empty())
312 this->SetError("not given name for SOURCE scope.");
316 // Get the source file.
317 if(cmSourceFile
* sf
=
318 this->Makefile
->GetOrCreateSource(this->Name
.c_str()))
321 this->StoreResult(sf
->GetPropertyForUser(this->PropertyName
.c_str()));
326 e
<< "given SOURCE name that could not be found or created: "
328 this->SetError(e
.str().c_str());
333 //----------------------------------------------------------------------------
334 bool cmGetPropertyCommand::HandleTestMode()
336 if(this->Name
.empty())
338 this->SetError("not given name for TEST scope.");
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.
350 e
<< "given TEST name that does not exist: " << this->Name
;
351 this->SetError(e
.str().c_str());
355 //----------------------------------------------------------------------------
356 bool cmGetPropertyCommand::HandleVariableMode()
358 if(!this->Name
.empty())
360 this->SetError("given name for VARIABLE scope.");
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.");
377 const char* value
= 0;
378 cmCacheManager::CacheIterator it
=
379 this->Makefile
->GetCacheManager()->GetCacheIterator(this->Name
.c_str());
382 value
= it
.GetProperty(this->PropertyName
.c_str());
384 this->StoreResult(value
);