CMake/Source/cmState.cxx

846 lines
26 KiB
C++
Raw Normal View History

Simplify CMake per-source license notices Per-source copyright/license notice headers that spell out copyright holder names and years are hard to maintain and often out-of-date or plain wrong. Precise contributor information is already maintained automatically by the version control tool. Ultimately it is the receiver of a file who is responsible for determining its licensing status, and per-source notices are merely a convenience. Therefore it is simpler and more accurate for each source to have a generic notice of the license name and references to more detailed information on copyright holders and full license terms. Our `Copyright.txt` file now contains a list of Contributors whose names appeared source-level copyright notices. It also references version control history for more precise information. Therefore we no longer need to spell out the list of Contributors in each source file notice. Replace CMake per-source copyright/license notice headers with a short description of the license and links to `Copyright.txt` and online information available from "https://cmake.org/licensing". The online URL also handles cases of modules being copied out of our source into other projects, so we can drop our notices about replacing links with full license text. Run the `Utilities/Scripts/filter-notices.bash` script to perform the majority of the replacements mechanically. Manually fix up shebang lines and trailing newlines in a few files. Manually update the notices in a few files that the script does not handle.
2016-09-27 19:01:08 +00:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmState.h"
#include <algorithm>
#include <assert.h>
#include <cmsys/RegularExpression.hxx>
#include <string.h>
#include <utility>
#include "cmAlgorithms.h"
#include "cmCacheManager.h"
#include "cmCommand.h"
2015-06-21 19:26:43 +00:00
#include "cmDefinitions.h"
#include "cmListFileCache.h"
#include "cmStatePrivate.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
#include "cmake.h"
cmState::cmState()
: IsInTryCompile(false)
, WindowsShell(false)
, WindowsVSIDE(false)
, WatcomWMake(false)
, MinGWMake(false)
, NMake(false)
, MSYSShell(false)
{
this->CacheManager = new cmCacheManager;
}
cmState::~cmState()
{
delete this->CacheManager;
cmDeleteAll(this->Commands);
}
const char* cmState::GetTargetTypeName(cmStateEnums::TargetType targetType)
{
switch (targetType) {
case cmStateEnums::STATIC_LIBRARY:
return "STATIC_LIBRARY";
case cmStateEnums::MODULE_LIBRARY:
return "MODULE_LIBRARY";
case cmStateEnums::SHARED_LIBRARY:
return "SHARED_LIBRARY";
case cmStateEnums::OBJECT_LIBRARY:
return "OBJECT_LIBRARY";
case cmStateEnums::EXECUTABLE:
return "EXECUTABLE";
case cmStateEnums::UTILITY:
return "UTILITY";
case cmStateEnums::GLOBAL_TARGET:
return "GLOBAL_TARGET";
case cmStateEnums::INTERFACE_LIBRARY:
return "INTERFACE_LIBRARY";
case cmStateEnums::UNKNOWN_LIBRARY:
return "UNKNOWN_LIBRARY";
}
assert(false && "Unexpected target type");
2016-06-27 20:44:16 +00:00
return CM_NULLPTR;
}
const char* cmCacheEntryTypes[] = { "BOOL", "PATH", "FILEPATH",
"STRING", "INTERNAL", "STATIC",
2016-06-27 20:44:16 +00:00
"UNINITIALIZED", CM_NULLPTR };
const char* cmState::CacheEntryTypeToString(cmStateEnums::CacheEntryType type)
{
if (type > 6) {
return cmCacheEntryTypes[6];
}
return cmCacheEntryTypes[type];
}
cmStateEnums::CacheEntryType cmState::StringToCacheEntryType(const char* s)
{
int i = 0;
while (cmCacheEntryTypes[i]) {
if (strcmp(s, cmCacheEntryTypes[i]) == 0) {
return static_cast<cmStateEnums::CacheEntryType>(i);
}
++i;
}
return cmStateEnums::STRING;
}
bool cmState::IsCacheEntryType(std::string const& key)
{
for (int i = 0; cmCacheEntryTypes[i]; ++i) {
if (strcmp(key.c_str(), cmCacheEntryTypes[i]) == 0) {
return true;
}
}
return false;
}
bool cmState::LoadCache(const std::string& path, bool internal,
std::set<std::string>& excludes,
std::set<std::string>& includes)
{
return this->CacheManager->LoadCache(path, internal, excludes, includes);
}
bool cmState::SaveCache(const std::string& path)
{
return this->CacheManager->SaveCache(path);
}
bool cmState::DeleteCache(const std::string& path)
{
return this->CacheManager->DeleteCache(path);
}
std::vector<std::string> cmState::GetCacheEntryKeys() const
{
std::vector<std::string> definitions;
definitions.reserve(this->CacheManager->GetSize());
cmCacheManager::CacheIterator cit = this->CacheManager->GetCacheIterator();
for (cit.Begin(); !cit.IsAtEnd(); cit.Next()) {
definitions.push_back(cit.GetName());
}
return definitions;
}
const char* cmState::GetCacheEntryValue(std::string const& key) const
{
cmCacheManager::CacheEntry* e = this->CacheManager->GetCacheEntry(key);
if (!e) {
2016-06-27 20:44:16 +00:00
return CM_NULLPTR;
}
return e->Value.c_str();
}
const char* cmState::GetInitializedCacheValue(std::string const& key) const
{
return this->CacheManager->GetInitializedCacheValue(key);
}
cmStateEnums::CacheEntryType cmState::GetCacheEntryType(
std::string const& key) const
{
cmCacheManager::CacheIterator it =
this->CacheManager->GetCacheIterator(key.c_str());
return it.GetType();
}
void cmState::SetCacheEntryValue(std::string const& key,
std::string const& value)
{
this->CacheManager->SetCacheEntryValue(key, value);
}
void cmState::SetCacheEntryProperty(std::string const& key,
std::string const& propertyName,
std::string const& value)
{
cmCacheManager::CacheIterator it =
this->CacheManager->GetCacheIterator(key.c_str());
it.SetProperty(propertyName, value.c_str());
}
void cmState::SetCacheEntryBoolProperty(std::string const& key,
std::string const& propertyName,
bool value)
{
cmCacheManager::CacheIterator it =
this->CacheManager->GetCacheIterator(key.c_str());
it.SetProperty(propertyName, value);
}
std::vector<std::string> cmState::GetCacheEntryPropertyList(
const std::string& key)
{
cmCacheManager::CacheIterator it =
this->CacheManager->GetCacheIterator(key.c_str());
return it.GetPropertyList();
}
const char* cmState::GetCacheEntryProperty(std::string const& key,
std::string const& propertyName)
{
cmCacheManager::CacheIterator it =
this->CacheManager->GetCacheIterator(key.c_str());
if (!it.PropertyExists(propertyName)) {
2016-06-27 20:44:16 +00:00
return CM_NULLPTR;
}
return it.GetProperty(propertyName);
}
bool cmState::GetCacheEntryPropertyAsBool(std::string const& key,
std::string const& propertyName)
{
return this->CacheManager->GetCacheIterator(key.c_str())
.GetPropertyAsBool(propertyName);
}
void cmState::AddCacheEntry(const std::string& key, const char* value,
const char* helpString,
cmStateEnums::CacheEntryType type)
{
this->CacheManager->AddCacheEntry(key, value, helpString, type);
}
void cmState::RemoveCacheEntry(std::string const& key)
{
this->CacheManager->RemoveCacheEntry(key);
}
void cmState::AppendCacheEntryProperty(const std::string& key,
const std::string& property,
const std::string& value, bool asString)
{
this->CacheManager->GetCacheIterator(key.c_str())
.AppendProperty(property, value.c_str(), asString);
}
void cmState::RemoveCacheEntryProperty(std::string const& key,
std::string const& propertyName)
{
this->CacheManager->GetCacheIterator(key.c_str())
2016-06-27 20:44:16 +00:00
.SetProperty(propertyName, (void*)CM_NULLPTR);
}
2015-04-04 21:33:26 +00:00
cmStateSnapshot cmState::Reset()
2015-04-04 21:33:26 +00:00
{
2015-04-11 12:17:46 +00:00
this->GlobalProperties.clear();
2015-04-04 21:33:26 +00:00
this->PropertyDefinitions.clear();
cmStateDetail::PositionType pos = this->SnapshotData.Truncate();
this->ExecutionListFiles.Truncate();
{
cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator it =
this->BuildsystemDirectory.Truncate();
it->IncludeDirectories.clear();
it->IncludeDirectoryBacktraces.clear();
it->CompileDefinitions.clear();
it->CompileDefinitionsBacktraces.clear();
it->CompileOptions.clear();
it->CompileOptionsBacktraces.clear();
it->DirectoryEnd = pos;
it->NormalTargetNames.clear();
it->Properties.clear();
it->Children.clear();
}
this->PolicyStack.Clear();
pos->Policies = this->PolicyStack.Root();
pos->PolicyRoot = this->PolicyStack.Root();
pos->PolicyScope = this->PolicyStack.Root();
assert(pos->Policies.IsValid());
assert(pos->PolicyRoot.IsValid());
{
std::string srcDir =
cmDefinitions::Get("CMAKE_SOURCE_DIR", pos->Vars, pos->Root);
std::string binDir =
cmDefinitions::Get("CMAKE_BINARY_DIR", pos->Vars, pos->Root);
this->VarTree.Clear();
pos->Vars = this->VarTree.Push(this->VarTree.Root());
pos->Parent = this->VarTree.Root();
pos->Root = this->VarTree.Root();
pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir.c_str());
pos->Vars->Set("CMAKE_BINARY_DIR", binDir.c_str());
}
this->DefineProperty("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY, "", "",
true);
this->DefineProperty("RULE_LAUNCH_LINK", cmProperty::DIRECTORY, "", "",
true);
this->DefineProperty("RULE_LAUNCH_CUSTOM", cmProperty::DIRECTORY, "", "",
true);
this->DefineProperty("RULE_LAUNCH_COMPILE", cmProperty::TARGET, "", "",
true);
this->DefineProperty("RULE_LAUNCH_LINK", cmProperty::TARGET, "", "", true);
this->DefineProperty("RULE_LAUNCH_CUSTOM", cmProperty::TARGET, "", "", true);
return cmStateSnapshot(this, pos);
2015-04-04 21:33:26 +00:00
}
void cmState::DefineProperty(const std::string& name,
cmProperty::ScopeType scope,
const char* ShortDescription,
const char* FullDescription, bool chained)
2015-04-04 21:33:26 +00:00
{
this->PropertyDefinitions[scope].DefineProperty(
name, scope, ShortDescription, FullDescription, chained);
2015-04-04 21:33:26 +00:00
}
cmPropertyDefinition const* cmState::GetPropertyDefinition(
const std::string& name, cmProperty::ScopeType scope) const
2015-04-04 21:33:26 +00:00
{
if (this->IsPropertyDefined(name, scope)) {
2015-06-06 07:46:38 +00:00
cmPropertyDefinitionMap const& defs =
this->PropertyDefinitions.find(scope)->second;
2015-06-06 07:46:38 +00:00
return &defs.find(name)->second;
}
2016-06-27 20:44:16 +00:00
return CM_NULLPTR;
2015-04-04 21:33:26 +00:00
}
bool cmState::IsPropertyDefined(const std::string& name,
2015-06-06 07:46:38 +00:00
cmProperty::ScopeType scope) const
2015-04-04 21:33:26 +00:00
{
std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it =
this->PropertyDefinitions.find(scope);
if (it == this->PropertyDefinitions.end()) {
2015-06-06 07:46:38 +00:00
return false;
}
2015-06-06 07:46:38 +00:00
return it->second.IsPropertyDefined(name);
2015-04-04 21:33:26 +00:00
}
bool cmState::IsPropertyChained(const std::string& name,
2015-06-06 07:46:38 +00:00
cmProperty::ScopeType scope) const
2015-04-04 21:33:26 +00:00
{
std::map<cmProperty::ScopeType, cmPropertyDefinitionMap>::const_iterator it =
this->PropertyDefinitions.find(scope);
if (it == this->PropertyDefinitions.end()) {
2015-06-06 07:46:38 +00:00
return false;
}
2015-06-06 07:46:38 +00:00
return it->second.IsPropertyChained(name);
2015-04-04 21:33:26 +00:00
}
void cmState::SetLanguageEnabled(std::string const& l)
{
std::vector<std::string>::iterator it = std::lower_bound(
this->EnabledLanguages.begin(), this->EnabledLanguages.end(), l);
if (it == this->EnabledLanguages.end() || *it != l) {
this->EnabledLanguages.insert(it, l);
}
}
bool cmState::GetLanguageEnabled(std::string const& l) const
{
return std::binary_search(this->EnabledLanguages.begin(),
this->EnabledLanguages.end(), l);
}
std::vector<std::string> cmState::GetEnabledLanguages() const
{
return this->EnabledLanguages;
}
void cmState::SetEnabledLanguages(std::vector<std::string> const& langs)
{
this->EnabledLanguages = langs;
}
void cmState::ClearEnabledLanguages()
{
this->EnabledLanguages.clear();
}
bool cmState::GetIsInTryCompile() const
{
return this->IsInTryCompile;
}
void cmState::SetIsInTryCompile(bool b)
{
this->IsInTryCompile = b;
}
void cmState::RenameCommand(std::string const& oldName,
std::string const& newName)
{
// if the command already exists, free the old one
std::string sOldName = cmSystemTools::LowerCase(oldName);
std::string sNewName = cmSystemTools::LowerCase(newName);
std::map<std::string, cmCommand*>::iterator pos =
this->Commands.find(sOldName);
if (pos == this->Commands.end()) {
return;
}
cmCommand* cmd = pos->second;
pos = this->Commands.find(sNewName);
if (pos != this->Commands.end()) {
delete pos->second;
this->Commands.erase(pos);
}
this->Commands.insert(std::make_pair(sNewName, cmd));
pos = this->Commands.find(sOldName);
this->Commands.erase(pos);
}
void cmState::AddCommand(cmCommand* command)
{
std::string name = cmSystemTools::LowerCase(command->GetName());
// if the command already exists, free the old one
std::map<std::string, cmCommand*>::iterator pos = this->Commands.find(name);
if (pos != this->Commands.end()) {
delete pos->second;
this->Commands.erase(pos);
}
this->Commands.insert(std::make_pair(name, command));
}
void cmState::RemoveUnscriptableCommands()
{
std::vector<std::string> unscriptableCommands;
for (std::map<std::string, cmCommand*>::iterator pos =
this->Commands.begin();
pos != this->Commands.end();) {
if (!pos->second->IsScriptable()) {
delete pos->second;
this->Commands.erase(pos++);
} else {
++pos;
}
}
}
cmCommand* cmState::GetCommand(std::string const& name) const
{
2016-06-27 20:44:16 +00:00
cmCommand* command = CM_NULLPTR;
std::string sName = cmSystemTools::LowerCase(name);
std::map<std::string, cmCommand*>::const_iterator pos =
this->Commands.find(sName);
if (pos != this->Commands.end()) {
command = (*pos).second;
}
return command;
}
std::vector<std::string> cmState::GetCommandNames() const
{
std::vector<std::string> commandNames;
commandNames.reserve(this->Commands.size());
std::map<std::string, cmCommand*>::const_iterator cmds =
this->Commands.begin();
for (; cmds != this->Commands.end(); ++cmds) {
commandNames.push_back(cmds->first);
}
return commandNames;
}
void cmState::RemoveUserDefinedCommands()
{
std::vector<cmCommand*> renamedCommands;
for (std::map<std::string, cmCommand*>::iterator j = this->Commands.begin();
j != this->Commands.end();) {
if (j->second->IsUserDefined()) {
delete j->second;
this->Commands.erase(j++);
} else if (j->first != j->second->GetName()) {
renamedCommands.push_back(j->second);
this->Commands.erase(j++);
} else {
++j;
}
}
for (std::vector<cmCommand*>::const_iterator it = renamedCommands.begin();
it != renamedCommands.end(); ++it) {
this->Commands[cmSystemTools::LowerCase((*it)->GetName())] = *it;
}
}
2015-04-11 12:17:46 +00:00
void cmState::SetGlobalProperty(const std::string& prop, const char* value)
{
this->GlobalProperties.SetProperty(prop, value);
2015-04-11 12:17:46 +00:00
}
void cmState::AppendGlobalProperty(const std::string& prop, const char* value,
bool asString)
2015-04-11 12:17:46 +00:00
{
this->GlobalProperties.AppendProperty(prop, value, asString);
2015-04-11 12:17:46 +00:00
}
const char* cmState::GetGlobalProperty(const std::string& prop)
2015-04-11 12:17:46 +00:00
{
if (prop == "CACHE_VARIABLES") {
2015-04-11 12:17:46 +00:00
std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
this->SetGlobalProperty("CACHE_VARIABLES", cmJoin(cacheKeys, ";").c_str());
} else if (prop == "COMMANDS") {
2015-04-11 12:17:46 +00:00
std::vector<std::string> commands = this->GetCommandNames();
this->SetGlobalProperty("COMMANDS", cmJoin(commands, ";").c_str());
} else if (prop == "IN_TRY_COMPILE") {
2015-04-11 12:17:46 +00:00
this->SetGlobalProperty("IN_TRY_COMPILE",
this->IsInTryCompile ? "1" : "0");
} else if (prop == "ENABLED_LANGUAGES") {
2015-04-11 12:17:46 +00:00
std::string langs;
langs = cmJoin(this->EnabledLanguages, ";");
this->SetGlobalProperty("ENABLED_LANGUAGES", langs.c_str());
}
2015-04-11 12:17:46 +00:00
#define STRING_LIST_ELEMENT(F) ";" #F
if (prop == "CMAKE_C_KNOWN_FEATURES") {
2015-04-11 12:17:46 +00:00
return FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT) + 1;
}
if (prop == "CMAKE_CXX_KNOWN_FEATURES") {
2015-04-11 12:17:46 +00:00
return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1;
}
2015-04-11 12:17:46 +00:00
#undef STRING_LIST_ELEMENT
return this->GlobalProperties.GetPropertyValue(prop);
2015-04-11 12:17:46 +00:00
}
bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
{
return cmSystemTools::IsOn(this->GetGlobalProperty(prop));
}
void cmState::SetSourceDirectory(std::string const& sourceDirectory)
{
this->SourceDirectory = sourceDirectory;
cmSystemTools::ConvertToUnixSlashes(this->SourceDirectory);
}
const char* cmState::GetSourceDirectory() const
{
return this->SourceDirectory.c_str();
}
void cmState::SetBinaryDirectory(std::string const& binaryDirectory)
{
this->BinaryDirectory = binaryDirectory;
cmSystemTools::ConvertToUnixSlashes(this->BinaryDirectory);
}
void cmState::SetWindowsShell(bool windowsShell)
{
this->WindowsShell = windowsShell;
}
bool cmState::UseWindowsShell() const
{
return this->WindowsShell;
}
void cmState::SetWindowsVSIDE(bool windowsVSIDE)
{
this->WindowsVSIDE = windowsVSIDE;
}
bool cmState::UseWindowsVSIDE() const
{
return this->WindowsVSIDE;
}
void cmState::SetWatcomWMake(bool watcomWMake)
{
this->WatcomWMake = watcomWMake;
}
bool cmState::UseWatcomWMake() const
{
return this->WatcomWMake;
}
void cmState::SetMinGWMake(bool minGWMake)
{
this->MinGWMake = minGWMake;
}
bool cmState::UseMinGWMake() const
{
return this->MinGWMake;
}
void cmState::SetNMake(bool nMake)
{
this->NMake = nMake;
}
bool cmState::UseNMake() const
{
return this->NMake;
}
void cmState::SetMSYSShell(bool mSYSShell)
{
this->MSYSShell = mSYSShell;
}
bool cmState::UseMSYSShell() const
{
return this->MSYSShell;
}
2015-10-10 12:34:26 +00:00
unsigned int cmState::GetCacheMajorVersion() const
{
return this->CacheManager->GetCacheMajorVersion();
2015-10-10 12:34:26 +00:00
}
unsigned int cmState::GetCacheMinorVersion() const
{
return this->CacheManager->GetCacheMinorVersion();
2015-10-10 12:34:26 +00:00
}
const char* cmState::GetBinaryDirectory() const
{
return this->BinaryDirectory.c_str();
}
cmStateSnapshot cmState::CreateBaseSnapshot()
{
cmStateDetail::PositionType pos =
this->SnapshotData.Push(this->SnapshotData.Root());
pos->DirectoryParent = this->SnapshotData.Root();
pos->ScopeParent = this->SnapshotData.Root();
pos->SnapshotType = cmStateEnums::BaseType;
pos->Keep = true;
pos->BuildSystemDirectory =
this->BuildsystemDirectory.Push(this->BuildsystemDirectory.Root());
pos->ExecutionListFile =
this->ExecutionListFiles.Push(this->ExecutionListFiles.Root());
pos->IncludeDirectoryPosition = 0;
pos->CompileDefinitionsPosition = 0;
pos->CompileOptionsPosition = 0;
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->Policies = this->PolicyStack.Root();
pos->PolicyRoot = this->PolicyStack.Root();
pos->PolicyScope = this->PolicyStack.Root();
assert(pos->Policies.IsValid());
assert(pos->PolicyRoot.IsValid());
pos->Vars = this->VarTree.Push(this->VarTree.Root());
2015-06-21 19:26:43 +00:00
assert(pos->Vars.IsValid());
pos->Parent = this->VarTree.Root();
pos->Root = this->VarTree.Root();
return cmStateSnapshot(this, pos);
}
cmStateSnapshot cmState::CreateBuildsystemDirectorySnapshot(
cmStateSnapshot originSnapshot)
{
assert(originSnapshot.IsValid());
cmStateDetail::PositionType pos =
this->SnapshotData.Push(originSnapshot.Position);
pos->DirectoryParent = originSnapshot.Position;
pos->ScopeParent = originSnapshot.Position;
pos->SnapshotType = cmStateEnums::BuildsystemDirectoryType;
pos->Keep = true;
pos->BuildSystemDirectory = this->BuildsystemDirectory.Push(
originSnapshot.Position->BuildSystemDirectory);
pos->ExecutionListFile =
this->ExecutionListFiles.Push(originSnapshot.Position->ExecutionListFile);
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->Policies = originSnapshot.Position->Policies;
pos->PolicyRoot = originSnapshot.Position->Policies;
pos->PolicyScope = originSnapshot.Position->Policies;
assert(pos->Policies.IsValid());
assert(pos->PolicyRoot.IsValid());
2015-06-21 19:26:43 +00:00
cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
2015-06-21 19:26:43 +00:00
pos->Parent = origin;
pos->Root = origin;
pos->Vars = this->VarTree.Push(origin);
cmStateSnapshot snapshot = cmStateSnapshot(this, pos);
originSnapshot.Position->BuildSystemDirectory->Children.push_back(snapshot);
snapshot.SetDefaultDefinitions();
snapshot.InitializeFromParent();
snapshot.SetDirectoryDefinitions();
return snapshot;
}
cmStateSnapshot cmState::CreateFunctionCallSnapshot(
cmStateSnapshot originSnapshot, std::string const& fileName)
{
cmStateDetail::PositionType pos =
this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
pos->ScopeParent = originSnapshot.Position;
pos->SnapshotType = cmStateEnums::FunctionCallType;
pos->Keep = false;
pos->ExecutionListFile = this->ExecutionListFiles.Push(
originSnapshot.Position->ExecutionListFile, fileName);
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
2015-06-21 19:26:43 +00:00
assert(originSnapshot.Position->Vars.IsValid());
cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
2015-06-21 19:26:43 +00:00
pos->Parent = origin;
pos->Vars = this->VarTree.Push(origin);
return cmStateSnapshot(this, pos);
}
cmStateSnapshot cmState::CreateMacroCallSnapshot(
cmStateSnapshot originSnapshot, std::string const& fileName)
{
cmStateDetail::PositionType pos =
this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
pos->SnapshotType = cmStateEnums::MacroCallType;
pos->Keep = false;
pos->ExecutionListFile = this->ExecutionListFiles.Push(
originSnapshot.Position->ExecutionListFile, fileName);
2015-06-21 19:26:43 +00:00
assert(originSnapshot.Position->Vars.IsValid());
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
return cmStateSnapshot(this, pos);
}
cmStateSnapshot cmState::CreateIncludeFileSnapshot(
cmStateSnapshot originSnapshot, const std::string& fileName)
{
cmStateDetail::PositionType pos =
this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
pos->SnapshotType = cmStateEnums::IncludeFileType;
pos->Keep = true;
pos->ExecutionListFile = this->ExecutionListFiles.Push(
originSnapshot.Position->ExecutionListFile, fileName);
2015-06-21 19:26:43 +00:00
assert(originSnapshot.Position->Vars.IsValid());
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
return cmStateSnapshot(this, pos);
}
cmStateSnapshot cmState::CreateVariableScopeSnapshot(
cmStateSnapshot originSnapshot)
{
cmStateDetail::PositionType pos =
this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
pos->ScopeParent = originSnapshot.Position;
pos->SnapshotType = cmStateEnums::VariableScopeType;
pos->Keep = false;
pos->PolicyScope = originSnapshot.Position->Policies;
2015-06-21 19:26:43 +00:00
assert(originSnapshot.Position->Vars.IsValid());
cmLinkedTree<cmDefinitions>::iterator origin = originSnapshot.Position->Vars;
2015-06-21 19:26:43 +00:00
pos->Parent = origin;
pos->Vars = this->VarTree.Push(origin);
2015-06-21 19:26:43 +00:00
assert(pos->Vars.IsValid());
return cmStateSnapshot(this, pos);
}
cmStateSnapshot cmState::CreateInlineListFileSnapshot(
cmStateSnapshot originSnapshot, const std::string& fileName)
{
cmStateDetail::PositionType pos =
this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
pos->SnapshotType = cmStateEnums::InlineListFileType;
pos->Keep = true;
pos->ExecutionListFile = this->ExecutionListFiles.Push(
originSnapshot.Position->ExecutionListFile, fileName);
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
return cmStateSnapshot(this, pos);
}
cmStateSnapshot cmState::CreatePolicyScopeSnapshot(
cmStateSnapshot originSnapshot)
2015-07-26 10:56:10 +00:00
{
cmStateDetail::PositionType pos =
this->SnapshotData.Push(originSnapshot.Position, *originSnapshot.Position);
pos->SnapshotType = cmStateEnums::PolicyScopeType;
pos->Keep = false;
pos->BuildSystemDirectory->DirectoryEnd = pos;
pos->PolicyScope = originSnapshot.Position->Policies;
return cmStateSnapshot(this, pos);
2015-07-26 10:56:10 +00:00
}
cmStateSnapshot cmState::Pop(cmStateSnapshot originSnapshot)
{
cmStateDetail::PositionType pos = originSnapshot.Position;
cmStateDetail::PositionType prevPos = pos;
++prevPos;
prevPos->IncludeDirectoryPosition =
prevPos->BuildSystemDirectory->IncludeDirectories.size();
prevPos->CompileDefinitionsPosition =
prevPos->BuildSystemDirectory->CompileDefinitions.size();
prevPos->CompileOptionsPosition =
prevPos->BuildSystemDirectory->CompileOptions.size();
prevPos->BuildSystemDirectory->DirectoryEnd = prevPos;
if (!pos->Keep && this->SnapshotData.IsLast(pos)) {
if (pos->Vars != prevPos->Vars) {
assert(this->VarTree.IsLast(pos->Vars));
this->VarTree.Pop(pos->Vars);
}
if (pos->ExecutionListFile != prevPos->ExecutionListFile) {
assert(this->ExecutionListFiles.IsLast(pos->ExecutionListFile));
this->ExecutionListFiles.Pop(pos->ExecutionListFile);
}
this->SnapshotData.Pop(pos);
}
return cmStateSnapshot(this, prevPos);
}
static bool ParseEntryWithoutType(const std::string& entry, std::string& var,
std::string& value)
{
// input line is: key=value
static cmsys::RegularExpression reg(
"^([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
// input line is: "key"=value
static cmsys::RegularExpression regQuoted(
"^\"([^\"]*)\"=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
bool flag = false;
if (regQuoted.find(entry)) {
var = regQuoted.match(1);
value = regQuoted.match(2);
flag = true;
} else if (reg.find(entry)) {
var = reg.match(1);
value = reg.match(2);
flag = true;
}
// if value is enclosed in single quotes ('foo') then remove them
// it is used to enclose trailing space or tab
if (flag && value.size() >= 2 && value[0] == '\'' &&
value[value.size() - 1] == '\'') {
value = value.substr(1, value.size() - 2);
}
return flag;
}
bool cmState::ParseCacheEntry(const std::string& entry, std::string& var,
std::string& value,
cmStateEnums::CacheEntryType& type)
{
// input line is: key:type=value
static cmsys::RegularExpression reg(
"^([^=:]*):([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
// input line is: "key":type=value
static cmsys::RegularExpression regQuoted(
"^\"([^\"]*)\":([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
bool flag = false;
if (regQuoted.find(entry)) {
var = regQuoted.match(1);
type = cmState::StringToCacheEntryType(regQuoted.match(2).c_str());
value = regQuoted.match(3);
flag = true;
} else if (reg.find(entry)) {
var = reg.match(1);
type = cmState::StringToCacheEntryType(reg.match(2).c_str());
value = reg.match(3);
flag = true;
}
// if value is enclosed in single quotes ('foo') then remove them
// it is used to enclose trailing space or tab
if (flag && value.size() >= 2 && value[0] == '\'' &&
value[value.size() - 1] == '\'') {
value = value.substr(1, value.size() - 2);
}
if (!flag) {
return ParseEntryWithoutType(entry, var, value);
}
return flag;
}