/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) 2000 National Library of Medicine All rights reserved. See COPYRIGHT.txt for copyright details. =========================================================================*/ #include "cmCacheManager.h" #include "cmSystemTools.h" #include "cmCacheManager.h" #include "cmMakefile.h" #include "cmRegularExpression.h" const char* cmCacheManagerTypes[] = { "BOOL", "PATH", "FILEPATH", "STRING", "INTERNAL", 0 }; cmCacheManager::CacheEntryType cmCacheManager::StringToType(const char* s) { int i = 0; while(cmCacheManagerTypes[i]) { if(strcmp(s, cmCacheManagerTypes[i]) == 0) { return static_cast(i); } ++i; } return STRING; } cmCacheManager* cmCacheManager::s_Instance = 0; cmCacheManager* cmCacheManager::GetInstance() { if(!cmCacheManager::s_Instance) { cmCacheManager::s_Instance = new cmCacheManager; } return cmCacheManager::s_Instance; } bool cmCacheManager::LoadCache(cmMakefile* mf) { return this->LoadCache(mf->GetHomeOutputDirectory()); } bool cmCacheManager::LoadCache(const char* path) { std::string cacheFile = path; cacheFile += "/CMakeCache.txt"; // clear the old cache m_Cache.clear(); std::ifstream fin(cacheFile.c_str()); if(!fin) { return false; } const int bsize = 4096; char buffer[bsize]; // input line is: key:type=value cmRegularExpression reg("(.*):(.*)=(.*)"); while(fin) { // Format is key:type=value CacheEntry e; fin.getline(buffer, bsize); // skip blank lines and comment lines if(buffer[0] == '#' || buffer[0] == 0) { continue; } while(buffer[0] == '/') { e.m_HelpString += &buffer[2]; fin.getline(buffer, bsize); if(!fin) { continue; } } if(reg.find(buffer)) { e.m_Type = cmCacheManager::StringToType(reg.match(2).c_str()); e.m_Value = reg.match(3); m_Cache[reg.match(1)] = e; } else { cmSystemTools::Error("Parse error in cache file ", cacheFile.c_str()); } } return true; } bool cmCacheManager::SaveCache(cmMakefile* mf) const { return this->SaveCache(mf->GetHomeOutputDirectory()); } bool cmCacheManager::SaveCache(const char* path) const { 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()); return false; } fout << "# This is the CMakeCache file.\n" << "# For build in directory: " << path << "\n" << "# You can edit this file to change values found and used by cmake.\n" << "# If you do not want to change any of the values, simply exit the editor.\n" << "# If you do want to change a value, simply edit, save, and exit the editor.\n" << "# The syntax for the file is as follows:\n" << "# KEY:TYPE=VALUE\n" << "# KEY is the name of a varible in the cache.\n" << "# TYPE is a hint to GUI's for the type of VALUE, DO NOT EDIT TYPE!.\n" << "# VALUE is the current value for the KEY.\n\n"; for( std::map::const_iterator i = m_Cache.begin(); i != m_Cache.end(); ++i) { const CacheEntry& ce = (*i).second; CacheEntryType t = ce.m_Type; // Format is key:type=value cmCacheManager::OutputHelpString(fout, ce.m_HelpString); fout << (*i).first.c_str() << ":" << cmCacheManagerTypes[t] << "=" << ce.m_Value << "\n"; } fout << "\n"; fout.close(); cmSystemTools::CopyFileIfDifferent(tempFile.c_str(), cacheFile.c_str()); cmSystemTools::RemoveFile(tempFile.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) { m_Cache.erase(key); } cmCacheManager::CacheEntry *cmCacheManager::GetCacheEntry(const char* key) { if(m_Cache.count(key)) { return &(m_Cache.find(key)->second); } return 0; } const char* cmCacheManager::GetCacheValue(const char* key) const { if(m_Cache.count(key)) { return m_Cache.find(key)->second.m_Value.c_str(); } return 0; } bool cmCacheManager::IsOn(const char* key) const { if(!m_Cache.count(key)) { return false; } const std::string &v = m_Cache.find(key)->second.m_Value; return cmSystemTools::IsOn(v.c_str()); } void cmCacheManager::PrintCache(std::ostream& out) const { out << "=================================================" << std::endl; out << "CMakeCache Contents:" << std::endl; for(std::map::const_iterator i = m_Cache.begin(); i != m_Cache.end(); ++i) { out << (*i).first.c_str() << " = " << (*i).second.m_Value.c_str() << std::endl; } out << "\n\n"; out << "To change values in the CMakeCache, \nedit 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; e.m_Value = value; e.m_Type = type; e.m_HelpString = helpString; m_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); } }