/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/

#include "cmCacheManager.h"
#include "cmSystemTools.h"
#include "cmCacheManager.h"
#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmake.h"
#include "cmVersion.h"

#include <cmsys/Directory.hxx>
#include <cmsys/Glob.hxx>

#include <cmsys/RegularExpression.hxx>

const char* cmCacheManagerTypes[] =
{ "BOOL",
  "PATH",
  "FILEPATH",
  "STRING",
  "INTERNAL",
  "STATIC",
  "UNINITIALIZED",
  0
};

cmCacheManager::cmCacheManager(cmake* cm)
{
  this->CacheMajorVersion = 0;
  this->CacheMinorVersion = 0;
  this->CMakeInstance = cm;
}

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::IsType(const char* s)
{
  for(int i=0; cmCacheManagerTypes[i]; ++i)
    {
    if(strcmp(s, cmCacheManagerTypes[i]) == 0)
      {
      return true;
      }
    }
  return false;
}

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);
}

static bool ParseEntryWithoutType(const char* entry,
                                  std::string& var,
                                  std::string& value)
{
  // input line is:         key=value
  static cmsys::RegularExpression reg(
    "^([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$");
  // input line is:         "key"=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);
    }

  if (!flag)
    {
    return ParseEntryWithoutType(entry, var, value);
    }

  return flag;
}

void cmCacheManager::CleanCMakeFiles(const char* path)
{
  std::string glob = path;
  glob += cmake::GetCMakeFilesDirectory();
  glob += "/*.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
    std::string helpString;
    CacheEntry e;
    e.Properties.SetCMakeInstance(this->CMakeInstance);
    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] == '/')
      {
      if ((realbuffer[2] == '\\') && (realbuffer[3]=='n'))
        {
        helpString += "\n";
        helpString += &realbuffer[4];
        }
      else
        {
        helpString += &realbuffer[2];
        }
      cmSystemTools::GetLineFromStream(fin, buffer);
      realbuffer = buffer.c_str();
      if(!fin)
        {
        continue;
        }
      }
    e.SetProperty("HELPSTRING", helpString.c_str());
    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;
            helpString = "DO NOT EDIT, ";
            helpString += entryKey;
            helpString += " loaded from external file.  "
              "To change this value edit this file: ";
            helpString += path;
            helpString += "/CMakeCache.txt"   ;
            e.SetProperty("HELPSTRING", helpString.c_str());
            }
          if(!this->ReadPropertyEntry(entryKey, e))
            {
            e.Initialized = true;
            this->Cache[entryKey] = e;
            }
          }
        }
      }
    else
      {
      cmSystemTools::Error("Parse error in cache file ", cacheFile.c_str(),
                           ". Offending entry: ", realbuffer);
      }
    }
  this->CacheMajorVersion = 0;
  this->CacheMinorVersion = 0;
  if(const char* cmajor = this->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION"))
    {
    unsigned int v=0;
    if(sscanf(cmajor, "%u", &v) == 1)
      {
      this->CacheMajorVersion = v;
      }
    if(const char* cminor = this->GetCacheValue("CMAKE_CACHE_MINOR_VERSION"))
      {
      if(sscanf(cminor, "%u", &v) == 1)
        {
        this->CacheMinorVersion = v;
        }
      }
    }
  else
    {
    // CMake version not found in the list file.
    // Set as version 0.0
    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 CMakeCache.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;
}

//----------------------------------------------------------------------------
const char* cmCacheManager::PersistentProperties[] =
{
  "ADVANCED",
  "MODIFIED",
  "STRINGS",
  0
};

//----------------------------------------------------------------------------
bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
                                       CacheEntry& e)
{
  // All property entries are internal.
  if(e.Type != cmCacheManager::INTERNAL)
    {
    return false;
    }

  const char* end = entryKey.c_str() + entryKey.size();
  for(const char** p = this->PersistentProperties; *p; ++p)
    {
    std::string::size_type plen = strlen(*p) + 1;
    if(entryKey.size() > plen && *(end-plen) == '-' &&
       strcmp(end-plen+1, *p) == 0)
      {
      std::string key = entryKey.substr(0, entryKey.size() - plen);
      cmCacheManager::CacheIterator it = this->GetCacheIterator(key.c_str());
      if(it.IsAtEnd())
        {
        // Create an entry and store the property.
        CacheEntry& ne = this->Cache[key];
        ne.Properties.SetCMakeInstance(this->CMakeInstance);
        ne.Type = cmCacheManager::UNINITIALIZED;
        ne.SetProperty(*p, e.Value.c_str());
        }
      else
        {
        // Store this property on its entry.
        it.SetProperty(*p, e.Value.c_str());
        }
      return true;
      }
    }
  return false;
}

//----------------------------------------------------------------------------
void cmCacheManager::WritePropertyEntries(std::ostream& os,
                                          CacheIterator const& i)
{
  for(const char** p = this->PersistentProperties; *p; ++p)
    {
    if(const char* value = i.GetProperty(*p))
      {
      std::string helpstring = *p;
      helpstring += " property for variable: ";
      helpstring += i.GetName();
      cmCacheManager::OutputHelpString(os, helpstring);

      std::string key = i.GetName();
      key += "-";
      key += *p;
      this->OutputKey(os, key);
      os << ":INTERNAL=";
      this->OutputValue(os, value);
      os << "\n";
      }
    }
}

bool cmCacheManager::SaveCache(cmMakefile* mf)
{
  return this->SaveCache(mf->GetHomeOutputDirectory());
}


bool cmCacheManager::SaveCache(const char* path)
{
  std::string cacheFile = path;
  cacheFile += "/CMakeCache.txt";
  cmGeneratedFileStream fout(cacheFile.c_str());
  fout.SetCopyIfDifferent(true);
  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", cmVersion::GetMinorVersion());
  this->AddCacheEntry("CMAKE_CACHE_MINOR_VERSION", temp,
                      "Minor version of cmake used to create the "
                      "current loaded cache", cmCacheManager::INTERNAL);
  sprintf(temp, "%d", cmVersion::GetMajorVersion());
  this->AddCacheEntry("CMAKE_CACHE_MAJOR_VERSION", temp,
                      "Major version of cmake used to create the "
                      "current loaded cache", cmCacheManager::INTERNAL);
  sprintf(temp, "%d", cmVersion::GetPatchVersion());
  this->AddCacheEntry("CMAKE_CACHE_PATCH_VERSION", temp,
                      "Patch 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] == ':' )
    {
    // Cast added to avoid compiler warning. Cast is ok because
    // value is guaranteed to fit in char by the above if...
    currentcwd[0] = static_cast<char>(currentcwd[0] - 'A' + 'a');
    }
  cmSystemTools::ConvertToUnixSlashes(currentcwd);
  this->AddCacheEntry("CMAKE_CACHEFILE_DIR", currentcwd.c_str(),
                      "This is the directory where this CMakeCache.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 GUIs 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(!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
      if(const char* help = ce.GetProperty("HELPSTRING"))
        {
        cmCacheManager::OutputHelpString(fout, help);
        }
      else
        {
        cmCacheManager::OutputHelpString(fout, "Missing description");
        }
      this->OutputKey(fout, i->first);
      fout << ":" << cmCacheManagerTypes[t] << "=";
      this->OutputValue(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();
    this->WritePropertyEntries(fout, i);
    if(t == cmCacheManager::INTERNAL)
      {
      // Format is key:type=value
      if(const char* help = i.GetProperty("HELPSTRING"))
        {
        this->OutputHelpString(fout, help);
        }
      this->OutputKey(fout, i.GetName());
      fout << ":" << cmCacheManagerTypes[t] << "=";
      this->OutputValue(fout, i.GetValue());
      fout << "\n";
      }
    }
  fout << "\n";
  fout.Close();
  std::string checkCacheFile = path;
  checkCacheFile += cmake::GetCMakeFilesDirectory();
  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";
  if(cmSystemTools::FileExists(cacheFile.c_str()))
    {
    cmSystemTools::RemoveFile(cacheFile.c_str());
    // now remove the files in the CMakeFiles directory
    // this cleans up language cache files
    cmakeFiles += cmake::GetCMakeFilesDirectory();
    if(cmSystemTools::FileIsDirectory(cmakeFiles.c_str()))
      {
      cmSystemTools::RemoveADirectory(cmakeFiles.c_str());
      }
    }
  return true;
}

void cmCacheManager::OutputKey(std::ostream& fout, std::string const& key)
{
  // support : in key name by double quoting
  const char* q = (key.find(':') != key.npos ||
                   key.find("//") == 0)? "\"" : "";
  fout << q << key << q;
}

void cmCacheManager::OutputValue(std::ostream& fout, std::string const& value)
{
  // if value has trailing space or tab, enclose it in single quotes
  if (value.size() &&
      (value[value.size() - 1] == ' ' ||
       value[value.size() - 1] == '\t'))
    {
    fout << '\'' << value << '\'';
    }
  else
    {
    fout << value;
    }
}

void cmCacheManager::OutputHelpString(std::ostream& 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;
  for (std::string::size_type i=0; i<=end; i++)
    {
    if ((i==end)
        || (helpString[i]=='\n')
        || ((i-pos >= 60) && (helpString[i]==' ')))
      {
      fout << "//";
      if (helpString[pos] == '\n')
        {
        pos++;
        fout << "\\n";
        }
      oneLine = helpString.substr(pos, i - pos);
      fout << oneLine.c_str() << "\n";
      pos = i;
      }
    }
}

void cmCacheManager::RemoveCacheEntry(const char* key)
{
  CacheEntryMap::iterator i = this->Cache.find(key);
  if(i != this->Cache.end())
    {
    this->Cache.erase(i);
    }
}


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];
  e.Properties.SetCMakeInstance(this->CMakeInstance);
  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)
    {
    if(e.Value.find(';') != e.Value.npos)
      {
      std::vector<std::string> paths;
      cmSystemTools::ExpandListArgument(e.Value, paths);
      const char* sep = "";
      e.Value = "";
      for(std::vector<std::string>::iterator i = paths.begin();
          i != paths.end(); ++i)
        {
        cmSystemTools::ConvertToUnixSlashes(*i);
        e.Value += sep;
        e.Value += *i;
        sep = ";";
        }
      }
    else
      {
      cmSystemTools::ConvertToUnixSlashes(e.Value);
      }
    }
  e.SetProperty("HELPSTRING", helpString? helpString :
                "(This variable does not exist and should not be used)");
  if (this->Cache[key].Value == e.Value)
    {
    this->CMakeInstance->UnwatchUnusedCli(key);
    }
  this->Cache[key] = e;
}

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 = "";
    }
}

//----------------------------------------------------------------------------
bool cmCacheManager::CacheIterator::GetValueAsBool() const
{
  return cmSystemTools::IsOn(this->GetEntry().Value.c_str());
}

//----------------------------------------------------------------------------
const char*
cmCacheManager::CacheEntry::GetProperty(const char* prop) const
{
  if(strcmp(prop, "TYPE") == 0)
    {
    return cmCacheManagerTypes[this->Type];
    }
  else if(strcmp(prop, "VALUE") == 0)
    {
    return this->Value.c_str();
    }
  bool c = false;
  return
    this->Properties.GetPropertyValue(prop, cmProperty::CACHE, c);
}

//----------------------------------------------------------------------------
void cmCacheManager::CacheEntry::SetProperty(const char* prop,
                                             const char* value)
{
  if(strcmp(prop, "TYPE") == 0)
    {
    this->Type = cmCacheManager::StringToType(value? value : "STRING");
    }
  else if(strcmp(prop, "VALUE") == 0)
    {
    this->Value = value? value : "";
    }
  else
    {
    this->Properties.SetProperty(prop, value, cmProperty::CACHE);
    }
}

//----------------------------------------------------------------------------
void cmCacheManager::CacheEntry::AppendProperty(const char* prop,
                                                const char* value,
                                                bool asString)
{
  if(strcmp(prop, "TYPE") == 0)
    {
    this->Type = cmCacheManager::StringToType(value? value : "STRING");
    }
  else if(strcmp(prop, "VALUE") == 0)
    {
    if(value)
      {
      if(!this->Value.empty() && *value && !asString)
        {
        this->Value += ";";
        }
      this->Value += value;
      }
    }
  else
    {
    this->Properties.AppendProperty(prop, value, cmProperty::CACHE, asString);
    }
}

//----------------------------------------------------------------------------
const char* cmCacheManager::CacheIterator::GetProperty(const char* prop) const
{
  if(!this->IsAtEnd())
    {
    return this->GetEntry().GetProperty(prop);
    }
  return 0;
}

//----------------------------------------------------------------------------
void cmCacheManager::CacheIterator::SetProperty(const char* p, const char* v)
{
  if(!this->IsAtEnd())
    {
    this->GetEntry().SetProperty(p, v);
    }
}

//----------------------------------------------------------------------------
void cmCacheManager::CacheIterator::AppendProperty(const char* p,
                                                   const char* v,
                                                   bool asString)
{
  if(!this->IsAtEnd())
    {
    this->GetEntry().AppendProperty(p, v, asString);
    }
}

//----------------------------------------------------------------------------
bool cmCacheManager::CacheIterator::GetPropertyAsBool(const char* prop) const
{
  if(const char* value = this->GetProperty(prop))
    {
    return cmSystemTools::IsOn(value);
    }
  return false;
}

//----------------------------------------------------------------------------
void cmCacheManager::CacheIterator::SetProperty(const char* p, bool v)
{
  this->SetProperty(p, v ? "ON" : "OFF");
}

//----------------------------------------------------------------------------
bool cmCacheManager::CacheIterator::PropertyExists(const char* prop) const
{
  return this->GetProperty(prop)? true:false;
}

//----------------------------------------------------------------------------
bool cmCacheManager::NeedCacheCompatibility(int major, int minor)
{
  // Compatibility is not needed if the cache version is zero because
  // the cache was created or modified by the user.
  if(this->CacheMajorVersion == 0)
    {
    return false;
    }

  // Compatibility is needed if the cache version is equal to or lower
  // than the given version.
  unsigned int actual_compat =
    CMake_VERSION_ENCODE(this->CacheMajorVersion, this->CacheMinorVersion, 0);
  return (actual_compat &&
          actual_compat <= CMake_VERSION_ENCODE(major, minor, 0));
}

//----------------------------------------------------------------------------
void cmCacheManager::DefineProperties(cmake *cm)
{
  cm->DefineProperty
    ("ADVANCED", cmProperty::CACHE,
     "True if entry should be hidden by default in GUIs.",
     "This is a boolean value indicating whether the entry is considered "
     "interesting only for advanced configuration.  "
     "The mark_as_advanced() command modifies this property."
      );

  cm->DefineProperty
    ("HELPSTRING", cmProperty::CACHE,
     "Help associated with entry in GUIs.",
     "This string summarizes the purpose of an entry to help users set it "
     "through a CMake GUI."
      );

  cm->DefineProperty
    ("TYPE", cmProperty::CACHE,
     "Widget type for entry in GUIs.",
     "Cache entry values are always strings, but CMake GUIs present widgets "
     "to help users set values.  "
     "The GUIs use this property as a hint to determine the widget type.  "
     "Valid TYPE values are:\n"
     "  BOOL          = Boolean ON/OFF value.\n"
     "  PATH          = Path to a directory.\n"
     "  FILEPATH      = Path to a file.\n"
     "  STRING        = Generic string value.\n"
     "  INTERNAL      = Do not present in GUI at all.\n"
     "  STATIC        = Value managed by CMake, do not change.\n"
     "  UNINITIALIZED = Type not yet specified.\n"
     "Generally the TYPE of a cache entry should be set by the command "
     "which creates it (set, option, find_library, etc.)."
      );

  cm->DefineProperty
    ("MODIFIED", cmProperty::CACHE,
     "Internal management property.  Do not set or get.",
     "This is an internal cache entry property managed by CMake to "
     "track interactive user modification of entries.  Ignore it."
      );

  cm->DefineProperty
    ("STRINGS", cmProperty::CACHE,
     "Enumerate possible STRING entry values for GUI selection.",
     "For cache entries with type STRING, this enumerates a set of values.  "
     "CMake GUIs may use this to provide a selection widget instead of a "
     "generic string entry field.  "
     "This is for convenience only.  "
     "CMake does not enforce that the value matches one of those listed."
      );

  cm->DefineProperty
    ("VALUE", cmProperty::CACHE,
     "Value of a cache entry.",
     "This property maps to the actual value of a cache entry.  "
     "Setting this property always sets the value without checking, so "
     "use with care."
      );
}
