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 | |
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.
-rw-r--r-- | Source/cmLoadCacheCommand.cxx | 145 | ||||
-rw-r--r-- | Source/cmLoadCacheCommand.h | 14 |
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); }; |