/*============================================================================
  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 "cmFileCommand.h"
#include "cmake.h"
#include "cmHexFileConverter.h"
#include "cmFileTimeComparison.h"

#if defined(CMAKE_BUILD_WITH_CMAKE)
#include "cm_curl.h"
#endif

#undef GetCurrentDirectory
#include <sys/types.h>
#include <sys/stat.h>

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

// Table of permissions flags.
#if defined(_WIN32) && !defined(__CYGWIN__)
static mode_t mode_owner_read = S_IREAD;
static mode_t mode_owner_write = S_IWRITE;
static mode_t mode_owner_execute = S_IEXEC;
static mode_t mode_group_read = 0;
static mode_t mode_group_write = 0;
static mode_t mode_group_execute = 0;
static mode_t mode_world_read = 0;
static mode_t mode_world_write = 0;
static mode_t mode_world_execute = 0;
static mode_t mode_setuid = 0;
static mode_t mode_setgid = 0;
#else
static mode_t mode_owner_read = S_IRUSR;
static mode_t mode_owner_write = S_IWUSR;
static mode_t mode_owner_execute = S_IXUSR;
static mode_t mode_group_read = S_IRGRP;
static mode_t mode_group_write = S_IWGRP;
static mode_t mode_group_execute = S_IXGRP;
static mode_t mode_world_read = S_IROTH;
static mode_t mode_world_write = S_IWOTH;
static mode_t mode_world_execute = S_IXOTH;
static mode_t mode_setuid = S_ISUID;
static mode_t mode_setgid = S_ISGID;
#endif

// cmLibraryCommand
bool cmFileCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if(args.size() < 2 )
    {
    this->SetError("must be called with at least two arguments.");
    return false;
    }
  std::string subCommand = args[0];
  if ( subCommand == "WRITE" )
    {
    return this->HandleWriteCommand(args, false);
    }
  else if ( subCommand == "APPEND" )
    {
    return this->HandleWriteCommand(args, true);
    }
  else if ( subCommand == "DOWNLOAD" )
    {
    return this->HandleDownloadCommand(args);
    }
  else if ( subCommand == "READ" )
    {
    return this->HandleReadCommand(args);
    }
  else if ( subCommand == "STRINGS" )
    {
    return this->HandleStringsCommand(args);
    }
  else if ( subCommand == "GLOB" )
    {
    return this->HandleGlobCommand(args, false);
    }
  else if ( subCommand == "GLOB_RECURSE" )
    {
    return this->HandleGlobCommand(args, true);
    }
  else if ( subCommand == "MAKE_DIRECTORY" )
    {
    return this->HandleMakeDirectoryCommand(args);
    }
  else if ( subCommand == "RENAME" )
    {
    return this->HandleRename(args);
    }
  else if ( subCommand == "REMOVE" )
    {
    return this->HandleRemove(args, false);
    }
  else if ( subCommand == "REMOVE_RECURSE" )
    {
    return this->HandleRemove(args, true);
    }
  else if ( subCommand == "COPY" )
    {
    return this->HandleCopyCommand(args);
    }
  else if ( subCommand == "INSTALL" )
    {
    return this->HandleInstallCommand(args);
    }
  else if ( subCommand == "DIFFERENT" )
    {
    return this->HandleDifferentCommand(args);
    }
  else if ( subCommand == "RPATH_CHANGE" || subCommand == "CHRPATH" )
    {
    return this->HandleRPathChangeCommand(args);
    }
  else if ( subCommand == "RPATH_CHECK" )
    {
    return this->HandleRPathCheckCommand(args);
    }
  else if ( subCommand == "RPATH_REMOVE" )
    {
    return this->HandleRPathRemoveCommand(args);
    }
  else if ( subCommand == "RELATIVE_PATH" )
    {
    return this->HandleRelativePathCommand(args);
    }
  else if ( subCommand == "TO_CMAKE_PATH" )
    {
    return this->HandleCMakePathCommand(args, false);
    }
  else if ( subCommand == "TO_NATIVE_PATH" )
    {
    return this->HandleCMakePathCommand(args, true);
    }

  std::string e = "does not recognize sub-command "+subCommand;
  this->SetError(e.c_str());
  return false;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
  bool append)
{
  std::string message;
  std::vector<std::string>::const_iterator i = args.begin();

  i++; // Get rid of subcommand

  std::string fileName = *i;
  if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) )
    {
    fileName = this->Makefile->GetCurrentDirectory();
    fileName += "/" + *i;
    }

  i++;

  for(;i != args.end(); ++i)
    {
    message += *i;
    }
  if ( !this->Makefile->CanIWriteThisFile(fileName.c_str()) )
    {
    std::string e
      = "attempted to write a file: " + fileName +
      " into a source directory.";
    this->SetError(e.c_str());
    cmSystemTools::SetFatalErrorOccured();
    return false;
    }
  std::string dir = cmSystemTools::GetFilenamePath(fileName);
  cmSystemTools::MakeDirectory(dir.c_str());

  mode_t mode =
#if defined( _MSC_VER ) || defined( __MINGW32__ )
    S_IREAD | S_IWRITE
#elif defined( __BORLANDC__ )
    S_IRUSR | S_IWUSR
#else
    0666
#endif
    ;

  // Set permissions to writable
  if ( cmSystemTools::GetPermissions(fileName.c_str(), mode) )
    {
    cmSystemTools::SetPermissions(fileName.c_str(),
#if defined( _MSC_VER ) || defined( __MINGW32__ )
      S_IREAD | S_IWRITE
#else
      0666
#endif
    );
    }
  // If GetPermissions fails, pretend like it is ok. File open will fail if
  // the file is not writable
  std::ofstream file(fileName.c_str(), append?std::ios::app: std::ios::out);
  if ( !file )
    {
    std::string error = "Internal CMake error when trying to open file: ";
    error += fileName.c_str();
    error += " for writing.";
    this->SetError(error.c_str());
    return false;
    }
  file << message;
  file.close();
  cmSystemTools::SetPermissions(fileName.c_str(), mode);
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
{
  if ( args.size() < 3 )
    {
    this->SetError("READ must be called with at least two additional "
                   "arguments");
    return false;
    }

  cmCommandArgumentsHelper argHelper;
  cmCommandArgumentGroup group;

  cmCAString readArg    (&argHelper, "READ");
  cmCAString fileNameArg    (&argHelper, 0);
  cmCAString resultArg      (&argHelper, 0);

  cmCAString offsetArg      (&argHelper, "OFFSET", &group);
  cmCAString limitArg       (&argHelper, "LIMIT", &group);
  cmCAEnabler hexOutputArg  (&argHelper, "HEX", &group);
  readArg.Follows(0);
  fileNameArg.Follows(&readArg);
  resultArg.Follows(&fileNameArg);
  group.Follows(&resultArg);
  argHelper.Parse(&args, 0);

  std::string fileName = fileNameArg.GetString();
  if ( !cmsys::SystemTools::FileIsFullPath(fileName.c_str()) )
    {
    fileName = this->Makefile->GetCurrentDirectory();
    fileName += "/" + fileNameArg.GetString();
    }

  std::string variable = resultArg.GetString();

  // Open the specified file.
#if defined(_WIN32) || defined(__CYGWIN__)
  std::ifstream file(fileName.c_str(), std::ios::in | 
               (hexOutputArg.IsEnabled() ? std::ios::binary : std::ios::in));
#else
  std::ifstream file(fileName.c_str(), std::ios::in);
#endif

  if ( !file )
    {
    std::string error = "Internal CMake error when trying to open file: ";
    error += fileName.c_str();
    error += " for reading.";
    this->SetError(error.c_str());
    return false;
    }

  // is there a limit?
  long sizeLimit = -1;
  if (limitArg.GetString().size() > 0)
    {
    sizeLimit = atoi(limitArg.GetCString());
    }

  // is there an offset?
  long offset = 0;
  if (offsetArg.GetString().size() > 0)
    {
    offset = atoi(offsetArg.GetCString());
    }

  file.seekg(offset);

  std::string output;

  if (hexOutputArg.IsEnabled())
    {
    // Convert part of the file into hex code
    char c;
    while((sizeLimit != 0) && (file.get(c)))
      {
      char hex[4];
      sprintf(hex, "%.2x", c&0xff);
      output += hex;
      if (sizeLimit > 0)
        {
        sizeLimit--;
        }
      }
    }
  else
    {
    std::string line;
    bool has_newline = false;
    while (sizeLimit != 0 &&
          cmSystemTools::GetLineFromStream(file, line, &has_newline,
                                            sizeLimit) )
      {
      if (sizeLimit > 0)
        {
        sizeLimit = sizeLimit - static_cast<long>(line.size());
        if (has_newline)
          {
          sizeLimit--;
          }
        if (sizeLimit < 0)
          {
          sizeLimit = 0;
          }
        }
      output += line;
      if ( has_newline )
        {
        output += "\n";
        }
      }
    }
  this->Makefile->AddDefinition(variable.c_str(), output.c_str());
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
{
  if(args.size() < 3)
    {
    this->SetError("STRINGS requires a file name and output variable");
    return false;
    }

  // Get the file to read.
  std::string fileName = args[1];
  if(!cmsys::SystemTools::FileIsFullPath(fileName.c_str()))
    {
    fileName = this->Makefile->GetCurrentDirectory();
    fileName += "/" + args[1];
    }

  // Get the variable in which to store the results.
  std::string outVar = args[2];

  // Parse the options.
  enum { arg_none,
         arg_limit_input,
         arg_limit_output,
         arg_limit_count,
         arg_length_minimum,
         arg_length_maximum,
         arg__maximum,
         arg_regex };
  unsigned int minlen = 0;
  unsigned int maxlen = 0;
  int limit_input = -1;
  int limit_output = -1;
  unsigned int limit_count = 0;
  cmsys::RegularExpression regex;
  bool have_regex = false;
  bool newline_consume = false;
  bool hex_conversion_enabled = true;
  int arg_mode = arg_none;
  for(unsigned int i=3; i < args.size(); ++i)
    {
    if(args[i] == "LIMIT_INPUT")
      {
      arg_mode = arg_limit_input;
      }
    else if(args[i] == "LIMIT_OUTPUT")
      {
      arg_mode = arg_limit_output;
      }
    else if(args[i] == "LIMIT_COUNT")
      {
      arg_mode = arg_limit_count;
      }
    else if(args[i] == "LENGTH_MINIMUM")
      {
      arg_mode = arg_length_minimum;
      }
    else if(args[i] == "LENGTH_MAXIMUM")
      {
      arg_mode = arg_length_maximum;
      }
    else if(args[i] == "REGEX")
      {
      arg_mode = arg_regex;
      }
    else if(args[i] == "NEWLINE_CONSUME")
      {
      newline_consume = true;
      arg_mode = arg_none;
      }
    else if(args[i] == "NO_HEX_CONVERSION")
      {
      hex_conversion_enabled = false;
      arg_mode = arg_none;
      }
    else if(arg_mode == arg_limit_input)
      {
      if(sscanf(args[i].c_str(), "%d", &limit_input) != 1 ||
         limit_input < 0)
        {
        cmOStringStream e;
        e << "STRINGS option LIMIT_INPUT value \""
          << args[i] << "\" is not an unsigned integer.";
        this->SetError(e.str().c_str());
        return false;
        }
      arg_mode = arg_none;
      }
    else if(arg_mode == arg_limit_output)
      {
      if(sscanf(args[i].c_str(), "%d", &limit_output) != 1 ||
         limit_output < 0)
        {
        cmOStringStream e;
        e << "STRINGS option LIMIT_OUTPUT value \""
          << args[i] << "\" is not an unsigned integer.";
        this->SetError(e.str().c_str());
        return false;
        }
      arg_mode = arg_none;
      }
    else if(arg_mode == arg_limit_count)
      {
      int count;
      if(sscanf(args[i].c_str(), "%d", &count) != 1 || count < 0)
        {
        cmOStringStream e;
        e << "STRINGS option LIMIT_COUNT value \""
          << args[i] << "\" is not an unsigned integer.";
        this->SetError(e.str().c_str());
        return false;
        }
      limit_count = count;
      arg_mode = arg_none;
      }
    else if(arg_mode == arg_length_minimum)
      {
      int len;
      if(sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0)
        {
        cmOStringStream e;
        e << "STRINGS option LENGTH_MINIMUM value \""
          << args[i] << "\" is not an unsigned integer.";
        this->SetError(e.str().c_str());
        return false;
        }
      minlen = len;
      arg_mode = arg_none;
      }
    else if(arg_mode == arg_length_maximum)
      {
      int len;
      if(sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0)
        {
        cmOStringStream e;
        e << "STRINGS option LENGTH_MAXIMUM value \""
          << args[i] << "\" is not an unsigned integer.";
        this->SetError(e.str().c_str());
        return false;
        }
      maxlen = len;
      arg_mode = arg_none;
      }
    else if(arg_mode == arg_regex)
      {
      if(!regex.compile(args[i].c_str()))
        {
        cmOStringStream e;
        e << "STRINGS option REGEX value \""
          << args[i] << "\" could not be compiled.";
        this->SetError(e.str().c_str());
        return false;
        }
      have_regex = true;
      arg_mode = arg_none;
      }
    else
      {
      cmOStringStream e;
      e << "STRINGS given unknown argument \""
        << args[i] << "\"";
      this->SetError(e.str().c_str());
      return false;
      }
    }

  if (hex_conversion_enabled)
    {
    // TODO: should work without temp file, but just on a memory buffer
    std::string binaryFileName = this->Makefile->GetCurrentOutputDirectory();
    binaryFileName += cmake::GetCMakeFilesDirectory();
    binaryFileName += "/FileCommandStringsBinaryFile";
    if(cmHexFileConverter::TryConvert(fileName.c_str(),binaryFileName.c_str()))
      {
      fileName = binaryFileName;
      }
    }

  // Open the specified file.
#if defined(_WIN32) || defined(__CYGWIN__)
  std::ifstream fin(fileName.c_str(), std::ios::in | std::ios::binary);
#else
  std::ifstream fin(fileName.c_str(), std::ios::in);
#endif
  if(!fin)
    {
    cmOStringStream e;
    e << "STRINGS file \"" << fileName << "\" cannot be read.";
    this->SetError(e.str().c_str());
    return false;
    }

  // At least one compiler (Portland Group Fortran) produces binaries
  // with some extra characters in strings.
  char extra[256]; // = {}; // some compilers do not like this
  memset(extra, 0, sizeof(extra));
  extra[0x0c] = 1; // FF  (form feed)
  extra[0x14] = 1; // DC4 (device control 4)

  // Parse strings out of the file.
  int output_size = 0;
  std::vector<std::string> strings;
  std::string s;
  int c;
  while((!limit_count || strings.size() < limit_count) &&
        (limit_input < 0 || static_cast<int>(fin.tellg()) < limit_input) &&
        (c = fin.get(), fin))
    {
    if(c == '\0')
      {
      // A terminating null character has been found.  Check if the
      // current string matches the requirements.  Since it was
      // terminated by a null character, we require that the length be
      // at least one no matter what the user specified.
      if(s.length() >= minlen && s.length() >= 1 &&
         (!have_regex || regex.find(s.c_str())))
        {
        output_size += static_cast<int>(s.size()) + 1;
        if(limit_output >= 0 && output_size >= limit_output)
          {
          s = "";
          break;
          }
        strings.push_back(s);
        }

      // Reset the string to empty.
      s = "";
      }
    else if(c == '\n' && !newline_consume)
      {
      // The current line has been terminated.  Check if the current
      // string matches the requirements.  The length may now be as
      // low as zero since blank lines are allowed.
      if(s.length() >= minlen &&
         (!have_regex || regex.find(s.c_str())))
        {
        output_size += static_cast<int>(s.size()) + 1;
        if(limit_output >= 0 && output_size >= limit_output)
          {
          s = "";
          break;
          }
        strings.push_back(s);
        }

      // Reset the string to empty.
      s = "";
      }
    else if(c == '\r')
      {
      // Ignore CR character to make output always have UNIX newlines.
      }
    else if((c >= 0x20 && c < 0x7F) || c == '\t' || extra[c] ||
            (c == '\n' && newline_consume))
      {
      // This is an ASCII character that may be part of a string.
      // Cast added to avoid compiler warning. Cast is ok because
      // c is guaranteed to fit in char by the above if...
      s += static_cast<char>(c);
      }
    else
      {
      // This is a non-string character.  Reset the string to emtpy.
      s = "";
      }

    // Terminate a string if the maximum length is reached.
    if(maxlen > 0 && s.size() == maxlen)
      {
      if(s.length() >= minlen &&
         (!have_regex || regex.find(s.c_str())))
        {
        output_size += static_cast<int>(s.size()) + 1;
        if(limit_output >= 0 && output_size >= limit_output)
          {
          s = "";
          break;
          }
        strings.push_back(s);
        }
      s = "";
      }
    }

  // If there is a non-empty current string we have hit the end of the
  // input file or the input size limit.  Check if the current string
  // matches the requirements.
  if((!limit_count || strings.size() < limit_count) &&
     !s.empty() && s.length() >= minlen &&
     (!have_regex || regex.find(s.c_str())))
    {
    output_size += static_cast<int>(s.size()) + 1;
    if(limit_output < 0 || output_size < limit_output)
      {
      strings.push_back(s);
      }
    }

  // Encode the result in a CMake list.
  const char* sep = "";
  std::string output;
  for(std::vector<std::string>::const_iterator si = strings.begin();
      si != strings.end(); ++si)
    {
    // Separate the strings in the output to make it a list.
    output += sep;
    sep = ";";

    // Store the string in the output, but escape semicolons to
    // make sure it is a list.
    std::string const& sr = *si;
    for(unsigned int i=0; i < sr.size(); ++i)
      {
      if(sr[i] == ';')
        {
        output += '\\';
        }
      output += sr[i];
      }
    }

  // Save the output in a makefile variable.
  this->Makefile->AddDefinition(outVar.c_str(), output.c_str());
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
  bool recurse)
{
  if ( args.size() < 2 )
    {
    this->SetError("GLOB requires at least a variable name");
    return false;
    }

  std::vector<std::string>::const_iterator i = args.begin();

  i++; // Get rid of subcommand

  std::string variable = *i;
  i++;
  cmsys::Glob g;
  g.SetRecurse(recurse);

  bool explicitFollowSymlinks = false;
  cmPolicies::PolicyStatus status =
    this->Makefile->GetPolicyStatus(cmPolicies::CMP0009);
  if(recurse)
    {
    switch(status)
      {
      case cmPolicies::NEW:
        g.RecurseThroughSymlinksOff();
        break;
      case cmPolicies::OLD:
      case cmPolicies::WARN:
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::REQUIRED_ALWAYS:
        g.RecurseThroughSymlinksOn();
        break;
      }
    }

  std::string output = "";
  bool first = true;
  for ( ; i != args.end(); ++i )
    {
    if ( recurse && (*i == "FOLLOW_SYMLINKS") )
      {
      explicitFollowSymlinks = true;
      g.RecurseThroughSymlinksOn();
      ++i;
      if ( i == args.end() )
        {
        this->SetError(
          "GLOB_RECURSE requires a glob expression after FOLLOW_SYMLINKS");
        return false;
        }
      }

    if ( *i == "RELATIVE" )
      {
      ++i; // skip RELATIVE
      if ( i == args.end() )
        {
        this->SetError("GLOB requires a directory after the RELATIVE tag");
        return false;
        }
      g.SetRelative(i->c_str());
      ++i;
      if(i == args.end())
        {
        this->SetError("GLOB requires a glob expression after the directory");
        return false;
        }
      }

    if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) )
      {
      std::string expr = this->Makefile->GetCurrentDirectory();
      // Handle script mode
      if ( expr.size() > 0 )
        {
        expr += "/" + *i;
        g.FindFiles(expr);
        }
      else
        {
        g.FindFiles(*i);
        }
      }
    else
      {
      g.FindFiles(*i);
      }

    std::vector<std::string>::size_type cc;
    std::vector<std::string>& files = g.GetFiles();
    for ( cc = 0; cc < files.size(); cc ++ )
      {
      if ( !first )
        {
        output += ";";
        }
      output += files[cc];
      first = false;
      }
    }

  if(recurse && !explicitFollowSymlinks)
    {
    switch (status)
      {
      case cmPolicies::NEW:
        // Correct behavior, yay!
        break;
      case cmPolicies::OLD:
        // Probably not really the expected behavior, but the author explicitly
        // asked for the old behavior... no warning.
      case cmPolicies::WARN:
        // Possibly unexpected old behavior *and* we actually traversed
        // symlinks without being explicitly asked to: warn the author.
        if(g.GetFollowedSymlinkCount() != 0)
          {
          this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
            this->Makefile->GetPolicies()->
              GetPolicyWarning(cmPolicies::CMP0009));
          }
        break;
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::REQUIRED_ALWAYS:
        this->SetError("policy CMP0009 error");
        this->Makefile->IssueMessage(cmake::FATAL_ERROR,
          this->Makefile->GetPolicies()->
            GetRequiredPolicyError(cmPolicies::CMP0009));
        return false;
      }
    }

  this->Makefile->AddDefinition(variable.c_str(), output.c_str());
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleMakeDirectoryCommand(
  std::vector<std::string> const& args)
{
  if(args.size() < 2 )
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }

  std::vector<std::string>::const_iterator i = args.begin();

  i++; // Get rid of subcommand

  std::string expr;
  for ( ; i != args.end(); ++i )
    {
    const std::string* cdir = &(*i);
    if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) )
      {
      expr = this->Makefile->GetCurrentDirectory();
      expr += "/" + *i;
      cdir = &expr;
      }
    if ( !this->Makefile->CanIWriteThisFile(cdir->c_str()) )
      {
      std::string e = "attempted to create a directory: " + *cdir
        + " into a source directory.";
      this->SetError(e.c_str());
      cmSystemTools::SetFatalErrorOccured();
      return false;
      }
    if ( !cmSystemTools::MakeDirectory(cdir->c_str()) )
      {
      std::string error = "problem creating directory: " + *cdir;
      this->SetError(error.c_str());
      return false;
      }
    }
  return true;
}

//----------------------------------------------------------------------------
bool
cmFileCommand::HandleDifferentCommand(std::vector<std::string> const& args)
{
  /*
    FILE(DIFFERENT <variable> FILES <lhs> <rhs>)
   */

  // Evaluate arguments.
  const char* file_lhs = 0;
  const char* file_rhs = 0;
  const char* var = 0;
  enum Doing { DoingNone, DoingVar, DoingFileLHS, DoingFileRHS };
  Doing doing = DoingVar;
  for(unsigned int i=1; i < args.size(); ++i)
    {
    if(args[i] == "FILES")
      {
      doing = DoingFileLHS;
      }
    else if(doing == DoingVar)
      {
      var = args[i].c_str();
      doing = DoingNone;
      }
    else if(doing == DoingFileLHS)
      {
      file_lhs = args[i].c_str();
      doing = DoingFileRHS;
      }
    else if(doing == DoingFileRHS)
      {
      file_rhs = args[i].c_str();
      doing = DoingNone;
      }
    else
      {
      cmOStringStream e;
      e << "DIFFERENT given unknown argument " << args[i];
      this->SetError(e.str().c_str());
      return false;
      }
    }
  if(!var)
    {
    this->SetError("DIFFERENT not given result variable name.");
    return false;
    }
  if(!file_lhs || !file_rhs)
    {
    this->SetError("DIFFERENT not given FILES option with two file names.");
    return false;
    }

  // Compare the files.
  const char* result =
    cmSystemTools::FilesDiffer(file_lhs, file_rhs)? "1" : "0";
  this->Makefile->AddDefinition(var, result);
  return true;
}

//----------------------------------------------------------------------------
// File installation helper class.
struct cmFileCopier
{
  cmFileCopier(cmFileCommand* command, const char* name = "COPY"):
    FileCommand(command),
    Makefile(command->GetMakefile()),
    Name(name),
    Always(false),
    MatchlessFiles(true),
    FilePermissions(0),
    DirPermissions(0),
    CurrentMatchRule(0),
    UseGivenPermissionsFile(false),
    UseGivenPermissionsDir(false),
    UseSourcePermissions(true),
    Doing(DoingNone)
    {
    }
  virtual ~cmFileCopier() {}

  bool Run(std::vector<std::string> const& args);
protected:

  cmFileCommand* FileCommand;
  cmMakefile* Makefile;
  const char* Name;
  bool Always;
  cmFileTimeComparison FileTimes;

  // Whether to install a file not matching any expression.
  bool MatchlessFiles;

  // Permissions for files and directories installed by this object.
  mode_t FilePermissions;
  mode_t DirPermissions;

  // Properties set by pattern and regex match rules.
  struct MatchProperties
  {
    bool Exclude;
    mode_t Permissions;
    MatchProperties(): Exclude(false), Permissions(0) {}
  };
  struct MatchRule;
  friend struct MatchRule;
  struct MatchRule
  {
    cmsys::RegularExpression Regex;
    MatchProperties Properties;
    std::string RegexString;
    MatchRule(std::string const& regex):
      Regex(regex.c_str()), RegexString(regex) {}
  };
  std::vector<MatchRule> MatchRules;

  // Get the properties from rules matching this input file.
  MatchProperties CollectMatchProperties(const char* file)
    {
    // Match rules are case-insensitive on some platforms.
#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
    std::string lower = cmSystemTools::LowerCase(file);
    file = lower.c_str();
#endif

    // Collect properties from all matching rules.
    bool matched = false;
    MatchProperties result;
    for(std::vector<MatchRule>::iterator mr = this->MatchRules.begin();
        mr != this->MatchRules.end(); ++mr)
      {
      if(mr->Regex.find(file))
        {
        matched = true;
        result.Exclude |= mr->Properties.Exclude;
        result.Permissions |= mr->Properties.Permissions;
        }
      }
    if(!matched && !this->MatchlessFiles)
      {
      result.Exclude = !cmSystemTools::FileIsDirectory(file);
      }
    return result;
    }

  bool SetPermissions(const char* toFile, mode_t permissions)
    {
    if(permissions && !cmSystemTools::SetPermissions(toFile, permissions))
      {
      cmOStringStream e;
      e << this->Name << " cannot set permissions on \"" << toFile << "\"";
      this->FileCommand->SetError(e.str().c_str());
      return false;
      }
    return true;
    }

  // Translate an argument to a permissions bit.
  bool CheckPermissions(std::string const& arg, mode_t& permissions)
    {
    if(arg == "OWNER_READ")         { permissions |= mode_owner_read; }
    else if(arg == "OWNER_WRITE")   { permissions |= mode_owner_write; }
    else if(arg == "OWNER_EXECUTE") { permissions |= mode_owner_execute; }
    else if(arg == "GROUP_READ")    { permissions |= mode_group_read; }
    else if(arg == "GROUP_WRITE")   { permissions |= mode_group_write; }
    else if(arg == "GROUP_EXECUTE") { permissions |= mode_group_execute; }
    else if(arg == "WORLD_READ")    { permissions |= mode_world_read; }
    else if(arg == "WORLD_WRITE")   { permissions |= mode_world_write; }
    else if(arg == "WORLD_EXECUTE") { permissions |= mode_world_execute; }
    else if(arg == "SETUID")        { permissions |= mode_setuid; }
    else if(arg == "SETGID")        { permissions |= mode_setgid; }
    else
      {
      cmOStringStream e;
      e << this->Name << " given invalid permission \"" << arg << "\".";
      this->FileCommand->SetError(e.str().c_str());
      return false;
      }
    return true;
    }

  bool InstallSymlink(const char* fromFile, const char* toFile);
  bool InstallFile(const char* fromFile, const char* toFile,
                   MatchProperties const& match_properties);
  bool InstallDirectory(const char* source, const char* destination,
                        MatchProperties const& match_properties);
  virtual bool Install(const char* fromFile, const char* toFile);
  virtual std::string const& ToName(std::string const& fromName)
    { return fromName; }

  enum Type
  {
    TypeFile,
    TypeDir,
    TypeLink
  };
  virtual void ReportCopy(const char*, Type, bool) {}
  virtual bool ReportMissing(const char* fromFile)
    {
    // The input file does not exist and installation is not optional.
    cmOStringStream e;
    e << this->Name << " cannot find \"" << fromFile << "\".";
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }

  MatchRule* CurrentMatchRule;
  bool UseGivenPermissionsFile;
  bool UseGivenPermissionsDir;
  bool UseSourcePermissions;
  std::string Destination;
  std::vector<std::string> Files;
  int Doing;

  virtual bool Parse(std::vector<std::string> const& args);
  enum
  {
    DoingNone,
    DoingError,
    DoingDestination,
    DoingFiles,
    DoingPattern,
    DoingRegex,
    DoingPermissionsFile,
    DoingPermissionsDir,
    DoingPermissionsMatch,
    DoingLast1
  };
  virtual bool CheckKeyword(std::string const& arg);
  virtual bool CheckValue(std::string const& arg);

  void NotBeforeMatch(std::string const& arg)
    {
    cmOStringStream e;
    e << "option " << arg << " may not appear before PATTERN or REGEX.";
    this->FileCommand->SetError(e.str().c_str());
    this->Doing = DoingError;
    }
  void NotAfterMatch(std::string const& arg)
    {
    cmOStringStream e;
    e << "option " << arg << " may not appear after PATTERN or REGEX.";
    this->FileCommand->SetError(e.str().c_str());
    this->Doing = DoingError;
    }
  virtual void DefaultFilePermissions()
    {
    // Use read/write permissions.
    this->FilePermissions = 0;
    this->FilePermissions |= mode_owner_read;
    this->FilePermissions |= mode_owner_write;
    this->FilePermissions |= mode_group_read;
    this->FilePermissions |= mode_world_read;
    }
  virtual void DefaultDirectoryPermissions()
    {
    // Use read/write/executable permissions.
    this->DirPermissions = 0;
    this->DirPermissions |= mode_owner_read;
    this->DirPermissions |= mode_owner_write;
    this->DirPermissions |= mode_owner_execute;
    this->DirPermissions |= mode_group_read;
    this->DirPermissions |= mode_group_execute;
    this->DirPermissions |= mode_world_read;
    this->DirPermissions |= mode_world_execute;
    }
};

//----------------------------------------------------------------------------
bool cmFileCopier::Parse(std::vector<std::string> const& args)
{
  this->Doing = DoingFiles;
  for(unsigned int i=1; i < args.size(); ++i)
    {
    // Check this argument.
    if(!this->CheckKeyword(args[i]) &&
       !this->CheckValue(args[i]))
      {
      cmOStringStream e;
      e << "called with unknown argument \"" << args[i] << "\".";
      this->FileCommand->SetError(e.str().c_str());
      return false;
      }

    // Quit if an argument is invalid.
    if(this->Doing == DoingError)
      {
      return false;
      }
    }

  // Require a destination.
  if(this->Destination.empty())
    {
    cmOStringStream e;
    e << this->Name << " given no DESTINATION";
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }

  // If file permissions were not specified set default permissions.
  if(!this->UseGivenPermissionsFile && !this->UseSourcePermissions)
    {
    this->DefaultFilePermissions();
    }

  // If directory permissions were not specified set default permissions.
  if(!this->UseGivenPermissionsDir && !this->UseSourcePermissions)
    {
    this->DefaultDirectoryPermissions();
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmFileCopier::CheckKeyword(std::string const& arg)
{
  if(arg == "DESTINATION")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingDestination;
      }
    }
  else if(arg == "PATTERN")
    {
    this->Doing = DoingPattern;
    }
  else if(arg == "REGEX")
    {
    this->Doing = DoingRegex;
    }
  else if(arg == "EXCLUDE")
    {
    // Add this property to the current match rule.
    if(this->CurrentMatchRule)
      {
      this->CurrentMatchRule->Properties.Exclude = true;
      this->Doing = DoingNone;
      }
    else
      {
      this->NotBeforeMatch(arg);
      }
    }
  else if(arg == "PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->Doing = DoingPermissionsMatch;
      }
    else
      {
      this->NotBeforeMatch(arg);
      }
    }
  else if(arg == "FILE_PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingPermissionsFile;
      this->UseGivenPermissionsFile = true;
      }
    }
  else if(arg == "DIRECTORY_PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingPermissionsDir;
      this->UseGivenPermissionsDir = true;
      }
    }
  else if(arg == "USE_SOURCE_PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingNone;
      this->UseSourcePermissions = true;
      }
    }
  else if(arg == "NO_SOURCE_PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingNone;
      this->UseSourcePermissions = false;
      }
    }
  else if(arg == "FILES_MATCHING")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingNone;
      this->MatchlessFiles = false;
      }
    }
  else
    {
    return false;
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCopier::CheckValue(std::string const& arg)
{
  switch(this->Doing)
    {
    case DoingFiles:
      if(arg.empty() || cmSystemTools::FileIsFullPath(arg.c_str()))
        {
        this->Files.push_back(arg);
        }
      else
        {
        std::string file = this->Makefile->GetCurrentDirectory();
        file += "/" + arg;
        this->Files.push_back(file);
        }
      break;
    case DoingDestination:
      if(arg.empty() || cmSystemTools::FileIsFullPath(arg.c_str()))
        {
        this->Destination = arg;
        }
      else
        {
        this->Destination = this->Makefile->GetCurrentOutputDirectory();
        this->Destination += "/" + arg;
        }
      this->Doing = DoingNone;
      break;
    case DoingPattern:
      {
      // Convert the pattern to a regular expression.  Require a
      // leading slash and trailing end-of-string in the matched
      // string to make sure the pattern matches only whole file
      // names.
      std::string regex = "/";
      regex += cmsys::Glob::PatternToRegex(arg, false);
      regex += "$";
      this->MatchRules.push_back(MatchRule(regex));
      this->CurrentMatchRule = &*(this->MatchRules.end()-1);
      if(this->CurrentMatchRule->Regex.is_valid())
        {
        this->Doing = DoingNone;
        }
      else
        {
        cmOStringStream e;
        e << "could not compile PATTERN \"" << arg << "\".";
        this->FileCommand->SetError(e.str().c_str());
        this->Doing = DoingError;
        }
      }
      break;
    case DoingRegex:
      this->MatchRules.push_back(MatchRule(arg));
      this->CurrentMatchRule = &*(this->MatchRules.end()-1);
      if(this->CurrentMatchRule->Regex.is_valid())
        {
        this->Doing = DoingNone;
        }
      else
        {
        cmOStringStream e;
        e << "could not compile REGEX \"" << arg << "\".";
        this->FileCommand->SetError(e.str().c_str());
        this->Doing = DoingError;
        }
      break;
    case DoingPermissionsFile:
      if(!this->CheckPermissions(arg, this->FilePermissions))
        {
        this->Doing = DoingError;
        }
      break;
    case DoingPermissionsDir:
      if(!this->CheckPermissions(arg, this->DirPermissions))
        {
        this->Doing = DoingError;
        }
      break;
    case DoingPermissionsMatch:
      if(!this->CheckPermissions(
           arg, this->CurrentMatchRule->Properties.Permissions))
        {
        this->Doing = DoingError;
        }
      break;
    default:
      return false;
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCopier::Run(std::vector<std::string> const& args)
{
  if(!this->Parse(args))
    {
    return false;
    }

  std::vector<std::string> const& files = this->Files;
  for(std::vector<std::string>::size_type i = 0; i < files.size(); ++i)
    {
    // Split the input file into its directory and name components.
    std::vector<std::string> fromPathComponents;
    cmSystemTools::SplitPath(files[i].c_str(), fromPathComponents);
    std::string fromName = *(fromPathComponents.end()-1);
    std::string fromDir = cmSystemTools::JoinPath(fromPathComponents.begin(),
                                                  fromPathComponents.end()-1);

    // Compute the full path to the destination file.
    std::string toFile = this->Destination;
    std::string const& toName = this->ToName(fromName);
    if(!toName.empty())
      {
      toFile += "/";
      toFile += toName;
      }

    // Construct the full path to the source file.  The file name may
    // have been changed above.
    std::string fromFile = fromDir;
    if(!fromName.empty())
      {
      fromFile += "/";
      fromFile += fromName;
      }

    if(!this->Install(fromFile.c_str(), toFile.c_str()))
      {
      return false;
      }
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCopier::Install(const char* fromFile, const char* toFile)
{
  if(!*fromFile)
    {
    cmOStringStream e;
    e << "INSTALL encountered an empty string input file name.";
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }

  // Collect any properties matching this file name.
  MatchProperties match_properties = this->CollectMatchProperties(fromFile);

  // Skip the file if it is excluded.
  if(match_properties.Exclude)
    {
    return true;
    }

  if(cmSystemTools::SameFile(fromFile, toFile))
    {
    return true;
    }
  else if(cmSystemTools::FileIsSymlink(fromFile))
    {
    return this->InstallSymlink(fromFile, toFile);
    }
  else if(cmSystemTools::FileIsDirectory(fromFile))
    {
    return this->InstallDirectory(fromFile, toFile, match_properties);
    }
  else if(cmSystemTools::FileExists(fromFile))
    {
    return this->InstallFile(fromFile, toFile, match_properties);
    }
  return this->ReportMissing(fromFile);
}

//----------------------------------------------------------------------------
bool cmFileCopier::InstallSymlink(const char* fromFile, const char* toFile)
{
  // Read the original symlink.
  std::string symlinkTarget;
  if(!cmSystemTools::ReadSymlink(fromFile, symlinkTarget))
    {
    cmOStringStream e;
    e << this->Name << " cannot read symlink \"" << fromFile
      << "\" to duplicate at \"" << toFile << "\".";
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }

  // Compare the symlink value to that at the destination if not
  // always installing.
  bool copy = true;
  if(!this->Always)
    {
    std::string oldSymlinkTarget;
    if(cmSystemTools::ReadSymlink(toFile, oldSymlinkTarget))
      {
      if(symlinkTarget == oldSymlinkTarget)
        {
        copy = false;
        }
      }
    }

  // Inform the user about this file installation.
  this->ReportCopy(toFile, TypeLink, copy);

  if(copy)
    {
    // Remove the destination file so we can always create the symlink.
    cmSystemTools::RemoveFile(toFile);

    // Create the symlink.
    if(!cmSystemTools::CreateSymlink(symlinkTarget.c_str(), toFile))
      {
      cmOStringStream e;
      e << this->Name <<  " cannot duplicate symlink \"" << fromFile
        << "\" at \"" << toFile << "\".";
      this->FileCommand->SetError(e.str().c_str());
      return false;
      }
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmFileCopier::InstallFile(const char* fromFile, const char* toFile,
                               MatchProperties const& match_properties)
{
  // Determine whether we will copy the file.
  bool copy = true;
  if(!this->Always)
    {
    // If both files exist with the same time do not copy.
    if(!this->FileTimes.FileTimesDiffer(fromFile, toFile))
      {
      copy = false;
      }
    }

  // Inform the user about this file installation.
  this->ReportCopy(toFile, TypeFile, copy);

  // Copy the file.
  if(copy && !cmSystemTools::CopyAFile(fromFile, toFile, true, false))
    {
    cmOStringStream e;
    e << this->Name << " cannot copy file \"" << fromFile
      << "\" to \"" << toFile << "\".";
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }

  // Set the file modification time of the destination file.
  if(copy && !this->Always)
    {
    if (!cmSystemTools::CopyFileTime(fromFile, toFile))
      {
      cmOStringStream e;
      e << this->Name << " cannot set modification time on \""
        << toFile << "\"";
      this->FileCommand->SetError(e.str().c_str());
      return false;
      }
    }

  // Set permissions of the destination file.
  mode_t permissions = (match_properties.Permissions?
                        match_properties.Permissions : this->FilePermissions);
  if(!permissions)
    {
    // No permissions were explicitly provided but the user requested
    // that the source file permissions be used.
    cmSystemTools::GetPermissions(fromFile, permissions);
    }
  return this->SetPermissions(toFile, permissions);
}

//----------------------------------------------------------------------------
bool cmFileCopier::InstallDirectory(const char* source,
                                    const char* destination,
                                    MatchProperties const& match_properties)
{
  // Inform the user about this directory installation.
  this->ReportCopy(destination, TypeDir, true);

  // Make sure the destination directory exists.
  if(!cmSystemTools::MakeDirectory(destination))
    {
    cmOStringStream e;
    e << this->Name << " cannot make directory \"" << destination << "\": "
      << cmSystemTools::GetLastSystemError();
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }

  // Compute the requested permissions for the destination directory.
  mode_t permissions = (match_properties.Permissions?
                        match_properties.Permissions : this->DirPermissions);
  if(!permissions)
    {
    // No permissions were explicitly provided but the user requested
    // that the source directory permissions be used.
    cmSystemTools::GetPermissions(source, permissions);
    }

  // Compute the set of permissions required on this directory to
  // recursively install files and subdirectories safely.
  mode_t required_permissions =
    mode_owner_read | mode_owner_write | mode_owner_execute;

  // If the required permissions are specified it is safe to set the
  // final permissions now.  Otherwise we must add the required
  // permissions temporarily during file installation.
  mode_t permissions_before = 0;
  mode_t permissions_after = 0;
  if((permissions & required_permissions) == required_permissions)
    {
    permissions_before = permissions;
    }
  else
    {
    permissions_before = permissions | required_permissions;
    permissions_after = permissions;
    }

  // Set the required permissions of the destination directory.
  if(!this->SetPermissions(destination, permissions_before))
    {
    return false;
    }

  // Load the directory contents to traverse it recursively.
  cmsys::Directory dir;
  if(source && *source)
    {
    dir.Load(source);
    }
  unsigned long numFiles = static_cast<unsigned long>(dir.GetNumberOfFiles());
  for(unsigned long fileNum = 0; fileNum < numFiles; ++fileNum)
    {
    if(!(strcmp(dir.GetFile(fileNum), ".") == 0 ||
         strcmp(dir.GetFile(fileNum), "..") == 0))
      {
      cmsys_stl::string fromPath = source;
      fromPath += "/";
      fromPath += dir.GetFile(fileNum);
      std::string toPath = destination;
      toPath += "/";
      toPath += dir.GetFile(fileNum);
      if(!this->Install(fromPath.c_str(), toPath.c_str()))
        {
        return false;
        }
      }
    }

  // Set the requested permissions of the destination directory.
  return this->SetPermissions(destination, permissions_after);
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleCopyCommand(std::vector<std::string> const& args)
{
  cmFileCopier copier(this);
  return copier.Run(args);
}

//----------------------------------------------------------------------------
struct cmFileInstaller: public cmFileCopier
{
  cmFileInstaller(cmFileCommand* command):
    cmFileCopier(command, "INSTALL"),
    InstallType(cmTarget::INSTALL_FILES),
    Optional(false),
    DestDirLength(0)
    {
    // Installation does not use source permissions by default.
    this->UseSourcePermissions = false;
    // Check whether to copy files always or only if they have changed.
    this->Always =
      cmSystemTools::IsOn(cmSystemTools::GetEnv("CMAKE_INSTALL_ALWAYS"));
    // Get the current manifest.
    this->Manifest =
      this->Makefile->GetSafeDefinition("CMAKE_INSTALL_MANIFEST_FILES");
    }
  ~cmFileInstaller()
    {
    // Save the updated install manifest.
    this->Makefile->AddDefinition("CMAKE_INSTALL_MANIFEST_FILES",
                                  this->Manifest.c_str());
    }

protected:
  cmTarget::TargetType InstallType;
  bool Optional;
  int DestDirLength;
  std::string Rename;

  std::string Manifest;
  void ManifestAppend(std::string const& file)
    {
    this->Manifest += ";";
    this->Manifest += file.substr(this->DestDirLength);
    }

  virtual std::string const& ToName(std::string const& fromName)
    { return this->Rename.empty()? fromName : this->Rename; }

  virtual void ReportCopy(const char* toFile, Type type, bool copy)
    {
    std::string message = (copy? "Installing: " : "Up-to-date: ");
    message += toFile;
    this->Makefile->DisplayStatus(message.c_str(), -1);
    if(type != TypeDir)
      {
      // Add the file to the manifest.
      this->ManifestAppend(toFile);
      }
    }
  virtual bool ReportMissing(const char* fromFile)
    {
    return (this->Optional ||
            this->cmFileCopier::ReportMissing(fromFile));
    }
  virtual bool Install(const char* fromFile, const char* toFile)
    {
    // Support installing from empty source to make a directory.
    if(this->InstallType == cmTarget::INSTALL_DIRECTORY && !*fromFile)
      {
      return this->InstallDirectory(fromFile, toFile, MatchProperties());
      }
    return this->cmFileCopier::Install(fromFile, toFile);
    }

  virtual bool Parse(std::vector<std::string> const& args);
  enum
  {
    DoingType = DoingLast1,
    DoingRename,
    DoingSelf24
  };
  virtual bool CheckKeyword(std::string const& arg);
  virtual bool CheckValue(std::string const& arg);
  virtual void DefaultFilePermissions()
    {
    this->cmFileCopier::DefaultFilePermissions();
    // Add execute permissions based on the target type.
    switch(this->InstallType)
      {
      case cmTarget::SHARED_LIBRARY:
      case cmTarget::MODULE_LIBRARY:
        if(this->Makefile->IsOn("CMAKE_INSTALL_SO_NO_EXE"))
          {
          break;
          }
      case cmTarget::EXECUTABLE:
      case cmTarget::INSTALL_PROGRAMS:
        this->FilePermissions |= mode_owner_execute;
        this->FilePermissions |= mode_group_execute;
        this->FilePermissions |= mode_world_execute;
        break;
      default: break;
      }
    }
  bool GetTargetTypeFromString(const std::string& stype);
  bool HandleInstallDestination();
};

//----------------------------------------------------------------------------
bool cmFileInstaller::Parse(std::vector<std::string> const& args)
{
  if(!this->cmFileCopier::Parse(args))
    {
    return false;
    }

  if(!this->Rename.empty())
    {
    if(this->InstallType != cmTarget::INSTALL_FILES &&
       this->InstallType != cmTarget::INSTALL_PROGRAMS)
      {
      this->FileCommand->SetError("INSTALL option RENAME may be used "
                                  "only with FILES or PROGRAMS.");
      return false;
      }
    if(this->Files.size() > 1)
      {
      this->FileCommand->SetError("INSTALL option RENAME may be used "
                                  "only with one file.");
      return false;
      }
    }

  if(!this->HandleInstallDestination())
    {
    return false;
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmFileInstaller::CheckKeyword(std::string const& arg)
{
  if(arg == "TYPE")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingType;
      }
    }
  else if(arg == "FILES")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingFiles;
      }
    }
  else if(arg == "RENAME")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingRename;
      }
    }
  else if(arg == "OPTIONAL")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      this->Doing = DoingNone;
      this->Optional = true;
      }
    }
  else if(arg == "PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->Doing = DoingPermissionsMatch;
      }
    else
      {
      // file(INSTALL) aliases PERMISSIONS to FILE_PERMISSIONS
      this->Doing = DoingPermissionsFile;
      this->UseGivenPermissionsFile = true;
      }
    }
  else if(arg == "DIR_PERMISSIONS")
    {
    if(this->CurrentMatchRule)
      {
      this->NotAfterMatch(arg);
      }
    else
      {
      // file(INSTALL) aliases DIR_PERMISSIONS to DIRECTORY_PERMISSIONS
      this->Doing = DoingPermissionsDir;
      this->UseGivenPermissionsDir = true;
      }
    }
  else if(arg == "COMPONENTS" || arg == "CONFIGURATIONS" ||
          arg == "PROPERTIES")
    {
    if(this->Makefile->IsOn("CMAKE_INSTALL_SELF_2_4"))
      {
      // When CMake 2.4 builds this CMake version we need to support
      // the install scripts it generates since it asks this CMake
      // to install itself using the rules it generated.
      this->Doing = DoingSelf24;
      }
    else
      {
      cmOStringStream e;
      e << "INSTALL called with old-style " << arg << " argument.  "
        << "This script was generated with an older version of CMake.  "
        << "Re-run this cmake version on your build tree.";
      this->FileCommand->SetError(e.str().c_str());
      this->Doing = DoingError;
      }
    }
  else
    {
    return this->cmFileCopier::CheckKeyword(arg);
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileInstaller::CheckValue(std::string const& arg)
{
  switch(this->Doing)
    {
    case DoingType:
      if(!this->GetTargetTypeFromString(arg))
        {
        this->Doing = DoingError;
        }
      break;
    case DoingRename:
      this->Rename = arg;
      break;
    case DoingSelf24:
      // Ignore these arguments for compatibility.  This should be
      // reached only when CMake 2.4 is installing the current
      // CMake.  It can be removed when CMake 2.6 or higher is
      // required to build CMake.
      break;
    default:
      return this->cmFileCopier::CheckValue(arg);
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileInstaller
::GetTargetTypeFromString(const std::string& stype)
{
  if ( stype == "EXECUTABLE" )
    {
    this->InstallType = cmTarget::EXECUTABLE;
    }
  else if ( stype == "FILE" )
    {
    this->InstallType = cmTarget::INSTALL_FILES;
    }
  else if ( stype == "PROGRAM" )
    {
    this->InstallType = cmTarget::INSTALL_PROGRAMS;
    }
  else if ( stype == "STATIC_LIBRARY" )
    {
    this->InstallType = cmTarget::STATIC_LIBRARY;
    }
  else if ( stype == "SHARED_LIBRARY" )
    {
    this->InstallType = cmTarget::SHARED_LIBRARY;
    }
  else if ( stype == "MODULE" )
    {
    this->InstallType = cmTarget::MODULE_LIBRARY;
    }
  else if ( stype == "DIRECTORY" )
    {
    this->InstallType = cmTarget::INSTALL_DIRECTORY;
    }
  else
    {
    cmOStringStream e;
    e << "Option TYPE given uknown value \"" << stype << "\".";
    this->FileCommand->SetError(e.str().c_str());
    return false;
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileInstaller::HandleInstallDestination()
{
  std::string& destination = this->Destination;

  // allow for / to be a valid destination
  if ( destination.size() < 2 && destination != "/" )
    {
    this->FileCommand->SetError("called with inapropriate arguments. "
        "No DESTINATION provided or .");
    return false;
    }

  const char* destdir = cmSystemTools::GetEnv("DESTDIR");
  if ( destdir && *destdir )
    {
    std::string sdestdir = destdir;
    cmSystemTools::ConvertToUnixSlashes(sdestdir);
    char ch1 = destination[0];
    char ch2 = destination[1];
    char ch3 = 0;
    if ( destination.size() > 2 )
      {
      ch3 = destination[2];
      }
    int skip = 0;
    if ( ch1 != '/' )
      {
      int relative = 0;
      if (((ch1 >= 'a' && ch1 <= 'z') || (ch1 >= 'A' && ch1 <= 'Z')) &&
             ch2 == ':' )
        {
        // Assume windows
        // let's do some destdir magic:
        skip = 2;
        if ( ch3 != '/' )
          {
          relative = 1;
          }
        }
      else
        {
        relative = 1;
        }
      if ( relative )
        {
        // This is relative path on unix or windows. Since we are doing
        // destdir, this case does not make sense.
        this->FileCommand->SetError(
          "called with relative DESTINATION. This "
          "does not make sense when using DESTDIR. Specify "
          "absolute path or remove DESTDIR environment variable.");
        return false;
        }
      }
    else
      {
      if ( ch2 == '/' )
        {
        // looks like a network path.
        std::string message = "called with network path DESTINATION. This "
          "does not make sense when using DESTDIR. Specify local "
          "absolute path or remove DESTDIR environment variable."
          "\nDESTINATION=\n";
        message += destination;
        this->FileCommand->SetError(message.c_str());
        return false;
        }
      }
    destination = sdestdir + (destination.c_str() + skip);
    this->DestDirLength = int(sdestdir.size());
    }

  if ( !cmSystemTools::FileExists(destination.c_str()) )
    {
    if ( !cmSystemTools::MakeDirectory(destination.c_str()) )
      {
      std::string errstring = "cannot create directory: " + destination +
          ". Maybe need administrative privileges.";
      this->FileCommand->SetError(errstring.c_str());
      return false;
      }
    }
  if ( !cmSystemTools::FileIsDirectory(destination.c_str()) )
    {
    std::string errstring = "INSTALL destination: " + destination +
        " is not a directory.";
    this->FileCommand->SetError(errstring.c_str());
    return false;
    }
  return true;
}

//----------------------------------------------------------------------------
bool
cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args)
{
  // Evaluate arguments.
  const char* file = 0;
  const char* oldRPath = 0;
  const char* newRPath = 0;
  enum Doing { DoingNone, DoingFile, DoingOld, DoingNew };
  Doing doing = DoingNone;
  for(unsigned int i=1; i < args.size(); ++i)
    {
    if(args[i] == "OLD_RPATH")
      {
      doing = DoingOld;
      }
    else if(args[i] == "NEW_RPATH")
      {
      doing = DoingNew;
      }
    else if(args[i] == "FILE")
      {
      doing = DoingFile;
      }
    else if(doing == DoingFile)
      {
      file = args[i].c_str();
      doing = DoingNone;
      }
    else if(doing == DoingOld)
      {
      oldRPath = args[i].c_str();
      doing = DoingNone;
      }
    else if(doing == DoingNew)
      {
      newRPath = args[i].c_str();
      doing = DoingNone;
      }
    else
      {
      cmOStringStream e;
      e << "RPATH_CHANGE given unknown argument " << args[i];
      this->SetError(e.str().c_str());
      return false;
      }
    }
  if(!file)
    {
    this->SetError("RPATH_CHANGE not given FILE option.");
    return false;
    }
  if(!oldRPath)
    {
    this->SetError("RPATH_CHANGE not given OLD_RPATH option.");
    return false;
    }
  if(!newRPath)
    {
    this->SetError("RPATH_CHANGE not given NEW_RPATH option.");
    return false;
    }
  if(!cmSystemTools::FileExists(file, true))
    {
    cmOStringStream e;
    e << "RPATH_CHANGE given FILE \"" << file << "\" that does not exist.";
    this->SetError(e.str().c_str());
    return false;
    }
  bool success = true;
  cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
  bool have_ft = cmSystemTools::FileTimeGet(file, ft);
  std::string emsg;
  bool changed;
  if(!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg, &changed))
    {
    cmOStringStream e;
    e << "RPATH_CHANGE could not write new RPATH:\n"
      << "  " << newRPath << "\n"
      << "to the file:\n"
      << "  " << file << "\n"
      << emsg;
    this->SetError(e.str().c_str());
    success = false;
    }
  if(success)
    {
    if(changed)
      {
      std::string message = "Set runtime path of \"";
      message += file;
      message += "\" to \"";
      message += newRPath;
      message += "\"";
      this->Makefile->DisplayStatus(message.c_str(), -1);
      }
    if(have_ft)
      {
      cmSystemTools::FileTimeSet(file, ft);
      }
    }
  cmSystemTools::FileTimeDelete(ft);
  return success;
}

//----------------------------------------------------------------------------
bool
cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
{
  // Evaluate arguments.
  const char* file = 0;
  enum Doing { DoingNone, DoingFile };
  Doing doing = DoingNone;
  for(unsigned int i=1; i < args.size(); ++i)
    {
    if(args[i] == "FILE")
      {
      doing = DoingFile;
      }
    else if(doing == DoingFile)
      {
      file = args[i].c_str();
      doing = DoingNone;
      }
    else
      {
      cmOStringStream e;
      e << "RPATH_REMOVE given unknown argument " << args[i];
      this->SetError(e.str().c_str());
      return false;
      }
    }
  if(!file)
    {
    this->SetError("RPATH_REMOVE not given FILE option.");
    return false;
    }
  if(!cmSystemTools::FileExists(file, true))
    {
    cmOStringStream e;
    e << "RPATH_REMOVE given FILE \"" << file << "\" that does not exist.";
    this->SetError(e.str().c_str());
    return false;
    }
  bool success = true;
  cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
  bool have_ft = cmSystemTools::FileTimeGet(file, ft);
  std::string emsg;
  bool removed;
  if(!cmSystemTools::RemoveRPath(file, &emsg, &removed))
    {
    cmOStringStream e;
    e << "RPATH_REMOVE could not remove RPATH from file:\n"
      << "  " << file << "\n"
      << emsg;
    this->SetError(e.str().c_str());
    success = false;
    }
  if(success)
    {
    if(removed)
      {
      std::string message = "Removed runtime path from \"";
      message += file;
      message += "\"";
      this->Makefile->DisplayStatus(message.c_str(), -1);
      }
    if(have_ft)
      {
      cmSystemTools::FileTimeSet(file, ft);
      }
    }
  cmSystemTools::FileTimeDelete(ft);
  return success;
}

//----------------------------------------------------------------------------
bool
cmFileCommand::HandleRPathCheckCommand(std::vector<std::string> const& args)
{
  // Evaluate arguments.
  const char* file = 0;
  const char* rpath = 0;
  enum Doing { DoingNone, DoingFile, DoingRPath };
  Doing doing = DoingNone;
  for(unsigned int i=1; i < args.size(); ++i)
    {
    if(args[i] == "RPATH")
      {
      doing = DoingRPath;
      }
    else if(args[i] == "FILE")
      {
      doing = DoingFile;
      }
    else if(doing == DoingFile)
      {
      file = args[i].c_str();
      doing = DoingNone;
      }
    else if(doing == DoingRPath)
      {
      rpath = args[i].c_str();
      doing = DoingNone;
      }
    else
      {
      cmOStringStream e;
      e << "RPATH_CHECK given unknown argument " << args[i];
      this->SetError(e.str().c_str());
      return false;
      }
    }
  if(!file)
    {
    this->SetError("RPATH_CHECK not given FILE option.");
    return false;
    }
  if(!rpath)
    {
    this->SetError("RPATH_CHECK not given RPATH option.");
    return false;
    }

  // If the file exists but does not have the desired RPath then
  // delete it.  This is used during installation to re-install a file
  // if its RPath will change.
  if(cmSystemTools::FileExists(file, true) &&
     !cmSystemTools::CheckRPath(file, rpath))
    {
    cmSystemTools::RemoveFile(file);
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleInstallCommand(std::vector<std::string> const& args)
{
  cmFileInstaller installer(this);
  return installer.Run(args);
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleRelativePathCommand(
  std::vector<std::string> const& args)
{
  if(args.size() != 4 )
    {
    this->SetError("RELATIVE_PATH called with incorrect number of arguments");
    return false;
    }

  const std::string& outVar = args[1];
  const std::string& directoryName = args[2];
  const std::string& fileName = args[3];

  if(!cmSystemTools::FileIsFullPath(directoryName.c_str()))
    {
    std::string errstring =
      "RELATIVE_PATH must be passed a full path to the directory: "
      + directoryName;
    this->SetError(errstring.c_str());
    return false;
    }
  if(!cmSystemTools::FileIsFullPath(fileName.c_str()))
    {
    std::string errstring =
      "RELATIVE_PATH must be passed a full path to the file: "
      + fileName;
    this->SetError(errstring.c_str());
    return false;
    }

  std::string res = cmSystemTools::RelativePath(directoryName.c_str(),
                                                fileName.c_str());
  this->Makefile->AddDefinition(outVar.c_str(),
    res.c_str());
  return true;
}


//----------------------------------------------------------------------------
bool cmFileCommand::HandleRename(std::vector<std::string> const& args)
{
  if(args.size() != 3)
    {
    this->SetError("RENAME given incorrect number of arguments.");
    return false;
    }

  // Compute full path for old and new names.
  std::string oldname = args[1];
  if(!cmsys::SystemTools::FileIsFullPath(oldname.c_str()))
    {
    oldname = this->Makefile->GetCurrentDirectory();
    oldname += "/" + args[1];
    }
  std::string newname = args[2];
  if(!cmsys::SystemTools::FileIsFullPath(newname.c_str()))
    {
    newname = this->Makefile->GetCurrentDirectory();
    newname += "/" + args[2];
    }

  if(!cmSystemTools::RenameFile(oldname.c_str(), newname.c_str()))
    {
    std::string err = cmSystemTools::GetLastSystemError();
    cmOStringStream e;
    e << "RENAME failed to rename\n"
      << "  " << oldname << "\n"
      << "to\n"
      << "  " << newname << "\n"
      << "because: " << err << "\n";
    this->SetError(e.str().c_str());
    return false;
    }
  return true;
}


//----------------------------------------------------------------------------
bool cmFileCommand::HandleRemove(std::vector<std::string> const& args,
                                 bool recurse)
{

  std::string message;
  std::vector<std::string>::const_iterator i = args.begin();

  i++; // Get rid of subcommand
  for(;i != args.end(); ++i)
    {
    std::string fileName = *i;
    if(!cmsys::SystemTools::FileIsFullPath(fileName.c_str()))
      {
      fileName = this->Makefile->GetCurrentDirectory();
      fileName += "/" + *i;
      }

    if(cmSystemTools::FileIsDirectory(fileName.c_str()) && recurse)
      {
      cmSystemTools::RemoveADirectory(fileName.c_str());
      }
    else
      {
      cmSystemTools::RemoveFile(fileName.c_str());
      }
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmFileCommand::HandleCMakePathCommand(std::vector<std::string>
                                           const& args,
                                           bool nativePath)
{
  std::vector<std::string>::const_iterator i = args.begin();
  if(args.size() != 3)
    {
    this->SetError("FILE([TO_CMAKE_PATH|TO_NATIVE_PATH] path result) must be "
      "called with exactly three arguments.");
    return false;
    }
  i++; // Get rid of subcommand
#if defined(_WIN32) && !defined(__CYGWIN__)
  char pathSep = ';';
#else
  char pathSep = ':';
#endif
  std::vector<cmsys::String> path = cmSystemTools::SplitString(i->c_str(),
                                                             pathSep);
  i++;
  const char* var =  i->c_str();
  std::string value;
  for(std::vector<cmsys::String>::iterator j = path.begin();
      j != path.end(); ++j)
    {
    if(j != path.begin())
      {
      value += ";";
      }
    if(!nativePath)
      {
      cmSystemTools::ConvertToUnixSlashes(*j);
      }
    else
      {
      *j = cmSystemTools::ConvertToOutputPath(j->c_str());
      // remove double quotes in the path
      cmsys::String& s = *j;

      if(s.size() > 1 && s[0] == '\"' && s[s.size()-1] == '\"')
        {
        s = s.substr(1,s.size()-2);
        }
      }
    value += *j;
    }
  this->Makefile->AddDefinition(var, value.c_str());
  return true;
}
#if defined(CMAKE_BUILD_WITH_CMAKE)

// Stuff for curl download
typedef std::vector<char> cmFileCommandVectorOfChar;
namespace{
  size_t
  cmFileCommandWriteMemoryCallback(void *ptr, size_t size, size_t nmemb,
                                          void *data)
  { 
    register int realsize = (int)(size * nmemb);
    std::ofstream* fout = static_cast<std::ofstream*>(data);
    const char* chPtr = static_cast<char*>(ptr);
    fout->write(chPtr, realsize);
    return realsize;
  }
  
  static size_t
  cmFileCommandCurlDebugCallback(CURL *, curl_infotype, char *chPtr,
                                        size_t size, void *data)
  {
    cmFileCommandVectorOfChar *vec
      = static_cast<cmFileCommandVectorOfChar*>(data);
    vec->insert(vec->end(), chPtr, chPtr + size);

    return size;
  }


}

#endif

#if defined(CMAKE_BUILD_WITH_CMAKE)
namespace {

  class cURLEasyGuard
  {
  public:
    cURLEasyGuard(CURL * easy)
      : Easy(easy)
      {}
    
    ~cURLEasyGuard(void) 
      {
        if (this->Easy)
          {
          ::curl_easy_cleanup(this->Easy);
          }
      }
    
    inline void release(void) 
      {
        this->Easy = 0;
        return;
      }
    
  private:
    ::CURL * Easy;
  };
  
}
#endif

bool
cmFileCommand::HandleDownloadCommand(std::vector<std::string>
                                     const& args)
{
#if defined(CMAKE_BUILD_WITH_CMAKE)
  std::vector<std::string>::const_iterator i = args.begin();
  if(args.size() < 3)
    {
    this->SetError("FILE(DOWNLOAD url file) must be called with "
                   "at least three arguments.");
    return false;
    }
  ++i; // Get rid of subcommand
  std::string url = *i;
  ++i;
  std::string file = *i;
  ++i;
  long timeout = 0;
  std::string verboseLog;
  std::string statusVar;
  while(i != args.end())
    {
    if(*i == "TIMEOUT")
      {
      ++i;
      if(i != args.end())
        {
        timeout = atol(i->c_str());
        }
      else
        {
        this->SetError("FILE(DOWNLOAD url file TIMEOUT time) missing "
                       "time for TIMEOUT.");
        return false;
        }
      }
    else if(*i == "LOG")
      {
      ++i;
      if( i == args.end())
        {
        this->SetError("FILE(DOWNLOAD url file LOG VAR) missing "
                       "VAR for LOG.");
        return false;
        }
      verboseLog = *i;
      }
    else if(*i == "STATUS")
      {
      ++i;
      if( i == args.end())
        {
        this->SetError("FILE(DOWNLOAD url file STATUS VAR) missing "
                       "VAR for STATUS.");
        return false;
        }
      statusVar = *i;
      }
    ++i;
    }

  std::string dir = cmSystemTools::GetFilenamePath(file.c_str());
  if(!cmSystemTools::FileExists(dir.c_str()) &&
     !cmSystemTools::MakeDirectory(dir.c_str()))
    {
    std::string errstring = "DOWNLOAD error: cannot create directory '"
      + dir + "' - Specify file by full path name and verify that you "
      "have directory creation and file write privileges.";
    this->SetError(errstring.c_str());
    return false;
    }

  std::ofstream fout(file.c_str(), std::ios::binary);
  if(!fout)
    {
    this->SetError("FILE(DOWNLOAD url file TIMEOUT time) can not open "
                       "file for write.");
    return false;
    }
  ::CURL *curl;
  ::curl_global_init(CURL_GLOBAL_DEFAULT);
  curl = ::curl_easy_init();
  if(!curl)
    {
    this->SetError("FILE(DOWNLOAD ) error "
                   "initializing curl.");
    return false;
    }

  cURLEasyGuard g_curl(curl);

  ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
  if (res != CURLE_OK)
    {
      std::string errstring = "FILE(DOWNLOAD ) error; cannot set url: ";
      errstring += ::curl_easy_strerror(res);
    return false;
    }

  res = ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
                             cmFileCommandWriteMemoryCallback);
  if (res != CURLE_OK)
      {
      std::string errstring =
        "FILE(DOWNLOAD ) error; cannot set write function: ";
      errstring += ::curl_easy_strerror(res);
    return false;
    }

  res = ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
                             cmFileCommandCurlDebugCallback);
  if (res != CURLE_OK)
    {
     std::string errstring =
       "FILE(DOWNLOAD ) error; cannot set debug function: ";
     errstring += ::curl_easy_strerror(res);
    return false;
    }

  cmFileCommandVectorOfChar chunkDebug;

  res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&fout);

  if (res != CURLE_OK)
    {
    std::string errstring = "FILE(DOWNLOAD ) error; cannot set write data: ";
    errstring += ::curl_easy_strerror(res);
    return false;
    }

  res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug);
  if (res != CURLE_OK)
    {
    std::string errstring = "FILE(DOWNLOAD ) error; cannot set write data: ";
    errstring += ::curl_easy_strerror(res);
    return false;
    }

  if(verboseLog.size())
    {
    res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);

    if (res != CURLE_OK)
      {
      std::string errstring = "FILE(DOWNLOAD ) error; cannot set verbose: ";
      errstring += ::curl_easy_strerror(res);
      return false;
      }
    }
  if(timeout > 0)
    {
    res = ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout );

    if (res != CURLE_OK)
      {
      std::string errstring = "FILE(DOWNLOAD ) error; cannot set verbose: ";
      errstring += ::curl_easy_strerror(res);
      return false;
      }
    }
  res = ::curl_easy_perform(curl);
  /* always cleanup */
  g_curl.release();
  ::curl_easy_cleanup(curl);
  if(statusVar.size())
    {
    cmOStringStream result;
    result << (int)res << ";\"" << ::curl_easy_strerror(res) << "\"";
    this->Makefile->AddDefinition(statusVar.c_str(),
                                  result.str().c_str());
    }
  ::curl_global_cleanup();
  if(chunkDebug.size())
    {
    chunkDebug.push_back(0);
    if(CURLE_OPERATION_TIMEOUTED == res)
      {
      std::string output = &*chunkDebug.begin();

      if(verboseLog.size())
        {
        this->Makefile->AddDefinition(verboseLog.c_str(),
                                      &*chunkDebug.begin());
        }
      }

    this->Makefile->AddDefinition(verboseLog.c_str(),
                                  &*chunkDebug.begin());
    }
  return true;
#else
  this->SetError("FILE(DOWNLOAD ) "
                 "not supported in bootstrap cmake ");
  return false;
#endif
}
