summaryrefslogtreecommitdiff
path: root/Source/cmLoadCacheCommand.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2002-11-20 18:00:02 -0500
committerBrad King <brad.king@kitware.com>2002-11-20 18:00:02 -0500
commit7ef61736648d213bdc147866da6e2d4cdaa9cf20 (patch)
tree1b1ab58b986765c59668da99c1044eddd902f066 /Source/cmLoadCacheCommand.cxx
parentc2addf16306c6f8cd971e7cbe62c71a040e9dab5 (diff)
downloadcmake-7ef61736648d213bdc147866da6e2d4cdaa9cf20.tar.gz
ENH: Added READ_WITH_PREFIX option to LOAD_CACHE command. This allows reading of cache values from another cache without actually creating local copies of the cache entires. The values are stored as prefixed local makefile variables.
Diffstat (limited to 'Source/cmLoadCacheCommand.cxx')
-rw-r--r--Source/cmLoadCacheCommand.cxx145
1 files changed, 144 insertions, 1 deletions
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
index f93efc9e86..0ec5cab3e9 100644
--- a/Source/cmLoadCacheCommand.cxx
+++ b/Source/cmLoadCacheCommand.cxx
@@ -17,7 +17,7 @@
#include "cmLoadCacheCommand.h"
-// cmLoadcacheCommand
+// cmLoadCacheCommand
bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& argsIn)
{
if (argsIn.size()< 1)
@@ -27,6 +27,11 @@ bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& argsIn)
std::vector<std::string> args;
cmSystemTools::ExpandListArguments(argsIn, args);
+ 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.
@@ -88,4 +93,142 @@ bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& argsIn)
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;
+ if(this->ParseEntry(line, var, value))
+ {
+ // 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())
+ {
+ m_Makefile->AddDefinition(var.c_str(), value.c_str());
+ }
+ else
+ {
+ m_Makefile->RemoveDefinition(var.c_str());
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmLoadCacheCommand::ParseEntry(const char* entry, std::string& var,
+ std::string& value)
+{
+ // input line is: key:type=value
+ cmRegularExpression reg("^([^:]*):([^=]*)=(.*[^\t ]|[\t ]*)[\t ]*$");
+ // input line is: "key":type=value
+ cmRegularExpression regQuoted("^\"([^\"]*)\":([^=]*)=(.*[^\t ]|[\t ]*)[\t ]*$");
+ bool flag = false;
+ if(regQuoted.find(entry))
+ {
+ var = regQuoted.match(1);
+ value = regQuoted.match(3);
+ flag = true;
+ }
+ else if (reg.find(entry))
+ {
+ var = reg.match(1);
+ 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);
+ }
+ return flag;
+}