| /*========================================================================= |
| |
| 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 "cmCacheManager.h" |
| #include "cmSystemTools.h" |
| #include "cmCacheManager.h" |
| #include "cmMakefile.h" |
| |
| #include <cmsys/Directory.hxx> |
| #include <cmsys/Glob.hxx> |
| |
| #include <cmsys/RegularExpression.hxx> |
| |
| #if defined(_WIN32) || defined(__CYGWIN__) |
| # include <windows.h> |
| #endif // _WIN32 |
| |
| const char* cmCacheManagerTypes[] = |
| { "BOOL", |
| "PATH", |
| "FILEPATH", |
| "STRING", |
| "INTERNAL", |
| "STATIC", |
| "UNINITIALIZED", |
| 0 |
| }; |
| |
| const char* cmCacheManager::TypeToString(cmCacheManager::CacheEntryType type) |
| { |
| if ( type > 6 ) |
| { |
| return cmCacheManagerTypes[6]; |
| } |
| return cmCacheManagerTypes[type]; |
| } |
| |
| cmCacheManager::CacheEntryType cmCacheManager::StringToType(const char* s) |
| { |
| int i = 0; |
| while(cmCacheManagerTypes[i]) |
| { |
| if(strcmp(s, cmCacheManagerTypes[i]) == 0) |
| { |
| return static_cast<CacheEntryType>(i); |
| } |
| ++i; |
| } |
| return STRING; |
| } |
| |
| bool cmCacheManager::LoadCache(cmMakefile* mf) |
| { |
| return this->LoadCache(mf->GetHomeOutputDirectory()); |
| } |
| |
| |
| bool cmCacheManager::LoadCache(const char* path) |
| { |
| return this->LoadCache(path,true); |
| } |
| |
| bool cmCacheManager::LoadCache(const char* path, |
| bool internal) |
| { |
| std::set<cmStdString> emptySet; |
| return this->LoadCache(path, internal, emptySet, emptySet); |
| } |
| |
| bool cmCacheManager::ParseEntry(const char* entry, |
| std::string& var, |
| std::string& value) |
| { |
| // input line is: key:type=value |
| static cmsys::RegularExpression reg( |
| "^([^:]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$"); |
| // input line is: "key":type=value |
| static cmsys::RegularExpression regQuoted( |
| "^\"([^\"]*)\"=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$"); |
| bool flag = false; |
| if(regQuoted.find(entry)) |
| { |
| var = regQuoted.match(1); |
| value = regQuoted.match(2); |
| flag = true; |
| } |
| else if (reg.find(entry)) |
| { |
| var = reg.match(1); |
| value = reg.match(2); |
| 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; |
| } |
| |
| bool cmCacheManager::ParseEntry(const char* entry, |
| std::string& var, |
| std::string& value, |
| CacheEntryType& type) |
| { |
| // input line is: key:type=value |
| static cmsys::RegularExpression reg( |
| "^([^:]*):([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$"); |
| // input line is: "key":type=value |
| static cmsys::RegularExpression regQuoted( |
| "^\"([^\"]*)\":([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$"); |
| bool flag = false; |
| if(regQuoted.find(entry)) |
| { |
| var = regQuoted.match(1); |
| type = cmCacheManager::StringToType(regQuoted.match(2).c_str()); |
| value = regQuoted.match(3); |
| flag = true; |
| } |
| else if (reg.find(entry)) |
| { |
| var = reg.match(1); |
| type = cmCacheManager::StringToType(reg.match(2).c_str()); |
| 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; |
| } |
| |
| void cmCacheManager::CleanCMakeFiles(const char* path) |
| { |
| std::string glob = path; |
| glob += "/CMakeFiles/*.cmake"; |
| cmsys::Glob globIt; |
| globIt.FindFiles(glob); |
| std::vector<std::string> files = globIt.GetFiles(); |
| for(std::vector<std::string>::iterator i = files.begin(); |
| i != files.end(); ++i) |
| { |
| cmSystemTools::RemoveFile(i->c_str()); |
| } |
| } |
| |
| bool cmCacheManager::LoadCache(const char* path, |
| bool internal, |
| std::set<cmStdString>& excludes, |
| std::set<cmStdString>& includes) |
| { |
| std::string cacheFile = path; |
| cacheFile += "/CMakeCache.txt"; |
| // clear the old cache, if we are reading in internal values |
| if ( internal ) |
| { |
| this->Cache.clear(); |
| } |
| if(!cmSystemTools::FileExists(cacheFile.c_str())) |
| { |
| this->CleanCMakeFiles(path); |
| return false; |
| } |
| |
| std::ifstream fin(cacheFile.c_str()); |
| if(!fin) |
| { |
| return false; |
| } |
| const char *realbuffer; |
| std::string buffer; |
| std::string entryKey; |
| while(fin) |
| { |
| // Format is key:type=value |
| CacheEntry e; |
| cmSystemTools::GetLineFromStream(fin, buffer); |
| realbuffer = buffer.c_str(); |
| while(*realbuffer != '0' && |
| (*realbuffer == ' ' || |
| *realbuffer == '\t' || |
| *realbuffer == '\r' || |
| *realbuffer == '\n')) |
| { |
| realbuffer++; |
| } |
| // skip blank lines and comment lines |
| if(realbuffer[0] == '#' || realbuffer[0] == 0) |
| { |
| continue; |
| } |
| while(realbuffer[0] == '/' && realbuffer[1] == '/') |
| { |
| e.Properties["HELPSTRING"] += &realbuffer[2]; |
| cmSystemTools::GetLineFromStream(fin, buffer); |
| realbuffer = buffer.c_str(); |
| if(!fin) |
| { |
| continue; |
| } |
| } |
| if(cmCacheManager::ParseEntry(realbuffer, entryKey, e.Value, e.Type)) |
| { |
| if ( excludes.find(entryKey) == excludes.end() ) |
| { |
| // Load internal values if internal is set. |
| // If the entry is not internal to the cache being loaded |
| // or if it is in the list of internal entries to be |
| // imported, load it. |
| if ( internal || (e.Type != INTERNAL) || |
| (includes.find(entryKey) != includes.end()) ) |
| { |
| // If we are loading the cache from another project, |
| // make all loaded entries internal so that it is |
| // not visible in the gui |
| if (!internal) |
| { |
| e.Type = INTERNAL; |
| e.Properties["HELPSTRING"] = "DO NOT EDIT, "; |
| e.Properties["HELPSTRING"] += entryKey; |
| e.Properties["HELPSTRING"] += " loaded from external file. " |
| "To change this value edit this file: "; |
| e.Properties["HELPSTRING"] += path; |
| e.Properties["HELPSTRING"] += "/CMakeCache.txt" ; |
| } |
| if ( e.Type == cmCacheManager::INTERNAL && |
| (entryKey.size() > strlen("-ADVANCED")) && |
| strcmp(entryKey.c_str() + (entryKey.size() - |
| strlen("-ADVANCED")), "-ADVANCED") == 0 ) |
| { |
| std::string value = e.Value; |
| std::string akey = |
| entryKey.substr(0, (entryKey.size() - strlen("-ADVANCED"))); |
| cmCacheManager::CacheIterator it = |
| this->GetCacheIterator(akey.c_str()); |
| if ( it.IsAtEnd() ) |
| { |
| e.Type = cmCacheManager::UNINITIALIZED; |
| this->Cache[akey] = e; |
| } |
| if (!it.Find(akey.c_str())) |
| { |
| cmSystemTools::Error("Internal CMake error when reading cache"); |
| } |
| it.SetProperty("ADVANCED", value.c_str()); |
| } |
| else if ( e.Type == cmCacheManager::INTERNAL && |
| (entryKey.size() > strlen("-MODIFIED")) && |
| strcmp(entryKey.c_str() + (entryKey.size() - |
| strlen("-MODIFIED")), "-MODIFIED") == 0 ) |
| { |
| std::string value = e.Value; |
| std::string akey = |
| entryKey.substr(0, (entryKey.size() - strlen("-MODIFIED"))); |
| cmCacheManager::CacheIterator it = |
| this->GetCacheIterator(akey.c_str()); |
| if ( it.IsAtEnd() ) |
| { |
| e.Type = cmCacheManager::UNINITIALIZED; |
| this->Cache[akey] = e; |
| } |
| if (!it.Find(akey.c_str())) |
| { |
| cmSystemTools::Error("Internal CMake error when reading cache"); |
| } |
| it.SetProperty("MODIFIED", value.c_str()); |
| } |
| else |
| { |
| e.Initialized = true; |
| this->Cache[entryKey] = e; |
| } |
| } |
| } |
| } |
| else |
| { |
| cmSystemTools::Error("Parse error in cache file ", cacheFile.c_str(), |
| ". Offending entry: ", realbuffer); |
| } |
| } |
| // if CMAKE version not found in the list file |
| // add them as version 0.0 |
| if(!this->GetCacheValue("CMAKE_CACHE_MINOR_VERSION")) |
| { |
| this->AddCacheEntry("CMAKE_CACHE_MINOR_VERSION", "0", |
| "Minor version of cmake used to create the " |
| "current loaded cache", cmCacheManager::INTERNAL); |
| this->AddCacheEntry("CMAKE_CACHE_MAJOR_VERSION", "0", |
| "Major version of cmake used to create the " |
| "current loaded cache", cmCacheManager::INTERNAL); |
| |
| } |
| // check to make sure the cache directory has not |
| // been moved |
| if ( internal && this->GetCacheValue("CMAKE_CACHEFILE_DIR") ) |
| { |
| std::string currentcwd = path; |
| std::string oldcwd = this->GetCacheValue("CMAKE_CACHEFILE_DIR"); |
| cmSystemTools::ConvertToUnixSlashes(currentcwd); |
| currentcwd += "/CMakeCache.txt"; |
| oldcwd += "/CMakeCache.txt"; |
| if(!cmSystemTools::SameFile(oldcwd.c_str(), currentcwd.c_str())) |
| { |
| std::string message = |
| std::string("The current CMakeCache.txt directory ") + |
| currentcwd + std::string(" is different than the directory ") + |
| std::string(this->GetCacheValue("CMAKE_CACHEFILE_DIR")) + |
| std::string(" where CMackeCache.txt was created. This may result " |
| "in binaries being created in the wrong place. If you " |
| "are not sure, reedit the CMakeCache.txt"); |
| cmSystemTools::Error(message.c_str()); |
| } |
| } |
| return true; |
| } |
| |
| bool cmCacheManager::SaveCache(cmMakefile* mf) |
| { |
| return this->SaveCache(mf->GetHomeOutputDirectory()); |
| } |
| |
| |
| bool cmCacheManager::SaveCache(const char* path) |
| { |
| std::string cacheFile = path; |
| cacheFile += "/CMakeCache.txt"; |
| std::string tempFile = cacheFile; |
| tempFile += ".tmp"; |
| std::ofstream fout(tempFile.c_str()); |
| if(!fout) |
| { |
| cmSystemTools::Error("Unable to open cache file for save. ", |
| cacheFile.c_str()); |
| cmSystemTools::ReportLastSystemError(""); |
| return false; |
| } |
| // before writing the cache, update the version numbers |
| // to the |
| char temp[1024]; |
| sprintf(temp, "%d", cmMakefile::GetMinorVersion()); |
| this->AddCacheEntry("CMAKE_CACHE_MINOR_VERSION", temp, |
| "Minor version of cmake used to create the " |
| "current loaded cache", cmCacheManager::INTERNAL); |
| sprintf(temp, "%d", cmMakefile::GetMajorVersion()); |
| this->AddCacheEntry("CMAKE_CACHE_MAJOR_VERSION", temp, |
| "Major version of cmake used to create the " |
| "current loaded cache", cmCacheManager::INTERNAL); |
| |
| this->AddCacheEntry("CMAKE_CACHE_RELEASE_VERSION", |
| cmMakefile::GetReleaseVersion(), |
| "Major version of cmake used to create the " |
| "current loaded cache", cmCacheManager::INTERNAL); |
| |
| // Let us store the current working directory so that if somebody |
| // Copies it, he will not be surprised |
| std::string currentcwd = path; |
| if ( currentcwd[0] >= 'A' && currentcwd[0] <= 'Z' && |
| currentcwd[1] == ':' ) |
| { |
| currentcwd[0] = currentcwd[0] - 'A' + 'a'; |
| } |
| cmSystemTools::ConvertToUnixSlashes(currentcwd); |
| this->AddCacheEntry("CMAKE_CACHEFILE_DIR", currentcwd.c_str(), |
| "This is the directory where this CMakeCahe.txt" |
| " was created", cmCacheManager::INTERNAL); |
| |
| fout << "# This is the CMakeCache file.\n" |
| << "# For build in directory: " << currentcwd << "\n"; |
| cmCacheManager::CacheEntry* cmakeCacheEntry |
| = this->GetCacheEntry("CMAKE_COMMAND"); |
| if ( cmakeCacheEntry ) |
| { |
| fout << "# It was generated by CMake: " << |
| cmakeCacheEntry->Value << std::endl; |
| } |
| |
| fout << "# You can edit this file to change values found and used by cmake." |
| << std::endl |
| << "# If you do not want to change any of the values, simply exit the " |
| "editor." << std::endl |
| << "# If you do want to change a value, simply edit, save, and exit " |
| "the editor." << std::endl |
| << "# The syntax for the file is as follows:\n" |
| << "# KEY:TYPE=VALUE\n" |
| << "# KEY is the name of a variable in the cache.\n" |
| << "# TYPE is a hint to GUI's for the type of VALUE, DO NOT EDIT " |
| "TYPE!." << std::endl |
| << "# VALUE is the current value for the KEY.\n\n"; |
| |
| fout << "########################\n"; |
| fout << "# EXTERNAL cache entries\n"; |
| fout << "########################\n"; |
| fout << "\n"; |
| |
| for( std::map<cmStdString, CacheEntry>::const_iterator i = |
| this->Cache.begin(); i != this->Cache.end(); ++i) |
| { |
| const CacheEntry& ce = (*i).second; |
| CacheEntryType t = ce.Type; |
| if(t == cmCacheManager::UNINITIALIZED || !ce.Initialized) |
| { |
| /* |
| // This should be added in, but is not for now. |
| cmSystemTools::Error("Cache entry \"", (*i).first.c_str(), |
| "\" is uninitialized"); |
| */ |
| } |
| else if(t != INTERNAL) |
| { |
| // Format is key:type=value |
| std::map<cmStdString,cmStdString>::const_iterator it = |
| ce.Properties.find("HELPSTRING"); |
| if ( it == ce.Properties.end() ) |
| { |
| cmCacheManager::OutputHelpString(fout, "Missing description"); |
| } |
| else |
| { |
| cmCacheManager::OutputHelpString(fout, it->second); |
| } |
| std::string key; |
| // support : in key name by double quoting |
| if((*i).first.find(':') != std::string::npos || |
| (*i).first.find("//") == 0) |
| { |
| key = "\""; |
| key += i->first; |
| key += "\""; |
| } |
| else |
| { |
| key = i->first; |
| } |
| fout << key.c_str() << ":" |
| << cmCacheManagerTypes[t] << "="; |
| // if value has trailing space or tab, enclose it in single quotes |
| if (ce.Value.size() && |
| (ce.Value[ce.Value.size() - 1] == ' ' || |
| ce.Value[ce.Value.size() - 1] == '\t')) |
| { |
| fout << '\'' << ce.Value << '\''; |
| } |
| else |
| { |
| fout << ce.Value; |
| } |
| fout << "\n\n"; |
| } |
| } |
| |
| fout << "\n"; |
| fout << "########################\n"; |
| fout << "# INTERNAL cache entries\n"; |
| fout << "########################\n"; |
| fout << "\n"; |
| |
| for( cmCacheManager::CacheIterator i = this->NewIterator(); |
| !i.IsAtEnd(); i.Next()) |
| { |
| if ( !i.Initialized() ) |
| { |
| continue; |
| } |
| |
| CacheEntryType t = i.GetType(); |
| bool advanced = i.PropertyExists("ADVANCED"); |
| if ( advanced ) |
| { |
| // Format is key:type=value |
| std::string key; |
| std::string rkey = i.GetName(); |
| std::string helpstring; |
| // If this is advanced variable, we have to do some magic for |
| // backward compatibility |
| helpstring = "Advanced flag for variable: "; |
| helpstring += i.GetName(); |
| rkey += "-ADVANCED"; |
| cmCacheManager::OutputHelpString(fout, helpstring.c_str()); |
| // support : in key name by double quoting |
| if(rkey.find(':') != std::string::npos || |
| rkey.find("//") == 0) |
| { |
| key = "\""; |
| key += rkey; |
| key += "\""; |
| } |
| else |
| { |
| key = rkey; |
| } |
| fout << key.c_str() << ":INTERNAL=" |
| << (i.GetPropertyAsBool("ADVANCED") ? "1" : "0") << "\n"; |
| } |
| bool modified = i.PropertyExists("MODIFIED"); |
| if ( modified ) |
| { |
| // Format is key:type=value |
| std::string key; |
| std::string rkey = i.GetName(); |
| std::string helpstring; |
| // If this is advanced variable, we have to do some magic for |
| // backward compatibility |
| helpstring = "Modified flag for variable: "; |
| helpstring += i.GetName(); |
| rkey += "-MODIFIED"; |
| cmCacheManager::OutputHelpString(fout, helpstring.c_str()); |
| // support : in key name by double quoting |
| if(rkey.find(':') != std::string::npos || |
| rkey.find("//") == 0) |
| { |
| key = "\""; |
| key += rkey; |
| key += "\""; |
| } |
| else |
| { |
| key = rkey; |
| } |
| fout << key.c_str() << ":INTERNAL=" |
| << (i.GetPropertyAsBool("MODIFIED") ? "1" : "0") << "\n"; |
| } |
| if(t == cmCacheManager::INTERNAL) |
| { |
| // Format is key:type=value |
| std::string key; |
| std::string rkey = i.GetName(); |
| std::string helpstring; |
| const char* hs = i.GetProperty("HELPSTRING"); |
| if ( hs ) |
| { |
| helpstring = i.GetProperty("HELPSTRING"); |
| } |
| else |
| { |
| helpstring = ""; |
| } |
| cmCacheManager::OutputHelpString(fout, helpstring.c_str()); |
| // support : in key name by double quoting |
| if(rkey.find(':') != std::string::npos || |
| rkey.find("//") == 0) |
| { |
| key = "\""; |
| key += rkey; |
| key += "\""; |
| } |
| else |
| { |
| key = rkey; |
| } |
| fout << key.c_str() << ":" |
| << cmCacheManagerTypes[t] << "="; |
| // if value has trailing space or tab, enclose it in single quotes |
| std::string value = i.GetValue(); |
| if (value.size() && |
| (value[value.size() - 1] == ' ' || |
| value[value.size() - 1] == '\t')) |
| { |
| fout << '\'' << value << '\''; |
| } |
| else |
| { |
| fout << value; |
| } |
| fout << "\n"; |
| } |
| } |
| fout << "\n"; |
| fout.close(); |
| cmSystemTools::CopyFileIfDifferent(tempFile.c_str(), |
| cacheFile.c_str()); |
| cmSystemTools::RemoveFile(tempFile.c_str()); |
| std::string checkCacheFile = path; |
| checkCacheFile += "/CMakeFiles"; |
| cmSystemTools::MakeDirectory(checkCacheFile.c_str()); |
| checkCacheFile += "/cmake.check_cache"; |
| std::ofstream checkCache(checkCacheFile.c_str()); |
| if(!checkCache) |
| { |
| cmSystemTools::Error("Unable to open check cache file for write. ", |
| checkCacheFile.c_str()); |
| return false; |
| } |
| checkCache << "# This file is generated by cmake for dependency checking " |
| "of the CMakeCache.txt file\n"; |
| return true; |
| } |
| |
| bool cmCacheManager::DeleteCache(const char* path) |
| { |
| std::string cacheFile = path; |
| cmSystemTools::ConvertToUnixSlashes(cacheFile); |
| std::string cmakeFiles = cacheFile; |
| cacheFile += "/CMakeCache.txt"; |
| cmSystemTools::RemoveFile(cacheFile.c_str()); |
| // now remove the files in the CMakeFiles directory |
| // this cleans up language cache files |
| cmsys::Directory dir; |
| cmakeFiles += "/CMakeFiles"; |
| dir.Load(cmakeFiles.c_str()); |
| for (unsigned long fileNum = 0; |
| fileNum < dir.GetNumberOfFiles(); |
| ++fileNum) |
| { |
| if(!cmSystemTools:: |
| FileIsDirectory(dir.GetFile(fileNum))) |
| { |
| std::string fullPath = cmakeFiles; |
| fullPath += "/"; |
| fullPath += dir.GetFile(fileNum); |
| cmSystemTools::RemoveFile(fullPath.c_str()); |
| } |
| } |
| return true; |
| } |
| |
| void cmCacheManager::OutputHelpString(std::ofstream& fout, |
| const std::string& helpString) |
| { |
| std::string::size_type end = helpString.size(); |
| if(end == 0) |
| { |
| return; |
| } |
| std::string oneLine; |
| std::string::size_type pos = 0; |
| std::string::size_type nextBreak = 60; |
| bool done = false; |
| |
| while(!done) |
| { |
| if(nextBreak >= end) |
| { |
| nextBreak = end; |
| done = true; |
| } |
| else |
| { |
| while(nextBreak < end && helpString[nextBreak] != ' ') |
| { |
| nextBreak++; |
| } |
| } |
| oneLine = helpString.substr(pos, nextBreak - pos); |
| fout << "//" << oneLine.c_str() << "\n"; |
| pos = nextBreak; |
| nextBreak += 60; |
| } |
| } |
| |
| void cmCacheManager::RemoveCacheEntry(const char* key) |
| { |
| CacheEntryMap::iterator i = this->Cache.find(key); |
| if(i != this->Cache.end()) |
| { |
| this->Cache.erase(i); |
| } |
| else |
| { |
| std::cerr << "Failed to remove entry:" << key << std::endl; |
| } |
| } |
| |
| |
| cmCacheManager::CacheEntry *cmCacheManager::GetCacheEntry(const char* key) |
| { |
| CacheEntryMap::iterator i = this->Cache.find(key); |
| if(i != this->Cache.end()) |
| { |
| return &i->second; |
| } |
| return 0; |
| } |
| |
| cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator( |
| const char *key) |
| { |
| return CacheIterator(*this, key); |
| } |
| |
| const char* cmCacheManager::GetCacheValue(const char* key) const |
| { |
| CacheEntryMap::const_iterator i = this->Cache.find(key); |
| if(i != this->Cache.end() && |
| i->second.Initialized) |
| { |
| return i->second.Value.c_str(); |
| } |
| return 0; |
| } |
| |
| |
| void cmCacheManager::PrintCache(std::ostream& out) const |
| { |
| out << "=================================================" << std::endl; |
| out << "CMakeCache Contents:" << std::endl; |
| for(std::map<cmStdString, CacheEntry>::const_iterator i = |
| this->Cache.begin(); i != this->Cache.end(); ++i) |
| { |
| if((*i).second.Type != INTERNAL) |
| { |
| out << (*i).first.c_str() << " = " << (*i).second.Value.c_str() |
| << std::endl; |
| } |
| } |
| out << "\n\n"; |
| out << "To change values in the CMakeCache, " |
| << std::endl << "edit CMakeCache.txt in your output directory.\n"; |
| out << "=================================================" << std::endl; |
| } |
| |
| |
| void cmCacheManager::AddCacheEntry(const char* key, |
| const char* value, |
| const char* helpString, |
| CacheEntryType type) |
| { |
| CacheEntry& e = this->Cache[key]; |
| if ( value ) |
| { |
| e.Value = value; |
| e.Initialized = true; |
| } |
| else |
| { |
| e.Value = ""; |
| } |
| e.Type = type; |
| // make sure we only use unix style paths |
| if(type == FILEPATH || type == PATH) |
| { |
| cmSystemTools::ConvertToUnixSlashes(e.Value); |
| } |
| if ( helpString ) |
| { |
| e.Properties["HELPSTRING"] = helpString; |
| } |
| else |
| { |
| e.Properties["HELPSTRING"] = |
| "(This variable does not exists and should not be used)"; |
| } |
| this->Cache[key] = e; |
| } |
| |
| void cmCacheManager::AddCacheEntry(const char* key, bool v, |
| const char* helpString) |
| { |
| if(v) |
| { |
| this->AddCacheEntry(key, "ON", helpString, cmCacheManager::BOOL); |
| } |
| else |
| { |
| this->AddCacheEntry(key, "OFF", helpString, cmCacheManager::BOOL); |
| } |
| } |
| |
| bool cmCacheManager::CacheIterator::IsAtEnd() const |
| { |
| return this->Position == this->Container.Cache.end(); |
| } |
| |
| void cmCacheManager::CacheIterator::Begin() |
| { |
| this->Position = this->Container.Cache.begin(); |
| } |
| |
| bool cmCacheManager::CacheIterator::Find(const char* key) |
| { |
| this->Position = this->Container.Cache.find(key); |
| return !this->IsAtEnd(); |
| } |
| |
| void cmCacheManager::CacheIterator::Next() |
| { |
| if (!this->IsAtEnd()) |
| { |
| ++this->Position; |
| } |
| } |
| |
| void cmCacheManager::CacheIterator::SetValue(const char* value) |
| { |
| if (this->IsAtEnd()) |
| { |
| return; |
| } |
| CacheEntry* entry = &this->GetEntry(); |
| if ( value ) |
| { |
| entry->Value = value; |
| entry->Initialized = true; |
| } |
| else |
| { |
| entry->Value = ""; |
| } |
| } |
| |
| const char* cmCacheManager::CacheIterator::GetProperty( |
| const char* property) const |
| { |
| // make sure it is not at the end |
| if (this->IsAtEnd()) |
| { |
| return 0; |
| } |
| |
| if ( !strcmp(property, "TYPE") || !strcmp(property, "VALUE") ) |
| { |
| cmSystemTools::Error("Property \"", property, |
| "\" cannot be accessed through the GetProperty()"); |
| return 0; |
| } |
| const CacheEntry* ent = &this->GetEntry(); |
| std::map<cmStdString,cmStdString>::const_iterator it = |
| ent->Properties.find(property); |
| if ( it == ent->Properties.end() ) |
| { |
| return 0; |
| } |
| return it->second.c_str(); |
| } |
| |
| void cmCacheManager::CacheIterator::SetProperty(const char* p, const char* v) |
| { |
| // make sure it is not at the end |
| if (this->IsAtEnd()) |
| { |
| return; |
| } |
| |
| if ( !strcmp(p, "TYPE") || !strcmp(p, "VALUE") ) |
| { |
| cmSystemTools::Error("Property \"", p, |
| "\" cannot be accessed through the SetProperty()"); |
| return; |
| } |
| CacheEntry* ent = &this->GetEntry(); |
| ent->Properties[p] = v; |
| } |
| |
| |
| bool cmCacheManager::CacheIterator::GetValueAsBool() const |
| { |
| return cmSystemTools::IsOn(this->GetEntry().Value.c_str()); |
| } |
| |
| bool cmCacheManager::CacheIterator::GetPropertyAsBool( |
| const char* property) const |
| { |
| // make sure it is not at the end |
| if (this->IsAtEnd()) |
| { |
| return false; |
| } |
| |
| if ( !strcmp(property, "TYPE") || !strcmp(property, "VALUE") ) |
| { |
| cmSystemTools::Error("Property \"", property, |
| "\" cannot be accessed through the GetPropertyAsBool()"); |
| return false; |
| } |
| const CacheEntry* ent = &this->GetEntry(); |
| std::map<cmStdString,cmStdString>::const_iterator it = |
| ent->Properties.find(property); |
| if ( it == ent->Properties.end() ) |
| { |
| return false; |
| } |
| return cmSystemTools::IsOn(it->second.c_str()); |
| } |
| |
| |
| void cmCacheManager::CacheIterator::SetProperty(const char* p, bool v) |
| { |
| // make sure it is not at the end |
| if (this->IsAtEnd()) |
| { |
| return; |
| } |
| |
| if ( !strcmp(p, "TYPE") || !strcmp(p, "VALUE") ) |
| { |
| cmSystemTools::Error("Property \"", p, |
| "\" cannot be accessed through the SetProperty()"); |
| return; |
| } |
| CacheEntry* ent = &this->GetEntry(); |
| ent->Properties[p] = v ? "ON" : "OFF"; |
| } |
| |
| bool cmCacheManager::CacheIterator::PropertyExists(const char* property) const |
| { |
| // make sure it is not at the end |
| if (this->IsAtEnd()) |
| { |
| return false; |
| } |
| |
| if ( !strcmp(property, "TYPE") || !strcmp(property, "VALUE") ) |
| { |
| cmSystemTools::Error("Property \"", property, |
| "\" cannot be accessed through the PropertyExists()"); |
| return false; |
| } |
| const CacheEntry* ent = &this->GetEntry(); |
| std::map<cmStdString,cmStdString>::const_iterator it = |
| ent->Properties.find(property); |
| if ( it == ent->Properties.end() ) |
| { |
| return false; |
| } |
| return true; |
| } |