Initial commit.
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmGetPropertyCommand.cxx
blob15fac9b89e932f6ea459b23388d97093ba0dea2f
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmGetPropertyCommand.cxx,v $
5 Language: C++
6 Date: $Date: 2008/01/30 16:21:54 $
7 Version: $Revision: 1.7 $
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
70 cmOStringStream e;
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());
75 return false;
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")
89 doing = DoingNone;
90 this->InfoType = OutBriefDoc;
92 else if(args[i] == "FULL_DOCS")
94 doing = DoingNone;
95 this->InfoType = OutFullDoc;
97 else if(args[i] == "DEFINED")
99 doing = DoingNone;
100 this->InfoType = OutDefined;
102 else if(doing == DoingName)
104 doing = DoingNone;
105 this->Name = args[i];
107 else if(doing == DoingProperty)
109 doing = DoingNone;
110 this->PropertyName = args[i];
112 else
114 cmOStringStream e;
115 e << "given invalid argument \"" << args[i] << "\".";
116 this->SetError(e.str().c_str());
117 return false;
121 // Make sure a property name was found.
122 if(this->PropertyName.empty())
124 this->SetError("not given a PROPERTY <name> argument.");
125 return false;
128 // Compute requested output.
129 if(this->InfoType == OutBriefDoc)
131 // Lookup brief documentation.
132 std::string output;
133 if(cmPropertyDefinition* def =
134 this->Makefile->GetCMakeInstance()->
135 GetPropertyDefinition(this->PropertyName.c_str(), scope))
137 output = def->GetShortDescription();
139 else
141 output = "NOTFOUND";
143 this->Makefile->AddDefinition(this->Variable.c_str(), output.c_str());
145 else if(this->InfoType == OutFullDoc)
147 // Lookup full documentation.
148 std::string output;
149 if(cmPropertyDefinition* def =
150 this->Makefile->GetCMakeInstance()->
151 GetPropertyDefinition(this->PropertyName.c_str(), scope))
153 output = def->GetFullDescription();
155 else
157 output = "NOTFOUND";
159 this->Makefile->AddDefinition(this->Variable.c_str(), output.c_str());
161 else
163 // Dispatch property getting.
164 switch(scope)
166 case cmProperty::GLOBAL: return this->HandleGlobalMode();
167 case cmProperty::DIRECTORY: return this->HandleDirectoryMode();
168 case cmProperty::TARGET: return this->HandleTargetMode();
169 case cmProperty::SOURCE_FILE: return this->HandleSourceMode();
170 case cmProperty::TEST: return this->HandleTestMode();
171 case cmProperty::VARIABLE: return this->HandleVariableMode();
173 case cmProperty::CACHED_VARIABLE:
174 break; // should never happen
178 return true;
181 //----------------------------------------------------------------------------
182 bool cmGetPropertyCommand::StoreResult(const char* value)
184 if(this->InfoType == OutDefined)
186 this->Makefile->AddDefinition(this->Variable.c_str(), value? "1":"0");
188 else // if(this->InfoType == OutValue)
190 this->Makefile->AddDefinition(this->Variable.c_str(), value);
192 return true;
195 //----------------------------------------------------------------------------
196 bool cmGetPropertyCommand::HandleGlobalMode()
198 if(!this->Name.empty())
200 this->SetError("given name for GLOBAL scope.");
201 return false;
204 // Get the property.
205 cmake* cm = this->Makefile->GetCMakeInstance();
206 return this->StoreResult(cm->GetProperty(this->PropertyName.c_str()));
209 //----------------------------------------------------------------------------
210 bool cmGetPropertyCommand::HandleDirectoryMode()
212 // Default to the current directory.
213 cmMakefile* mf = this->Makefile;
215 // Lookup the directory if given.
216 if(!this->Name.empty())
218 // Construct the directory name. Interpret relative paths with
219 // respect to the current directory.
220 std::string dir = this->Name;
221 if(!cmSystemTools::FileIsFullPath(dir.c_str()))
223 dir = this->Makefile->GetCurrentDirectory();
224 dir += "/";
225 dir += this->Name;
228 // The local generators are associated with collapsed paths.
229 dir = cmSystemTools::CollapseFullPath(dir.c_str());
231 // Lookup the generator.
232 if(cmLocalGenerator* lg =
233 (this->Makefile->GetLocalGenerator()
234 ->GetGlobalGenerator()->FindLocalGenerator(dir.c_str())))
236 // Use the makefile for the directory found.
237 mf = lg->GetMakefile();
239 else
241 // Could not find the directory.
242 this->SetError
243 ("DIRECTORY scope provided but requested directory was not found. "
244 "This could be because the directory argument was invalid or, "
245 "it is valid but has not been processed yet.");
246 return false;
250 // Get the property.
251 return this->StoreResult(mf->GetProperty(this->PropertyName.c_str()));
254 //----------------------------------------------------------------------------
255 bool cmGetPropertyCommand::HandleTargetMode()
257 if(this->Name.empty())
259 this->SetError("not given name for TARGET scope.");
260 return false;
263 if(cmTarget* target = this->Makefile->FindTargetToUse(this->Name.c_str()))
265 return this->StoreResult(target->GetProperty(this->PropertyName.c_str()));
267 else
269 cmOStringStream e;
270 e << "could not find TARGET " << this->Name
271 << ". Perhaps it has not yet been created.";
272 this->SetError(e.str().c_str());
273 return false;
277 //----------------------------------------------------------------------------
278 bool cmGetPropertyCommand::HandleSourceMode()
280 if(this->Name.empty())
282 this->SetError("not given name for SOURCE scope.");
283 return false;
286 // Get the source file.
287 if(cmSourceFile* sf =
288 this->Makefile->GetOrCreateSource(this->Name.c_str()))
290 return
291 this->StoreResult(sf->GetPropertyForUser(this->PropertyName.c_str()));
293 else
295 cmOStringStream e;
296 e << "given SOURCE name that could not be found or created: "
297 << this->Name;
298 this->SetError(e.str().c_str());
299 return false;
303 //----------------------------------------------------------------------------
304 bool cmGetPropertyCommand::HandleTestMode()
306 if(this->Name.empty())
308 this->SetError("not given name for TEST scope.");
309 return false;
312 // Loop over all tests looking for matching names.
313 std::vector<cmTest*> const& tests = *this->Makefile->GetTests();
314 for(std::vector<cmTest*>::const_iterator ti = tests.begin();
315 ti != tests.end(); ++ti)
317 cmTest* test = *ti;
318 if(test->GetName() == this->Name)
320 return this->StoreResult(test->GetProperty(this->PropertyName.c_str()));
324 // If not found it is an error.
325 cmOStringStream e;
326 e << "given TEST name that does not exist: " << this->Name;
327 this->SetError(e.str().c_str());
328 return false;
331 //----------------------------------------------------------------------------
332 bool cmGetPropertyCommand::HandleVariableMode()
334 if(!this->Name.empty())
336 this->SetError("given name for VARIABLE scope.");
337 return false;
340 return this->StoreResult
341 (this->Makefile->GetDefinition(this->PropertyName.c_str()));