/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#include "cmFileCommand.h"

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iterator>
#include <map>
#include <set>
#include <sstream>
#include <utility>
#include <vector>

#include <cm/memory>
#include <cm/optional>
#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/string_view>

#include <cm3p/kwiml/int.h>

#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
#include "cmsys/String.h"

#include "cm_sys_stat.h"

#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
#include "cmCMakePath.h"
#include "cmCryptoHash.h"
#include "cmDiagnostics.h"
#include "cmELF.h"
#include "cmExecutionStatus.h"
#include "cmFSPermissions.h"
#include "cmFileCommand_ReadMacho.h"
#include "cmFileCopier.h"
#include "cmFileInstaller.h"
#include "cmFileLockPool.h"
#include "cmFileTimes.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGlobCacheEntry.h"
#include "cmGlobalGenerator.h"
#include "cmHexFileConverter.h"
#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmNewLineStyle.h"
#include "cmPolicies.h"
#include "cmRange.h"
#include "cmRuntimeDependencyArchive.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cmValue.h"
#include "cmWorkingDirectory.h"
#include "cmake.h"

#if !defined(CMAKE_BOOTSTRAP)
#  include <cm3p/curl/curl.h>

#  include "cmCurl.h"
#  include "cmFileLockResult.h"
#endif

namespace {

bool HandleWriteImpl(std::vector<std::string> const& args, bool append,
                     cmExecutionStatus& status)
{
  if (args.size() < 2) {
    status.SetError(cmStrCat(
      args[0], " must be called with at least one additional argument."));
    return false;
  }
  auto i = args.begin();

  i++; // Get rid of subcommand

  std::string fileName = *i;
  if (!cmsys::SystemTools::FileIsFullPath(*i)) {
    fileName =
      cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', *i);
  }

  i++;

  if (!status.GetMakefile().CanIWriteThisFile(fileName)) {
    std::string e = cmStrCat("attempted to write a file: ", fileName,
                             " into a source directory.");
    status.SetError(e);
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }
  std::string dir = cmSystemTools::GetFilenamePath(fileName);
  cmSystemTools::MakeDirectory(dir);

  mode_t mode = 0;
  bool writable = false;

  // Set permissions to writable
  if (cmSystemTools::GetPermissions(fileName, mode)) {
#if defined(_MSC_VER) || defined(__MINGW32__)
    writable = (mode & S_IWRITE) != 0;
    mode_t newMode = mode | S_IWRITE;
#else
    writable = mode & S_IWUSR;
    mode_t newMode = mode | S_IWUSR | S_IWGRP;
#endif
    if (!writable) {
      cmSystemTools::SetPermissions(fileName, newMode);
    }
  }
  // If GetPermissions fails, pretend like it is ok. File open will fail if
  // the file is not writable
  cmsys::ofstream file(fileName.c_str(),
                       append ? std::ios::app : std::ios::out);
  if (!file) {
    std::string error =
      cmStrCat("failed to open for writing (",
               cmSystemTools::GetLastSystemError(), "):\n  ", fileName);
    status.SetError(error);
    return false;
  }
  std::string message = cmJoin(cmMakeRange(i, args.end()), std::string());
  file << message;
  if (!file) {
    std::string error =
      cmStrCat("write failed (", cmSystemTools::GetLastSystemError(), "):\n  ",
               fileName);
    status.SetError(error);
    return false;
  }
  file.close();
  if (mode && !writable) {
    cmSystemTools::SetPermissions(fileName, mode);
  }
  return true;
}

bool HandleWriteCommand(std::vector<std::string> const& args,
                        cmExecutionStatus& status)
{
  return HandleWriteImpl(args, false, status);
}

bool HandleAppendCommand(std::vector<std::string> const& args,
                         cmExecutionStatus& status)
{
  return HandleWriteImpl(args, true, status);
}

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

  std::string const& fileNameArg = args[1];
  std::string const& variable = args[2];

  struct Arguments
  {
    std::string Offset;
    std::string Limit;
    bool Hex = false;
  };

  static auto const parser = cmArgumentParser<Arguments>{}
                               .Bind("OFFSET"_s, &Arguments::Offset)
                               .Bind("LIMIT"_s, &Arguments::Limit)
                               .Bind("HEX"_s, &Arguments::Hex);

  Arguments const arguments = parser.Parse(cmMakeRange(args).advance(3),
                                           /*unparsedArguments=*/nullptr);

  std::string fileName = fileNameArg;
  if (!cmsys::SystemTools::FileIsFullPath(fileName)) {
    fileName = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/',
                        fileNameArg);
  }

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

  if (!file) {
    std::string error =
      cmStrCat("failed to open for reading (",
               cmSystemTools::GetLastSystemError(), "):\n  ", fileName);
    status.SetError(error);
    return false;
  }

  // is there a limit?
  std::string::size_type sizeLimit = std::string::npos;
  if (!arguments.Limit.empty()) {
    unsigned long long limit;
    if (cmStrToULongLong(arguments.Limit, &limit)) {
      sizeLimit = static_cast<std::string::size_type>(limit);
    }
  }

  // is there an offset?
  cmsys::ifstream::off_type offset = 0;
  if (!arguments.Offset.empty()) {
    long long off;
    if (cmStrToLongLong(arguments.Offset, &off)) {
      offset = static_cast<cmsys::ifstream::off_type>(off);
    }
  }

  file.seekg(offset, std::ios::beg); // explicit ios::beg for IBM VisualAge 6

  std::string output;

  if (arguments.Hex) {
    // Convert part of the file into hex code
    char c;
    while ((sizeLimit > 0) && (file.get(c))) {
      char hex[4];
      snprintf(hex, sizeof(hex), "%.2x", c & 0xFFu);
      output += hex;
      sizeLimit--;
    }
  } else {
    std::string line;
    bool has_newline = false;
    while (
      sizeLimit > 0 &&
      cmSystemTools::GetLineFromStream(file, line, &has_newline, sizeLimit)) {
      sizeLimit = sizeLimit - line.size();
      if (has_newline && sizeLimit > 0) {
        sizeLimit--;
      }
      output += line;
      if (has_newline) {
        output += "\n";
      }
    }
  }
  status.GetMakefile().AddDefinition(variable, output);
  return true;
}

bool HandleHashCommand(std::vector<std::string> const& args,
                       cmExecutionStatus& status)
{
#if !defined(CMAKE_BOOTSTRAP)
  if (args.size() != 3) {
    status.SetError(
      cmStrCat(args[0], " requires a file name and output variable"));
    return false;
  }

  std::unique_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0]));
  if (hash) {
    std::string out = hash->HashFile(args[1]);
    if (!out.empty()) {
      status.GetMakefile().AddDefinition(args[2], out);
      return true;
    }
    status.SetError(cmStrCat(args[0], " failed to read file \"", args[1],
                             "\": ", cmSystemTools::GetLastSystemError()));
  }
  return false;
#else
  status.SetError(cmStrCat(args[0], " not available during bootstrap"));
  return false;
#endif
}

bool HandleStringsCommand(std::vector<std::string> const& args,
                          cmExecutionStatus& status)
{
  if (args.size() < 3) {
    status.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)) {
    fileName =
      cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[1]);
  }

  // Get the variable in which to store the results.
  std::string const& 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,
    arg_encoding
  };
  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 store_regex = true;
  bool newline_consume = false;
  bool hex_conversion_enabled = true;
  enum
  {
    encoding_none = cmsys::FStream::BOM_None,
    encoding_utf8 = cmsys::FStream::BOM_UTF8,
    encoding_utf16le = cmsys::FStream::BOM_UTF16LE,
    encoding_utf16be = cmsys::FStream::BOM_UTF16BE,
    encoding_utf32le = cmsys::FStream::BOM_UTF32LE,
    encoding_utf32be = cmsys::FStream::BOM_UTF32BE
  };
  int encoding = encoding_none;
  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 (args[i] == "ENCODING") {
      arg_mode = arg_encoding;
    } else if (arg_mode == arg_limit_input) {
      if (sscanf(args[i].c_str(), "%d", &limit_input) != 1 ||
          limit_input < 0) {
        status.SetError(cmStrCat("STRINGS option LIMIT_INPUT value \"",
                                 args[i], "\" is not an unsigned integer."));
        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) {
        status.SetError(cmStrCat("STRINGS option LIMIT_OUTPUT value \"",
                                 args[i], "\" is not an unsigned integer."));
        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) {
        status.SetError(cmStrCat("STRINGS option LIMIT_COUNT value \"",
                                 args[i], "\" is not an unsigned integer."));
        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) {
        status.SetError(cmStrCat("STRINGS option LENGTH_MINIMUM value \"",
                                 args[i], "\" is not an unsigned integer."));
        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) {
        status.SetError(cmStrCat("STRINGS option LENGTH_MAXIMUM value \"",
                                 args[i], "\" is not an unsigned integer."));
        return false;
      }
      maxlen = len;
      arg_mode = arg_none;
    } else if (arg_mode == arg_regex) {
      if (!regex.compile(args[i])) {
        status.SetError(cmStrCat("STRINGS option REGEX value \"", args[i],
                                 "\" could not be compiled."));
        return false;
      }
      have_regex = true;
      switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0159)) {
        case cmPolicies::NEW:
          // store_regex = true
          break;
        case cmPolicies::WARN:
          if (status.GetMakefile().PolicyOptionalWarningEnabled(
                "CMAKE_POLICY_WARNING_CMP0159")) {
            status.GetMakefile().IssueDiagnostic(
              cmDiagnostics::CMD_AUTHOR,
              cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0159),
                       "\n"
                       "For compatibility, CMake is leaving CMAKE_MATCH_<n> "
                       "unchanged."));
          }
          CM_FALLTHROUGH;
        case cmPolicies::OLD:
          store_regex = false;
          break;
      }
      arg_mode = arg_none;
    } else if (arg_mode == arg_encoding) {
      if (args[i] == "UTF-8") {
        encoding = encoding_utf8;
      } else if (args[i] == "UTF-16LE") {
        encoding = encoding_utf16le;
      } else if (args[i] == "UTF-16BE") {
        encoding = encoding_utf16be;
      } else if (args[i] == "UTF-32LE") {
        encoding = encoding_utf32le;
      } else if (args[i] == "UTF-32BE") {
        encoding = encoding_utf32be;
      } else {
        status.SetError(cmStrCat("STRINGS option ENCODING \"", args[i],
                                 "\" not recognized."));
        return false;
      }
      arg_mode = arg_none;
    } else {
      status.SetError(
        cmStrCat("STRINGS given unknown argument \"", args[i], '"'));
      return false;
    }
  }

  if (hex_conversion_enabled) {
    // TODO: should work without temp file, but just on a memory buffer
    std::string binaryFileName =
      cmStrCat(status.GetMakefile().GetCurrentBinaryDirectory(),
               "/CMakeFiles/FileCommandStringsBinaryFile");
    if (cmHexFileConverter::TryConvert(fileName, binaryFileName)) {
      fileName = binaryFileName;
    }
  }

// Open the specified file.
#if defined(_WIN32) || defined(__CYGWIN__)
  cmsys::ifstream fin(fileName.c_str(), std::ios::in | std::ios::binary);
#else
  cmsys::ifstream fin(fileName.c_str());
#endif
  if (!fin) {
    status.SetError(
      cmStrCat("STRINGS file \"", fileName, "\" cannot be read."));
    return false;
  }

  // If BOM is found and encoding was not specified, use the BOM
  int bom_found = cmsys::FStream::ReadBOM(fin);
  if (encoding == encoding_none && bom_found != cmsys::FStream::BOM_None) {
    encoding = bom_found;
  }

  unsigned int bytes_rem = 0;
  if (encoding == encoding_utf16le || encoding == encoding_utf16be) {
    bytes_rem = 1;
  }
  if (encoding == encoding_utf32le || encoding == encoding_utf32be) {
    bytes_rem = 3;
  }

  // Parse strings out of the file.
  int output_size = 0;
  std::vector<std::string> strings;
  std::string s;
  while ((!limit_count || strings.size() < limit_count) &&
         (limit_input < 0 || static_cast<int>(fin.tellg()) < limit_input) &&
         fin) {
    std::string current_str;

    int c = fin.get();
    for (unsigned int i = 0; i < bytes_rem; ++i) {
      int c1 = fin.get();
      if (!fin) {
        fin.putback(static_cast<char>(c1));
        break;
      }
      c = (c << 8) | c1;
    }
    if (encoding == encoding_utf16le) {
      c = ((c & 0xFF) << 8) | ((c & 0xFF00) >> 8);
    } else if (encoding == encoding_utf32le) {
      c = (((c & 0xFF) << 24) | ((c & 0xFF00) << 8) | ((c & 0xFF0000) >> 8) |
           ((c & 0xFF000000) >> 24));
    }

    if (c == '\r') {
      // Ignore CR character to make output always have UNIX newlines.
      continue;
    }

    if (c >= 0 && c <= 0xFF &&
        (cmsysString_isprint(static_cast<char>(c)) || c == '\t' ||
         (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...
      current_str += static_cast<char>(c);
    } else if (encoding == encoding_utf8) {
      // Check for UTF-8 encoded string (up to 4 octets)
      static unsigned char const utf8_check_table[3][2] = {
        { 0xE0, 0xC0 },
        { 0xF0, 0xE0 },
        { 0xF8, 0xF0 },
      };

      // how many octets are there?
      unsigned int num_utf8_bytes = 0;
      for (unsigned int j = 0; num_utf8_bytes == 0 && j < 3; j++) {
        if ((c & utf8_check_table[j][0]) == utf8_check_table[j][1]) {
          num_utf8_bytes = j + 2;
        }
      }

      // get subsequent octets and check that they are valid
      for (unsigned int j = 0; j < num_utf8_bytes; j++) {
        if (j != 0) {
          c = fin.get();
          if (!fin || (c & 0xC0) != 0x80) {
            fin.putback(static_cast<char>(c));
            break;
          }
        }
        current_str += static_cast<char>(c);
      }

      // if this was an invalid utf8 sequence, discard the data, and put
      // back subsequent characters
      if ((current_str.length() != num_utf8_bytes)) {
        for (unsigned int j = 0; j < current_str.size() - 1; j++) {
          fin.putback(current_str[current_str.size() - 1 - j]);
        }
        current_str.clear();
      }
    }

    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))) {
        if (store_regex) {
          status.GetMakefile().ClearMatches();
          status.GetMakefile().StoreMatches(regex);
        }
        output_size += static_cast<int>(s.size()) + 1;
        if (limit_output >= 0 && output_size >= limit_output) {
          s.clear();
          break;
        }
        strings.push_back(s);
      }

      // Reset the string to empty.
      s.clear();
    } else if (current_str.empty()) {
      // A non-string character has been found.  Check if the current
      // string matches the requirements.  We require that the length
      // be at least one no matter what the user specified.
      if (s.length() >= minlen && !s.empty() &&
          (!have_regex || regex.find(s))) {
        if (store_regex) {
          status.GetMakefile().ClearMatches();
          status.GetMakefile().StoreMatches(regex);
        }
        output_size += static_cast<int>(s.size()) + 1;
        if (limit_output >= 0 && output_size >= limit_output) {
          s.clear();
          break;
        }
        strings.push_back(s);
      }

      // Reset the string to empty.
      s.clear();
    } else {
      s += current_str;
    }

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

  // 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))) {
    if (store_regex) {
      status.GetMakefile().ClearMatches();
      status.GetMakefile().StoreMatches(regex);
    }
    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.
  char const* sep = "";
  std::string output;
  for (std::string const& sr : strings) {
    // 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.
    for (char i : sr) {
      if (i == ';') {
        output += '\\';
      }
      output += i;
    }
  }

  // Save the output in a makefile variable.
  status.GetMakefile().AddDefinition(outVar, output);
  return true;
}

bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse,
                    cmExecutionStatus& status)
{
  if (args.size() < 2) {
    status.SetError(cmStrCat(
      args[0], " must be called with at least one additional argument."));
    return false;
  }

  auto i = args.begin();

  i++; // Get rid of subcommand

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

  cmake* cm = status.GetMakefile().GetCMakeInstance();
  std::vector<std::string> files;
  bool configureDepends = false;
  bool warnConfigureLate = false;
  while (i != args.end()) {
    if (*i == "LIST_DIRECTORIES") {
      ++i; // skip LIST_DIRECTORIES
      if (i != args.end()) {
        if (cmIsOn(*i)) {
          g.SetListDirs(true);
          g.SetRecurseListDirs(true);
        } else if (cmIsOff(*i)) {
          g.SetListDirs(false);
          g.SetRecurseListDirs(false);
        } else {
          status.SetError("LIST_DIRECTORIES missing bool value.");
          return false;
        }
        ++i;
      } else {
        status.SetError("LIST_DIRECTORIES missing bool value.");
        return false;
      }
    } else if (*i == "FOLLOW_SYMLINKS") {
      ++i; // skip FOLLOW_SYMLINKS
      if (recurse) {
        g.RecurseThroughSymlinksOn();
        if (i == args.end()) {
          status.SetError(
            "GLOB_RECURSE requires a glob expression after FOLLOW_SYMLINKS.");
          return false;
        }
      }
    } else if (*i == "RELATIVE") {
      ++i; // skip RELATIVE
      if (i == args.end()) {
        status.SetError("GLOB requires a directory after the RELATIVE tag.");
        return false;
      }
      g.SetRelative(i->c_str());
      ++i;
      if (i == args.end()) {
        status.SetError(
          "GLOB requires a glob expression after the directory.");
        return false;
      }
    } else if (*i == "CONFIGURE_DEPENDS") {
      // Generated build system depends on glob results
      if (!configureDepends && warnConfigureLate) {
        status.GetMakefile().IssueDiagnostic(
          cmDiagnostics::CMD_AUTHOR,
          "CONFIGURE_DEPENDS flag was given after a glob expression was "
          "already evaluated.");
      }
      if (cm->GetState()->GetRole() != cmState::Role::Project) {
        status.GetMakefile().IssueMessage(
          MessageType::FATAL_ERROR,
          "CONFIGURE_DEPENDS is invalid for script and find package modes.");
        return false;
      }
      configureDepends = true;
      ++i;
      if (i == args.end()) {
        status.SetError(
          "GLOB requires a glob expression after CONFIGURE_DEPENDS.");
        return false;
      }
    } else {
      std::string expr = *i;
      if (!cmsys::SystemTools::FileIsFullPath(*i)) {
        expr = status.GetMakefile().GetCurrentSourceDirectory();
        // Handle script mode
        if (!expr.empty()) {
          expr += "/" + *i;
        } else {
          expr = *i;
        }
      }

      cmsys::Glob::GlobMessages globMessages;
      g.FindFiles(expr, &globMessages);

      if (!globMessages.empty()) {
        bool shouldExit = false;
        for (cmsys::Glob::Message const& globMessage : globMessages) {
          if (globMessage.type == cmsys::Glob::cyclicRecursion) {
            status.GetMakefile().IssueDiagnostic(
              cmDiagnostics::CMD_AUTHOR,
              cmStrCat("Cyclic recursion detected while globbing for '", *i,
                       "':\n", globMessage.content));
          } else if (globMessage.type == cmsys::Glob::error) {
            status.GetMakefile().IssueMessage(
              MessageType::FATAL_ERROR,
              cmStrCat("Error has occurred while globbing for '", *i, "' - ",
                       globMessage.content));
            shouldExit = true;
          } else if (cm->GetDebugOutput() || cm->GetTrace()) {
            status.GetMakefile().IssueMessage(
              MessageType::LOG,
              cmStrCat("Globbing for\n  ", *i, "\nEncountered an error:\n ",
                       globMessage.content));
          }
        }
        if (shouldExit) {
          return false;
        }
      }

      std::vector<std::string>& foundFiles = g.GetFiles();
      cm::append(files, foundFiles);

      if (configureDepends) {
        std::sort(foundFiles.begin(), foundFiles.end());
        foundFiles.erase(std::unique(foundFiles.begin(), foundFiles.end()),
                         foundFiles.end());
        auto entry = cmGlobCacheEntry{
          recurse,
          (recurse ? g.GetRecurseListDirs() : g.GetListDirs()),
          (recurse ? g.GetRecurseThroughSymlinks() : false),
          (g.GetRelative() ? g.GetRelative() : ""),
          expr,
          foundFiles
        };
        cm->AddGlobCacheEntry(entry, variable,
                              status.GetMakefile().GetBacktrace());
      } else {
        warnConfigureLate = true;
      }
      ++i;
    }
  }

  std::sort(files.begin(), files.end());
  files.erase(std::unique(files.begin(), files.end()), files.end());
  status.GetMakefile().AddDefinition(variable, cmList::to_string(files));
  return true;
}

bool HandleGlobCommand(std::vector<std::string> const& args,
                       cmExecutionStatus& status)
{
  return HandleGlobImpl(args, false, status);
}

bool HandleGlobRecurseCommand(std::vector<std::string> const& args,
                              cmExecutionStatus& status)
{
  return HandleGlobImpl(args, true, status);
}

bool HandleMakeDirectoryCommand(std::vector<std::string> const& args,
                                cmExecutionStatus& status)
{
  // Projects might pass a dynamically generated list of directories, and it
  // could be an empty list. We should not assume there is at least one.

  cmRange<std::vector<std::string>::const_iterator> argsRange =
    cmMakeRange(args).advance(1); // Get rid of subcommand

  struct Arguments : public ArgumentParser::ParseResult
  {
    std::string Result;
  };
  Arguments arguments;

  auto resultPosItr =
    std::find(cm::begin(argsRange), cm::end(argsRange), "RESULT");
  if (resultPosItr != cm::end(argsRange)) {
    static auto const parser =
      cmArgumentParser<Arguments>{}.Bind("RESULT"_s, &Arguments::Result);
    std::vector<std::string> unparsedArguments;
    auto resultDistanceFromBegin =
      std::distance(cm::begin(argsRange), resultPosItr);
    arguments =
      parser.Parse(cmMakeRange(argsRange).advance(resultDistanceFromBegin),
                   &unparsedArguments);

    if (!unparsedArguments.empty()) {
      std::string unexpectedArgsStr = cmJoin(
        cmMakeRange(cm::begin(unparsedArguments), cm::end(unparsedArguments)),
        "\n");
      status.SetError("MAKE_DIRECTORY called with unexpected\n"
                      "arguments:\n  " +
                      unexpectedArgsStr);
      return false;
    }

    auto resultDistanceFromEnd =
      std::distance(cm::end(argsRange), resultPosItr);
    argsRange = argsRange.retreat(-resultDistanceFromEnd);
  }

  std::string expr;
  for (std::string const& arg : argsRange) {
    std::string const* cdir = &arg;
    if (!cmsys::SystemTools::FileIsFullPath(arg)) {
      expr =
        cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', arg);
      cdir = &expr;
    }
    if (!status.GetMakefile().CanIWriteThisFile(*cdir)) {
      std::string e = cmStrCat("attempted to create a directory: ", *cdir,
                               " into a source directory.");
      if (arguments.Result.empty()) {
        status.SetError(e);
        cmSystemTools::SetFatalErrorOccurred();
        return false;
      }
      status.GetMakefile().AddDefinition(arguments.Result, e);
      return true;
    }
    cmsys::Status mkdirStatus = cmSystemTools::MakeDirectory(*cdir);
    if (!mkdirStatus) {
      if (arguments.Result.empty()) {
        std::string errorOutput =
          cmStrCat("failed to create directory:\n  ", *cdir,
                   "\nbecause: ", mkdirStatus.GetString());
        status.SetError(errorOutput);
        return false;
      }
      std::string errorResult = cmStrCat("Failed to create directory: ", *cdir,
                                         " Error: ", mkdirStatus.GetString());
      status.GetMakefile().AddDefinition(arguments.Result, errorResult);
      return true;
    }
  }
  if (!arguments.Result.empty()) {
    status.GetMakefile().AddDefinition(arguments.Result, "0");
  }
  return true;
}

bool HandleTouchImpl(std::vector<std::string> const& args, bool create,
                     cmExecutionStatus& status)
{
  // Projects might pass a dynamically generated list of files, and it
  // could be an empty list. We should not assume there is at least one.

  for (std::string const& arg :
       cmMakeRange(args).advance(1)) // Get rid of subcommand
  {
    std::string tfile = arg;
    if (!cmsys::SystemTools::FileIsFullPath(tfile)) {
      tfile =
        cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', arg);
    }
    if (!status.GetMakefile().CanIWriteThisFile(tfile)) {
      std::string e = cmStrCat("attempted to touch a file: ", tfile,
                               " in a source directory.");
      status.SetError(e);
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }
    if (!cmSystemTools::Touch(tfile, create)) {
      std::string error = "problem touching file: " + tfile;
      status.SetError(error);
      return false;
    }
  }
  return true;
}

bool HandleTouchCommand(std::vector<std::string> const& args,
                        cmExecutionStatus& status)
{
  return HandleTouchImpl(args, true, status);
}

bool HandleTouchNocreateCommand(std::vector<std::string> const& args,
                                cmExecutionStatus& status)
{
  return HandleTouchImpl(args, false, status);
}

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

  // Evaluate arguments.
  char const* file_lhs = nullptr;
  char const* file_rhs = nullptr;
  char const* var = nullptr;
  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 {
      status.SetError(cmStrCat("DIFFERENT given unknown argument ", args[i]));
      return false;
    }
  }
  if (!var) {
    status.SetError("DIFFERENT not given result variable name.");
    return false;
  }
  if (!file_lhs || !file_rhs) {
    status.SetError("DIFFERENT not given FILES option with two file names.");
    return false;
  }

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

bool HandleCopyCommand(std::vector<std::string> const& args,
                       cmExecutionStatus& status)
{
  cmFileCopier copier(status);
  return copier.Run(args);
}

bool HandleRPathChangeCommand(std::vector<std::string> const& args,
                              cmExecutionStatus& status)
{
  // Evaluate arguments.
  std::string file;
  cm::optional<std::string> oldRPath;
  cm::optional<std::string> newRPath;
  bool removeEnvironmentRPath = false;
  cmArgumentParser<void> parser;
  std::vector<std::string> unknownArgs;
  parser.Bind("FILE"_s, file)
    .Bind("OLD_RPATH"_s, oldRPath)
    .Bind("NEW_RPATH"_s, newRPath)
    .Bind("INSTALL_REMOVE_ENVIRONMENT_RPATH"_s, removeEnvironmentRPath);
  ArgumentParser::ParseResult parseResult =
    parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
  if (!unknownArgs.empty()) {
    status.SetError(
      cmStrCat("RPATH_CHANGE given unknown argument ", unknownArgs.front()));
    return false;
  }
  if (parseResult.MaybeReportError(status.GetMakefile())) {
    return true;
  }
  if (file.empty()) {
    status.SetError("RPATH_CHANGE not given FILE option.");
    return false;
  }
  if (!oldRPath) {
    status.SetError("RPATH_CHANGE not given OLD_RPATH option.");
    return false;
  }
  if (!newRPath) {
    status.SetError("RPATH_CHANGE not given NEW_RPATH option.");
    return false;
  }
  if (!cmSystemTools::FileExists(file, true)) {
    status.SetError(
      cmStrCat("RPATH_CHANGE given FILE \"", file, "\" that does not exist."));
    return false;
  }
  bool success = true;
  cmFileTimes const ft(file);
  std::string emsg;
  bool changed;

  if (!cmSystemTools::ChangeRPath(file, *oldRPath, *newRPath,
                                  removeEnvironmentRPath, &emsg, &changed)) {
    status.SetError(cmStrCat("RPATH_CHANGE could not write new RPATH:\n  ",
                             *newRPath, "\nto the file:\n  ", file, '\n',
                             emsg));
    success = false;
  }
  if (success) {
    if (changed) {
      std::string message =
        cmStrCat("Set non-toolchain portion of runtime path of \"", file,
                 "\" to \"", *newRPath, '"');
      status.GetMakefile().DisplayStatus(message, -1);
    }
    ft.Store(file);
  }
  return success;
}

bool HandleRPathSetCommand(std::vector<std::string> const& args,
                           cmExecutionStatus& status)
{
  // Evaluate arguments.
  std::string file;
  cm::optional<std::string> newRPath;
  cmArgumentParser<void> parser;
  std::vector<std::string> unknownArgs;
  parser.Bind("FILE"_s, file).Bind("NEW_RPATH"_s, newRPath);
  ArgumentParser::ParseResult parseResult =
    parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
  if (!unknownArgs.empty()) {
    status.SetError(cmStrCat("RPATH_SET given unrecognized argument \"",
                             unknownArgs.front(), "\"."));
    return false;
  }
  if (parseResult.MaybeReportError(status.GetMakefile())) {
    return true;
  }
  if (file.empty()) {
    status.SetError("RPATH_SET not given FILE option.");
    return false;
  }
  if (!newRPath) {
    status.SetError("RPATH_SET not given NEW_RPATH option.");
    return false;
  }
  if (!cmSystemTools::FileExists(file, true)) {
    status.SetError(
      cmStrCat("RPATH_SET given FILE \"", file, "\" that does not exist."));
    return false;
  }
  bool success = true;
  cmFileTimes const ft(file);
  std::string emsg;
  bool changed;

  if (!cmSystemTools::SetRPath(file, *newRPath, &emsg, &changed)) {
    status.SetError(cmStrCat("RPATH_SET could not write new RPATH:\n  ",
                             *newRPath, "\nto the file:\n  ", file, '\n',
                             emsg));
    success = false;
  }
  if (success) {
    if (changed) {
      std::string message =
        cmStrCat("Set non-toolchain portion of runtime path of \"", file,
                 "\" to \"", *newRPath, '"');
      status.GetMakefile().DisplayStatus(message, -1);
    }
    ft.Store(file);
  }
  return success;
}

bool HandleRPathRemoveCommand(std::vector<std::string> const& args,
                              cmExecutionStatus& status)
{
  // Evaluate arguments.
  std::string file;
  cmArgumentParser<void> parser;
  std::vector<std::string> unknownArgs;
  parser.Bind("FILE"_s, file);
  ArgumentParser::ParseResult parseResult =
    parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
  if (!unknownArgs.empty()) {
    status.SetError(
      cmStrCat("RPATH_REMOVE given unknown argument ", unknownArgs.front()));
    return false;
  }
  if (parseResult.MaybeReportError(status.GetMakefile())) {
    return true;
  }
  if (file.empty()) {
    status.SetError("RPATH_REMOVE not given FILE option.");
    return false;
  }
  if (!cmSystemTools::FileExists(file, true)) {
    status.SetError(
      cmStrCat("RPATH_REMOVE given FILE \"", file, "\" that does not exist."));
    return false;
  }
  bool success = true;
  cmFileTimes const ft(file);
  std::string emsg;
  bool removed;
  if (!cmSystemTools::RemoveRPath(file, &emsg, &removed)) {
    status.SetError(
      cmStrCat("RPATH_REMOVE could not remove RPATH from file: \n  ", file,
               '\n', emsg));
    success = false;
  }
  if (success) {
    if (removed) {
      std::string message =
        cmStrCat("Removed runtime path from \"", file, '"');
      status.GetMakefile().DisplayStatus(message, -1);
    }
    ft.Store(file);
  }
  return success;
}

bool HandleRPathCheckCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
{
  // Evaluate arguments.
  std::string file;
  cm::optional<std::string> rpath;
  cmArgumentParser<void> parser;
  std::vector<std::string> unknownArgs;
  parser.Bind("FILE"_s, file).Bind("RPATH"_s, rpath);
  ArgumentParser::ParseResult parseResult =
    parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
  if (!unknownArgs.empty()) {
    status.SetError(
      cmStrCat("RPATH_CHECK given unknown argument ", unknownArgs.front()));
    return false;
  }
  if (parseResult.MaybeReportError(status.GetMakefile())) {
    return true;
  }
  if (file.empty()) {
    status.SetError("RPATH_CHECK not given FILE option.");
    return false;
  }
  if (!rpath) {
    status.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 HandleReadElfCommand(std::vector<std::string> const& args,
                          cmExecutionStatus& status)
{
  if (args.size() < 4) {
    status.SetError("READ_ELF must be called with at least three additional "
                    "arguments.");
    return false;
  }

  std::string const& fileNameArg = args[1];

  struct Arguments
  {
    std::string RPath;
    std::string RunPath;
    std::string Error;
  };

  static auto const parser = cmArgumentParser<Arguments>{}
                               .Bind("RPATH"_s, &Arguments::RPath)
                               .Bind("RUNPATH"_s, &Arguments::RunPath)
                               .Bind("CAPTURE_ERROR"_s, &Arguments::Error);
  Arguments const arguments = parser.Parse(cmMakeRange(args).advance(2),
                                           /*unparsedArguments=*/nullptr);

  if (!cmSystemTools::FileExists(fileNameArg, true)) {
    status.SetError(cmStrCat("READ_ELF given FILE \"", fileNameArg,
                             "\" that does not exist."));
    return false;
  }

  cmELF elf(fileNameArg.c_str());
  if (!elf) {
    if (arguments.Error.empty()) {
      status.SetError(cmStrCat("READ_ELF given FILE:\n  ", fileNameArg,
                               "\nthat is not a valid ELF file."));
      return false;
    }
    status.GetMakefile().AddDefinition(arguments.Error,
                                       "not a valid ELF file");
    return true;
  }

  if (!arguments.RPath.empty()) {
    if (cmELF::StringEntry const* se_rpath = elf.GetRPath()) {
      std::string rpath(se_rpath->Value);
      std::replace(rpath.begin(), rpath.end(), ':', ';');
      status.GetMakefile().AddDefinition(arguments.RPath, rpath);
    }
  }
  if (!arguments.RunPath.empty()) {
    if (cmELF::StringEntry const* se_runpath = elf.GetRunPath()) {
      std::string runpath(se_runpath->Value);
      std::replace(runpath.begin(), runpath.end(), ':', ';');
      status.GetMakefile().AddDefinition(arguments.RunPath, runpath);
    }
  }

  return true;
}

bool HandleInstallCommand(std::vector<std::string> const& args,
                          cmExecutionStatus& status)
{
  cmFileInstaller installer(status);
  return installer.Run(args);
}

bool HandleRealPathCommand(std::vector<std::string> const& args,
                           cmExecutionStatus& status)
{
  if (args.size() < 3) {
    status.SetError("REAL_PATH requires a path and an output variable");
    return false;
  }

  struct Arguments : public ArgumentParser::ParseResult
  {
    cm::optional<std::string> BaseDirectory;
    bool ExpandTilde = false;
  };
  static auto const parser =
    cmArgumentParser<Arguments>{}
      .Bind("BASE_DIRECTORY"_s, &Arguments::BaseDirectory)
      .Bind("EXPAND_TILDE"_s, &Arguments::ExpandTilde);

  std::vector<std::string> unparsedArguments;
  auto arguments =
    parser.Parse(cmMakeRange(args).advance(3), &unparsedArguments);

  if (!unparsedArguments.empty()) {
    status.SetError("REAL_PATH called with unexpected arguments");
    return false;
  }
  if (arguments.MaybeReportError(status.GetMakefile())) {
    return true;
  }

  if (!arguments.BaseDirectory) {
    arguments.BaseDirectory = status.GetMakefile().GetCurrentSourceDirectory();
  }

  auto input = args[1];
  if (arguments.ExpandTilde && !input.empty()) {
    if (input[0] == '~' && (input.length() == 1 || input[1] == '/')) {
      std::string home;
      if (
#if defined(_WIN32) && !defined(__CYGWIN__)
        cmSystemTools::GetEnv("USERPROFILE", home) ||
#endif
        cmSystemTools::GetEnv("HOME", home)) {
        input.replace(0, 1, home);
      }
    }
  }

  bool warnAbout152 = false;
  bool use152New = true;
  cmPolicies::PolicyStatus policyStatus =
    status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0152);
  switch (policyStatus) {
    case cmPolicies::NEW:
      break;
    case cmPolicies::WARN:
      use152New = false;
      warnAbout152 = true;
      break;
    case cmPolicies::OLD:
      use152New = false;
      warnAbout152 = false;
      break;
  }

  auto computeNewPath = [=](std::string const& in, std::string& result) {
    auto path = cmCMakePath{ in };
    if (path.IsRelative()) {
      auto basePath = cmCMakePath{ *arguments.BaseDirectory };
      path = basePath.Append(path);
    }
    result = cmSystemTools::GetRealPath(path.String());
  };

  std::string realPath;
  if (use152New) {
    computeNewPath(input, realPath);
  } else {
    std::string oldPolicyPath =
      cmSystemTools::CollapseFullPath(input, *arguments.BaseDirectory);
    oldPolicyPath = cmSystemTools::GetRealPath(oldPolicyPath);
    if (warnAbout152) {
      computeNewPath(input, realPath);
      if (oldPolicyPath != realPath) {
        status.GetMakefile().IssueDiagnostic(
          cmDiagnostics::CMD_AUTHOR,
          cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0152),
                   "\n"
                   "From input path:\n  ",
                   input, "\nthe policy OLD behavior produces path:\n  ",
                   oldPolicyPath,
                   "\nbut the policy NEW behavior produces path:\n  ",
                   realPath,
                   "\nSince the policy is not set, CMake is using the OLD "
                   "behavior for compatibility."));
      }
    }
    realPath = oldPolicyPath;
  }

  if (!cmSystemTools::FileExists(realPath)) {
    status.GetMakefile().IssueDiagnostic(
      cmDiagnostics::CMD_AUTHOR,
      cmStrCat("Given path:\n  ", input,
               "\ndoes not refer to an existing path on disk."));
  }

  status.GetMakefile().AddDefinition(args[2], realPath);

  return true;
}

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

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

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

  std::string res = cmSystemTools::RelativePath(directoryName, fileName);
  status.GetMakefile().AddDefinition(outVar, res);
  return true;
}

bool HandleRename(std::vector<std::string> const& args,
                  cmExecutionStatus& status)
{
  if (args.size() < 3) {
    status.SetError("RENAME must be called with at least two additional "
                    "arguments");
    return false;
  }

  // Compute full path for old and new names.
  std::string oldname = args[1];
  if (!cmsys::SystemTools::FileIsFullPath(oldname)) {
    oldname =
      cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[1]);
  }
  std::string newname = args[2];
  if (!cmsys::SystemTools::FileIsFullPath(newname)) {
    newname =
      cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[2]);
  }

  struct Arguments
  {
    bool NoReplace = false;
    std::string Result;
  };

  static auto const parser = cmArgumentParser<Arguments>{}
                               .Bind("NO_REPLACE"_s, &Arguments::NoReplace)
                               .Bind("RESULT"_s, &Arguments::Result);

  std::vector<std::string> unconsumedArgs;
  Arguments const arguments =
    parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs);
  if (!unconsumedArgs.empty()) {
    status.SetError("RENAME unknown argument:\n  " + unconsumedArgs.front());
    return false;
  }

  std::string err;
  switch (cmSystemTools::RenameFile(oldname, newname,
                                    arguments.NoReplace
                                      ? cmSystemTools::Replace::No
                                      : cmSystemTools::Replace::Yes,
                                    &err)) {
    case cmSystemTools::RenameResult::Success:
      if (!arguments.Result.empty()) {
        status.GetMakefile().AddDefinition(arguments.Result, "0");
      }
      return true;
    case cmSystemTools::RenameResult::NoReplace:
      if (!arguments.Result.empty()) {
        err = "NO_REPLACE";
      } else {
        err = "path not replaced";
      }
      CM_FALLTHROUGH;
    case cmSystemTools::RenameResult::Failure:
      if (!arguments.Result.empty()) {
        status.GetMakefile().AddDefinition(arguments.Result, err);
        return true;
      }
      break;
  }
  status.SetError(cmStrCat("RENAME failed to rename\n  ", oldname, "\nto\n  ",
                           newname, "\nbecause: ", err, '\n'));
  return false;
}

bool HandleCopyFile(std::vector<std::string> const& args,
                    cmExecutionStatus& status)
{
  if (args.size() < 3) {
    status.SetError("COPY_FILE must be called with at least two additional "
                    "arguments");
    return false;
  }

  // Compute full path for old and new names.
  std::string oldname = args[1];
  if (!cmsys::SystemTools::FileIsFullPath(oldname)) {
    oldname =
      cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[1]);
  }
  std::string newname = args[2];
  if (!cmsys::SystemTools::FileIsFullPath(newname)) {
    newname =
      cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', args[2]);
  }

  struct Arguments
  {
    bool InputMayBeRecent = false;
    bool OnlyIfDifferent = false;
    std::string Result;
  };

  static auto const parser =
    cmArgumentParser<Arguments>{}
      .Bind("INPUT_MAY_BE_RECENT"_s, &Arguments::InputMayBeRecent)
      .Bind("ONLY_IF_DIFFERENT"_s, &Arguments::OnlyIfDifferent)
      .Bind("RESULT"_s, &Arguments::Result);

  std::vector<std::string> unconsumedArgs;
  Arguments const arguments =
    parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs);
  if (!unconsumedArgs.empty()) {
    status.SetError("COPY_FILE unknown argument:\n  " +
                    unconsumedArgs.front());
    return false;
  }

  bool result = true;
  if (cmsys::SystemTools::FileIsDirectory(oldname)) {
    if (!arguments.Result.empty()) {
      status.GetMakefile().AddDefinition(arguments.Result,
                                         "cannot copy a directory");
    } else {
      status.SetError(
        cmStrCat("COPY_FILE cannot copy a directory\n  ", oldname));
      result = false;
    }
    return result;
  }
  if (cmsys::SystemTools::FileIsDirectory(newname)) {
    if (!arguments.Result.empty()) {
      status.GetMakefile().AddDefinition(arguments.Result,
                                         "cannot copy to a directory");
    } else {
      status.SetError(
        cmStrCat("COPY_FILE cannot copy to a directory\n  ", newname));
      result = false;
    }
    return result;
  }

  cmSystemTools::CopyWhen when;
  if (arguments.OnlyIfDifferent) {
    when = cmSystemTools::CopyWhen::OnlyIfDifferent;
  } else {
    when = cmSystemTools::CopyWhen::Always;
  }
  cmSystemTools::CopyInputRecent const inputRecent = arguments.InputMayBeRecent
    ? cmSystemTools::CopyInputRecent::Yes
    : cmSystemTools::CopyInputRecent::No;

  std::string err;
  if (cmSystemTools::CopySingleFile(oldname, newname, when, inputRecent,
                                    &err) ==
      cmSystemTools::CopyResult::Success) {
    if (!arguments.Result.empty()) {
      status.GetMakefile().AddDefinition(arguments.Result, "0");
    }
  } else {
    if (!arguments.Result.empty()) {
      status.GetMakefile().AddDefinition(arguments.Result, err);
    } else {
      status.SetError(cmStrCat("COPY_FILE failed to copy\n  ", oldname,
                               "\nto\n  ", newname, "\nbecause: ", err, '\n'));
      result = false;
    }
  }

  return result;
}

bool HandleRemoveImpl(std::vector<std::string> const& args, bool recurse,
                      cmExecutionStatus& status)
{
  for (std::string const& arg :
       cmMakeRange(args).advance(1)) // Get rid of subcommand
  {
    std::string fileName = arg;
    if (fileName.empty()) {
      std::string r = recurse ? "REMOVE_RECURSE" : "REMOVE";
      status.GetMakefile().IssueDiagnostic(
        cmDiagnostics::CMD_AUTHOR,
        cmStrCat("Ignoring empty file name in ", std::move(r), '.'));
      continue;
    }
    if (!cmsys::SystemTools::FileIsFullPath(fileName)) {
      fileName =
        cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', arg);
    }

    if (cmSystemTools::FileIsDirectory(fileName) &&
        !cmSystemTools::FileIsSymlink(fileName) && recurse) {
      cmSystemTools::RepeatedRemoveDirectory(fileName);
    } else {
      cmSystemTools::RemoveFile(fileName);
    }
  }
  return true;
}

bool HandleRemove(std::vector<std::string> const& args,
                  cmExecutionStatus& status)
{
  return HandleRemoveImpl(args, false, status);
}

bool HandleRemoveRecurse(std::vector<std::string> const& args,
                         cmExecutionStatus& status)
{
  return HandleRemoveImpl(args, true, status);
}

std::string ToNativePath(std::string const& path)
{
  auto const& outPath = cmSystemTools::ConvertToOutputPath(path);
  if (outPath.size() > 1 && outPath.front() == '\"' &&
      outPath.back() == '\"') {
    return outPath.substr(1, outPath.size() - 2);
  }
  return outPath;
}

std::string ToCMakePath(std::string const& path)
{
  auto temp = path;
  cmSystemTools::ConvertToUnixSlashes(temp);
  return temp;
}

bool HandlePathCommand(std::vector<std::string> const& args,
                       std::string (*convert)(std::string const&),
                       cmExecutionStatus& status)
{
  if (args.size() != 3) {
    status.SetError("FILE([TO_CMAKE_PATH|TO_NATIVE_PATH] path result) must be "
                    "called with exactly three arguments.");
    return false;
  }
#if defined(_WIN32) && !defined(__CYGWIN__)
  char pathSep = ';';
#else
  char pathSep = ':';
#endif
  std::vector<std::string> path = cmSystemTools::SplitString(args[1], pathSep);

  std::string value = cmList::to_string(cmMakeRange(path).transform(convert));
  status.GetMakefile().AddDefinition(args[2], value);
  return true;
}

bool HandleCMakePathCommand(std::vector<std::string> const& args,
                            cmExecutionStatus& status)
{
  return HandlePathCommand(args, ToCMakePath, status);
}

bool HandleNativePathCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
{
  return HandlePathCommand(args, ToNativePath, status);
}

#if !defined(CMAKE_BOOTSTRAP)

bool const TLS_VERIFY_DEFAULT = true;
std::string const TLS_VERSION_DEFAULT = "1.2";

// Stuff for curl download/upload
using cmFileCommandVectorOfChar = std::vector<char>;

std::string CurlCompatFileURL(std::string url)
{
  if (cmHasLiteralPrefix(url, "file://")) {
    // libcurl 7.77 and below accidentally allowed spaces in file:// URLs,
    // which CMake has long accepted as a result.  Explicitly encode spaces.
    cmSystemTools::ReplaceString(url, " ", "%20");
  }
  return url;
}

size_t cmWriteToFileCallback(void* ptr, size_t size, size_t nmemb, void* data)
{
  int realsize = static_cast<int>(size * nmemb);
  cmsys::ofstream* fout = static_cast<cmsys::ofstream*>(data);
  if (fout) {
    char const* chPtr = static_cast<char*>(ptr);
    if (!fout->write(chPtr, realsize)) {
      return CURL_WRITEFUNC_ERROR;
    }
  }
  return realsize;
}

size_t cmWriteToMemoryCallback(void* ptr, size_t size, size_t nmemb,
                               void* data)
{
  int realsize = static_cast<int>(size * nmemb);
  char const* chPtr = static_cast<char*>(ptr);
  cm::append(*static_cast<cmFileCommandVectorOfChar*>(data), chPtr,
             chPtr + realsize);
  return realsize;
}

int cmFileCommandCurlDebugCallback(CURL*, curl_infotype type, char* chPtr,
                                   size_t size, void* data)
{
  cmFileCommandVectorOfChar& vec =
    *static_cast<cmFileCommandVectorOfChar*>(data);
  switch (type) {
    case CURLINFO_TEXT:
    case CURLINFO_HEADER_IN:
    case CURLINFO_HEADER_OUT:
      cm::append(vec, chPtr, chPtr + size);
      break;
    case CURLINFO_DATA_IN:
    case CURLINFO_DATA_OUT:
    case CURLINFO_SSL_DATA_IN:
    case CURLINFO_SSL_DATA_OUT: {
      char buf[128];
      int n =
        snprintf(buf, sizeof(buf), "[%" KWIML_INT_PRIu64 " bytes data]\n",
                 static_cast<KWIML_INT_uint64_t>(size));
      if (n > 0) {
        cm::append(vec, buf, buf + n);
      }
    } break;
    default:
      break;
  }
  return 0;
}

#  if defined(LIBCURL_VERSION_NUM) && LIBCURL_VERSION_NUM >= 0x072000
CURLoption const CM_CURLOPT_XFERINFOFUNCTION = CURLOPT_XFERINFOFUNCTION;
using cm_curl_off_t = curl_off_t;
#  else
CURLoption const CM_CURLOPT_XFERINFOFUNCTION = CURLOPT_PROGRESSFUNCTION;
using cm_curl_off_t = double;
#  endif

class cURLProgressHelper
{
public:
  cURLProgressHelper(cmMakefile* mf, char const* text)
    : Makefile(mf)
    , Text(text)
  {
  }

  bool UpdatePercentage(cm_curl_off_t value, cm_curl_off_t total,
                        std::string& status)
  {
    long OldPercentage = this->CurrentPercentage;

    if (total > 0) {
      this->CurrentPercentage = std::lround(
        static_cast<double>(value) / static_cast<double>(total) * 100.0);
      if (this->CurrentPercentage > 100) {
        // Avoid extra progress reports for unexpected data beyond total.
        this->CurrentPercentage = 100;
      }
    }

    bool updated = (OldPercentage != this->CurrentPercentage);

    if (updated) {
      status =
        cmStrCat('[', this->Text, ' ', this->CurrentPercentage, "% complete]");
    }

    return updated;
  }

  cmMakefile* GetMakefile() { return this->Makefile; }

private:
  long CurrentPercentage = -1;
  cmMakefile* Makefile;
  std::string Text;
};

int cmFileDownloadProgressCallback(void* clientp, cm_curl_off_t dltotal,
                                   cm_curl_off_t dlnow, cm_curl_off_t ultotal,
                                   cm_curl_off_t ulnow)
{
  cURLProgressHelper* helper = reinterpret_cast<cURLProgressHelper*>(clientp);

  static_cast<void>(ultotal);
  static_cast<void>(ulnow);

  std::string status;
  if (helper->UpdatePercentage(dlnow, dltotal, status)) {
    cmMakefile* mf = helper->GetMakefile();
    mf->DisplayStatus(status, -1);
  }

  return 0;
}

int cmFileUploadProgressCallback(void* clientp, cm_curl_off_t dltotal,
                                 cm_curl_off_t dlnow, cm_curl_off_t ultotal,
                                 cm_curl_off_t ulnow)
{
  cURLProgressHelper* helper = reinterpret_cast<cURLProgressHelper*>(clientp);

  static_cast<void>(dltotal);
  static_cast<void>(dlnow);

  std::string status;
  if (helper->UpdatePercentage(ulnow, ultotal, status)) {
    cmMakefile* mf = helper->GetMakefile();
    mf->DisplayStatus(status, -1);
  }

  return 0;
}

class cURLEasyGuard
{
public:
  cURLEasyGuard(CURL* easy)
    : Easy(easy)
  {
  }

  ~cURLEasyGuard()
  {
    if (this->Easy) {
      ::curl_easy_cleanup(this->Easy);
    }
  }

  cURLEasyGuard(cURLEasyGuard const&) = delete;
  cURLEasyGuard& operator=(cURLEasyGuard const&) = delete;

  void release() { this->Easy = nullptr; }

private:
  ::CURL* Easy;
};

#endif

#define check_curl_result(result, errstr)                                     \
  do {                                                                        \
    if (result != CURLE_OK) {                                                 \
      std::string e(errstr);                                                  \
      e += ::curl_easy_strerror(result);                                      \
      status.SetError(e);                                                     \
      return false;                                                           \
    }                                                                         \
  } while (false)

bool HandleDownloadCommand(std::vector<std::string> const& args,
                           cmExecutionStatus& status)
{
#if !defined(CMAKE_BOOTSTRAP)
  auto i = args.begin();
  if (args.size() < 2) {
    status.SetError("DOWNLOAD must be called with at least two arguments.");
    return false;
  }
  ++i; // Get rid of subcommand
  std::string url = *i;
  ++i;
  std::string file;

  long timeout = 0;
  long inactivity_timeout = 0;
  std::string logVar;
  std::string statusVar;
  cm::optional<std::string> tlsVersionOpt;
  cm::optional<bool> tlsVerifyOpt;
  cmValue cainfo = status.GetMakefile().GetDefinition("CMAKE_TLS_CAINFO");
  std::string netrc_level =
    status.GetMakefile().GetSafeDefinition("CMAKE_NETRC");
  std::string netrc_file =
    status.GetMakefile().GetSafeDefinition("CMAKE_NETRC_FILE");
  std::string expectedHash;
  std::string hashMatchMSG;
  std::unique_ptr<cmCryptoHash> hash;
  bool showProgress = false;
  std::string userpwd;

  std::vector<std::string> curl_headers;
  std::vector<std::pair<std::string, cm::optional<std::string>>> curl_ranges;

  while (i != args.end()) {
    if (*i == "TIMEOUT") {
      ++i;
      if (i != args.end()) {
        timeout = atol(i->c_str());
      } else {
        status.SetError("DOWNLOAD missing time for TIMEOUT.");
        return false;
      }
    } else if (*i == "INACTIVITY_TIMEOUT") {
      ++i;
      if (i != args.end()) {
        inactivity_timeout = atol(i->c_str());
      } else {
        status.SetError("DOWNLOAD missing time for INACTIVITY_TIMEOUT.");
        return false;
      }
    } else if (*i == "LOG") {
      ++i;
      if (i == args.end()) {
        status.SetError("DOWNLOAD missing VAR for LOG.");
        return false;
      }
      logVar = *i;
    } else if (*i == "STATUS") {
      ++i;
      if (i == args.end()) {
        status.SetError("DOWNLOAD missing VAR for STATUS.");
        return false;
      }
      statusVar = *i;
    } else if (*i == "TLS_VERSION") {
      ++i;
      if (i != args.end()) {
        tlsVersionOpt = *i;
      } else {
        status.SetError("DOWNLOAD missing value for TLS_VERSION.");
        return false;
      }
    } else if (*i == "TLS_VERIFY") {
      ++i;
      if (i != args.end()) {
        tlsVerifyOpt = cmIsOn(*i);
      } else {
        status.SetError("DOWNLOAD missing bool value for TLS_VERIFY.");
        return false;
      }
    } else if (*i == "TLS_CAINFO") {
      ++i;
      if (i != args.end()) {
        cainfo = cmValue(*i);
      } else {
        status.SetError("DOWNLOAD missing file value for TLS_CAINFO.");
        return false;
      }
    } else if (*i == "NETRC_FILE") {
      ++i;
      if (i != args.end()) {
        netrc_file = *i;
      } else {
        status.SetError("DOWNLOAD missing file value for NETRC_FILE.");
        return false;
      }
    } else if (*i == "NETRC") {
      ++i;
      if (i != args.end()) {
        netrc_level = *i;
      } else {
        status.SetError("DOWNLOAD missing level value for NETRC.");
        return false;
      }
    } else if (*i == "EXPECTED_MD5") {
      ++i;
      if (i == args.end()) {
        status.SetError("DOWNLOAD missing sum value for EXPECTED_MD5.");
        return false;
      }
      hash = cm::make_unique<cmCryptoHash>(cmCryptoHash::AlgoMD5);
      hashMatchMSG = "MD5 sum";
      expectedHash = cmSystemTools::LowerCase(*i);
    } else if (*i == "SHOW_PROGRESS") {
      showProgress = true;
    } else if (*i == "EXPECTED_HASH") {
      ++i;
      if (i == args.end()) {
        status.SetError("DOWNLOAD missing ALGO=value for EXPECTED_HASH.");
        return false;
      }
      std::string::size_type pos = i->find("=");
      if (pos == std::string::npos) {
        std::string err =
          cmStrCat("DOWNLOAD EXPECTED_HASH expects ALGO=value but got: ", *i);
        status.SetError(err);
        return false;
      }
      std::string algo = i->substr(0, pos);
      expectedHash = cmSystemTools::LowerCase(i->substr(pos + 1));
      hash = cmCryptoHash::New(algo);
      if (!hash) {
        std::string err =
          cmStrCat("DOWNLOAD EXPECTED_HASH given unknown ALGO: ", algo);
        status.SetError(err);
        return false;
      }
      hashMatchMSG = algo + " hash";
    } else if (*i == "USERPWD") {
      ++i;
      if (i == args.end()) {
        status.SetError("DOWNLOAD missing string for USERPWD.");
        return false;
      }
      userpwd = *i;
    } else if (*i == "HTTPHEADER") {
      ++i;
      if (i == args.end()) {
        status.SetError("DOWNLOAD missing string for HTTPHEADER.");
        return false;
      }
      curl_headers.push_back(*i);
    } else if (*i == "RANGE_START") {
      ++i;
      if (i == args.end()) {
        status.SetError("DOWNLOAD missing value for RANGE_START.");
        return false;
      }
      curl_ranges.emplace_back(*i, cm::nullopt);
    } else if (*i == "RANGE_END") {
      ++i;
      if (curl_ranges.empty()) {
        curl_ranges.emplace_back("0", *i);
      } else {
        auto& last_range = curl_ranges.back();
        if (!last_range.second.has_value()) {
          last_range.second = *i;
        } else {
          status.SetError("Multiple RANGE_END values is provided without "
                          "the corresponding RANGE_START.");
          return false;
        }
      }
    } else if (file.empty()) {
      file = *i;
    } else {
      // Do not return error for compatibility reason.
      status.GetMakefile().IssueDiagnostic(
        cmDiagnostics::CMD_AUTHOR, cmStrCat("Unexpected argument: ", *i));
    }
    ++i;
  }

  if (!tlsVerifyOpt.has_value()) {
    if (cmValue v = status.GetMakefile().GetDefinition("CMAKE_TLS_VERIFY")) {
      tlsVerifyOpt = v.IsOn();
    }
  }
  if (!tlsVerifyOpt.has_value()) {
    if (cm::optional<std::string> v =
          cmSystemTools::GetEnvVar("CMAKE_TLS_VERIFY")) {
      tlsVerifyOpt = cmIsOn(*v);
    }
  }
  bool tlsVerifyDefaulted = false;
  if (!tlsVerifyOpt.has_value()) {
    tlsVerifyOpt = TLS_VERIFY_DEFAULT;
    tlsVerifyDefaulted = true;
  }

  if (!tlsVersionOpt.has_value()) {
    if (cmValue v = status.GetMakefile().GetDefinition("CMAKE_TLS_VERSION")) {
      tlsVersionOpt = *v;
    }
  }
  if (!tlsVersionOpt.has_value()) {
    if (cm::optional<std::string> v =
          cmSystemTools::GetEnvVar("CMAKE_TLS_VERSION")) {
      tlsVersionOpt = std::move(v);
    }
  }
  bool tlsVersionDefaulted = false;
  if (!tlsVersionOpt.has_value()) {
    tlsVersionOpt = TLS_VERSION_DEFAULT;
    tlsVersionDefaulted = true;
  }

  // Can't calculate hash if we don't save the file.
  // TODO Incrementally calculate hash in the write callback as the file is
  // being downloaded so this check can be relaxed.
  if (file.empty() && hash) {
    status.SetError("DOWNLOAD cannot calculate hash if file is not saved.");
    return false;
  }
  // If file exists already, and caller specified an expected md5 or sha,
  // and the existing file already has the expected hash, then simply
  // return.
  //
  if (!file.empty() && cmSystemTools::FileExists(file) && hash.get()) {
    std::string msg;
    std::string actualHash = hash->HashFile(file);
    if (actualHash == expectedHash) {
      msg = cmStrCat("skipping download as file already exists with expected ",
                     hashMatchMSG, '"');
      if (!statusVar.empty()) {
        status.GetMakefile().AddDefinition(statusVar, cmStrCat(0, ";\"", msg));
      }
      return true;
    }
  }
  // Make sure parent directory exists so we can write to the file
  // as we receive downloaded bits from curl...
  //
  if (!file.empty()) {
    std::string dir = cmSystemTools::GetFilenamePath(file);
    if (!dir.empty() && !cmSystemTools::FileExists(dir) &&
        !cmSystemTools::MakeDirectory(dir)) {
      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.";
      status.SetError(errstring);
      return false;
    }
  }

  cmsys::ofstream fout;
  if (!file.empty()) {
    fout.open(file.c_str(), std::ios::binary);
    if (!fout) {
      status.SetError(cmStrCat("DOWNLOAD cannot open file for write\n"
                               "  file: \"",
                               file, '"'));
      return false;
    }
  }

  url = CurlCompatFileURL(url);

  ::CURL* curl;
  cm_curl_global_init(CURL_GLOBAL_DEFAULT);
  curl = cm_curl_easy_init();
  if (!curl) {
    status.SetError("DOWNLOAD error initializing curl.");
    return false;
  }

  cURLEasyGuard g_curl(curl);
  ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
  check_curl_result(res, "DOWNLOAD cannot set url: ");

  // enable HTTP ERROR parsing
  res = ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
  check_curl_result(res, "DOWNLOAD cannot set http failure option: ");

  curl_version_info_data* cv = curl_version_info(CURLVERSION_FIRST);
  res = ::curl_easy_setopt(
    curl, CURLOPT_USERAGENT,
    cmStrCat("curl/", cv ? cv->version : LIBCURL_VERSION).c_str());
  check_curl_result(res, "DOWNLOAD cannot set user agent option: ");

  res = ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cmWriteToFileCallback);
  check_curl_result(res, "DOWNLOAD cannot set write function: ");

  res = ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
                           cmFileCommandCurlDebugCallback);
  check_curl_result(res, "DOWNLOAD cannot set debug function: ");

  if (tlsVersionOpt.has_value()) {
    if (cm::optional<int> v = cmCurlParseTLSVersion(*tlsVersionOpt)) {
      res = ::curl_easy_setopt(curl, CURLOPT_SSLVERSION, *v);
      if (tlsVersionDefaulted && res == CURLE_NOT_BUILT_IN) {
        res = CURLE_OK;
      }
      check_curl_result(res,
                        cmStrCat("DOWNLOAD cannot set TLS/SSL version ",
                                 *tlsVersionOpt, ": "));
    } else {
      status.SetError(
        cmStrCat("DOWNLOAD given unknown TLS/SSL version ", *tlsVersionOpt));
      return false;
    }
  }

  // check to see if TLS verification is requested
  if (tlsVerifyOpt.has_value() && tlsVerifyOpt.value()) {
    res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
    check_curl_result(res, "DOWNLOAD cannot set TLS/SSL Verify on: ");
  } else {
    res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    check_curl_result(res, "DOWNLOAD cannot set TLS/SSL Verify off: ");
  }

  for (auto const& range : curl_ranges) {
    std::string curl_range =
      cmStrCat(range.first, '-',
               (range.second.has_value() ? range.second.value() : ""));
    res = ::curl_easy_setopt(curl, CURLOPT_RANGE, curl_range.c_str());
    check_curl_result(res, "DOWNLOAD cannot set range: ");
  }

  // check to see if a CAINFO file has been specified
  // command arg comes first
  std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo);
  if (!cainfo_err.empty()) {
    status.SetError(cainfo_err);
    return false;
  }

  // check to see if netrc parameters have been specified
  // local command args takes precedence over CMAKE_NETRC*
  netrc_level = cmSystemTools::UpperCase(netrc_level);
  std::string const& netrc_option_err =
    cmCurlSetNETRCOption(curl, netrc_level, netrc_file);
  if (!netrc_option_err.empty()) {
    status.SetError(netrc_option_err);
    return false;
  }

  cmFileCommandVectorOfChar chunkDebug;

  res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA,
                           file.empty() ? nullptr : &fout);
  check_curl_result(res, "DOWNLOAD cannot set write data: ");

  res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &chunkDebug);
  check_curl_result(res, "DOWNLOAD cannot set debug data: ");

  res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  check_curl_result(res, "DOWNLOAD cannot set follow-redirect option: ");

  if (!logVar.empty()) {
    res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
    check_curl_result(res, "DOWNLOAD cannot set verbose: ");
  }

  if (timeout > 0) {
    res = ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
    check_curl_result(res, "DOWNLOAD cannot set timeout: ");
  }

  if (inactivity_timeout > 0) {
    // Give up if there is no progress for a long time.
    ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1);
    ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, inactivity_timeout);
  }

  // Need the progress helper's scope to last through the duration of
  // the curl_easy_perform call... so this object is declared at function
  // scope intentionally, rather than inside the "if(showProgress)"
  // block...
  //
  cURLProgressHelper helper(&status.GetMakefile(), "download");

  if (showProgress) {
    res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
    check_curl_result(res, "DOWNLOAD cannot set noprogress value: ");

    res = ::curl_easy_setopt(curl, CM_CURLOPT_XFERINFOFUNCTION,
                             cmFileDownloadProgressCallback);
    check_curl_result(res, "DOWNLOAD cannot set progress function: ");

    res = ::curl_easy_setopt(curl, CURLOPT_PROGRESSDATA,
                             reinterpret_cast<void*>(&helper));
    check_curl_result(res, "DOWNLOAD cannot set progress data: ");
  }

  if (!userpwd.empty()) {
    res = ::curl_easy_setopt(curl, CURLOPT_USERPWD, userpwd.c_str());
    check_curl_result(res, "DOWNLOAD cannot set user password: ");
  }

  struct curl_slist* headers = nullptr;
  for (std::string const& h : curl_headers) {
    headers = ::curl_slist_append(headers, h.c_str());
  }
  ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

  res = ::curl_easy_perform(curl);

  ::curl_slist_free_all(headers);

  /* always cleanup */
  g_curl.release();
  ::curl_easy_cleanup(curl);

  // Explicitly close the file so we can check for write errors.
  if (!file.empty()) {
    fout.close();
    if (!fout) {
      res = CURLE_WRITE_ERROR;
    }
  }

  if (!statusVar.empty()) {
    std::string m = curl_easy_strerror(res);
    if ((res == CURLE_SSL_CONNECT_ERROR ||
         res == CURLE_PEER_FAILED_VERIFICATION) &&
        tlsVerifyDefaulted) {
      m = cmStrCat(
        std::move(m),
        ".  If this is due to https certificate verification failure, one may "
        "set environment variable CMAKE_TLS_VERIFY=0 to suppress it.");
    }
    status.GetMakefile().AddDefinition(
      statusVar, cmStrCat(static_cast<int>(res), ";\"", std::move(m), '"'));
  }

  ::curl_global_cleanup();

  // Ensure requested curl logs are returned (especially in case of failure)
  //
  if (!logVar.empty()) {
    chunkDebug.push_back(0);
    status.GetMakefile().AddDefinition(logVar, chunkDebug.data());
  }

  // Verify MD5 sum if requested:
  //
  if (hash) {
    if (res != CURLE_OK) {
      status.SetError(
        cmStrCat("DOWNLOAD cannot compute hash on failed download\n"
                 "  from url: \"",
                 url, "\"\n  status: [", static_cast<int>(res), ";\"",
                 ::curl_easy_strerror(res), "\"]"));
      return false;
    }

    std::string actualHash = hash->HashFile(file);
    if (actualHash.empty()) {
      status.SetError(cmStrCat("DOWNLOAD cannot compute hash on download\n"
                               "  for file: \"",
                               file, '"'));
      return false;
    }

    if (expectedHash != actualHash) {
      if (!statusVar.empty() && res == 0) {
        status.GetMakefile().AddDefinition(statusVar,
                                           "1;HASH mismatch: "
                                           "expected: " +
                                             expectedHash +
                                             " actual: " + actualHash);
      }

      status.SetError(cmStrCat("DOWNLOAD HASH mismatch\n"
                               "  for file: \"",
                               file,
                               "\"\n"
                               "    expected hash: \"",
                               expectedHash,
                               "\"\n"
                               "      actual hash: \"",
                               actualHash, "\"\n"));
      return false;
    }
  }

  return true;
#else
  status.SetError("DOWNLOAD not supported by bootstrap cmake.");
  return false;
#endif
}

bool HandleUploadCommand(std::vector<std::string> const& args,
                         cmExecutionStatus& status)
{
#if !defined(CMAKE_BOOTSTRAP)
  if (args.size() < 3) {
    status.SetError("UPLOAD must be called with at least three arguments.");
    return false;
  }
  auto i = args.begin();
  ++i;
  std::string filename = *i;
  ++i;
  std::string url = *i;
  ++i;

  long timeout = 0;
  long inactivity_timeout = 0;
  std::string logVar;
  std::string statusVar;
  bool showProgress = false;
  cm::optional<std::string> tlsVersionOpt;
  cm::optional<bool> tlsVerifyOpt;
  cmValue cainfo = status.GetMakefile().GetDefinition("CMAKE_TLS_CAINFO");
  std::string userpwd;
  std::string netrc_level =
    status.GetMakefile().GetSafeDefinition("CMAKE_NETRC");
  std::string netrc_file =
    status.GetMakefile().GetSafeDefinition("CMAKE_NETRC_FILE");

  std::vector<std::string> curl_headers;

  while (i != args.end()) {
    if (*i == "TIMEOUT") {
      ++i;
      if (i != args.end()) {
        timeout = atol(i->c_str());
      } else {
        status.SetError("UPLOAD missing time for TIMEOUT.");
        return false;
      }
    } else if (*i == "INACTIVITY_TIMEOUT") {
      ++i;
      if (i != args.end()) {
        inactivity_timeout = atol(i->c_str());
      } else {
        status.SetError("UPLOAD missing time for INACTIVITY_TIMEOUT.");
        return false;
      }
    } else if (*i == "LOG") {
      ++i;
      if (i == args.end()) {
        status.SetError("UPLOAD missing VAR for LOG.");
        return false;
      }
      logVar = *i;
    } else if (*i == "STATUS") {
      ++i;
      if (i == args.end()) {
        status.SetError("UPLOAD missing VAR for STATUS.");
        return false;
      }
      statusVar = *i;
    } else if (*i == "SHOW_PROGRESS") {
      showProgress = true;
    } else if (*i == "TLS_VERSION") {
      ++i;
      if (i != args.end()) {
        tlsVersionOpt = *i;
      } else {
        status.SetError("UPLOAD missing value for TLS_VERSION.");
        return false;
      }
    } else if (*i == "TLS_VERIFY") {
      ++i;
      if (i != args.end()) {
        tlsVerifyOpt = cmIsOn(*i);
      } else {
        status.SetError("UPLOAD missing bool value for TLS_VERIFY.");
        return false;
      }
    } else if (*i == "TLS_CAINFO") {
      ++i;
      if (i != args.end()) {
        cainfo = cmValue(*i);
      } else {
        status.SetError("UPLOAD missing file value for TLS_CAINFO.");
        return false;
      }
    } else if (*i == "NETRC_FILE") {
      ++i;
      if (i != args.end()) {
        netrc_file = *i;
      } else {
        status.SetError("UPLOAD missing file value for NETRC_FILE.");
        return false;
      }
    } else if (*i == "NETRC") {
      ++i;
      if (i != args.end()) {
        netrc_level = *i;
      } else {
        status.SetError("UPLOAD missing level value for NETRC.");
        return false;
      }
    } else if (*i == "USERPWD") {
      ++i;
      if (i == args.end()) {
        status.SetError("UPLOAD missing string for USERPWD.");
        return false;
      }
      userpwd = *i;
    } else if (*i == "HTTPHEADER") {
      ++i;
      if (i == args.end()) {
        status.SetError("UPLOAD missing string for HTTPHEADER.");
        return false;
      }
      curl_headers.push_back(*i);
    } else {
      // Do not return error for compatibility reason.
      status.GetMakefile().IssueDiagnostic(
        cmDiagnostics::CMD_AUTHOR, cmStrCat("Unexpected argument: ", *i));
    }

    ++i;
  }

  if (!tlsVerifyOpt.has_value()) {
    if (cmValue v = status.GetMakefile().GetDefinition("CMAKE_TLS_VERIFY")) {
      tlsVerifyOpt = v.IsOn();
    }
  }
  if (!tlsVerifyOpt.has_value()) {
    if (cm::optional<std::string> v =
          cmSystemTools::GetEnvVar("CMAKE_TLS_VERIFY")) {
      tlsVerifyOpt = cmIsOn(*v);
    }
  }
  bool tlsVerifyDefaulted = false;
  if (!tlsVerifyOpt.has_value()) {
    tlsVerifyOpt = TLS_VERIFY_DEFAULT;
    tlsVerifyDefaulted = true;
  }

  if (!tlsVersionOpt.has_value()) {
    if (cmValue v = status.GetMakefile().GetDefinition("CMAKE_TLS_VERSION")) {
      tlsVersionOpt = *v;
    }
  }
  if (!tlsVersionOpt.has_value()) {
    if (cm::optional<std::string> v =
          cmSystemTools::GetEnvVar("CMAKE_TLS_VERSION")) {
      tlsVersionOpt = std::move(v);
    }
  }
  bool tlsVersionDefaulted = false;
  if (!tlsVersionOpt.has_value()) {
    tlsVersionOpt = TLS_VERSION_DEFAULT;
    tlsVersionDefaulted = true;
  }

  // Open file for reading:
  //
  FILE* fin = cmsys::SystemTools::Fopen(filename, "rb");
  if (!fin) {
    std::string errStr =
      cmStrCat("UPLOAD cannot open file '", filename, "' for reading.");
    status.SetError(errStr);
    return false;
  }

  unsigned long file_size = cmsys::SystemTools::FileLength(filename);

  url = CurlCompatFileURL(url);

  ::CURL* curl;
  cm_curl_global_init(CURL_GLOBAL_DEFAULT);
  curl = cm_curl_easy_init();
  if (!curl) {
    status.SetError("UPLOAD error initializing curl.");
    fclose(fin);
    return false;
  }

  cURLEasyGuard g_curl(curl);

  // enable HTTP ERROR parsing
  ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
  check_curl_result(res, "UPLOAD cannot set fail on error flag: ");

  // enable uploading
  res = ::curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
  check_curl_result(res, "UPLOAD cannot set upload flag: ");

  res = ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
  check_curl_result(res, "UPLOAD cannot set url: ");

  res =
    ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cmWriteToMemoryCallback);
  check_curl_result(res, "UPLOAD cannot set write function: ");

  res = ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
                           cmFileCommandCurlDebugCallback);
  check_curl_result(res, "UPLOAD cannot set debug function: ");

  if (tlsVersionOpt.has_value()) {
    if (cm::optional<int> v = cmCurlParseTLSVersion(*tlsVersionOpt)) {
      res = ::curl_easy_setopt(curl, CURLOPT_SSLVERSION, *v);
      if (tlsVersionDefaulted && res == CURLE_NOT_BUILT_IN) {
        res = CURLE_OK;
      }
      check_curl_result(
        res,
        cmStrCat("UPLOAD cannot set TLS/SSL version ", *tlsVersionOpt, ": "));
    } else {
      status.SetError(
        cmStrCat("UPLOAD given unknown TLS/SSL version ", *tlsVersionOpt));
      return false;
    }
  }

  // check to see if TLS verification is requested
  if (tlsVerifyOpt.has_value() && tlsVerifyOpt.value()) {
    res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
    check_curl_result(res, "UPLOAD cannot set TLS/SSL Verify on: ");
  } else {
    res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    check_curl_result(res, "UPLOAD cannot set TLS/SSL Verify off: ");
  }

  // check to see if a CAINFO file has been specified
  // command arg comes first
  std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo);
  if (!cainfo_err.empty()) {
    status.SetError(cainfo_err);
    return false;
  }

  cmFileCommandVectorOfChar chunkResponse;
  cmFileCommandVectorOfChar chunkDebug;

  res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunkResponse);
  check_curl_result(res, "UPLOAD cannot set write data: ");

  res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &chunkDebug);
  check_curl_result(res, "UPLOAD cannot set debug data: ");

  res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
  check_curl_result(res, "UPLOAD cannot set follow-redirect option: ");

  if (!logVar.empty()) {
    res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
    check_curl_result(res, "UPLOAD cannot set verbose: ");
  }

  if (timeout > 0) {
    res = ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
    check_curl_result(res, "UPLOAD cannot set timeout: ");
  }

  if (inactivity_timeout > 0) {
    // Give up if there is no progress for a long time.
    ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1);
    ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, inactivity_timeout);
  }

  // Need the progress helper's scope to last through the duration of
  // the curl_easy_perform call... so this object is declared at function
  // scope intentionally, rather than inside the "if(showProgress)"
  // block...
  //
  cURLProgressHelper helper(&status.GetMakefile(), "upload");

  if (showProgress) {
    res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
    check_curl_result(res, "UPLOAD cannot set noprogress value: ");

    res = ::curl_easy_setopt(curl, CM_CURLOPT_XFERINFOFUNCTION,
                             cmFileUploadProgressCallback);
    check_curl_result(res, "UPLOAD cannot set progress function: ");

    res = ::curl_easy_setopt(curl, CURLOPT_PROGRESSDATA,
                             reinterpret_cast<void*>(&helper));
    check_curl_result(res, "UPLOAD cannot set progress data: ");
  }

  // now specify which file to upload
  res = ::curl_easy_setopt(curl, CURLOPT_INFILE, fin);
  check_curl_result(res, "UPLOAD cannot set input file: ");

  // and give the size of the upload (optional)
  res =
    ::curl_easy_setopt(curl, CURLOPT_INFILESIZE, static_cast<long>(file_size));
  check_curl_result(res, "UPLOAD cannot set input file size: ");

  if (!userpwd.empty()) {
    res = ::curl_easy_setopt(curl, CURLOPT_USERPWD, userpwd.c_str());
    check_curl_result(res, "UPLOAD cannot set user password: ");
  }

  // check to see if netrc parameters have been specified
  // local command args takes precedence over CMAKE_NETRC*
  netrc_level = cmSystemTools::UpperCase(netrc_level);
  std::string const& netrc_option_err =
    cmCurlSetNETRCOption(curl, netrc_level, netrc_file);
  if (!netrc_option_err.empty()) {
    status.SetError(netrc_option_err);
    return false;
  }

  struct curl_slist* headers = nullptr;
  for (std::string const& h : curl_headers) {
    headers = ::curl_slist_append(headers, h.c_str());
  }
  ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

  res = ::curl_easy_perform(curl);

  ::curl_slist_free_all(headers);

  /* always cleanup */
  g_curl.release();
  ::curl_easy_cleanup(curl);

  if (!statusVar.empty()) {
    std::string m = curl_easy_strerror(res);
    if ((res == CURLE_SSL_CONNECT_ERROR ||
         res == CURLE_PEER_FAILED_VERIFICATION) &&
        tlsVerifyDefaulted) {
      m = cmStrCat(
        std::move(m),
        ".  If this is due to https certificate verification failure, one may "
        "set environment variable CMAKE_TLS_VERIFY=0 to suppress it.");
    }
    status.GetMakefile().AddDefinition(
      statusVar, cmStrCat(static_cast<int>(res), ";\"", std::move(m), '"'));
  }

  ::curl_global_cleanup();

  fclose(fin);
  fin = nullptr;

  if (!logVar.empty()) {
    std::string log;

    if (!chunkResponse.empty()) {
      chunkResponse.push_back(0);
      log += "Response:\n";
      log += chunkResponse.data();
      log += "\n";
    }

    if (!chunkDebug.empty()) {
      chunkDebug.push_back(0);
      log += "Debug:\n";
      log += chunkDebug.data();
      log += "\n";
    }

    status.GetMakefile().AddDefinition(logVar, log);
  }

  return true;
#else
  status.SetError("UPLOAD not supported by bootstrap cmake.");
  return false;
#endif
}

void AddEvaluationFile(std::string const& inputName,
                       std::string const& targetName,
                       std::string const& outputExpr,
                       std::string const& condition, bool inputIsContent,
                       std::string const& newLineCharacter, mode_t permissions,
                       cmExecutionStatus& status)
{
  cmListFileBacktrace lfbt = status.GetMakefile().GetBacktrace();

  cmGeneratorExpression outputGe(*status.GetMakefile().GetCMakeInstance(),
                                 lfbt);
  std::unique_ptr<cmCompiledGeneratorExpression> outputCge =
    outputGe.Parse(outputExpr);

  cmGeneratorExpression conditionGe(*status.GetMakefile().GetCMakeInstance(),
                                    lfbt);
  std::unique_ptr<cmCompiledGeneratorExpression> conditionCge =
    conditionGe.Parse(condition);

  status.GetMakefile().AddEvaluationFile(
    inputName, targetName, std::move(outputCge), std::move(conditionCge),
    newLineCharacter, permissions, inputIsContent);
}

bool HandleGenerateCommand(std::vector<std::string> const& args,
                           cmExecutionStatus& status)
{
  if (args.size() < 5) {
    status.SetError("Incorrect arguments to GENERATE subcommand.");
    return false;
  }

  struct Arguments : public ArgumentParser::ParseResult
  {
    cm::optional<std::string> Output;
    cm::optional<std::string> Input;
    cm::optional<std::string> Content;
    cm::optional<std::string> Condition;
    cm::optional<std::string> Target;
    cm::optional<std::string> NewLineStyle;
    bool NoSourcePermissions = false;
    bool UseSourcePermissions = false;
    ArgumentParser::NonEmpty<std::vector<std::string>> FilePermissions;
    std::vector<cm::string_view> ParsedKeywords;
  };

  static auto const parser =
    cmArgumentParser<Arguments>{}
      .Bind("OUTPUT"_s, &Arguments::Output)
      .Bind("INPUT"_s, &Arguments::Input)
      .Bind("CONTENT"_s, &Arguments::Content)
      .Bind("CONDITION"_s, &Arguments::Condition)
      .Bind("TARGET"_s, &Arguments::Target)
      .Bind("NO_SOURCE_PERMISSIONS"_s, &Arguments::NoSourcePermissions)
      .Bind("USE_SOURCE_PERMISSIONS"_s, &Arguments::UseSourcePermissions)
      .Bind("FILE_PERMISSIONS"_s, &Arguments::FilePermissions)
      .Bind("NEWLINE_STYLE"_s, &Arguments::NewLineStyle)
      .BindParsedKeywords(&Arguments::ParsedKeywords);

  std::vector<std::string> unparsedArguments;
  Arguments const arguments =
    parser.Parse(cmMakeRange(args).advance(1), &unparsedArguments);

  if (arguments.MaybeReportError(status.GetMakefile())) {
    return true;
  }

  if (!unparsedArguments.empty()) {
    status.SetError("Unknown argument to GENERATE subcommand.");
    return false;
  }

  if (!arguments.Output || arguments.ParsedKeywords[0] != "OUTPUT"_s) {
    status.SetError("GENERATE requires OUTPUT as first option.");
    return false;
  }
  std::string const& output = *arguments.Output;

  if (!arguments.Input && !arguments.Content) {
    status.SetError("GENERATE requires INPUT or CONTENT option.");
    return false;
  }
  bool const inputIsContent = arguments.ParsedKeywords[1] == "CONTENT"_s;
  if (!inputIsContent && arguments.ParsedKeywords[1] != "INPUT") {
    status.SetError("Unknown argument to GENERATE subcommand.");
    return false;
  }
  std::string const& input =
    inputIsContent ? *arguments.Content : *arguments.Input;

  if (arguments.Condition && arguments.Condition->empty()) {
    status.SetError("CONDITION of sub-command GENERATE must not be empty "
                    "if specified.");
    return false;
  }
  std::string const& condition =
    arguments.Condition ? *arguments.Condition : std::string();

  if (arguments.Target && arguments.Target->empty()) {
    status.SetError("TARGET of sub-command GENERATE must not be empty "
                    "if specified.");
    return false;
  }
  std::string const& target =
    arguments.Target ? *arguments.Target : std::string();

  cmNewLineStyle newLineStyle;
  if (arguments.NewLineStyle) {
    std::string errorMessage;
    if (!newLineStyle.ReadFromArguments(args, errorMessage)) {
      status.SetError(cmStrCat("GENERATE ", errorMessage));
      return false;
    }
  }

  if (arguments.NoSourcePermissions && arguments.UseSourcePermissions) {
    status.SetError("given both NO_SOURCE_PERMISSIONS and "
                    "USE_SOURCE_PERMISSIONS. Only one option allowed.");
    return false;
  }

  if (!arguments.FilePermissions.empty()) {
    if (arguments.NoSourcePermissions) {
      status.SetError("given both NO_SOURCE_PERMISSIONS and "
                      "FILE_PERMISSIONS. Only one option allowed.");
      return false;
    }
    if (arguments.UseSourcePermissions) {
      status.SetError("given both USE_SOURCE_PERMISSIONS and "
                      "FILE_PERMISSIONS. Only one option allowed.");
      return false;
    }
  }

  if (arguments.UseSourcePermissions) {
    if (inputIsContent) {
      status.SetError("given USE_SOURCE_PERMISSIONS without a file INPUT.");
      return false;
    }
  }

  mode_t permissions = 0;
  if (arguments.NoSourcePermissions) {
    permissions |= cmFSPermissions::mode_owner_read;
    permissions |= cmFSPermissions::mode_owner_write;
    permissions |= cmFSPermissions::mode_group_read;
    permissions |= cmFSPermissions::mode_world_read;
  }

  if (!arguments.FilePermissions.empty()) {
    std::vector<std::string> invalidOptions;
    for (auto const& e : arguments.FilePermissions) {
      if (!cmFSPermissions::stringToModeT(e, permissions)) {
        invalidOptions.push_back(e);
      }
    }
    if (!invalidOptions.empty()) {
      std::ostringstream oss;
      oss << "given invalid permission ";
      for (auto i = 0u; i < invalidOptions.size(); i++) {
        if (i == 0u) {
          oss << "\"" << invalidOptions[i] << "\"";
        } else {
          oss << ",\"" << invalidOptions[i] << "\"";
        }
      }
      oss << ".";
      status.SetError(oss.str());
      return false;
    }
  }

  AddEvaluationFile(input, target, output, condition, inputIsContent,
                    newLineStyle.GetCharacters(), permissions, status);
  return true;
}

bool HandleLockCommand(std::vector<std::string> const& args,
                       cmExecutionStatus& status)
{
#if !defined(CMAKE_BOOTSTRAP)
  // Default values
  bool directory = false;
  bool release = false;
  enum Guard
  {
    GUARD_FUNCTION,
    GUARD_FILE,
    GUARD_PROCESS
  };
  Guard guard = GUARD_PROCESS;
  std::string resultVariable;
  unsigned long timeout = static_cast<unsigned long>(-1);

  // Parse arguments
  if (args.size() < 2) {
    status.GetMakefile().IssueMessage(
      MessageType::FATAL_ERROR,
      "sub-command LOCK requires at least two arguments.");
    return false;
  }

  std::string path = args[1];
  for (unsigned i = 2; i < args.size(); ++i) {
    if (args[i] == "DIRECTORY") {
      directory = true;
    } else if (args[i] == "RELEASE") {
      release = true;
    } else if (args[i] == "GUARD") {
      ++i;
      char const* merr = "expected FUNCTION, FILE or PROCESS after GUARD";
      if (i >= args.size()) {
        status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, merr);
        return false;
      }
      if (args[i] == "FUNCTION") {
        guard = GUARD_FUNCTION;
      } else if (args[i] == "FILE") {
        guard = GUARD_FILE;
      } else if (args[i] == "PROCESS") {
        guard = GUARD_PROCESS;
      } else {
        status.GetMakefile().IssueMessage(
          MessageType::FATAL_ERROR,
          cmStrCat(merr, ", but got:\n  \"", args[i], "\"."));
        return false;
      }

    } else if (args[i] == "RESULT_VARIABLE") {
      ++i;
      if (i >= args.size()) {
        status.GetMakefile().IssueMessage(
          MessageType::FATAL_ERROR,
          "expected variable name after RESULT_VARIABLE");
        return false;
      }
      resultVariable = args[i];
    } else if (args[i] == "TIMEOUT") {
      ++i;
      if (i >= args.size()) {
        status.GetMakefile().IssueMessage(
          MessageType::FATAL_ERROR, "expected timeout value after TIMEOUT");
        return false;
      }
      long scanned;
      if (!cmStrToLong(args[i], &scanned) || scanned < 0) {
        status.GetMakefile().IssueMessage(
          MessageType::FATAL_ERROR,
          cmStrCat("TIMEOUT value \"", args[i],
                   "\" is not an unsigned integer."));
        return false;
      }
      timeout = static_cast<unsigned long>(scanned);
    } else {
      status.GetMakefile().IssueMessage(
        MessageType::FATAL_ERROR,
        cmStrCat("expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or "
                 "TIMEOUT\nbut got: \"",
                 args[i], "\"."));
      return false;
    }
  }

  if (directory) {
    path += "/cmake.lock";
  }

  // Unify path (remove '//', '/../', ...)
  path = cmSystemTools::CollapseFullPath(
    path, status.GetMakefile().GetCurrentSourceDirectory());

  // Create file and directories if needed
  std::string parentDir = cmSystemTools::GetParentDirectory(path);
  if (!cmSystemTools::MakeDirectory(parentDir)) {
    status.GetMakefile().IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat("directory\n  \"", parentDir,
               "\"\ncreation failed (check permissions)."));
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }
  FILE* file = cmsys::SystemTools::Fopen(path, "a");
  if (!file) {
    status.GetMakefile().IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat("file\n  \"", path,
               "\"\ncreation failed (check permissions)."));
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }
  fclose(file);

  // Actual lock/unlock
  cmFileLockPool& lockPool =
    status.GetMakefile().GetGlobalGenerator()->GetFileLockPool();

  cmFileLockResult fileLockResult(cmFileLockResult::MakeOk());
  if (release) {
    fileLockResult = lockPool.Release(path);
  } else {
    switch (guard) {
      case GUARD_FUNCTION:
        fileLockResult = lockPool.LockFunctionScope(path, timeout);
        break;
      case GUARD_FILE:
        fileLockResult = lockPool.LockFileScope(path, timeout);
        break;
      case GUARD_PROCESS:
        fileLockResult = lockPool.LockProcessScope(path, timeout);
        break;
      default:
        cmSystemTools::SetFatalErrorOccurred();
        return false;
    }
  }

  std::string const result = fileLockResult.GetOutputMessage();

  if (resultVariable.empty() && !fileLockResult.IsOk()) {
    status.GetMakefile().IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat("error locking file\n  \"", path, "\"\n", result, '.'));
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  if (!resultVariable.empty()) {
    status.GetMakefile().AddDefinition(resultVariable, result);
  }

  return true;
#else
  static_cast<void>(args);
  status.SetError("sub-command LOCK not implemented in bootstrap cmake");
  return false;
#endif
}

bool HandleTimestampCommand(std::vector<std::string> const& args,
                            cmExecutionStatus& status)
{
  if (args.size() < 3) {
    status.SetError("sub-command TIMESTAMP requires at least two arguments.");
    return false;
  }
  if (args.size() > 5) {
    status.SetError("sub-command TIMESTAMP takes at most four arguments.");
    return false;
  }

  unsigned int argsIndex = 1;

  std::string filename = args[argsIndex++];
  if (!cmsys::SystemTools::FileIsFullPath(filename)) {
    filename = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/',
                        filename);
  }

  std::string const& outputVariable = args[argsIndex++];

  std::string formatString;
  if (args.size() > argsIndex && args[argsIndex] != "UTC") {
    formatString = args[argsIndex++];
  }

  bool utcFlag = false;
  if (args.size() > argsIndex) {
    if (args[argsIndex] == "UTC") {
      utcFlag = true;
    } else {
      std::string e =
        cmStrCat(" TIMESTAMP sub-command does not recognize option ",
                 args[argsIndex], '.');
      status.SetError(e);
      return false;
    }
  }

  cmTimestamp timestamp;
  std::string result =
    timestamp.FileModificationTime(filename.c_str(), formatString, utcFlag);
  status.GetMakefile().AddDefinition(outputVariable, result);

  return true;
}

bool HandleSizeCommand(std::vector<std::string> const& args,
                       cmExecutionStatus& status)
{
  if (args.size() != 3) {
    status.SetError(
      cmStrCat(args[0], " requires a file name and output variable"));
    return false;
  }

  unsigned int argsIndex = 1;

  std::string const& filename = args[argsIndex++];

  std::string const& outputVariable = args[argsIndex++];

  if (!cmSystemTools::FileExists(filename, true)) {
    status.SetError(
      cmStrCat("SIZE requested of path that is not readable:\n  ", filename));
    return false;
  }

  status.GetMakefile().AddDefinition(
    outputVariable, std::to_string(cmSystemTools::FileLength(filename)));

  return true;
}

bool HandleReadSymlinkCommand(std::vector<std::string> const& args,
                              cmExecutionStatus& status)
{
  if (args.size() < 3) {
    status.SetError(
      cmStrCat(args[0], " requires a file name and output variable"));
    return false;
  }

  std::string const& filename = args[1];
  std::string const& outputVariable = args[2];

  struct Arguments
  {
    std::string Result;
  };

  static auto const parser =
    cmArgumentParser<Arguments>{}.Bind("RESULT"_s, &Arguments::Result);

  std::vector<std::string> unconsumedArgs;
  Arguments const arguments =
    parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs);
  if (!unconsumedArgs.empty()) {
    status.SetError(
      cmStrCat("READ_SYMLINK unknown argument:\n  ", unconsumedArgs.front()));
    return false;
  }

  std::string result;
  if (!cmSystemTools::ReadSymlink(filename, result)) {
    std::string const error = cmStrCat(
      "READ_SYMLINK requested of path that is not a symlink:\n  ", filename);
    if (!arguments.Result.empty()) {
      status.GetMakefile().AddDefinition(arguments.Result, error);
      return true;
    }
    status.SetError(error);
    return false;
  }

  status.GetMakefile().AddDefinition(outputVariable, result);
  if (!arguments.Result.empty()) {
    status.GetMakefile().AddDefinition(arguments.Result, "0");
  }

  return true;
}

bool HandleCreateLinkCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
{
  if (args.size() < 3) {
    status.SetError("CREATE_LINK must be called with at least two additional "
                    "arguments");
    return false;
  }

  std::string const& fileName = args[1];
  std::string const& newFileName = args[2];

  struct Arguments
  {
    std::string Result;
    bool CopyOnError = false;
    bool Symbolic = false;
  };

  static auto const parser =
    cmArgumentParser<Arguments>{}
      .Bind("RESULT"_s, &Arguments::Result)
      .Bind("COPY_ON_ERROR"_s, &Arguments::CopyOnError)
      .Bind("SYMBOLIC"_s, &Arguments::Symbolic);

  std::vector<std::string> unconsumedArgs;
  Arguments const arguments =
    parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs);

  if (!unconsumedArgs.empty()) {
    status.SetError(cmStrCat("unknown argument: \"",
                             std::move(unconsumedArgs.front()), '\"'));
    return false;
  }

  // The system error message generated in the operation.
  std::string result;

  // Check if the paths are distinct.
  if (fileName == newFileName) {
    result = "CREATE_LINK cannot use same file and newfile";
    if (!arguments.Result.empty()) {
      status.GetMakefile().AddDefinition(arguments.Result, result);
      return true;
    }
    status.SetError(result);
    return false;
  }

  cmPolicies::PolicyStatus const cmp0205 =
    status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0205);

  // Hard link requires original file to exist.
  if (!arguments.Symbolic &&
      (!cmSystemTools::PathExists(fileName) ||
       (cmp0205 != cmPolicies::NEW && !cmSystemTools::FileExists(fileName)))) {
    result =
      cmStrCat("Cannot hard link \'", fileName, "\' as it does not exist.");
    if (!arguments.Result.empty()) {
      status.GetMakefile().AddDefinition(arguments.Result, result);
      return true;
    }
    status.SetError(result);
    return false;
  }

  // Check if the new file already exists and remove it.
  if (cmSystemTools::PathExists(newFileName)) {
    cmsys::Status rmStatus;
    if (cmp0205 == cmPolicies::NEW && arguments.CopyOnError &&
        cmSystemTools::FileIsDirectory(newFileName) &&
        !cmSystemTools::FileIsSymlink(newFileName)) {
      rmStatus = cmSystemTools::RepeatedRemoveDirectory(newFileName);
    } else {
      rmStatus = cmSystemTools::RemoveFile(newFileName);
    }
    if (!rmStatus) {
      std::string err = cmStrCat("Failed to create link '", newFileName,
                                 "' because existing path cannot be removed: ",
                                 rmStatus.GetString(), '\n');

      if (!arguments.Result.empty()) {
        status.GetMakefile().AddDefinition(arguments.Result, err);
        return true;
      }
      status.SetError(err);
      return false;
    }
  }

  bool const sourceIsDirectory = cmSystemTools::FileIsDirectory(fileName);

  // Whether the operation completed successfully.
  bool completed = false;

  // Check if the command requires a symbolic link.
  if (arguments.Symbolic) {
    cmsys::Status linked =
      cmSystemTools::CreateSymlinkQuietly(fileName, newFileName);
    if (linked) {
      completed = true;
    } else {
      result = cmStrCat("failed to create symbolic link '", newFileName,
                        "': ", linked.GetString());
    }
  } else {
    bool needToTry = true;
    if (sourceIsDirectory) {
      if (cmp0205 == cmPolicies::NEW) {
        needToTry = false;
      } else if (cmp0205 == cmPolicies::WARN && arguments.CopyOnError) {
        status.GetMakefile().IssueDiagnostic(
          cmDiagnostics::CMD_AUTHOR,
          cmStrCat("Path\n  ", fileName,
                   "\nis a directory. Hard link creation is not supported "
                   "for directories.\n",
                   cmPolicies::GetPolicyWarning(cmPolicies::CMP0205)));
      }
    }

    if (needToTry) {
      cmsys::Status linked =
        cmSystemTools::CreateLinkQuietly(fileName, newFileName);
      if (linked) {
        completed = true;
      } else {
        result = cmStrCat("failed to create link '", newFileName,
                          "': ", linked.GetString());
      }
    } else {
      result =
        cmStrCat("failed to create link '", newFileName, "': not supported");
    }
  }

  if (cmp0205 == cmPolicies::WARN && arguments.CopyOnError &&
      sourceIsDirectory) {
    status.GetMakefile().IssueDiagnostic(
      cmDiagnostics::CMD_AUTHOR,
      cmStrCat("Path\n  ", fileName,
               "\nis a directory. It will be copied "
               "recursively when CMP0205 is set to NEW.\n",
               cmPolicies::GetPolicyWarning(cmPolicies::CMP0205)));
  }

  // Check if copy-on-error is enabled in the arguments.
  if (!completed && arguments.CopyOnError) {
    cmsys::Status copied;
    if (cmp0205 == cmPolicies::NEW && sourceIsDirectory) {
      copied = cmsys::SystemTools::CopyADirectory(fileName, newFileName);
    } else {
      copied = cmsys::SystemTools::CopyFileAlways(fileName, newFileName);
    }

    if (copied) {
      completed = true;
    } else {
      result = "Copy failed: " + copied.GetString();
    }
  }

  // Check if the operation was successful.
  if (completed) {
    result = "0";
  } else if (arguments.Result.empty()) {
    // The operation failed and the result is not reported in a variable.
    status.SetError(result);
    return false;
  }

  if (!arguments.Result.empty()) {
    status.GetMakefile().AddDefinition(arguments.Result, result);
  }

  return true;
}

bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
                                         cmExecutionStatus& status)
{
  std::string platform =
    status.GetMakefile().GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME");
  if (!cmRuntimeDependencyArchive::PlatformSupportsRuntimeDependencies(
        platform)) {
    status.SetError(
      cmStrCat("GET_RUNTIME_DEPENDENCIES is not supported on system \"",
               platform, '"'));
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  if (status.GetMakefile().GetState()->GetRole() == cmState::Role::Project) {
    status.GetMakefile().IssueDiagnostic(
      cmDiagnostics::CMD_AUTHOR,
      "You have used file(GET_RUNTIME_DEPENDENCIES)"
      " in project mode. This is probably not what "
      "you intended to do. Instead, please consider"
      " using it in an install(CODE) or "
      "install(SCRIPT) command. For example:"
      "\n  install(CODE [["
      "\n    file(GET_RUNTIME_DEPENDENCIES"
      "\n      # ..."
      "\n      )"
      "\n    ]])");
  }

  struct Arguments : public ArgumentParser::ParseResult
  {
    std::string ResolvedDependenciesVar;
    std::string UnresolvedDependenciesVar;
    std::string ConflictingDependenciesPrefix;
    std::string RPathPrefix;
    std::string BundleExecutable;
    ArgumentParser::MaybeEmpty<std::vector<std::string>> Executables;
    ArgumentParser::MaybeEmpty<std::vector<std::string>> Libraries;
    ArgumentParser::MaybeEmpty<std::vector<std::string>> Directories;
    ArgumentParser::MaybeEmpty<std::vector<std::string>> Modules;
    ArgumentParser::MaybeEmpty<std::vector<std::string>> PreIncludeRegexes;
    ArgumentParser::MaybeEmpty<std::vector<std::string>> PreExcludeRegexes;
    ArgumentParser::MaybeEmpty<std::vector<std::string>> PostIncludeRegexes;
    ArgumentParser::MaybeEmpty<std::vector<std::string>> PostExcludeRegexes;
    ArgumentParser::MaybeEmpty<std::vector<std::string>> PostIncludeFiles;
    ArgumentParser::MaybeEmpty<std::vector<std::string>> PostExcludeFiles;
    ArgumentParser::MaybeEmpty<std::vector<std::string>>
      PostExcludeFilesStrict;
  };

  static auto const parser =
    cmArgumentParser<Arguments>{}
      .Bind("RESOLVED_DEPENDENCIES_VAR"_s, &Arguments::ResolvedDependenciesVar)
      .Bind("UNRESOLVED_DEPENDENCIES_VAR"_s,
            &Arguments::UnresolvedDependenciesVar)
      .Bind("CONFLICTING_DEPENDENCIES_PREFIX"_s,
            &Arguments::ConflictingDependenciesPrefix)
      .Bind("RPATH_PREFIX"_s, &Arguments::RPathPrefix)
      .Bind("BUNDLE_EXECUTABLE"_s, &Arguments::BundleExecutable)
      .Bind("EXECUTABLES"_s, &Arguments::Executables)
      .Bind("LIBRARIES"_s, &Arguments::Libraries)
      .Bind("MODULES"_s, &Arguments::Modules)
      .Bind("DIRECTORIES"_s, &Arguments::Directories)
      .Bind("PRE_INCLUDE_REGEXES"_s, &Arguments::PreIncludeRegexes)
      .Bind("PRE_EXCLUDE_REGEXES"_s, &Arguments::PreExcludeRegexes)
      .Bind("POST_INCLUDE_REGEXES"_s, &Arguments::PostIncludeRegexes)
      .Bind("POST_EXCLUDE_REGEXES"_s, &Arguments::PostExcludeRegexes)
      .Bind("POST_INCLUDE_FILES"_s, &Arguments::PostIncludeFiles)
      .Bind("POST_EXCLUDE_FILES"_s, &Arguments::PostExcludeFiles)
      .Bind("POST_EXCLUDE_FILES_STRICT"_s, &Arguments::PostExcludeFilesStrict);

  std::vector<std::string> unrecognizedArguments;
  auto parsedArgs =
    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
  auto argIt = unrecognizedArguments.begin();
  if (argIt != unrecognizedArguments.end()) {
    status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, '"'));
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  if (parsedArgs.MaybeReportError(status.GetMakefile())) {
    cmSystemTools::SetFatalErrorOccurred();
    return true;
  }

  cmRuntimeDependencyArchive archive(
    status, parsedArgs.Directories, parsedArgs.BundleExecutable,
    parsedArgs.PreIncludeRegexes, parsedArgs.PreExcludeRegexes,
    parsedArgs.PostIncludeRegexes, parsedArgs.PostExcludeRegexes,
    std::move(parsedArgs.PostIncludeFiles),
    std::move(parsedArgs.PostExcludeFiles),
    std::move(parsedArgs.PostExcludeFilesStrict));
  if (!archive.Prepare()) {
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  if (!archive.GetRuntimeDependencies(
        parsedArgs.Executables, parsedArgs.Libraries, parsedArgs.Modules)) {
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  std::vector<std::string> deps;
  std::vector<std::string> unresolvedDeps;
  std::vector<std::string> conflictingDeps;
  for (auto const& val : archive.GetResolvedPaths()) {
    bool unique = true;
    auto it = val.second.begin();
    assert(it != val.second.end());
    auto const& firstPath = *it;
    while (++it != val.second.end()) {
      if (!cmSystemTools::SameFile(firstPath, *it)) {
        unique = false;
        break;
      }
    }

    if (unique) {
      deps.push_back(firstPath);
      if (!parsedArgs.RPathPrefix.empty()) {
        status.GetMakefile().AddDefinition(
          cmStrCat(parsedArgs.RPathPrefix, '_', firstPath),
          cmList::to_string(archive.GetRPaths().at(firstPath)));
      }
    } else if (!parsedArgs.ConflictingDependenciesPrefix.empty()) {
      conflictingDeps.push_back(val.first);
      std::vector<std::string> paths;
      paths.insert(paths.begin(), val.second.begin(), val.second.end());
      std::string varName =
        cmStrCat(parsedArgs.ConflictingDependenciesPrefix, '_', val.first);
      std::string pathsStr = cmList::to_string(paths);
      status.GetMakefile().AddDefinition(varName, pathsStr);
    } else {
      std::ostringstream e;
      e << "Multiple conflicting paths found for " << val.first << ":";
      for (auto const& path : val.second) {
        e << "\n  " << path;
      }
      status.SetError(e.str());
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }
  }
  if (!archive.GetUnresolvedPaths().empty()) {
    if (!parsedArgs.UnresolvedDependenciesVar.empty()) {
      unresolvedDeps.insert(unresolvedDeps.begin(),
                            archive.GetUnresolvedPaths().begin(),
                            archive.GetUnresolvedPaths().end());
    } else {
      std::ostringstream e;
      e << "Could not resolve runtime dependencies:";
      for (auto const& path : archive.GetUnresolvedPaths()) {
        e << "\n  " << path;
      }
      status.SetError(e.str());
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }
  }

  if (!parsedArgs.ResolvedDependenciesVar.empty()) {
    std::string val = cmList::to_string(deps);
    status.GetMakefile().AddDefinition(parsedArgs.ResolvedDependenciesVar,
                                       val);
  }
  if (!parsedArgs.UnresolvedDependenciesVar.empty()) {
    std::string val = cmList::to_string(unresolvedDeps);
    status.GetMakefile().AddDefinition(parsedArgs.UnresolvedDependenciesVar,
                                       val);
  }
  if (!parsedArgs.ConflictingDependenciesPrefix.empty()) {
    std::string val = cmList::to_string(conflictingDeps);
    status.GetMakefile().AddDefinition(
      parsedArgs.ConflictingDependenciesPrefix + "_FILENAMES", val);
  }
  return true;
}

bool HandleConfigureCommand(std::vector<std::string> const& args,
                            cmExecutionStatus& status)
{
  struct Arguments : public ArgumentParser::ParseResult
  {
    cm::optional<std::string> Output;
    cm::optional<std::string> Content;
    bool EscapeQuotes = false;
    bool AtOnly = false;
    // "NEWLINE_STYLE" requires one value, but we use a custom check below.
    ArgumentParser::Maybe<std::string> NewlineStyle;
  };

  static auto const parser =
    cmArgumentParser<Arguments>{}
      .Bind("OUTPUT"_s, &Arguments::Output)
      .Bind("CONTENT"_s, &Arguments::Content)
      .Bind("ESCAPE_QUOTES"_s, &Arguments::EscapeQuotes)
      .Bind("@ONLY"_s, &Arguments::AtOnly)
      .Bind("NEWLINE_STYLE"_s, &Arguments::NewlineStyle);

  std::vector<std::string> unrecognizedArguments;
  auto parsedArgs =
    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);

  auto argIt = unrecognizedArguments.begin();
  if (argIt != unrecognizedArguments.end()) {
    status.SetError(
      cmStrCat("CONFIGURE Unrecognized argument: \"", *argIt, '"'));
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  if (parsedArgs.MaybeReportError(status.GetMakefile())) {
    cmSystemTools::SetFatalErrorOccurred();
    return true;
  }

  if (!parsedArgs.Output) {
    status.SetError("CONFIGURE OUTPUT option is mandatory.");
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }
  if (!parsedArgs.Content) {
    status.SetError("CONFIGURE CONTENT option is mandatory.");
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  std::string errorMessage;
  cmNewLineStyle newLineStyle;
  if (!newLineStyle.ReadFromArguments(args, errorMessage)) {
    status.SetError(cmStrCat("CONFIGURE ", errorMessage));
    return false;
  }

  // Check for generator expressions
  std::string outputFile = cmSystemTools::CollapseFullPath(
    *parsedArgs.Output, status.GetMakefile().GetCurrentBinaryDirectory());

  std::string::size_type pos = outputFile.find_first_of("<>");
  if (pos != std::string::npos) {
    status.SetError(cmStrCat("CONFIGURE called with OUTPUT containing a \"",
                             outputFile[pos],
                             "\".  This character is not allowed."));
    return false;
  }

  cmMakefile& makeFile = status.GetMakefile();
  if (!makeFile.CanIWriteThisFile(outputFile)) {
    cmSystemTools::Error("Attempt to write file: " + outputFile +
                         " into a source directory.");
    return false;
  }

  cmSystemTools::ConvertToUnixSlashes(outputFile);

  // Re-generate if non-temporary outputs are missing.
  // when we finalize the configuration we will remove all
  // output files that now don't exist.
  makeFile.AddCMakeOutputFile(outputFile);

  // Create output directory
  std::string::size_type const slashPos = outputFile.rfind('/');
  if (slashPos != std::string::npos) {
    std::string const path = outputFile.substr(0, slashPos);
    cmSystemTools::MakeDirectory(path);
  }

  std::string newLineCharacters = "\n";
  bool open_with_binary_flag = false;
  if (newLineStyle.IsValid()) {
    newLineCharacters = newLineStyle.GetCharacters();
    open_with_binary_flag = true;
  }

  cmGeneratedFileStream fout;
  fout.Open(outputFile, false, open_with_binary_flag);
  if (!fout) {
    cmSystemTools::Error("Could not open file for write in copy operation " +
                         outputFile);
    cmSystemTools::ReportLastSystemError("");
    return false;
  }
  fout.SetCopyIfDifferent(true);

  // copy input to output and expand variables from input at the same time
  std::stringstream sin(*parsedArgs.Content, std::ios::in);
  std::string inLine;
  std::string outLine;
  bool hasNewLine = false;
  while (cmSystemTools::GetLineFromStream(sin, inLine, &hasNewLine)) {
    outLine.clear();
    makeFile.ConfigureString(inLine, outLine, parsedArgs.AtOnly,
                             parsedArgs.EscapeQuotes);
    fout << outLine;
    if (hasNewLine || newLineStyle.IsValid()) {
      fout << newLineCharacters;
    }
  }

  // close file before attempting to copy
  fout.close();

  return true;
}

bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
                                cmExecutionStatus& status)
{
  struct Arguments : public ArgumentParser::ParseResult
  {
    std::string Output;
    std::string Format;
    std::string Compression;
    std::string CompressionLevel;
    std::string Encoding;
    // "MTIME" should require one value, but it has long been accidentally
    // accepted without one and treated as if an empty value were given.
    // Fixing this would require a policy.
    ArgumentParser::Maybe<std::string> MTime;
    std::string Threads;
    std::string WorkingDirectory;
    bool Verbose = false;
    // "PATHS" requires at least one value, but use a custom check below.
    ArgumentParser::MaybeEmpty<std::vector<std::string>> Paths;
  };

  static auto const parser =
    cmArgumentParser<Arguments>{}
      .Bind("OUTPUT"_s, &Arguments::Output)
      .Bind("FORMAT"_s, &Arguments::Format)
      .Bind("COMPRESSION"_s, &Arguments::Compression)
      .Bind("COMPRESSION_LEVEL"_s, &Arguments::CompressionLevel)
      .Bind("ENCODING"_s, &Arguments::Encoding)
      .Bind("MTIME"_s, &Arguments::MTime)
      .Bind("THREADS"_s, &Arguments::Threads)
      .Bind("WORKING_DIRECTORY"_s, &Arguments::WorkingDirectory)
      .Bind("VERBOSE"_s, &Arguments::Verbose)
      .Bind("PATHS"_s, &Arguments::Paths);

  std::vector<std::string> unrecognizedArguments;
  auto parsedArgs =
    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
  auto argIt = unrecognizedArguments.begin();
  if (argIt != unrecognizedArguments.end()) {
    status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, '"'));
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  if (parsedArgs.MaybeReportError(status.GetMakefile())) {
    cmSystemTools::SetFatalErrorOccurred();
    return true;
  }

  char const* knownFormats[] = {
    "7zip", "gnutar", "pax", "paxr", "raw", "zip"
  };

  if (!parsedArgs.Format.empty() &&
      !cm::contains(knownFormats, parsedArgs.Format)) {
    status.SetError(
      cmStrCat("archive format ", parsedArgs.Format, " not supported"));
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  static std::map<std::string, cmSystemTools::cmTarCompression>
    compressionTypeMap = { { "None", cmSystemTools::TarCompressNone },
                           { "BZip2", cmSystemTools::TarCompressBZip2 },
                           { "Deflate", cmSystemTools::TarCompressGZip },
                           { "GZip", cmSystemTools::TarCompressGZip },
                           { "LZMA", cmSystemTools::TarCompressLZMA },
                           { "LZMA2", cmSystemTools::TarCompressXZ },
                           { "PPMd", cmSystemTools::TarCompressPPMd },
                           { "XZ", cmSystemTools::TarCompressXZ },
                           { "Zstd", cmSystemTools::TarCompressZstd } };

  cmSystemTools::cmTarCompression compress = cmSystemTools::TarCompressAuto;
  auto typeIt = compressionTypeMap.find(parsedArgs.Compression);
  if (typeIt != compressionTypeMap.end()) {
    compress = typeIt->second;
  } else if (!parsedArgs.Compression.empty()) {
    status.SetError(cmStrCat("compression type ", parsedArgs.Compression,
                             " is not supported"));
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  if (compress == cmSystemTools::TarCompressPPMd &&
      parsedArgs.Format != "7zip") {
    status.SetError(cmStrCat("PPMd compression is not supported for ",
                             parsedArgs.Format, " format"));
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  int compressionLevel = 0;
  constexpr int minCompressionLevel = 0;
  int maxCompressionLevel = 9;
  if (compress == cmSystemTools::TarCompressZstd &&
      parsedArgs.Format != "zip") {
    maxCompressionLevel = 19;
  }

  if (!parsedArgs.CompressionLevel.empty()) {
    if (parsedArgs.CompressionLevel.size() != 1 &&
        !cmsysString_isdigit(parsedArgs.CompressionLevel[0])) {
      status.SetError(
        cmStrCat("compression level ", parsedArgs.CompressionLevel, " for ",
                 parsedArgs.Compression, " should be in range ",
                 minCompressionLevel, " to ", maxCompressionLevel));
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }
    compressionLevel = std::stoi(parsedArgs.CompressionLevel);
    if (compressionLevel < minCompressionLevel ||
        compressionLevel > maxCompressionLevel) {
      status.SetError(
        cmStrCat("compression level ", parsedArgs.CompressionLevel, " for ",
                 parsedArgs.Compression, " should be in range ",
                 minCompressionLevel, " to ", maxCompressionLevel));
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }
    if (compress == cmSystemTools::TarCompressNone) {
      status.SetError(
        cmStrCat("compression level is not supported for "
                 "compression \"None\". Provided compression level: ",
                 parsedArgs.CompressionLevel));
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }
  }

  // Use the single thread by default for backward compatibility
  int threads = 1;
  constexpr int minThreads = 0;
  if (!parsedArgs.Threads.empty()) {
    if (parsedArgs.Threads.size() != 1 &&
        !cmsysString_isdigit(parsedArgs.Threads[0])) {
      status.SetError(cmStrCat("number of threads ", parsedArgs.Threads,
                               " should be at least ", minThreads));
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }
    threads = std::stoi(parsedArgs.Threads);
    if (threads < minThreads) {
      status.SetError(cmStrCat("number of threads ", parsedArgs.Threads,
                               " should be at least ", minThreads));
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }
  }

  if (parsedArgs.Paths.empty()) {
    status.SetError("ARCHIVE_CREATE requires a non-empty list of PATHS");
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  if (parsedArgs.Encoding.empty()) {
    if (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0213) ==
        cmPolicies::NEW) {
      parsedArgs.Encoding = "UTF-8";
    } else {
      parsedArgs.Encoding = "OEM";
    }
  }

  if (!cmSystemTools::CreateTar(
        parsedArgs.Output, parsedArgs.Paths, parsedArgs.WorkingDirectory,
        compress, parsedArgs.Encoding, parsedArgs.Verbose, parsedArgs.MTime,
        parsedArgs.Format, compressionLevel, threads)) {
    status.SetError(cmStrCat("failed to compress: ", parsedArgs.Output));
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  return true;
}

bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
                                 cmExecutionStatus& status)
{
  struct Arguments : public ArgumentParser::ParseResult
  {
    std::string Input;
    std::string Encoding;
    bool Verbose = false;
    bool ListOnly = false;
    std::string Destination;
    ArgumentParser::MaybeEmpty<std::vector<std::string>> Patterns;
    bool Touch = false;
  };

  static auto const parser = cmArgumentParser<Arguments>{}
                               .Bind("INPUT"_s, &Arguments::Input)
                               .Bind("ENCODING"_s, &Arguments::Encoding)
                               .Bind("VERBOSE"_s, &Arguments::Verbose)
                               .Bind("LIST_ONLY"_s, &Arguments::ListOnly)
                               .Bind("DESTINATION"_s, &Arguments::Destination)
                               .Bind("PATTERNS"_s, &Arguments::Patterns)
                               .Bind("TOUCH"_s, &Arguments::Touch);

  std::vector<std::string> unrecognizedArguments;
  auto parsedArgs =
    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
  auto argIt = unrecognizedArguments.begin();
  if (argIt != unrecognizedArguments.end()) {
    status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, '"'));
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  if (parsedArgs.MaybeReportError(status.GetMakefile())) {
    cmSystemTools::SetFatalErrorOccurred();
    return true;
  }

  std::string inFile = parsedArgs.Input;

  if (parsedArgs.Encoding.empty()) {
    if (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0213) ==
        cmPolicies::NEW) {
      parsedArgs.Encoding = "UTF-8";
    } else {
      parsedArgs.Encoding = "OEM";
    }
  }

  if (parsedArgs.ListOnly) {
    if (!cmSystemTools::ListTar(inFile, parsedArgs.Patterns,
                                parsedArgs.Encoding, parsedArgs.Verbose)) {
      status.SetError(cmStrCat("failed to list: ", inFile));
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }
  } else {
    std::string destDir = status.GetMakefile().GetCurrentBinaryDirectory();
    if (!parsedArgs.Destination.empty()) {
      if (cmSystemTools::FileIsFullPath(parsedArgs.Destination)) {
        destDir = parsedArgs.Destination;
      } else {
        destDir = cmStrCat(destDir, '/', parsedArgs.Destination);
      }

      if (!cmSystemTools::MakeDirectory(destDir)) {
        status.SetError(cmStrCat("failed to create directory: ", destDir));
        cmSystemTools::SetFatalErrorOccurred();
        return false;
      }

      if (!cmSystemTools::FileIsFullPath(inFile)) {
        inFile =
          cmStrCat(cmSystemTools::GetLogicalWorkingDirectory(), '/', inFile);
      }
    }

    cmWorkingDirectory workdir(destDir);
    if (workdir.Failed()) {
      status.SetError(workdir.GetError());
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }

    if (!cmSystemTools::ExtractTar(
          inFile, parsedArgs.Patterns,
          parsedArgs.Touch ? cmSystemTools::cmTarExtractTimestamps::No
                           : cmSystemTools::cmTarExtractTimestamps::Yes,
          parsedArgs.Encoding, parsedArgs.Verbose)) {
      status.SetError(cmStrCat("failed to extract:\n  ", inFile));
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }
  }

  return true;
}

bool ValidateAndConvertPermissions(
  cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> const&
    permissions,
  mode_t& perms, cmExecutionStatus& status)
{
  if (!permissions) {
    return true;
  }
  for (auto const& i : *permissions) {
    if (!cmFSPermissions::stringToModeT(i, perms)) {
      status.SetError(i + " is an invalid permission specifier");
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }
  }
  return true;
}

bool SetPermissions(std::string const& filename, mode_t perms,
                    cmExecutionStatus& status)
{
  if (!cmSystemTools::SetPermissions(filename, perms)) {
    status.SetError("Failed to set permissions for " + filename);
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }
  return true;
}

bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
                            cmExecutionStatus& status)
{
  mode_t perms = 0;
  mode_t fperms = 0;
  mode_t dperms = 0;
  cmsys::Glob globber;

  globber.SetRecurse(recurse);
  globber.SetRecurseListDirs(recurse);

  struct Arguments : public ArgumentParser::ParseResult
  {
    cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
      Permissions;
    cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
      FilePermissions;
    cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
      DirectoryPermissions;
  };

  static auto const parser =
    cmArgumentParser<Arguments>{}
      .Bind("PERMISSIONS"_s, &Arguments::Permissions)
      .Bind("FILE_PERMISSIONS"_s, &Arguments::FilePermissions)
      .Bind("DIRECTORY_PERMISSIONS"_s, &Arguments::DirectoryPermissions);

  std::vector<std::string> pathEntries;
  Arguments parsedArgs =
    parser.Parse(cmMakeRange(args).advance(1), &pathEntries);

  // check validity of arguments
  if (!parsedArgs.Permissions && !parsedArgs.FilePermissions &&
      !parsedArgs.DirectoryPermissions) // no permissions given
  {
    status.SetError("No permissions given");
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  if (parsedArgs.Permissions && parsedArgs.FilePermissions &&
      parsedArgs.DirectoryPermissions) // all keywords are used
  {
    status.SetError("Remove either PERMISSIONS or FILE_PERMISSIONS or "
                    "DIRECTORY_PERMISSIONS from the invocation");
    cmSystemTools::SetFatalErrorOccurred();
    return false;
  }

  if (parsedArgs.MaybeReportError(status.GetMakefile())) {
    cmSystemTools::SetFatalErrorOccurred();
    return true;
  }

  // validate permissions
  bool validatePermissions =
    ValidateAndConvertPermissions(parsedArgs.Permissions, perms, status) &&
    ValidateAndConvertPermissions(parsedArgs.FilePermissions, fperms,
                                  status) &&
    ValidateAndConvertPermissions(parsedArgs.DirectoryPermissions, dperms,
                                  status);
  if (!validatePermissions) {
    return false;
  }

  std::vector<std::string> allPathEntries;

  if (recurse) {
    std::vector<std::string> tempPathEntries;
    for (auto const& i : pathEntries) {
      if (cmSystemTools::FileIsDirectory(i)) {
        globber.FindFiles(i + "/*");
        tempPathEntries = globber.GetFiles();
        allPathEntries.insert(allPathEntries.end(), tempPathEntries.begin(),
                              tempPathEntries.end());
        allPathEntries.emplace_back(i);
      } else {
        allPathEntries.emplace_back(i); // We validate path entries below
      }
    }
  } else {
    allPathEntries = std::move(pathEntries);
  }

  // chmod
  for (auto const& i : allPathEntries) {
    if (!(cmSystemTools::FileExists(i) || cmSystemTools::FileIsDirectory(i))) {
      status.SetError(cmStrCat("does not exist:\n  ", i));
      cmSystemTools::SetFatalErrorOccurred();
      return false;
    }

    if (cmSystemTools::FileExists(i, true)) {
      bool success = true;
      mode_t filePermissions = parsedArgs.FilePermissions ? fperms : perms;
      if (filePermissions) {
        success = SetPermissions(i, filePermissions, status);
      }
      if (!success) {
        return false;
      }
    }

    else if (cmSystemTools::FileIsDirectory(i)) {
      bool success = true;
      mode_t directoryPermissions =
        parsedArgs.DirectoryPermissions ? dperms : perms;
      if (directoryPermissions) {
        success = SetPermissions(i, directoryPermissions, status);
      }
      if (!success) {
        return false;
      }
    }
  }

  return true;
}

bool HandleChmodCommand(std::vector<std::string> const& args,
                        cmExecutionStatus& status)
{
  return HandleChmodCommandImpl(args, false, status);
}

bool HandleChmodRecurseCommand(std::vector<std::string> const& args,
                               cmExecutionStatus& status)
{
  return HandleChmodCommandImpl(args, true, status);
}

} // namespace

bool cmFileCommand(std::vector<std::string> const& args,
                   cmExecutionStatus& status)
{
  if (args.empty()) {
    status.SetError(
      "given no arguments, but it requires at least a sub-command.");
    return false;
  }

  static cmSubcommandTable const subcommand{
    { "WRITE"_s, HandleWriteCommand },
    { "APPEND"_s, HandleAppendCommand },
    { "DOWNLOAD"_s, HandleDownloadCommand },
    { "UPLOAD"_s, HandleUploadCommand },
    { "READ"_s, HandleReadCommand },
    { "MD5"_s, HandleHashCommand },
    { "SHA1"_s, HandleHashCommand },
    { "SHA224"_s, HandleHashCommand },
    { "SHA256"_s, HandleHashCommand },
    { "SHA384"_s, HandleHashCommand },
    { "SHA512"_s, HandleHashCommand },
    { "SHA3_224"_s, HandleHashCommand },
    { "SHA3_256"_s, HandleHashCommand },
    { "SHA3_384"_s, HandleHashCommand },
    { "SHA3_512"_s, HandleHashCommand },
    { "STRINGS"_s, HandleStringsCommand },
    { "GLOB"_s, HandleGlobCommand },
    { "GLOB_RECURSE"_s, HandleGlobRecurseCommand },
    { "MAKE_DIRECTORY"_s, HandleMakeDirectoryCommand },
    { "RENAME"_s, HandleRename },
    { "COPY_FILE"_s, HandleCopyFile },
    { "REMOVE"_s, HandleRemove },
    { "REMOVE_RECURSE"_s, HandleRemoveRecurse },
    { "COPY"_s, HandleCopyCommand },
    { "INSTALL"_s, HandleInstallCommand },
    { "DIFFERENT"_s, HandleDifferentCommand },
    { "RPATH_CHANGE"_s, HandleRPathChangeCommand },
    { "CHRPATH"_s, HandleRPathChangeCommand },
    { "RPATH_SET"_s, HandleRPathSetCommand },
    { "RPATH_CHECK"_s, HandleRPathCheckCommand },
    { "RPATH_REMOVE"_s, HandleRPathRemoveCommand },
    { "READ_ELF"_s, HandleReadElfCommand },
    { "READ_MACHO"_s, HandleReadMachoCommand },
    { "REAL_PATH"_s, HandleRealPathCommand },
    { "RELATIVE_PATH"_s, HandleRelativePathCommand },
    { "TO_CMAKE_PATH"_s, HandleCMakePathCommand },
    { "TO_NATIVE_PATH"_s, HandleNativePathCommand },
    { "TOUCH"_s, HandleTouchCommand },
    { "TOUCH_NOCREATE"_s, HandleTouchNocreateCommand },
    { "TIMESTAMP"_s, HandleTimestampCommand },
    { "GENERATE"_s, HandleGenerateCommand },
    { "LOCK"_s, HandleLockCommand },
    { "SIZE"_s, HandleSizeCommand },
    { "READ_SYMLINK"_s, HandleReadSymlinkCommand },
    { "CREATE_LINK"_s, HandleCreateLinkCommand },
    { "GET_RUNTIME_DEPENDENCIES"_s, HandleGetRuntimeDependenciesCommand },
    { "CONFIGURE"_s, HandleConfigureCommand },
    { "ARCHIVE_CREATE"_s, HandleArchiveCreateCommand },
    { "ARCHIVE_EXTRACT"_s, HandleArchiveExtractCommand },
    { "CHMOD"_s, HandleChmodCommand },
    { "CHMOD_RECURSE"_s, HandleChmodRecurseCommand },
  };

  return subcommand(args[0], args, status);
}
