diff options
Diffstat (limited to 'Source/cmGetPropertyCommand.cxx')
-rw-r--r-- | Source/cmGetPropertyCommand.cxx | 432 |
1 files changed, 432 insertions, 0 deletions
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx new file mode 100644 index 0000000..3c59c25 --- /dev/null +++ b/Source/cmGetPropertyCommand.cxx @@ -0,0 +1,432 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmGetPropertyCommand.h" + +#include "cmake.h" +#include "cmTest.h" +#include "cmGlobalGenerator.h" +#include "cmLocalGenerator.h" +#include "cmSourceFile.h" +#include "cmPropertyDefinition.h" + +//---------------------------------------------------------------------------- +cmGetPropertyCommand::cmGetPropertyCommand() +{ + this->InfoType = OutValue; +} + +//---------------------------------------------------------------------------- +bool cmGetPropertyCommand +::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) +{ + if(args.size() < 3 ) + { + this->SetError("called with incorrect number of arguments"); + return false; + } + + // The cmake variable in which to store the result. + this->Variable = args[0]; + + // Get the scope from which to get the property. + cmProperty::ScopeType scope; + if(args[1] == "GLOBAL") + { + scope = cmProperty::GLOBAL; + } + else if(args[1] == "DIRECTORY") + { + scope = cmProperty::DIRECTORY; + } + else if(args[1] == "TARGET") + { + scope = cmProperty::TARGET; + } + else if(args[1] == "SOURCE") + { + scope = cmProperty::SOURCE_FILE; + } + else if(args[1] == "TEST") + { + scope = cmProperty::TEST; + } + else if(args[1] == "VARIABLE") + { + scope = cmProperty::VARIABLE; + } + else if(args[1] == "CACHE") + { + scope = cmProperty::CACHE; + } + else if(args[1] == "INSTALL") + { + scope = cmProperty::INSTALL; + } + else + { + cmOStringStream e; + e << "given invalid scope " << args[1] << ". " + << "Valid scopes are " + << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL."; + this->SetError(e.str()); + return false; + } + + // Parse remaining arguments. + enum Doing { DoingNone, DoingName, DoingProperty, DoingType }; + Doing doing = DoingName; + for(unsigned int i=2; i < args.size(); ++i) + { + if(args[i] == "PROPERTY") + { + doing = DoingProperty; + } + else if(args[i] == "BRIEF_DOCS") + { + doing = DoingNone; + this->InfoType = OutBriefDoc; + } + else if(args[i] == "FULL_DOCS") + { + doing = DoingNone; + this->InfoType = OutFullDoc; + } + else if(args[i] == "SET") + { + doing = DoingNone; + this->InfoType = OutSet; + } + else if(args[i] == "DEFINED") + { + doing = DoingNone; + this->InfoType = OutDefined; + } + else if(doing == DoingName) + { + doing = DoingNone; + this->Name = args[i]; + } + else if(doing == DoingProperty) + { + doing = DoingNone; + this->PropertyName = args[i]; + } + else + { + cmOStringStream e; + e << "given invalid argument \"" << args[i] << "\"."; + this->SetError(e.str()); + return false; + } + } + + // Make sure a property name was found. + if(this->PropertyName.empty()) + { + this->SetError("not given a PROPERTY <name> argument."); + return false; + } + + // Compute requested output. + if(this->InfoType == OutBriefDoc) + { + // Lookup brief documentation. + std::string output; + if(cmPropertyDefinition* def = + this->Makefile->GetCMakeInstance()-> + GetPropertyDefinition(this->PropertyName, scope)) + { + output = def->GetShortDescription(); + } + else + { + output = "NOTFOUND"; + } + this->Makefile->AddDefinition(this->Variable, output.c_str()); + } + else if(this->InfoType == OutFullDoc) + { + // Lookup full documentation. + std::string output; + if(cmPropertyDefinition* def = + this->Makefile->GetCMakeInstance()-> + GetPropertyDefinition(this->PropertyName, scope)) + { + output = def->GetFullDescription(); + } + else + { + output = "NOTFOUND"; + } + this->Makefile->AddDefinition(this->Variable, output.c_str()); + } + else if(this->InfoType == OutDefined) + { + // Lookup if the property is defined + if(this->Makefile->GetCMakeInstance()-> + GetPropertyDefinition(this->PropertyName, scope)) + { + this->Makefile->AddDefinition(this->Variable, "1"); + } + else + { + this->Makefile->AddDefinition(this->Variable, "0"); + } + } + else + { + // Dispatch property getting. + switch(scope) + { + case cmProperty::GLOBAL: return this->HandleGlobalMode(); + case cmProperty::DIRECTORY: return this->HandleDirectoryMode(); + case cmProperty::TARGET: return this->HandleTargetMode(); + case cmProperty::SOURCE_FILE: return this->HandleSourceMode(); + case cmProperty::TEST: return this->HandleTestMode(); + case cmProperty::VARIABLE: return this->HandleVariableMode(); + case cmProperty::CACHE: return this->HandleCacheMode(); + case cmProperty::INSTALL: return this->HandleInstallMode(); + + case cmProperty::CACHED_VARIABLE: + break; // should never happen + } + } + + return true; +} + +//---------------------------------------------------------------------------- +bool cmGetPropertyCommand::StoreResult(const char* value) +{ + if(this->InfoType == OutSet) + { + this->Makefile->AddDefinition(this->Variable, value? "1":"0"); + } + else // if(this->InfoType == OutValue) + { + if(value) + { + this->Makefile->AddDefinition(this->Variable, value); + } + else + { + this->Makefile->RemoveDefinition(this->Variable); + } + } + return true; +} + +//---------------------------------------------------------------------------- +bool cmGetPropertyCommand::HandleGlobalMode() +{ + if(!this->Name.empty()) + { + this->SetError("given name for GLOBAL scope."); + return false; + } + + // Get the property. + cmake* cm = this->Makefile->GetCMakeInstance(); + return this->StoreResult(cm->GetProperty(this->PropertyName)); +} + +//---------------------------------------------------------------------------- +bool cmGetPropertyCommand::HandleDirectoryMode() +{ + // Default to the current directory. + cmMakefile* mf = this->Makefile; + + // Lookup the directory if given. + if(!this->Name.empty()) + { + // Construct the directory name. Interpret relative paths with + // respect to the current directory. + std::string dir = this->Name; + if(!cmSystemTools::FileIsFullPath(dir.c_str())) + { + dir = this->Makefile->GetCurrentDirectory(); + dir += "/"; + dir += this->Name; + } + + // The local generators are associated with collapsed paths. + dir = cmSystemTools::CollapseFullPath(dir); + + // Lookup the generator. + if(cmLocalGenerator* lg = + (this->Makefile->GetLocalGenerator() + ->GetGlobalGenerator()->FindLocalGenerator(dir))) + { + // Use the makefile for the directory found. + mf = lg->GetMakefile(); + } + else + { + // Could not find the directory. + this->SetError + ("DIRECTORY scope provided but requested directory was not found. " + "This could be because the directory argument was invalid or, " + "it is valid but has not been processed yet."); + return false; + } + } + + // Get the property. + return this->StoreResult(mf->GetProperty(this->PropertyName)); +} + +//---------------------------------------------------------------------------- +bool cmGetPropertyCommand::HandleTargetMode() +{ + if(this->Name.empty()) + { + this->SetError("not given name for TARGET scope."); + return false; + } + + if(this->PropertyName == "ALIASED_TARGET") + { + if(this->Makefile->IsAlias(this->Name)) + { + if(cmTarget* target = + this->Makefile->FindTargetToUse(this->Name)) + { + return this->StoreResult(target->GetName().c_str()); + } + } + return this->StoreResult((this->Variable + "-NOTFOUND").c_str()); + } + if(cmTarget* target = this->Makefile->FindTargetToUse(this->Name)) + { + return this->StoreResult(target->GetProperty(this->PropertyName, + this->Makefile)); + } + else + { + cmOStringStream e; + e << "could not find TARGET " << this->Name + << ". Perhaps it has not yet been created."; + this->SetError(e.str()); + return false; + } +} + +//---------------------------------------------------------------------------- +bool cmGetPropertyCommand::HandleSourceMode() +{ + if(this->Name.empty()) + { + this->SetError("not given name for SOURCE scope."); + return false; + } + + // Get the source file. + if(cmSourceFile* sf = + this->Makefile->GetOrCreateSource(this->Name)) + { + return + this->StoreResult(sf->GetPropertyForUser(this->PropertyName)); + } + else + { + cmOStringStream e; + e << "given SOURCE name that could not be found or created: " + << this->Name; + this->SetError(e.str()); + return false; + } +} + +//---------------------------------------------------------------------------- +bool cmGetPropertyCommand::HandleTestMode() +{ + if(this->Name.empty()) + { + this->SetError("not given name for TEST scope."); + return false; + } + + // Loop over all tests looking for matching names. + if(cmTest* test = this->Makefile->GetTest(this->Name)) + { + return this->StoreResult(test->GetProperty(this->PropertyName)); + } + + // If not found it is an error. + cmOStringStream e; + e << "given TEST name that does not exist: " << this->Name; + this->SetError(e.str()); + return false; +} + +//---------------------------------------------------------------------------- +bool cmGetPropertyCommand::HandleVariableMode() +{ + if(!this->Name.empty()) + { + this->SetError("given name for VARIABLE scope."); + return false; + } + + return this->StoreResult + (this->Makefile->GetDefinition(this->PropertyName)); +} + +//---------------------------------------------------------------------------- +bool cmGetPropertyCommand::HandleCacheMode() +{ + if(this->Name.empty()) + { + this->SetError("not given name for CACHE scope."); + return false; + } + + const char* value = 0; + cmCacheManager::CacheIterator it = + this->Makefile->GetCacheManager()->GetCacheIterator(this->Name.c_str()); + if(!it.IsAtEnd()) + { + value = it.GetProperty(this->PropertyName); + } + this->StoreResult(value); + return true; +} + +//---------------------------------------------------------------------------- +bool cmGetPropertyCommand::HandleInstallMode() +{ + if(this->Name.empty()) + { + this->SetError("not given name for INSTALL scope."); + return false; + } + + // Get the installed file. + cmake* cm = this->Makefile->GetCMakeInstance(); + + if(cmInstalledFile* file = cm->GetOrCreateInstalledFile( + this->Makefile, this->Name)) + { + std::string value; + bool isSet = file->GetProperty(this->PropertyName, value); + + return this->StoreResult(isSet ? value.c_str() : 0); + } + else + { + cmOStringStream e; + e << "given INSTALL name that could not be found or created: " + << this->Name; + this->SetError(e.str()); + return false; + } +} |