diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx index ae89e07ad..aa8120353 100644 --- a/Source/CursesDialog/cmCursesMainForm.cxx +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -784,9 +784,7 @@ void cmCursesMainForm::RemoveEntry(const char* value) // copy from the list box to the cache manager void cmCursesMainForm::FillCacheManagerFromUI() -{ - std::string tmpString; - +{ int size = m_Entries->size(); for(int i=0; i < size; i++) { @@ -795,17 +793,40 @@ void cmCursesMainForm::FillCacheManagerFromUI() (*m_Entries)[i]->m_Key.c_str()); if (!it.IsAtEnd()) { - tmpString = (*m_Entries)[i]->m_Entry->GetValue(); + std::string oldValue = it.GetValue(); + std::string newValue = (*m_Entries)[i]->m_Entry->GetValue(); + std::string fixedOldValue; + std::string fixedNewValue; + this->FixValue(it.GetType(), oldValue, fixedOldValue); + this->FixValue(it.GetType(), newValue, fixedNewValue); - // Remove trailing spaces, convert path to unix slashes - std::string tmpSubString = - tmpString.substr(0,tmpString.find_last_not_of(" ")+1); - if ( it.GetType() == cmCacheManager::PATH || - it.GetType() == cmCacheManager::FILEPATH ) + if(!(fixedOldValue == fixedNewValue)) { - cmSystemTools::ConvertToUnixSlashes(tmpSubString); + // The user has changed the value. Mark it as modified. + it.SetProperty("MODIFIED", true); } - it.SetValue(tmpSubString.c_str()); + it.SetValue(fixedNewValue.c_str()); + } + } +} + +void cmCursesMainForm::FixValue(cmCacheManager::CacheEntryType type, + const std::string& in, std::string& out) const +{ + out = in.substr(0,in.find_last_not_of(" ")+1); + if(type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH) + { + cmSystemTools::ConvertToUnixSlashes(out); + } + if(type == cmCacheManager::BOOL) + { + if(cmSystemTools::IsOff(out.c_str())) + { + out = "OFF"; + } + else + { + out = "ON"; } } } diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h index 9cfce3d84..d74c25af2 100644 --- a/Source/CursesDialog/cmCursesMainForm.h +++ b/Source/CursesDialog/cmCursesMainForm.h @@ -117,6 +117,9 @@ protected: // Copy the cache values from the user interface to the actual // cache. void FillCacheManagerFromUI(); + // Fix formatting of values to a consistent form. + void FixValue(cmCacheManager::CacheEntryType type, + const std::string& in, std::string& out) const; // Re-post the existing fields. Used to toggle between // normal and advanced modes. Render() should be called // afterwards. diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 01a341110..c48d485b2 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -244,6 +244,25 @@ bool cmCacheManager::LoadCache(const char* path, } it.SetProperty("ADVANCED", value.c_str()); } + else if ( e.m_Type == cmCacheManager::INTERNAL && + (entryKey.size() > strlen("-MODIFIED")) && + strcmp(entryKey.c_str() + (entryKey.size() - strlen("-MODIFIED")), + "-MODIFIED") == 0 ) + { + std::string value = e.m_Value; + std::string akey = entryKey.substr(0, (entryKey.size() - strlen("-MODIFIED"))); + cmCacheManager::CacheIterator it = this->GetCacheIterator(akey.c_str()); + if ( it.IsAtEnd() ) + { + e.m_Type = cmCacheManager::UNINITIALIZED; + m_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.m_Initialized = true; @@ -457,6 +476,34 @@ bool cmCacheManager::SaveCache(const char* path) 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