summaryrefslogtreecommitdiff
path: root/Source/cmLoadCacheCommand.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmLoadCacheCommand.cxx')
-rw-r--r--Source/cmLoadCacheCommand.cxx196
1 files changed, 196 insertions, 0 deletions
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
new file mode 100644
index 000000000..a239e55bf
--- /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());
+ }
+ }
+ }
+}