123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /*=========================================================================
- Program: CMake - Cross-Platform Makefile Generator
- Module: $RCSfile$
- Language: C++
- Date: $Date$
- Version: $Revision$
- Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
- See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notices for more information.
- =========================================================================*/
- #include "cmLoadCacheCommand.h"
- // cmLoadCacheCommand
- bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& args)
- {
- if (args.size()< 1)
- {
- this->SetError("called with wrong number of arguments.");
- }
- 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.
- bool excludeFiles=false;
- unsigned int i;
- std::set<std::string> excludes;
- for(i=0; i<args.size(); i++)
- {
- if (excludeFiles)
- {
- excludes.insert(args[i]);
- }
- if (args[i] == "EXCLUDE")
- {
- excludeFiles=true;
- }
- if (excludeFiles && (args[i] == "INCLUDE_INTERNALS"))
- {
- break;
- }
- }
- // Internal cache entries to be imported.
- // If this set is empty, no internal cache entries are
- // brought in.
- bool includeFiles=false;
- std::set<std::string> includes;
- for(i=0; i<args.size(); i++)
- {
- if (includeFiles)
- {
- includes.insert(args[i]);
- }
- if (args[i] == "INCLUDE_INTERNALS")
- {
- includeFiles=true;
- }
- if (includeFiles && (args[i] == "EXCLUDE"))
- {
- break;
- }
- }
- // Loop over each build directory listed in the arguments. Each
- // directory has a cache file.
- for(i=0; i<args.size(); i++)
- {
- if ((args[i] == "EXCLUDE") || (args[i] == "INCLUDE_INTERNALS"))
- {
- break;
- }
- m_Makefile->GetCacheManager()->LoadCache(args[i].c_str(), false,
- excludes, includes);
- }
- 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;
- }
|