summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2002-11-20 23:00:02 (GMT)
committerBrad King <brad.king@kitware.com>2002-11-20 23:00:02 (GMT)
commit7ef61736648d213bdc147866da6e2d4cdaa9cf20 (patch)
tree1b1ab58b986765c59668da99c1044eddd902f066
parentc2addf16306c6f8cd971e7cbe62c71a040e9dab5 (diff)
downloadCMake-7ef61736648d213bdc147866da6e2d4cdaa9cf20.zip
CMake-7ef61736648d213bdc147866da6e2d4cdaa9cf20.tar.gz
CMake-7ef61736648d213bdc147866da6e2d4cdaa9cf20.tar.bz2
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.
-rw-r--r--Source/cmLoadCacheCommand.cxx145
-rw-r--r--Source/cmLoadCacheCommand.h14
2 files changed, 157 insertions, 2 deletions
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
index f93efc9..0ec5cab 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;
+}
diff --git a/Source/cmLoadCacheCommand.h b/Source/cmLoadCacheCommand.h
index c0b5ad7..925cd3b 100644
--- a/Source/cmLoadCacheCommand.h
+++ b/Source/cmLoadCacheCommand.h
@@ -65,14 +65,26 @@ public:
{
return
"LOAD_CACHE(pathToCacheFile [EXCLUDE entry1...] [INCLUDE_INTERNALS entry1...])\n"
+ "LOAD_CACHE(pathToCacheFile READ_WITH_PREFIX prefix entry1...)\n"
"Load in the values from another cache. This is useful for a project "
"that depends on another project built in a different tree."
"EXCLUDE option can be used to provide a list of entries to be excluded."
"INCLUDE_INTERNALS can be used to provide a list of internal entries"
- "to be included. Normally, no internal entries are brougt in.";
+ "to be included. Normally, no internal entries are brougt in.\n"
+ "The READ_WITH_PREFIX form will read the cache and store the requested "
+ "entries in variables with their name prefixed with the given prefix. "
+ "This form only reads the values, and does not create local cache entries.";
}
cmTypeMacro(cmLoadCacheCommand, cmCommand);
+protected:
+
+ std::set<cmStdString> VariablesToRead;
+ std::string Prefix;
+
+ bool ReadWithPrefix(std::vector<std::string> const& args);
+ void CheckLine(const char* line);
+ bool ParseEntry(const char* entry, std::string& var, std::string& value);
};