1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmGetPropertyCommand.cxx,v $
6 Date: $Date: 2008-04-01 19:22:30 $
7 Version: $Revision: 1.9 $
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
;
71 e
<< "given invalid scope " << args
[1] << ". "
72 << "Valid scopes are "
73 << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE.";
74 this->SetError(e
.str().c_str());
78 // Parse remaining arguments.
79 enum Doing
{ DoingNone
, DoingName
, DoingProperty
, DoingType
};
80 Doing doing
= DoingName
;
81 for(unsigned int i
=2; i
< args
.size(); ++i
)
83 if(args
[i
] == "PROPERTY")
85 doing
= DoingProperty
;
87 else if(args
[i
] == "BRIEF_DOCS")
90 this->InfoType
= OutBriefDoc
;
92 else if(args
[i
] == "FULL_DOCS")
95 this->InfoType
= OutFullDoc
;
97 else if(args
[i
] == "SET")
100 this->InfoType
= OutSet
;
102 else if(args
[i
] == "DEFINED")
105 this->InfoType
= OutDefined
;
107 else if(doing
== DoingName
)
110 this->Name
= args
[i
];
112 else if(doing
== DoingProperty
)
115 this->PropertyName
= args
[i
];
120 e
<< "given invalid argument \"" << args
[i
] << "\".";
121 this->SetError(e
.str().c_str());
126 // Make sure a property name was found.
127 if(this->PropertyName
.empty())
129 this->SetError("not given a PROPERTY <name> argument.");
133 // Compute requested output.
134 if(this->InfoType
== OutBriefDoc
)
136 // Lookup brief documentation.
138 if(cmPropertyDefinition
* def
=
139 this->Makefile
->GetCMakeInstance()->
140 GetPropertyDefinition(this->PropertyName
.c_str(), scope
))
142 output
= def
->GetShortDescription();
148 this->Makefile
->AddDefinition(this->Variable
.c_str(), output
.c_str());
150 else if(this->InfoType
== OutFullDoc
)
152 // Lookup full documentation.
154 if(cmPropertyDefinition
* def
=
155 this->Makefile
->GetCMakeInstance()->
156 GetPropertyDefinition(this->PropertyName
.c_str(), scope
))
158 output
= def
->GetFullDescription();
164 this->Makefile
->AddDefinition(this->Variable
.c_str(), output
.c_str());
166 else if(this->InfoType
== OutDefined
)
168 // Lookup if the property is defined
169 if(this->Makefile
->GetCMakeInstance()->
170 GetPropertyDefinition(this->PropertyName
.c_str(), scope
))
172 this->Makefile
->AddDefinition(this->Variable
.c_str(), "1");
176 this->Makefile
->AddDefinition(this->Variable
.c_str(), "0");
181 // Dispatch property getting.
184 case cmProperty::GLOBAL
: return this->HandleGlobalMode();
185 case cmProperty::DIRECTORY
: return this->HandleDirectoryMode();
186 case cmProperty::TARGET
: return this->HandleTargetMode();
187 case cmProperty::SOURCE_FILE
: return this->HandleSourceMode();
188 case cmProperty::TEST
: return this->HandleTestMode();
189 case cmProperty::VARIABLE
: return this->HandleVariableMode();
191 case cmProperty::CACHED_VARIABLE
:
192 break; // should never happen
199 //----------------------------------------------------------------------------
200 bool cmGetPropertyCommand::StoreResult(const char* value
)
202 if(this->InfoType
== OutSet
)
204 this->Makefile
->AddDefinition(this->Variable
.c_str(), value
? "1":"0");
206 else // if(this->InfoType == OutValue)
208 this->Makefile
->AddDefinition(this->Variable
.c_str(), value
);
213 //----------------------------------------------------------------------------
214 bool cmGetPropertyCommand::HandleGlobalMode()
216 if(!this->Name
.empty())
218 this->SetError("given name for GLOBAL scope.");
223 cmake
* cm
= this->Makefile
->GetCMakeInstance();
224 return this->StoreResult(cm
->GetProperty(this->PropertyName
.c_str()));
227 //----------------------------------------------------------------------------
228 bool cmGetPropertyCommand::HandleDirectoryMode()
230 // Default to the current directory.
231 cmMakefile
* mf
= this->Makefile
;
233 // Lookup the directory if given.
234 if(!this->Name
.empty())
236 // Construct the directory name. Interpret relative paths with
237 // respect to the current directory.
238 std::string dir
= this->Name
;
239 if(!cmSystemTools::FileIsFullPath(dir
.c_str()))
241 dir
= this->Makefile
->GetCurrentDirectory();
246 // The local generators are associated with collapsed paths.
247 dir
= cmSystemTools::CollapseFullPath(dir
.c_str());
249 // Lookup the generator.
250 if(cmLocalGenerator
* lg
=
251 (this->Makefile
->GetLocalGenerator()
252 ->GetGlobalGenerator()->FindLocalGenerator(dir
.c_str())))
254 // Use the makefile for the directory found.
255 mf
= lg
->GetMakefile();
259 // Could not find the directory.
261 ("DIRECTORY scope provided but requested directory was not found. "
262 "This could be because the directory argument was invalid or, "
263 "it is valid but has not been processed yet.");
269 return this->StoreResult(mf
->GetProperty(this->PropertyName
.c_str()));
272 //----------------------------------------------------------------------------
273 bool cmGetPropertyCommand::HandleTargetMode()
275 if(this->Name
.empty())
277 this->SetError("not given name for TARGET scope.");
281 if(cmTarget
* target
= this->Makefile
->FindTargetToUse(this->Name
.c_str()))
283 return this->StoreResult(target
->GetProperty(this->PropertyName
.c_str()));
288 e
<< "could not find TARGET " << this->Name
289 << ". Perhaps it has not yet been created.";
290 this->SetError(e
.str().c_str());
295 //----------------------------------------------------------------------------
296 bool cmGetPropertyCommand::HandleSourceMode()
298 if(this->Name
.empty())
300 this->SetError("not given name for SOURCE scope.");
304 // Get the source file.
305 if(cmSourceFile
* sf
=
306 this->Makefile
->GetOrCreateSource(this->Name
.c_str()))
309 this->StoreResult(sf
->GetPropertyForUser(this->PropertyName
.c_str()));
314 e
<< "given SOURCE name that could not be found or created: "
316 this->SetError(e
.str().c_str());
321 //----------------------------------------------------------------------------
322 bool cmGetPropertyCommand::HandleTestMode()
324 if(this->Name
.empty())
326 this->SetError("not given name for TEST scope.");
330 // Loop over all tests looking for matching names.
331 std::vector
<cmTest
*> const& tests
= *this->Makefile
->GetTests();
332 for(std::vector
<cmTest
*>::const_iterator ti
= tests
.begin();
333 ti
!= tests
.end(); ++ti
)
336 if(test
->GetName() == this->Name
)
338 return this->StoreResult(test
->GetProperty(this->PropertyName
.c_str()));
342 // If not found it is an error.
344 e
<< "given TEST name that does not exist: " << this->Name
;
345 this->SetError(e
.str().c_str());
349 //----------------------------------------------------------------------------
350 bool cmGetPropertyCommand::HandleVariableMode()
352 if(!this->Name
.empty())
354 this->SetError("given name for VARIABLE scope.");
358 return this->StoreResult
359 (this->Makefile
->GetDefinition(this->PropertyName
.c_str()));