Jelajahi Sumber

ENH: Adding MODIFIED property to cache values that have been changed by the user.

Brad King 21 tahun lalu
induk
melakukan
4eb0400c98

+ 33 - 12
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();
-
-      // 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 )
+      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);
+
+      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";
       }
     }
 }

+ 3 - 0
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.

+ 47 - 0
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