diff options
author | Brad King <brad.king@kitware.com> | 2002-11-20 23:00:02 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2002-11-20 23:00:02 (GMT) |
commit | 7ef61736648d213bdc147866da6e2d4cdaa9cf20 (patch) | |
tree | 1b1ab58b986765c59668da99c1044eddd902f066 /Source/cmLoadCacheCommand.cxx | |
parent | c2addf16306c6f8cd971e7cbe62c71a040e9dab5 (diff) | |
download | CMake-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.
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; +} |