diff options
Diffstat (limited to 'Source/cmLoadCacheCommand.cxx')
-rw-r--r-- | Source/cmLoadCacheCommand.cxx | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx new file mode 100644 index 0000000..a239e55 --- /dev/null +++ b/Source/cmLoadCacheCommand.cxx @@ -0,0 +1,196 @@ +/*============================================================================ + 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 "cmLoadCacheCommand.h" + +#include <cmsys/RegularExpression.hxx> + +// cmLoadCacheCommand +bool cmLoadCacheCommand +::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) +{ + if (args.size()< 1) + { + this->SetError("called with wrong number of arguments."); + } + + if(args.size() >= 2 && args[1] == "READ_WITH_PREFIX") + { + return this->ReadWithPrefix(args); + } + + // Cache entries to be excluded from the import list. + // If this set is empty, all cache entries are brought in + // and they can not be overridden. + bool excludeFiles=false; + unsigned int i; + std::set<cmStdString> excludes; + + for(i=0; i<args.size(); i++) + { + if (excludeFiles) + { + excludes.insert(args[i]); + } + if (args[i] == "EXCLUDE") + { + excludeFiles=true; + } + if (excludeFiles && (args[i] == "INCLUDE_INTERNALS")) + { + break; + } + } + + // Internal cache entries to be imported. + // If this set is empty, no internal cache entries are + // brought in. + bool includeFiles=false; + std::set<cmStdString> includes; + + for(i=0; i<args.size(); i++) + { + if (includeFiles) + { + includes.insert(args[i]); + } + if (args[i] == "INCLUDE_INTERNALS") + { + includeFiles=true; + } + if (includeFiles && (args[i] == "EXCLUDE")) + { + break; + } + } + + // Loop over each build directory listed in the arguments. Each + // directory has a cache file. + for(i=0; i<args.size(); i++) + { + if ((args[i] == "EXCLUDE") || (args[i] == "INCLUDE_INTERNALS")) + { + break; + } + this->Makefile->GetCacheManager()->LoadCache(args[i].c_str(), false, + excludes, includes); + } + + + return true; +} + +//---------------------------------------------------------------------------- +bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) +{ + // Make sure we have a prefix. + if(args.size() < 3) + { + this->SetError("READ_WITH_PREFIX form must specify a prefix."); + return false; + } + + // Make sure the cache file exists. + std::string cacheFile = args[0]+"/CMakeCache.txt"; + if(!cmSystemTools::FileExists(cacheFile.c_str())) + { + std::string e = "Cannot load cache file from " + cacheFile; + this->SetError(e.c_str()); + return false; + } + + // Prepare the table of variables to read. + this->Prefix = args[2]; + for(unsigned int i=3; i < args.size(); ++i) + { + this->VariablesToRead.insert(args[i]); + } + + // Read the cache file. + std::ifstream fin(cacheFile.c_str()); + + // This is a big hack read loop to overcome a buggy ifstream + // implementation on HP-UX. This should work on all platforms even + // for small buffer sizes. + const int bufferSize = 4096; + char buffer[bufferSize]; + std::string line; + while(fin) + { + // Read a block of the file. + fin.read(buffer, bufferSize); + if(fin.gcount()) + { + // Parse for newlines directly. + const char* i = buffer; + const char* end = buffer+fin.gcount(); + while(i != end) + { + const char* begin = i; + while(i != end && *i != '\n') { ++i; } + if(i == begin || *(i-1) != '\r') + { + // Include this portion of the line. + line += std::string(begin, i-begin); + } + else + { + // Include this portion of the line. + // Don't include the \r in a \r\n pair. + line += std::string(begin, i-1-begin); + } + if(i != end) + { + // Completed a line. + this->CheckLine(line.c_str()); + line = ""; + + // Skip the newline character. + ++i; + } + } + } + } + if(line.length()) + { + // Partial last line. + this->CheckLine(line.c_str()); + } + + return true; +} + +//---------------------------------------------------------------------------- +void cmLoadCacheCommand::CheckLine(const char* line) +{ + // Check one line of the cache file. + std::string var; + std::string value; + cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED; + if(cmCacheManager::ParseEntry(line, var, value, type)) + { + // Found a real entry. See if this one was requested. + if(this->VariablesToRead.find(var) != this->VariablesToRead.end()) + { + // This was requested. Set this variable locally with the given + // prefix. + var = this->Prefix + var; + if(value.length()) + { + this->Makefile->AddDefinition(var.c_str(), value.c_str()); + } + else + { + this->Makefile->RemoveDefinition(var.c_str()); + } + } + } +} |