diff options
Diffstat (limited to 'Source/cmLoadCacheCommand.cxx')
-rw-r--r-- | Source/cmLoadCacheCommand.cxx | 145 |
1 files changed, 144 insertions, 1 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; +} |