/*============================================================================
  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 "cmLoadCacheCommand.h"

#include <cmsys/RegularExpression.hxx>
#include <cmsys/FStream.hxx>

// cmLoadCacheCommand
bool cmLoadCacheCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if (args.size()< 1)
    {
    this->SetError("called with wrong number of arguments.");
    }

  if(args.size() >= 2 && args[1] == "READ_WITH_PREFIX")
    {
    return this->ReadWithPrefix(args);
    }

  // Cache entries to be excluded from the import list.
  // If this set is empty, all cache entries are brought in
  // and they can not be overridden.
  bool excludeFiles=false;
  unsigned int i;
  std::set<cmStdString> excludes;

  for(i=0; i<args.size(); i++)
    {
    if (excludeFiles)
      {
      excludes.insert(args[i]);
      }
    if (args[i] == "EXCLUDE")
      {
      excludeFiles=true;
      }
    if (excludeFiles && (args[i] == "INCLUDE_INTERNALS"))
      {
      break;
      }
    }

  // Internal cache entries to be imported.
  // If this set is empty, no internal cache entries are
  // brought in.
  bool includeFiles=false;
  std::set<cmStdString> includes;

  for(i=0; i<args.size(); i++)
    {
    if (includeFiles)
      {
      includes.insert(args[i]);
      }
    if (args[i] == "INCLUDE_INTERNALS")
      {
      includeFiles=true;
      }
    if (includeFiles && (args[i] == "EXCLUDE"))
      {
      break;
      }
    }

  // Loop over each build directory listed in the arguments.  Each
  // directory has a cache file.
  for(i=0; i<args.size(); i++)
    {
    if ((args[i] == "EXCLUDE") || (args[i] == "INCLUDE_INTERNALS"))
      {
      break;
      }
    this->Makefile->GetCacheManager()->LoadCache(args[i].c_str(), false,
                                             excludes, includes);
    }


  return true;
}

//----------------------------------------------------------------------------
bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args)
{
  // Make sure we have a prefix.
  if(args.size() < 3)
    {
    this->SetError("READ_WITH_PREFIX form must specify a prefix.");
    return false;
    }

  // Make sure the cache file exists.
  std::string cacheFile = args[0]+"/CMakeCache.txt";
  if(!cmSystemTools::FileExists(cacheFile.c_str()))
    {
    std::string e = "Cannot load cache file from " + cacheFile;
    this->SetError(e.c_str());
    return false;
    }

  // Prepare the table of variables to read.
  this->Prefix = args[2];
  for(unsigned int i=3; i < args.size(); ++i)
    {
    this->VariablesToRead.insert(args[i]);
    }

  // Read the cache file.
  cmsys::ifstream fin(cacheFile.c_str());

  // This is a big hack read loop to overcome a buggy ifstream
  // implementation on HP-UX.  This should work on all platforms even
  // for small buffer sizes.
  const int bufferSize = 4096;
  char buffer[bufferSize];
  std::string line;
  while(fin)
    {
    // Read a block of the file.
    fin.read(buffer, bufferSize);
    if(fin.gcount())
      {
      // Parse for newlines directly.
      const char* i = buffer;
      const char* end = buffer+fin.gcount();
      while(i != end)
        {
        const char* begin = i;
        while(i != end && *i != '\n') { ++i; }
        if(i == begin || *(i-1) != '\r')
          {
          // Include this portion of the line.
          line += std::string(begin, i-begin);
          }
        else
          {
          // Include this portion of the line.
          // Don't include the \r in a \r\n pair.
          line += std::string(begin, i-1-begin);
          }
        if(i != end)
          {
          // Completed a line.
          this->CheckLine(line.c_str());
          line = "";

          // Skip the newline character.
          ++i;
          }
        }
      }
    }
  if(line.length())
    {
    // Partial last line.
    this->CheckLine(line.c_str());
    }

  return true;
}

//----------------------------------------------------------------------------
void cmLoadCacheCommand::CheckLine(const char* line)
{
  // Check one line of the cache file.
  std::string var;
  std::string value;
  cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED;
  if(cmCacheManager::ParseEntry(line, var, value, type))
    {
    // Found a real entry.  See if this one was requested.
    if(this->VariablesToRead.find(var) != this->VariablesToRead.end())
      {
      // This was requested.  Set this variable locally with the given
      // prefix.
      var = this->Prefix + var;
      if(value.length())
        {
        this->Makefile->AddDefinition(var.c_str(), value.c_str());
        }
      else
        {
        this->Makefile->RemoveDefinition(var.c_str());
        }
      }
    }
}
