|
|
@@ -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;
|
|
|
+}
|