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

#if !defined(_WIN32) && !defined(__sun) && !defined(__OpenBSD__)
// POSIX APIs are needed
// NOLINTNEXTLINE(bugprone-reserved-identifier)
#  define _POSIX_C_SOURCE 200809L
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) ||  \
  defined(__QNX__)
// For isascii
// NOLINTNEXTLINE(bugprone-reserved-identifier)
#  define _XOPEN_SOURCE 700
#endif
#if defined(__APPLE__)
// Restore Darwin APIs removed by _POSIX_C_SOURCE.
// NOLINTNEXTLINE(bugprone-reserved-identifier)
#  define _DARWIN_C_SOURCE
#endif

#ifndef __has_feature
#  define __has_feature(x) 0
#endif

#if !defined(__clang__) || __has_feature(cxx_thread_local)
#  define CM_HAVE_THREAD_LOCAL
#endif

#include "cmSystemTools.h"

#include <iterator>

#if defined(_WIN32) || defined(__APPLE__)
#  include <unordered_map>
#endif

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

#include <cm3p/uv.h>

#include "cmDuration.h"
#include "cmELF.h"
#include "cmMessageMetadata.h"
#include "cmPathResolver.h"
#include "cmProcessOutput.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmUVHandlePtr.h"
#include "cmUVProcessChain.h"
#include "cmUVStream.h"
#include "cmValue.h"
#include "cmWorkingDirectory.h"

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

#  include "cmArchiveWrite.h"
#  include "cmLocale.h"
#  ifndef __LA_INT64_T
#    define __LA_INT64_T la_int64_t
#  endif
#  ifndef __LA_SSIZE_T
#    define __LA_SSIZE_T la_ssize_t
#  endif
#endif

#if defined(CMake_USE_MACH_PARSER)
#  include "cmMachO.h"
#endif

#if defined(CMake_USE_XCOFF_PARSER)
#  include "cmXCOFF.h"
#endif

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iostream>
#include <memory>
#include <random>
#include <sstream>
#include <utility>
#include <vector>

#ifndef CM_HAVE_THREAD_LOCAL
#  include <mutex>
#endif

#include <fcntl.h>

#include "cmsys/Directory.hxx"
#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
#include "cmsys/System.h"

#if defined(_WIN32)
#  include <windows.h>

#  include <knownfolders.h>
#  include <shlobj.h>
// include wincrypt.h after windows.h
#  include <wincrypt.h>
#else
#  include <unistd.h>

#  include <sys/time.h>
#endif

#if defined(_WIN32) &&                                                        \
  (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__))
#  include <io.h>
#endif

#if defined(__APPLE__)
#  include <mach-o/dyld.h>
#endif

#ifdef __QNX__
#  include <malloc.h> /* for malloc/free on QNX */
#endif

#ifdef __linux__
#  include <linux/fs.h>

#  include <sys/ioctl.h>
#endif

#if !defined(_WIN32) && !defined(__ANDROID__)
#  include <sys/utsname.h>
#endif

#if defined(CMAKE_BOOTSTRAP) && defined(__sun) && defined(__i386)
#  define CMAKE_NO_MKDTEMP
#endif

#ifdef CMAKE_NO_MKDTEMP
#  include <dlfcn.h>
#endif

#ifndef CMAKE_NO_GETPWNAM
#  if defined(_WIN32)
#    define CMAKE_NO_GETPWNAM
#  endif
#endif
#ifndef CMAKE_NO_GETPWNAM
#  include <pwd.h>
#endif

#if defined(_MSC_VER) && _MSC_VER >= 1800
#  define CM_WINDOWS_DEPRECATED_GetVersionEx
#endif

namespace {

cmSystemTools::InterruptCallback s_InterruptCallback;
cmSystemTools::MessageCallback s_MessageCallback;
cmSystemTools::OutputCallback s_StderrCallback;
cmSystemTools::OutputCallback s_StdoutCallback;

std::string ResolveTildePath(std::string p)
{
  if (!p.empty() && p[0] == '~') {
    cm::optional<std::string> home;
    std::string::size_type last = p.find_first_of("/\\");
    if (last == std::string::npos) {
      last = p.size();
    }
    if (last == 1) {
#if defined(_WIN32) && !defined(__CYGWIN__)
      home = cmSystemTools::GetEnvVar("USERPROFILE");
      if (!home)
#endif
        home = cmSystemTools::GetEnvVar("HOME");
#ifndef CMAKE_NO_GETPWNAM
    } else if (last > 1) {
      std::string user = p.substr(1, last - 1);
      if (passwd* pw = getpwnam(user.c_str())) {
        home = std::string(pw->pw_dir);
      }
#endif
    }
    if (home) {
      p.replace(0, last, *home);
    }
  }
  return p;
}

#ifdef _WIN32
std::string GetDosDriveWorkingDirectory(char letter)
{
  // The Windows command processor tracks a per-drive working
  // directory for compatibility with MS-DOS by using special
  // environment variables named "=C:".
  // https://web.archive.org/web/20100522040616/
  // https://blogs.msdn.com/oldnewthing/archive/2010/05/06/10008132.aspx
  return cmSystemTools::GetEnvVar(cmStrCat('=', letter, ':'))
    .value_or(std::string());
}

cmsys::Status ReadNameOnDisk(std::string const& path, std::string& name)
{
  std::wstring wp = cmsys::Encoding::ToWide(path);
  HANDLE h = CreateFileW(
    wp.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
    FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, nullptr);
  if (h == INVALID_HANDLE_VALUE) {
    return cmsys::Status::Windows_GetLastError();
  }

  WCHAR local_fni[((sizeof(FILE_NAME_INFO) - 1) / sizeof(WCHAR)) + 1024];
  size_t fni_size = sizeof(local_fni);
  auto* fni = reinterpret_cast<FILE_NAME_INFO*>(local_fni);
  if (!GetFileInformationByHandleEx(h, FileNameInfo, fni, fni_size)) {
    DWORD e = GetLastError();
    if (e != ERROR_MORE_DATA) {
      CloseHandle(h);
      return cmsys::Status::Windows(e);
    }
    fni_size = fni->FileNameLength;
    fni = static_cast<FILE_NAME_INFO*>(malloc(fni_size));
    if (!fni) {
      e = ERROR_NOT_ENOUGH_MEMORY;
      CloseHandle(h);
      return cmsys::Status::Windows(e);
    }
    if (!GetFileInformationByHandleEx(h, FileNameInfo, fni, fni_size)) {
      e = GetLastError();
      free(fni);
      CloseHandle(h);
      return cmsys::Status::Windows(e);
    }
  }

  std::wstring wn{ fni->FileName, fni->FileNameLength / sizeof(WCHAR) };
  std::string nn = cmsys::Encoding::ToNarrow(wn);
  std::string::size_type last_slash = nn.find_last_of("/\\");
  if (last_slash != std::string::npos) {
    name = nn.substr(last_slash + 1);
  }
  if (fni != reinterpret_cast<FILE_NAME_INFO*>(local_fni)) {
    free(fni);
  }
  CloseHandle(h);
  return cmsys::Status::Success();
}
#elif defined(__APPLE__)
cmsys::Status ReadNameOnDiskIterateDir(std::string const& path,
                                       std::string& name)
{
  // Read contents of the parent directory to find the
  // entry matching the given path.
  std::string const bn = cmSystemTools::GetFilenameName(path);
  std::string const dn = cmSystemTools::GetFilenamePath(path);
  DIR* d = opendir(dn.c_str());
  while (struct dirent* dr = readdir(d)) {
    if (strcasecmp(dr->d_name, bn.c_str()) == 0) {
      name = dr->d_name;
      closedir(d);
      return cmsys::Status::Success();
    }
  }
  closedir(d);
  return cmsys::Status::POSIX(ENOENT);
}

cmsys::Status ReadNameOnDiskFcntlGetPath(std::string const& path,
                                         std::string& name)
{
  // macOS (and *BSD) offer a syscall to get an on-disk path to
  // a descriptor's file.
  int fd = open(path.c_str(), O_SYMLINK | O_RDONLY);
  if (fd == -1) {
    return cmsys::Status::POSIX(errno);
  }
  char out[MAXPATHLEN + 1];
  if (fcntl(fd, F_GETPATH, out) == -1) {
    int e = errno;
    close(fd);
    return cmsys::Status::POSIX(e);
  }
  close(fd);
  name = cmSystemTools::GetFilenameName(out);
  return cmsys::Status::Success();
}

cmsys::Status ReadNameOnDisk(std::string const& path, std::string& name)
{
  struct stat stat_path;
  if (lstat(path.c_str(), &stat_path) != 0) {
    return cmsys::Status::POSIX(errno);
  }
  // macOS (and *BSD) use namei(9) to cache file paths.  Use it unless
  // the inode has multiple hardlinks: if it is opened through multiple
  // paths, the results may be unpredictable.
  if (S_ISDIR(stat_path.st_mode) || stat_path.st_nlink < 2) {
    return ReadNameOnDiskFcntlGetPath(path, name);
  }
  // Fall back to reading the parent directory.
  return ReadNameOnDiskIterateDir(path, name);
}
#endif

class RealSystem : public cm::PathResolver::System
{
public:
  ~RealSystem() override = default;
  cmsys::Status ReadSymlink(std::string const& path,
                            std::string& link) override
  {
    return cmSystemTools::ReadSymlink(path, link);
  }
  bool PathExists(std::string const& path) override
  {
    return cmSystemTools::PathExists(path);
  }
  std::string GetWorkingDirectory() override
  {
    return cmSystemTools::GetLogicalWorkingDirectory();
  }
#ifdef _WIN32
  std::string GetWorkingDirectoryOnDrive(char letter) override
  {
    return GetDosDriveWorkingDirectory(letter);
  }
#endif

#if defined(_WIN32) || defined(__APPLE__)
  struct NameOnDisk
  {
    cmsys::Status Status;
    std::string Name;
  };
  using NameOnDiskMap = std::unordered_map<std::string, NameOnDisk>;
  NameOnDiskMap CachedNameOnDisk;

  cmsys::Status ReadName(std::string const& path, std::string& name) override
  {
    // Cache results to avoid repeated filesystem access.
    // We assume any files created by our own process keep their case.
    // Index the cache by lower-case paths to make it case-insensitive.
    std::string path_lower = cmSystemTools::LowerCase(path);
    auto i = this->CachedNameOnDisk.find(path_lower);
    if (i == this->CachedNameOnDisk.end()) {
      i = this->CachedNameOnDisk.emplace(path_lower, NameOnDisk()).first;
      i->second.Status = ReadNameOnDisk(path, i->second.Name);
    }
    name = i->second.Name;
    return i->second.Status;
  }
#endif
};

RealSystem RealOS;

} // namespace

#if !defined(HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE)
// For GetEnvironmentVariables
#  if defined(_WIN32)
extern __declspec(dllimport) char** environ;
#  else
extern char** environ; // NOLINT(readability-redundant-declaration)
#  endif
#endif

#if !defined(CMAKE_BOOTSTRAP)
static std::string cm_archive_entry_pathname(struct archive_entry* entry)
{
  return cmsys::Encoding::ToNarrow(archive_entry_pathname_w(entry));
}

static int cm_archive_read_open_file(struct archive* a, char const* file,
                                     int block_size)
{
  std::wstring wfile = cmsys::Encoding::ToWide(file);
  return archive_read_open_filename_w(a, wfile.c_str(), block_size);
}
#endif

#ifdef _WIN32
#elif defined(__APPLE__)
#  include <crt_externs.h>

#  define environ (*_NSGetEnviron())
#endif

bool cmSystemTools::s_RunCommandHideConsole = false;
bool cmSystemTools::s_DisableRunCommandOutput = false;
bool cmSystemTools::s_ErrorOccurred = false;
bool cmSystemTools::s_FatalErrorOccurred = false;
bool cmSystemTools::s_ForceUnixPaths = false;

// replace replace with with as many times as it shows up in source.
// write the result into source.
#if defined(_WIN32) && !defined(__CYGWIN__)
void cmSystemTools::ExpandRegistryValues(std::string& source, KeyWOW64 view)
{
  // Regular expression to match anything inside [...] that begins in HKEY.
  // Note that there is a special rule for regular expressions to match a
  // close square-bracket inside a list delimited by square brackets.
  // The "[^]]" part of this expression will match any character except
  // a close square-bracket.  The ']' character must be the first in the
  // list of characters inside the [^...] block of the expression.
  cmsys::RegularExpression regEntry("\\[(HKEY[^]]*)\\]");

  // check for black line or comment
  while (regEntry.find(source)) {
    // the arguments are the second match
    std::string key = regEntry.match(1);
    std::string val;
    if (ReadRegistryValue(key.c_str(), val, view)) {
      std::string reg = cmStrCat('[', key, ']');
      cmSystemTools::ReplaceString(source, reg.c_str(), val.c_str());
    } else {
      std::string reg = cmStrCat('[', key, ']');
      cmSystemTools::ReplaceString(source, reg.c_str(), "/registry");
    }
  }
}
#else
void cmSystemTools::ExpandRegistryValues(std::string& source,
                                         KeyWOW64 /*unused*/)
{
  cmsys::RegularExpression regEntry("\\[(HKEY[^]]*)\\]");
  while (regEntry.find(source)) {
    // the arguments are the second match
    std::string key = regEntry.match(1);
    std::string reg = cmStrCat('[', key, ']');
    cmSystemTools::ReplaceString(source, reg.c_str(), "/registry");
  }
}
#endif

// Return a lower case string
std::string cmSystemTools::LowerCase(cm::string_view s)
{
  std::string n;
  n.resize(s.size());
  for (size_t i = 0; i < s.size(); i++) {
    n[i] = static_cast<std::string::value_type>(tolower(s[i]));
  }
  return n;
}

// Return an upper case string
std::string cmSystemTools::UpperCase(cm::string_view s)
{
  std::string n;
  n.resize(s.size());
  for (size_t i = 0; i < s.size(); i++) {
    n[i] = static_cast<std::string::value_type>(toupper(s[i]));
  }
  return n;
}

std::string cmSystemTools::HelpFileName(cm::string_view str)
{
  std::string name(str);
  cmSystemTools::ReplaceString(name, "<", "");
  cmSystemTools::ReplaceString(name, ">", "");
  return name;
}

void cmSystemTools::Error(std::string const& m)
{
  std::string message = "CMake Error: " + m;
  cmSystemTools::s_ErrorOccurred = true;
  cmSystemTools::Message(message, "Error");
}

void cmSystemTools::SetInterruptCallback(InterruptCallback f)
{
  s_InterruptCallback = std::move(f);
}

bool cmSystemTools::GetInterruptFlag()
{
  if (s_InterruptCallback) {
    return s_InterruptCallback();
  }
  return false;
}

void cmSystemTools::SetMessageCallback(MessageCallback f)
{
  s_MessageCallback = std::move(f);
}

void cmSystemTools::SetStdoutCallback(OutputCallback f)
{
  s_StdoutCallback = std::move(f);
}

void cmSystemTools::SetStderrCallback(OutputCallback f)
{
  s_StderrCallback = std::move(f);
}

void cmSystemTools::Stderr(std::string const& s)
{
  if (s_StderrCallback) {
    s_StderrCallback(s);
  } else {
    std::cerr << s << std::flush;
  }
}

void cmSystemTools::Stdout(std::string const& s)
{
  if (s_StdoutCallback) {
    s_StdoutCallback(s);
  } else {
    std::cout << s << std::flush;
  }
}

void cmSystemTools::Message(std::string const& m, char const* title)
{
  cmMessageMetadata md;
  md.title = title;
  Message(m, md);
}

void cmSystemTools::Message(std::string const& m, cmMessageMetadata const& md)
{
  if (s_MessageCallback) {
    s_MessageCallback(m, md);
  } else {
    std::cerr << m << std::endl;
  }
}

void cmSystemTools::ReportLastSystemError(char const* msg)
{
  std::string m =
    cmStrCat(msg, ": System Error: ", Superclass::GetLastSystemError());
  cmSystemTools::Error(m);
}

void cmSystemTools::ParseWindowsCommandLine(char const* command,
                                            std::vector<std::string>& args)
{
  // See the MSDN document "Parsing C Command-Line Arguments" at
  // http://msdn2.microsoft.com/en-us/library/a1y7w461.aspx for rules
  // of parsing the windows command line.

  bool in_argument = false;
  bool in_quotes = false;
  int backslashes = 0;
  std::string arg;
  for (char const* c = command; *c; ++c) {
    if (*c == '\\') {
      ++backslashes;
      in_argument = true;
    } else if (*c == '"') {
      int backslash_pairs = backslashes >> 1;
      int backslash_escaped = backslashes & 1;
      arg.append(backslash_pairs, '\\');
      backslashes = 0;
      if (backslash_escaped) {
        /* An odd number of backslashes precede this quote.
           It is escaped.  */
        arg.append(1, '"');
      } else {
        /* An even number of backslashes precede this quote.
           It is not escaped.  */
        in_quotes = !in_quotes;
      }
      in_argument = true;
    } else {
      arg.append(backslashes, '\\');
      backslashes = 0;
      if (cmIsSpace(*c)) {
        if (in_quotes) {
          arg.append(1, *c);
        } else if (in_argument) {
          args.push_back(arg);
          arg.clear();
          in_argument = false;
        }
      } else {
        in_argument = true;
        arg.append(1, *c);
      }
    }
  }
  arg.append(backslashes, '\\');
  if (in_argument) {
    args.push_back(arg);
  }
}

class cmSystemToolsArgV
{
  char** ArgV;

public:
  cmSystemToolsArgV(char** argv)
    : ArgV(argv)
  {
  }
  ~cmSystemToolsArgV()
  {
    for (char** arg = this->ArgV; arg && *arg; ++arg) {
      free(*arg);
    }
    free(this->ArgV);
  }
  cmSystemToolsArgV(cmSystemToolsArgV const&) = delete;
  cmSystemToolsArgV& operator=(cmSystemToolsArgV const&) = delete;
  void Store(std::vector<std::string>& args) const
  {
    for (char** arg = this->ArgV; arg && *arg; ++arg) {
      args.emplace_back(*arg);
    }
  }
};

void cmSystemTools::ParseUnixCommandLine(char const* command,
                                         std::vector<std::string>& args)
{
  // Invoke the underlying parser.
  cmSystemToolsArgV argv(cmsysSystem_Parse_CommandForUnix(command, 0));
  argv.Store(args);
}

std::vector<std::string> cmSystemTools::HandleResponseFile(
  std::vector<std::string>::const_iterator argBeg,
  std::vector<std::string>::const_iterator argEnd)
{
  std::vector<std::string> arg_full;
  for (std::string const& arg : cmMakeRange(argBeg, argEnd)) {
    if (cmHasPrefix(arg, '@')) {
      cmsys::ifstream responseFile(arg.substr(1).c_str(), std::ios::in);
      if (!responseFile) {
        std::string error = cmStrCat("failed to open for reading (",
                                     cmSystemTools::GetLastSystemError(),
                                     "):\n  ", cm::string_view(arg).substr(1));
        cmSystemTools::Error(error);
      } else {
        std::string line;
        cmSystemTools::GetLineFromStream(responseFile, line);
        std::vector<std::string> args2;
#ifdef _WIN32
        cmSystemTools::ParseWindowsCommandLine(line.c_str(), args2);
#else
        cmSystemTools::ParseUnixCommandLine(line.c_str(), args2);
#endif
        cm::append(arg_full, args2);
      }
    } else {
      arg_full.push_back(arg);
    }
  }
  return arg_full;
}

std::vector<std::string> cmSystemTools::ParseArguments(std::string const& cmd)
{
  std::vector<std::string> args;
  std::string arg;

  bool win_path = false;

  char const* command = cmd.c_str();
  if (command[0] && command[1] &&
      ((command[0] != '/' && command[1] == ':' && command[2] == '\\') ||
       (command[0] == '\"' && command[1] != '/' && command[2] == ':' &&
        command[3] == '\\') ||
       (command[0] == '\'' && command[1] != '/' && command[2] == ':' &&
        command[3] == '\\') ||
       (command[0] == '\\' && command[1] == '\\'))) {
    win_path = true;
  }
  // Split the command into an argv array.
  for (char const* c = command; *c;) {
    // Skip over whitespace.
    while (*c == ' ' || *c == '\t') {
      ++c;
    }
    arg.clear();
    if (*c == '"') {
      // Parse a quoted argument.
      ++c;
      while (*c && *c != '"') {
        arg.append(1, *c);
        ++c;
      }
      if (*c) {
        ++c;
      }
      args.push_back(arg);
    } else if (*c == '\'') {
      // Parse a quoted argument.
      ++c;
      while (*c && *c != '\'') {
        arg.append(1, *c);
        ++c;
      }
      if (*c) {
        ++c;
      }
      args.push_back(arg);
    } else if (*c) {
      // Parse an unquoted argument.
      while (*c && *c != ' ' && *c != '\t') {
        if (*c == '\\' && !win_path) {
          ++c;
          if (*c) {
            arg.append(1, *c);
            ++c;
          }
        } else {
          arg.append(1, *c);
          ++c;
        }
      }
      args.push_back(arg);
    }
  }

  return args;
}

bool cmSystemTools::SplitProgramFromArgs(std::string const& command,
                                         std::string& program,
                                         std::string& args)
{
  char const* c = command.c_str();

  // Skip leading whitespace.
  while (cmIsSpace(*c)) {
    ++c;
  }

  // Parse one command-line element up to an unquoted space.
  bool in_escape = false;
  bool in_double = false;
  bool in_single = false;
  for (; *c; ++c) {
    if (in_single) {
      if (*c == '\'') {
        in_single = false;
      } else {
        program += *c;
      }
    } else if (in_escape) {
      in_escape = false;
      program += *c;
    } else if (*c == '\\') {
      in_escape = true;
    } else if (in_double) {
      if (*c == '"') {
        in_double = false;
      } else {
        program += *c;
      }
    } else if (*c == '"') {
      in_double = true;
    } else if (*c == '\'') {
      in_single = true;
    } else if (cmIsSpace(*c)) {
      break;
    } else {
      program += *c;
    }
  }

  // The remainder of the command line holds unparsed arguments.
  args = c;

  return !in_single && !in_escape && !in_double;
}

std::size_t cmSystemTools::CalculateCommandLineLengthLimit()
{
  size_t sz =
#ifdef _WIN32
    // There's a maximum of 65536 bytes and thus 32768 WCHARs on Windows
    // However, cmd.exe itself can only handle 8191 WCHARs and Ninja for
    // example uses it to spawn processes.
    size_t(8191);
#elif defined(__linux)
    // MAX_ARG_STRLEN is the maximum length of a string permissible for
    // the execve() syscall on Linux. It's defined as (PAGE_SIZE * 32)
    // in Linux's binfmts.h
    static_cast<size_t>(sysconf(_SC_PAGESIZE) * 32);
#else
    size_t(0);
#endif

#if defined(_SC_ARG_MAX)
  // ARG_MAX is the maximum size of the command and environment
  // that can be passed to the exec functions on UNIX.
  // The value in climits does not need to be present and may
  // depend upon runtime memory constraints, hence sysconf()
  // should be used to query it.
  long szArgMax = sysconf(_SC_ARG_MAX);
  // A return value of -1 signifies an undetermined limit, but
  // it does not imply an infinite limit, and thus is ignored.
  if (szArgMax != -1) {
    // We estimate the size of the environment block to be 1000.
    // This isn't accurate at all, but leaves some headroom.
    szArgMax = szArgMax < 1000 ? 0 : szArgMax - 1000;
#  if defined(_WIN32) || defined(__linux)
    sz = std::min(sz, static_cast<size_t>(szArgMax));
#  else
    sz = static_cast<size_t>(szArgMax);
#  endif
  }
#endif
  return sz;
}

void cmSystemTools::MaybePrependCmdExe(std::vector<std::string>& cmdLine)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
  if (!cmdLine.empty()) {
    std::string& applicationName = cmdLine.at(0);
    static cmsys::RegularExpression const winCmdRegex(
      "\\.([Bb][Aa][Tt]|[Cc][Mm][Dd])$");
    cmsys::RegularExpressionMatch winCmdMatch;
    if (winCmdRegex.find(applicationName.c_str(), winCmdMatch)) {
      // Wrap `.bat` and `.cmd` commands with `cmd /c call`.
      std::vector<std::string> output;
      output.reserve(cmdLine.size() + 3);
      output.emplace_back(cmSystemTools::GetComspec());
      output.emplace_back("/c");
      output.emplace_back("call");
      // Convert the batch file path to use backslashes for cmd.exe to parse.
      std::replace(applicationName.begin(), applicationName.end(), '/', '\\');
      output.emplace_back(applicationName);
      std::move(cmdLine.begin() + 1, cmdLine.end(),
                std::back_inserter(output));
      cmdLine = std::move(output);
    }
  }
#else
  static_cast<void>(cmdLine);
#endif
}

bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
                                     std::string* captureStdOut,
                                     std::string* captureStdErr, int* retVal,
                                     char const* dir, OutputOption outputflag,
                                     cmDuration timeout, Encoding encoding)
{
  cmUVProcessChainBuilder builder;
  builder.SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT, stdin)
    .AddCommand(command);
  if (dir) {
    builder.SetWorkingDirectory(dir);
  }

  if (outputflag == OUTPUT_PASSTHROUGH) {
    captureStdOut = nullptr;
    captureStdErr = nullptr;
    builder.SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT, stdout)
      .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR, stderr);
  } else if (outputflag == OUTPUT_MERGE ||
             (captureStdErr && captureStdErr == captureStdOut)) {
    builder.SetMergedBuiltinStreams();
    captureStdErr = nullptr;
  } else {
    builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
      .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
  }
  assert(!captureStdErr || captureStdErr != captureStdOut);

  auto chain = builder.Start();
  bool timedOut = false;
  cm::uv_timer_ptr timer;
  if (timeout.count()) {
    timer.init(chain.GetLoop(), &timedOut);
    timer.start(
      [](uv_timer_t* t) {
        auto* timedOutPtr = static_cast<bool*>(t->data);
        *timedOutPtr = true;
      },
      static_cast<uint64_t>(timeout.count() * 1000.0), 0,
      cm::uv_update_time::yes);
  }

  std::vector<char> tempStdOut;
  std::vector<char> tempStdErr;
  cm::uv_pipe_ptr outStream;
  bool outFinished = true;
  cm::uv_pipe_ptr errStream;
  bool errFinished = true;
  cmProcessOutput processOutput(encoding);
  std::unique_ptr<cmUVStreamReadHandle> outputHandle;
  std::unique_ptr<cmUVStreamReadHandle> errorHandle;
  if (outputflag != OUTPUT_PASSTHROUGH &&
      (captureStdOut || captureStdErr || outputflag != OUTPUT_NONE)) {
    auto startRead =
      [&outputflag, &processOutput,
       &chain](cm::uv_pipe_ptr& pipe, int stream, std::string* captureStd,
               std::vector<char>& tempStd, int id,
               void (*outputFunc)(std::string const&),
               bool& finished) -> std::unique_ptr<cmUVStreamReadHandle> {
      if (stream < 0) {
        return nullptr;
      }

      pipe.init(chain.GetLoop(), 0);
      uv_pipe_open(pipe, stream);

      finished = false;
      return cmUVStreamRead(
        pipe,
        [outputflag, &processOutput, captureStd, &tempStd, id,
         outputFunc](std::vector<char> data) {
          // Translate NULL characters in the output into valid text.
          for (auto& c : data) {
            if (c == '\0') {
              c = ' ';
            }
          }

          if (outputflag != OUTPUT_NONE) {
            std::string strdata;
            processOutput.DecodeText(data.data(), data.size(), strdata, id);
            outputFunc(strdata);
          }
          if (captureStd) {
            cm::append(tempStd, data.data(), data.data() + data.size());
          }
        },
        [&finished, outputflag, &processOutput, id, outputFunc]() {
          finished = true;
          if (outputflag != OUTPUT_NONE) {
            std::string strdata;
            processOutput.DecodeText(std::string(), strdata, id);
            if (!strdata.empty()) {
              outputFunc(strdata);
            }
          }
        });
    };

    outputHandle =
      startRead(outStream, chain.OutputStream(), captureStdOut, tempStdOut, 1,
                cmSystemTools::Stdout, outFinished);
    if (chain.OutputStream() != chain.ErrorStream()) {
      errorHandle =
        startRead(errStream, chain.ErrorStream(), captureStdErr, tempStdErr, 2,
                  cmSystemTools::Stderr, errFinished);
    }
  }

  while (!timedOut && !(chain.Finished() && outFinished && errFinished)) {
    uv_run(&chain.GetLoop(), UV_RUN_ONCE);
  }

  if (captureStdOut) {
    captureStdOut->assign(tempStdOut.begin(), tempStdOut.end());
    processOutput.DecodeText(*captureStdOut, *captureStdOut);
  }
  if (captureStdErr) {
    captureStdErr->assign(tempStdErr.begin(), tempStdErr.end());
    processOutput.DecodeText(*captureStdErr, *captureStdErr);
  }

  bool result = true;
  if (timedOut) {
    chain.Terminate();
    char const* error_str = "Process terminated due to timeout\n";
    if (outputflag != OUTPUT_NONE) {
      std::cerr << error_str << std::endl;
    }
    if (captureStdErr) {
      captureStdErr->append(error_str, strlen(error_str));
    }
    result = false;
  } else {
    auto const& status = chain.GetStatus(0);
    auto exception = status.GetException();

    switch (exception.first) {
      case cmUVProcessChain::ExceptionCode::None:
        if (retVal) {
          *retVal = static_cast<int>(status.ExitStatus);
        } else {
          if (status.ExitStatus != 0) {
            result = false;
          }
        }
        break;
      default: {
        if (outputflag != OUTPUT_NONE) {
          std::cerr << exception.second << std::endl;
        }
        if (captureStdErr) {
          captureStdErr->append(exception.second);
        } else if (captureStdOut) {
          captureStdOut->append(exception.second);
        }
        result = false;
      } break;
    }
  }

  return result;
}

bool cmSystemTools::RunSingleCommand(std::string const& command,
                                     std::string* captureStdOut,
                                     std::string* captureStdErr, int* retVal,
                                     char const* dir, OutputOption outputflag,
                                     cmDuration timeout)
{
  if (s_DisableRunCommandOutput) {
    outputflag = OUTPUT_NONE;
  }

  std::vector<std::string> args = cmSystemTools::ParseArguments(command);

  if (args.empty()) {
    return false;
  }
  return cmSystemTools::RunSingleCommand(args, captureStdOut, captureStdErr,
                                         retVal, dir, outputflag, timeout);
}

std::string cmSystemTools::PrintSingleCommand(
  std::vector<std::string> const& command)
{
  if (command.empty()) {
    return std::string();
  }

  return cmWrap('"', command, '"', " ");
}

bool cmSystemTools::DoesFileExistWithExtensions(
  std::string const& name, std::vector<std::string> const& headerExts)
{
  std::string hname;

  for (std::string const& headerExt : headerExts) {
    hname = cmStrCat(name, '.', headerExt);
    if (cmSystemTools::FileExists(hname)) {
      return true;
    }
  }
  return false;
}

std::string cmSystemTools::FileExistsInParentDirectories(
  std::string const& fname, std::string const& directory,
  std::string const& toplevel)
{
  std::string file = fname;
  cmSystemTools::ConvertToUnixSlashes(file);
  std::string dir = directory;
  cmSystemTools::ConvertToUnixSlashes(dir);
  std::string prevDir;
  while (dir != prevDir) {
    std::string path = cmStrCat(dir, '/', file);
    if (cmSystemTools::FileExists(path)) {
      return path;
    }
    if (dir.size() < toplevel.size()) {
      break;
    }
    prevDir = dir;
    dir = cmSystemTools::GetParentDirectory(dir);
  }
  return "";
}

#ifdef _WIN32
namespace {

/* Helper class to save and restore the specified file (or directory)
   attribute bits. Instantiate this class as an automatic variable on the
   stack. Its constructor saves a copy of the file attributes, and then its
   destructor restores the original attribute settings.  */
class SaveRestoreFileAttributes
{
public:
  SaveRestoreFileAttributes(std::wstring const& path,
                            uint32_t file_attrs_to_set);
  ~SaveRestoreFileAttributes();

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

  void SetPath(std::wstring const& path) { path_ = path; }

private:
  std::wstring path_;
  uint32_t original_attr_bits_;
};

SaveRestoreFileAttributes::SaveRestoreFileAttributes(
  std::wstring const& path, uint32_t file_attrs_to_set)
  : path_(path)
  , original_attr_bits_(0)
{
  // Set the specified attributes for the source file/directory.
  original_attr_bits_ = GetFileAttributesW(path_.c_str());
  if ((INVALID_FILE_ATTRIBUTES != original_attr_bits_) &&
      ((file_attrs_to_set & original_attr_bits_) != file_attrs_to_set)) {
    SetFileAttributesW(path_.c_str(), original_attr_bits_ | file_attrs_to_set);
  }
}

// We set attribute bits.  Now we need to restore their original state.
SaveRestoreFileAttributes::~SaveRestoreFileAttributes()
{
  DWORD last_error = GetLastError();
  // Verify or restore the original attributes.
  const DWORD source_attr_bits = GetFileAttributesW(path_.c_str());
  if (INVALID_FILE_ATTRIBUTES != source_attr_bits) {
    if (original_attr_bits_ != source_attr_bits) {
      // The file still exists, and its attributes aren't our saved values.
      // Time to restore them.
      SetFileAttributesW(path_.c_str(), original_attr_bits_);
    }
  }
  SetLastError(last_error);
}

struct WindowsFileRetryInit
{
  cmSystemTools::WindowsFileRetry Retry;
  bool Explicit;
};

WindowsFileRetryInit InitWindowsFileRetry(wchar_t const* const values[2],
                                          unsigned int const defaults[2])
{
  unsigned int data[2] = { 0, 0 };
  HKEY const keys[2] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
  for (int k = 0; k < 2; ++k) {
    HKEY hKey;
    if (RegOpenKeyExW(keys[k], L"Software\\Kitware\\CMake\\Config", 0,
                      KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {
      for (int v = 0; v < 2; ++v) {
        DWORD dwData, dwType, dwSize = 4;
        if (!data[v] &&
            RegQueryValueExW(hKey, values[v], 0, &dwType, (BYTE*)&dwData,
                             &dwSize) == ERROR_SUCCESS &&
            dwType == REG_DWORD && dwSize == 4) {
          data[v] = static_cast<unsigned int>(dwData);
        }
      }
      RegCloseKey(hKey);
    }
  }
  WindowsFileRetryInit init;
  init.Explicit = data[0] || data[1];
  init.Retry.Count = data[0] ? data[0] : defaults[0];
  init.Retry.Delay = data[1] ? data[1] : defaults[1];
  return init;
}

WindowsFileRetryInit InitWindowsFileRetry()
{
  static wchar_t const* const values[2] = { L"FilesystemRetryCount",
                                            L"FilesystemRetryDelay" };
  static unsigned int const defaults[2] = { 5, 500 };
  return InitWindowsFileRetry(values, defaults);
}

WindowsFileRetryInit InitWindowsDirectoryRetry()
{
  static wchar_t const* const values[2] = { L"FilesystemDirectoryRetryCount",
                                            L"FilesystemDirectoryRetryDelay" };
  static unsigned int const defaults[2] = { 120, 500 };
  WindowsFileRetryInit dirInit = InitWindowsFileRetry(values, defaults);
  if (dirInit.Explicit) {
    return dirInit;
  }
  WindowsFileRetryInit fileInit = InitWindowsFileRetry();
  if (fileInit.Explicit) {
    return fileInit;
  }
  return dirInit;
}

cmSystemTools::WindowsFileRetry GetWindowsRetry(std::wstring const& path)
{
  // If we are performing a directory operation, then try and get the
  // appropriate timing info.
  DWORD const attrs = GetFileAttributesW(path.c_str());
  if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
    return cmSystemTools::GetWindowsDirectoryRetry();
  }
  return cmSystemTools::GetWindowsFileRetry();
}

} // end of anonymous namespace

cmSystemTools::WindowsFileRetry cmSystemTools::GetWindowsFileRetry()
{
  static WindowsFileRetry retry = InitWindowsFileRetry().Retry;
  return retry;
}

cmSystemTools::WindowsFileRetry cmSystemTools::GetWindowsDirectoryRetry()
{
  static cmSystemTools::WindowsFileRetry retry =
    InitWindowsDirectoryRetry().Retry;
  return retry;
}

cmSystemTools::WindowsVersion cmSystemTools::GetWindowsVersion()
{
  /* Windows version number data.  */
  OSVERSIONINFOEXW osviex;
  ZeroMemory(&osviex, sizeof(osviex));
  osviex.dwOSVersionInfoSize = sizeof(osviex);

#  ifdef CM_WINDOWS_DEPRECATED_GetVersionEx
#    pragma warning(push)
#    ifdef __INTEL_COMPILER
#      pragma warning(disable : 1478)
#    elif defined __clang__
#      pragma clang diagnostic push
#      pragma clang diagnostic ignored "-Wdeprecated-declarations"
#    else
#      pragma warning(disable : 4996)
#    endif
#  endif
  GetVersionExW((OSVERSIONINFOW*)&osviex);
#  ifdef CM_WINDOWS_DEPRECATED_GetVersionEx
#    ifdef __clang__
#      pragma clang diagnostic pop
#    else
#      pragma warning(pop)
#    endif
#  endif

  WindowsVersion result;
  result.dwMajorVersion = osviex.dwMajorVersion;
  result.dwMinorVersion = osviex.dwMinorVersion;
  result.dwBuildNumber = osviex.dwBuildNumber;
  return result;
}

std::string cmSystemTools::GetComspec()
{
  std::string comspec;
  if (!cmSystemTools::GetEnv("COMSPEC", comspec) ||
      !cmSystemTools::FileIsFullPath(comspec)) {
    comspec = "cmd.exe";
  }
  return comspec;
}

#endif

// File changes involve removing SETUID/SETGID bits when a file is modified.
// This behavior is consistent across most Unix-like operating systems.
class FileModeGuard
{
public:
  FileModeGuard(std::string const& file_path, std::string* emsg);
  bool Restore(std::string* emsg);
  bool HasErrors() const;

private:
#ifndef _WIN32
  mode_t mode_;
#endif
  std::string filepath_;
};

FileModeGuard::FileModeGuard(std::string const& file_path, std::string* emsg)
{
#ifndef _WIN32
  struct stat file_stat;
  if (stat(file_path.c_str(), &file_stat) != 0) {
    if (emsg) {
      *emsg = cmStrCat("Cannot get file stat: ", strerror(errno));
    }
    return;
  }

  mode_ = file_stat.st_mode;
#else
  static_cast<void>(emsg);
#endif
  filepath_ = file_path;
}

bool FileModeGuard::Restore(std::string* emsg)
{
  assert(filepath_.empty() == false);

#ifndef _WIN32
  struct stat file_stat;
  if (stat(filepath_.c_str(), &file_stat) != 0) {
    if (emsg) {
      *emsg = cmStrCat("Cannot get file stat: ", strerror(errno));
    }
    return false;
  }

  // Nothing changed; everything is in the expected state
  if (file_stat.st_mode == mode_) {
    return true;
  }

  if (chmod(filepath_.c_str(), mode_) != 0) {
    if (emsg) {
      *emsg = cmStrCat("Cannot restore the file mode: ", strerror(errno));
    }
    return false;
  }
#else
  static_cast<void>(emsg);
#endif

  return true;
}

bool FileModeGuard::HasErrors() const
{
  return filepath_.empty();
}

std::string cmSystemTools::GetRealPathResolvingWindowsSubst(
  std::string const& path, std::string* errorMessage)
{
#ifdef _WIN32
  // uv_fs_realpath uses Windows Vista API so fallback to kwsys if not found
  std::string resolved_path;
  uv_fs_t req;
  int err = uv_fs_realpath(nullptr, &req, path.c_str(), nullptr);
  if (!err) {
    resolved_path = std::string((char*)req.ptr);
    cmSystemTools::ConvertToUnixSlashes(resolved_path);
  } else if (err == UV_ENOSYS) {
    resolved_path = cmsys::SystemTools::GetRealPath(path, errorMessage);
  } else if (errorMessage) {
    cmsys::Status status =
      cmsys::Status::Windows(uv_fs_get_system_error(&req));
    *errorMessage = status.GetString();
    resolved_path.clear();
  } else {
    resolved_path = path;
  }
  // Normalize to upper-case drive letter as cm::PathResolver does.
  if (resolved_path.size() > 1 && resolved_path[1] == ':') {
    resolved_path[0] = toupper(resolved_path[0]);
  }
  return resolved_path;
#else
  return cmsys::SystemTools::GetRealPath(path, errorMessage);
#endif
}

std::string cmSystemTools::GetRealPath(std::string const& path,
                                       std::string* errorMessage)
{
#ifdef _WIN32
  std::string resolved_path =
    cmSystemTools::GetRealPathResolvingWindowsSubst(path, errorMessage);

  // If the original path used a subst drive and the real path starts
  // with the substitution, restore the subst drive prefix.  This may
  // incorrectly restore a subst drive if the underlying drive was
  // encountered via an absolute symlink, but this is an acceptable
  // limitation to otherwise preserve susbt drives.
  if (resolved_path.size() >= 2 && resolved_path[1] == ':' &&
      path.size() >= 2 && path[1] == ':' &&
      toupper(resolved_path[0]) != toupper(path[0])) {
    // FIXME: Add thread_local or mutex if we use threads.
    static std::map<char, std::string> substMap;
    char const drive = static_cast<char>(toupper(path[0]));
    std::string maybe_subst = cmStrCat(drive, ":/");
    auto smi = substMap.find(drive);
    if (smi == substMap.end()) {
      smi = substMap
              .emplace(
                drive,
                cmSystemTools::GetRealPathResolvingWindowsSubst(maybe_subst))
              .first;
    }
    std::string const& resolved_subst = smi->second;
    std::string::size_type const ns = resolved_subst.size();
    if (ns > 0) {
      std::string::size_type const np = resolved_path.size();
      if (ns == np && resolved_path == resolved_subst) {
        resolved_path = maybe_subst;
      } else if (ns > 0 && ns < np && resolved_path[ns] == '/' &&
                 resolved_path.compare(0, ns, resolved_subst) == 0) {
        resolved_path.replace(0, ns + 1, maybe_subst);
      }
    }
  }

  return resolved_path;
#else
  return cmsys::SystemTools::GetRealPath(path, errorMessage);
#endif
}

void cmSystemTools::InitializeLibUV()
{
#if defined(_WIN32)
  // Perform libuv one-time initialization now, and then un-do its
  // global _fmode setting so that using libuv does not change the
  // default file text/binary mode.  See libuv issue 840.
  if (uv_loop_t* loop = uv_default_loop()) {
    uv_loop_close(loop);
  }
#  ifdef _MSC_VER
  _set_fmode(_O_TEXT);
#  else
  _fmode = _O_TEXT;
#  endif
  // Replace libuv's report handler with our own to suppress popups.
  cmSystemTools::EnableMSVCDebugHook();
#endif
}

#if defined(_WIN32)
#  include <random>

#  include <wctype.h>
#  ifdef _MSC_VER
using mode_t = cmSystemTools::SystemTools::mode_t;
#  endif
#else
#  include <sys/stat.h>
#endif

inline int Mkdir(char const* dir, mode_t const* mode)
{
#if defined(_WIN32)
  int ret = _wmkdir(cmSystemTools::ConvertToWindowsExtendedPath(dir).c_str());
  if (ret == 0 && mode)
    cmSystemTools::SystemTools::SetPermissions(dir, *mode);
  return ret;
#else
  return mkdir(dir, mode ? *mode : 0777);
#endif
}

#ifdef CMAKE_NO_MKDTEMP
namespace {
char* cm_mkdtemp_fallback(char* template_)
{
  if (mktemp(template_) == nullptr || mkdir(template_, 0700) != 0) {
    return nullptr;
  }
  return template_;
}
using cm_mkdtemp_t = char* (*)(char*);
cm_mkdtemp_t const cm_mkdtemp = []() -> cm_mkdtemp_t {
  cm_mkdtemp_t f = (cm_mkdtemp_t)dlsym(RTLD_DEFAULT, "mkdtemp");
  dlerror(); // Ignore/cleanup dlsym errors.
  if (!f) {
    f = cm_mkdtemp_fallback;
  }
  return f;
}();
}
#else
#  define cm_mkdtemp mkdtemp
#endif

cmsys::Status cmSystemTools::MakeTempDirectory(std::string& path,
                                               mode_t const* mode)
{
  if (path.empty()) {
    return cmsys::Status::POSIX(EINVAL);
  }
  return cmSystemTools::MakeTempDirectory(&path.front(), mode);
}

cmsys::Status cmSystemTools::MakeTempDirectory(char* path, mode_t const* mode)
{
  if (!path) {
    return cmsys::Status::POSIX(EINVAL);
  }

  // verify that path ends with "XXXXXX"
  auto const l = std::strlen(path);
  if (!cmHasLiteralSuffix(cm::string_view{ path, l }, "XXXXXX")) {
    return cmsys::Status::POSIX(EINVAL);
  }

  // create parent directories
  auto* sep = path;
  while ((sep = strchr(sep, '/'))) {
    // all underlying functions use C strings,
    // so temporarily end the string here
    *sep = '\0';
    Mkdir(path, mode);

    *sep = '/';
    ++sep;
  }

#ifdef _WIN32
  int const nchars = 36;
  char const chars[nchars + 1] = "abcdefghijklmnopqrstuvwxyz0123456789";

  std::random_device rd;
  std::mt19937 rg{ rd() };
  std::uniform_int_distribution<int> dist{ 0, nchars - 1 };

  for (auto tries = 100; tries; --tries) {
    for (auto n = l - 6; n < l; ++n) {
      path[n] = chars[dist(rg)];
    }
    if (Mkdir(path, mode) == 0) {
      return cmsys::Status::Success();
    } else if (errno != EEXIST) {
      return cmsys::Status::POSIX_errno();
    }
  }
  return cmsys::Status::POSIX(EAGAIN);
#else
  if (cm_mkdtemp(path)) {
    if (mode) {
      chmod(path, *mode);
    }
  } else {
    return cmsys::Status::POSIX_errno();
  }
  return cmsys::Status::Success();
#endif
}

#ifdef _WIN32
namespace {
bool cmMoveFile(std::wstring const& oldname, std::wstring const& newname,
                cmSystemTools::Replace replace)
{
  // Not only ignore any previous error, but clear any memory of it.
  SetLastError(0);

  DWORD flags = 0;
  if (replace == cmSystemTools::Replace::Yes) {
    // Use MOVEFILE_REPLACE_EXISTING to replace an existing destination file.
    flags = flags | MOVEFILE_REPLACE_EXISTING;
  }

  return MoveFileExW(oldname.c_str(), newname.c_str(), flags);
}
}
#endif

cmSystemTools::CopyResult cmSystemTools::CopySingleFile(
  std::string const& oldname, std::string const& newname, CopyWhen when,
  CopyInputRecent inputRecent, std::string* err)
{
  switch (when) {
    case CopyWhen::Always:
      break;
    case CopyWhen::OnlyIfDifferent:
      if (!FilesDiffer(oldname, newname)) {
        return CopyResult::Success;
      }
      break;
    case CopyWhen::OnlyIfNewer: {
      if (!SystemTools::FileExists(newname)) {
        break;
      }
      int timeResult = 0;
      cmsys::Status timeStatus =
        cmsys::SystemTools::FileTimeCompare(oldname, newname, &timeResult);
      if (timeStatus.IsSuccess() && timeResult <= 0) {
        return CopyResult::Success;
      }
      break;
    }
  }

  mode_t perm = 0;
  cmsys::Status perms = SystemTools::GetPermissions(oldname, perm);

  // If files are the same do not copy
  if (SystemTools::SameFile(oldname, newname)) {
    return CopyResult::Success;
  }

  cmsys::SystemTools::CopyStatus status;
  status = cmsys::SystemTools::CloneFileContent(oldname, newname);
  if (!status) {
    // if cloning did not succeed, fall back to blockwise copy
#ifdef _WIN32
    if (inputRecent == CopyInputRecent::Yes) {
      // Windows sometimes locks a file immediately after creation.
      // Retry a few times.
      WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry();
      while ((status =
                cmsys::SystemTools::CopyFileContentBlockwise(oldname, newname),
              status.Path == cmsys::SystemTools::CopyStatus::SourcePath &&
                status.GetPOSIX() == EACCES && --retry.Count)) {
        cmSystemTools::Delay(retry.Delay);
      }
    } else {
      status = cmsys::SystemTools::CopyFileContentBlockwise(oldname, newname);
    }
#else
    static_cast<void>(inputRecent);
    status = cmsys::SystemTools::CopyFileContentBlockwise(oldname, newname);
#endif
  }
  if (!status) {
    if (err) {
      *err = status.GetString();
      switch (status.Path) {
        case cmsys::SystemTools::CopyStatus::SourcePath:
          *err = cmStrCat(*err, " (input)");
          break;
        case cmsys::SystemTools::CopyStatus::DestPath:
          *err = cmStrCat(*err, " (output)");
          break;
        default:
          break;
      }
    }
    return CopyResult::Failure;
  }
  if (perms) {
    perms = SystemTools::SetPermissions(newname, perm);
    if (!perms) {
      if (err) {
        *err = cmStrCat(perms.GetString(), " (output)");
      }
      return CopyResult::Failure;
    }
  }
  return CopyResult::Success;
}

bool cmSystemTools::RenameFile(std::string const& oldname,
                               std::string const& newname)
{
  return cmSystemTools::RenameFile(oldname, newname, Replace::Yes) ==
    RenameResult::Success;
}

cmSystemTools::RenameResult cmSystemTools::RenameFile(
  std::string const& oldname, std::string const& newname, Replace replace,
  std::string* err)
{
#ifdef _WIN32
#  ifndef INVALID_FILE_ATTRIBUTES
#    define INVALID_FILE_ATTRIBUTES ((DWORD) - 1)
#  endif
  std::wstring const oldname_wstr =
    SystemTools::ConvertToWindowsExtendedPath(oldname);
  std::wstring const newname_wstr =
    SystemTools::ConvertToWindowsExtendedPath(newname);

  /* Windows MoveFileEx may not replace read-only or in-use files.  If it
     fails then remove the read-only attribute from any existing destination.
     Try multiple times since we may be racing against another process
     creating/opening the destination file just before our MoveFileEx.  */
  WindowsFileRetry retry = GetWindowsRetry(oldname_wstr);

  // Use RAII to set the attribute bit blocking Microsoft Search Indexing,
  // and restore the previous value upon return.
  SaveRestoreFileAttributes save_restore_file_attributes(
    oldname_wstr, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);

  DWORD move_last_error = 0;
  while (!cmMoveFile(oldname_wstr, newname_wstr, replace) && --retry.Count) {
    move_last_error = GetLastError();

    // There was no error ==> the operation is not yet complete.
    if (move_last_error == NO_ERROR) {
      break;
    }

    // Try again only if failure was due to access/sharing permissions.
    // Most often ERROR_ACCESS_DENIED (a.k.a. I/O error) for a directory, and
    // ERROR_SHARING_VIOLATION for a file, are caused by one of the following:
    // 1) Anti-Virus Software
    // 2) Windows Search Indexer
    // 3) Windows Explorer has an associated directory already opened.
    if (move_last_error != ERROR_ACCESS_DENIED &&
        move_last_error != ERROR_SHARING_VIOLATION) {
      if (replace == Replace::No && move_last_error == ERROR_ALREADY_EXISTS) {
        return RenameResult::NoReplace;
      }
      if (err) {
        *err = cmsys::Status::Windows(move_last_error).GetString();
      }
      return RenameResult::Failure;
    }

    DWORD const attrs = GetFileAttributesW(newname_wstr.c_str());
    if ((attrs != INVALID_FILE_ATTRIBUTES) &&
        (attrs & FILE_ATTRIBUTE_READONLY) &&
        // FILE_ATTRIBUTE_READONLY is not honored on directories.
        !(attrs & FILE_ATTRIBUTE_DIRECTORY)) {
      // Remove the read-only attribute from the destination file.
      SetFileAttributesW(newname_wstr.c_str(),
                         attrs & ~FILE_ATTRIBUTE_READONLY);
    } else {
      // The file may be temporarily in use so wait a bit.
      cmSystemTools::Delay(retry.Delay);
    }
  }

  // If we were successful, then there was no error.
  if (retry.Count > 0) {
    move_last_error = 0;
    // Restore the attributes on the new name.
    save_restore_file_attributes.SetPath(newname_wstr);
  }
  SetLastError(move_last_error);
  if (retry.Count > 0) {
    return RenameResult::Success;
  }
  if (replace == Replace::No && GetLastError() == ERROR_ALREADY_EXISTS) {
    return RenameResult::NoReplace;
  }
  if (err) {
    *err = cmsys::Status::Windows_GetLastError().GetString();
  }
  return RenameResult::Failure;
#else
  // On UNIX we have OS-provided calls to create 'newname' atomically.
  if (replace == Replace::No) {
    if (link(oldname.c_str(), newname.c_str()) == 0) {
      return RenameResult::Success;
    }
    if (errno == EEXIST) {
      return RenameResult::NoReplace;
    }
    if (err) {
      *err = cmsys::Status::POSIX_errno().GetString();
    }
    return RenameResult::Failure;
  }
  if (rename(oldname.c_str(), newname.c_str()) == 0) {
    return RenameResult::Success;
  }
  if (err) {
    *err = cmsys::Status::POSIX_errno().GetString();
  }
  return RenameResult::Failure;
#endif
}

cmsys::Status cmSystemTools::MoveFileIfDifferent(
  std::string const& source, std::string const& destination)
{
  cmsys::Status res = {};
  if (FilesDiffer(source, destination)) {
    if (RenameFile(source, destination)) {
      return res;
    }
    res = CopyFileAlways(source, destination);
  }
  RemoveFile(source);
  return res;
}

void cmSystemTools::Glob(std::string const& directory,
                         std::string const& regexp,
                         std::vector<std::string>& files)
{
  cmsys::Directory d;
  cmsys::RegularExpression reg(regexp.c_str());

  if (d.Load(directory)) {
    size_t numf;
    unsigned int i;
    numf = d.GetNumberOfFiles();
    for (i = 0; i < numf; i++) {
      std::string fname = d.GetFile(i);
      if (reg.find(fname)) {
        files.push_back(std::move(fname));
      }
    }
  }
}

void cmSystemTools::GlobDirs(std::string const& path,
                             std::vector<std::string>& files)
{
  std::string::size_type pos = path.find("/*");
  if (pos == std::string::npos) {
    files.push_back(path);
    return;
  }
  std::string startPath = path.substr(0, pos);
  std::string finishPath = path.substr(pos + 2);

  cmsys::Directory d;
  if (d.Load(startPath)) {
    for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i) {
      if ((std::string(d.GetFile(i)) != ".") &&
          (std::string(d.GetFile(i)) != "..")) {
        std::string fname = cmStrCat(startPath, '/', d.GetFile(i));
        if (cmSystemTools::FileIsDirectory(fname)) {
          fname += finishPath;
          cmSystemTools::GlobDirs(fname, files);
        }
      }
    }
  }
}

bool cmSystemTools::SimpleGlob(std::string const& glob,
                               std::vector<std::string>& files,
                               int type /* = 0 */)
{
  files.clear();
  if (glob.back() != '*') {
    return false;
  }
  std::string path = cmSystemTools::GetFilenamePath(glob);
  std::string ppath = cmSystemTools::GetFilenameName(glob);
  ppath = ppath.substr(0, ppath.size() - 1);
  if (path.empty()) {
    path = "/";
  }

  bool res = false;
  cmsys::Directory d;
  if (d.Load(path)) {
    for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i) {
      if ((std::string(d.GetFile(i)) != ".") &&
          (std::string(d.GetFile(i)) != "..")) {
        std::string fname = path;
        if (path.back() != '/') {
          fname += "/";
        }
        fname += d.GetFile(i);
        std::string sfname = d.GetFile(i);
        if (type > 0 && cmSystemTools::FileIsDirectory(fname)) {
          continue;
        }
        if (type < 0 && !cmSystemTools::FileIsDirectory(fname)) {
          continue;
        }
        if (cmHasPrefix(sfname, ppath)) {
          files.push_back(fname);
          res = true;
        }
      }
    }
  }
  return res;
}

std::string cmSystemTools::ConvertToOutputPath(std::string const& path)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
  if (s_ForceUnixPaths) {
    return cmSystemTools::ConvertToUnixOutputPath(path);
  }
  return cmSystemTools::ConvertToWindowsOutputPath(path);
#else
  return cmSystemTools::ConvertToUnixOutputPath(path);
#endif
}

void cmSystemTools::ConvertToOutputSlashes(std::string& path)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
  if (!s_ForceUnixPaths) {
    // Convert to windows slashes.
    std::string::size_type pos = 0;
    while ((pos = path.find('/', pos)) != std::string::npos) {
      path[pos++] = '\\';
    }
  }
#else
  static_cast<void>(path);
#endif
}

void cmSystemTools::ConvertToLongPath(std::string& path)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
  // Try to convert path to a long path only if the path contains character '~'
  if (path.find('~') == std::string::npos) {
    return;
  }

  std::wstring wPath = cmsys::Encoding::ToWide(path);
  DWORD ret = GetLongPathNameW(wPath.c_str(), nullptr, 0);
  std::vector<wchar_t> buffer(ret);
  if (ret != 0) {
    ret = GetLongPathNameW(wPath.c_str(), buffer.data(),
                           static_cast<DWORD>(buffer.size()));
  }

  if (ret != 0) {
    path = cmsys::Encoding::ToNarrow(buffer.data());
  }
#else
  static_cast<void>(path);
#endif
}

std::string cmSystemTools::ConvertToRunCommandPath(std::string const& path)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
  return cmSystemTools::ConvertToWindowsOutputPath(path);
#else
  return cmSystemTools::ConvertToUnixOutputPath(path);
#endif
}

// compute the relative path from here to there
std::string cmSystemTools::RelativePath(std::string const& local,
                                        std::string const& remote)
{
  if (!cmSystemTools::FileIsFullPath(local)) {
    cmSystemTools::Error("RelativePath must be passed a full path to local: " +
                         local);
  }
  if (!cmSystemTools::FileIsFullPath(remote)) {
    cmSystemTools::Error(
      "RelativePath must be passed a full path to remote: " + remote);
  }
  return cmsys::SystemTools::RelativePath(local, remote);
}

std::string cmSystemTools::ForceToRelativePath(std::string const& local_path,
                                               std::string const& remote_path)
{
  // The paths should never be quoted.
  assert(local_path.front() != '\"');
  assert(remote_path.front() != '\"');

  // The local path should never have a trailing slash except if it is just the
  // bare root directory
  assert(local_path.empty() || local_path.back() != '/' ||
         local_path.size() == 1 ||
         (local_path.size() == 3 && local_path[1] == ':' &&
          ((local_path[0] >= 'A' && local_path[0] <= 'Z') ||
           (local_path[0] >= 'a' && local_path[0] <= 'z'))));

  // If the path is already relative then just return the path.
  if (!cmSystemTools::FileIsFullPath(remote_path)) {
    return remote_path;
  }

  // Identify the longest shared path component between the remote
  // path and the local path.
  std::vector<std::string> local;
  cmSystemTools::SplitPath(local_path, local);
  std::vector<std::string> remote;
  cmSystemTools::SplitPath(remote_path, remote);
  unsigned int common = 0;
  while (common < remote.size() && common < local.size() &&
         cmSystemTools::ComparePath(remote[common], local[common])) {
    ++common;
  }

  // If no part of the path is in common then return the full path.
  if (common == 0) {
    return remote_path;
  }

  // If the entire path is in common then just return a ".".
  if (common == remote.size() && common == local.size()) {
    return ".";
  }

  // If the entire path is in common except for a trailing slash then
  // just return a "./".
  if (common + 1 == remote.size() && remote[common].empty() &&
      common == local.size()) {
    return "./";
  }

  // Construct the relative path.
  std::string relative;

  // First add enough ../ to get up to the level of the shared portion
  // of the path.  Leave off the trailing slash.  Note that the last
  // component of local will never be empty because local should never
  // have a trailing slash.
  for (unsigned int i = common; i < local.size(); ++i) {
    relative += "..";
    if (i < local.size() - 1) {
      relative += "/";
    }
  }

  // Now add the portion of the destination path that is not included
  // in the shared portion of the path.  Add a slash the first time
  // only if there was already something in the path.  If there was a
  // trailing slash in the input then the last iteration of the loop
  // will add a slash followed by an empty string which will preserve
  // the trailing slash in the output.

  if (!relative.empty() && !remote.empty()) {
    relative += "/";
  }
  relative += cmJoin(cmMakeRange(remote).advance(common), "/");

  // Finally return the path.
  return relative;
}

std::string cmSystemTools::RelativeIfUnder(std::string const& top,
                                           std::string const& in)
{
  std::string out;
  if (in == top) {
    out = ".";
  } else if (cmSystemTools::IsSubDirectory(in, top)) {
    out = in.substr(top.size() + (top.back() == '/' ? 0 : 1));
  } else {
    out = in;
  }
  return out;
}

cm::optional<std::string> cmSystemTools::GetEnvVar(std::string const& var)
{
  cm::optional<std::string> result;
  {
    std::string value;
    if (cmSystemTools::GetEnv(var, value)) {
      result = std::move(value);
    }
  }
  return result;
}

std::vector<std::string> cmSystemTools::GetEnvPathNormalized(
  std::string const& var)
{
  std::vector<std::string> result;
  if (cm::optional<std::string> env = cmSystemTools::GetEnvVar(var)) {
    std::vector<std::string> p = cmSystemTools::SplitEnvPathNormalized(*env);
    std::move(p.begin(), p.end(), std::back_inserter(result));
  }
  return result;
}

std::vector<std::string> cmSystemTools::SplitEnvPath(cm::string_view in)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
  static cm::string_view sep = ";"_s;
#else
  static cm::string_view sep = ":"_s;
#endif
  std::vector<std::string> paths;
  cm::string_view::size_type e = 0;
  for (;;) {
    cm::string_view::size_type b = in.find_first_not_of(sep, e);
    if (b == cm::string_view::npos) {
      break;
    }
    e = in.find_first_of(sep, b);
    if (e == cm::string_view::npos) {
      paths.emplace_back(in.substr(b));
      break;
    }
    paths.emplace_back(in.substr(b, e - b));
  }
  return paths;
}

std::vector<std::string> cmSystemTools::SplitEnvPathNormalized(
  cm::string_view in)
{
  std::vector<std::string> paths = cmSystemTools::SplitEnvPath(in);
  std::transform(paths.begin(), paths.end(), paths.begin(),
                 cmSystemTools::ToNormalizedPathOnDisk);
  return paths;
}

std::string cmSystemTools::ToNormalizedPathOnDisk(std::string p)
{
  p = ResolveTildePath(p);
  using namespace cm::PathResolver;
#ifdef _WIN32
  // IWYU pragma: no_forward_declare cm::PathResolver::Policies::CasePath
  static Resolver<Policies::CasePath> const resolver(RealOS);
#else
  // IWYU pragma: no_forward_declare cm::PathResolver::Policies::LogicalPath
  static Resolver<Policies::LogicalPath> const resolver(RealOS);
#endif
  resolver.Resolve(std::move(p), p);
  return p;
}

#ifndef CMAKE_BOOTSTRAP
bool cmSystemTools::UnsetEnv(char const* value)
{
#  if !defined(HAVE_UNSETENV)
  return cmSystemTools::UnPutEnv(value);
#  else
  unsetenv(value);
  return true;
#  endif
}

std::vector<std::string> cmSystemTools::GetEnvironmentVariables()
{
  std::vector<std::string> env;
  int cc;
#  ifdef _WIN32
  // if program starts with main, _wenviron is initially NULL, call to
  // _wgetenv and create wide-character string environment
  _wgetenv(L"");
  for (cc = 0; _wenviron[cc]; ++cc) {
    env.emplace_back(cmsys::Encoding::ToNarrow(_wenviron[cc]));
  }
#  else
  for (cc = 0; environ[cc]; ++cc) {
    env.emplace_back(environ[cc]);
  }
#  endif
  return env;
}

void cmSystemTools::AppendEnv(std::vector<std::string> const& env)
{
  for (std::string const& var : env) {
    cmSystemTools::PutEnv(var);
  }
}

void cmSystemTools::EnvDiff::AppendEnv(std::vector<std::string> const& env)
{
  for (std::string const& var : env) {
    this->PutEnv(var);
  }
}

void cmSystemTools::EnvDiff::PutEnv(std::string const& env)
{
  auto const eq_loc = env.find('=');
  if (eq_loc != std::string::npos) {
    std::string name = env.substr(0, eq_loc);
    diff[name] = env.substr(eq_loc + 1);
  } else {
    this->UnPutEnv(env);
  }
}

void cmSystemTools::EnvDiff::UnPutEnv(std::string const& env)
{
  diff[env] = cm::nullopt;
}

bool cmSystemTools::EnvDiff::ParseOperation(std::string const& envmod)
{
  char path_sep = GetSystemPathlistSeparator();

  auto apply_diff = [this](std::string const& name,
                           std::function<void(std::string&)> const& apply) {
    cm::optional<std::string> old_value = diff[name];
    std::string output;
    if (old_value) {
      output = *old_value;
    } else {
      char const* curval = cmSystemTools::GetEnv(name);
      if (curval) {
        output = curval;
      }
    }
    apply(output);
    diff[name] = output;
  };

  // Split on `=`
  auto const eq_loc = envmod.find_first_of('=');
  if (eq_loc == std::string::npos) {
    cmSystemTools::Error(cmStrCat(
      "Error: Missing `=` after the variable name in: ", envmod, '\n'));
    return false;
  }

  auto const name = envmod.substr(0, eq_loc);

  // Split value on `:`
  auto const op_value_start = eq_loc + 1;
  auto const colon_loc = envmod.find_first_of(':', op_value_start);
  if (colon_loc == std::string::npos) {
    cmSystemTools::Error(
      cmStrCat("Error: Missing `:` after the operation in: ", envmod, '\n'));
    return false;
  }
  auto const op = envmod.substr(op_value_start, colon_loc - op_value_start);

  auto const value_start = colon_loc + 1;
  auto const value = envmod.substr(value_start);

  // Determine what to do with the operation.
  if (op == "reset"_s) {
    auto entry = diff.find(name);
    if (entry != diff.end()) {
      diff.erase(entry);
    }
  } else if (op == "set"_s) {
    diff[name] = value;
  } else if (op == "unset"_s) {
    diff[name] = cm::nullopt;
  } else if (op == "string_append"_s) {
    apply_diff(name, [&value](std::string& output) { output += value; });
  } else if (op == "string_prepend"_s) {
    apply_diff(name,
               [&value](std::string& output) { output.insert(0, value); });
  } else if (op == "path_list_append"_s) {
    apply_diff(name, [&value, path_sep](std::string& output) {
      if (!output.empty()) {
        output += path_sep;
      }
      output += value;
    });
  } else if (op == "path_list_prepend"_s) {
    apply_diff(name, [&value, path_sep](std::string& output) {
      if (!output.empty()) {
        output.insert(output.begin(), path_sep);
      }
      output.insert(0, value);
    });
  } else if (op == "cmake_list_append"_s) {
    apply_diff(name, [&value](std::string& output) {
      if (!output.empty()) {
        output += ';';
      }
      output += value;
    });
  } else if (op == "cmake_list_prepend"_s) {
    apply_diff(name, [&value](std::string& output) {
      if (!output.empty()) {
        output.insert(output.begin(), ';');
      }
      output.insert(0, value);
    });
  } else {
    cmSystemTools::Error(cmStrCat(
      "Error: Unrecognized environment manipulation argument: ", op, '\n'));
    return false;
  }

  return true;
}

void cmSystemTools::EnvDiff::ApplyToCurrentEnv(std::ostringstream* measurement)
{
  for (auto const& env_apply : diff) {
    if (env_apply.second) {
      auto const env_update =
        cmStrCat(env_apply.first, '=', *env_apply.second);
      cmSystemTools::PutEnv(env_update);
      if (measurement) {
        *measurement << env_update << std::endl;
      }
    } else {
      cmSystemTools::UnsetEnv(env_apply.first.c_str());
      if (measurement) {
        // Signify that this variable is being actively unset
        *measurement << '#' << env_apply.first << "=\n";
      }
    }
  }
}

cmSystemTools::SaveRestoreEnvironment::SaveRestoreEnvironment()
{
  this->Env = cmSystemTools::GetEnvironmentVariables();
}

cmSystemTools::SaveRestoreEnvironment::~SaveRestoreEnvironment()
{
  // First clear everything in the current environment:
  std::vector<std::string> currentEnv = GetEnvironmentVariables();
  for (std::string var : currentEnv) {
    std::string::size_type pos = var.find('=');
    if (pos != std::string::npos) {
      var = var.substr(0, pos);
    }

    cmSystemTools::UnsetEnv(var.c_str());
  }

  // Then put back each entry from the original environment:
  cmSystemTools::AppendEnv(this->Env);
}
#endif

cmSystemTools::ScopedEnv::ScopedEnv(cm::string_view var)
{
  std::string::size_type pos = var.find('=');
  if (pos != std::string::npos) {
    this->Key = std::string{ var.substr(0, pos) };
    this->Original = cmSystemTools::GetEnvVar(this->Key);

    cm::string_view value = var.substr(pos + 1);

    if (!this->Original && value.empty()) {
      // nothing to do if the environment variable wasn't already set and the
      // new value is also empty. clear the Key member so the destructor also
      // does nothing.
      this->Key.clear();
    } else {
      if (value.empty()) {
        cmSystemTools::UnPutEnv(this->Key);
      } else {
        cmSystemTools::PutEnv(cmStrCat(this->Key, '=', value));
      }
    }
  }
}

cmSystemTools::ScopedEnv::~ScopedEnv()
{
  if (!this->Key.empty()) {
    if (this->Original) {
      cmSystemTools::PutEnv(cmStrCat(this->Key, '=', *this->Original));
    } else {
      cmSystemTools::UnPutEnv(Key);
    }
  }
}

void cmSystemTools::EnableVSConsoleOutput()
{
#ifdef _WIN32
  // Visual Studio tools like devenv may not
  // display output to the console unless this environment variable is
  // set.  We need it to capture the output of these build tools.
  // Note for future work that one could pass "/out \\.\pipe\NAME" to
  // either of these executables where NAME is created with
  // CreateNamedPipe.  This would bypass the internal buffering of the
  // output and allow it to be captured on the fly.
  cmSystemTools::PutEnv("vsconsoleoutput=1");

#  ifndef CMAKE_BOOTSTRAP
  // VS sets an environment variable to tell MS tools like "cl" to report
  // output through a backdoor pipe instead of stdout/stderr.  Unset the
  // environment variable to close this backdoor for any path of process
  // invocations that passes through CMake so we can capture the output.
  cmSystemTools::UnsetEnv("VS_UNICODE_OUTPUT");
#  endif
#endif
}

bool cmSystemTools::IsPathToFramework(std::string const& path)
{
  return (cmSystemTools::FileIsFullPath(path) &&
          cmHasLiteralSuffix(path, ".framework"));
}

bool cmSystemTools::IsPathToXcFramework(std::string const& path)
{
  return (cmSystemTools::FileIsFullPath(path) &&
          cmHasLiteralSuffix(path, ".xcframework"));
}

bool cmSystemTools::IsPathToMacOSSharedLibrary(std::string const& path)
{
  return (cmSystemTools::FileIsFullPath(path) &&
          cmHasLiteralSuffix(path, ".dylib"));
}

bool cmSystemTools::CreateTar(std::string const& outFileName,
                              std::vector<std::string> const& files,
                              std::string const& workingDirectory,
                              cmTarCompression compressType, bool verbose,
                              std::string const& mtime,
                              std::string const& format, int compressionLevel,
                              int numThreads)
{
#if !defined(CMAKE_BOOTSTRAP)
  cmWorkingDirectory workdir(cmSystemTools::GetLogicalWorkingDirectory());
  if (!workingDirectory.empty()) {
    workdir.SetDirectory(workingDirectory);
  }

  std::string const cwd = cmSystemTools::GetLogicalWorkingDirectory();
  cmsys::ofstream fout(outFileName.c_str(), std::ios::out | std::ios::binary);
  if (!fout) {
    std::string e = cmStrCat("Cannot open output file \"", outFileName,
                             "\": ", cmSystemTools::GetLastSystemError());
    cmSystemTools::Error(e);
    return false;
  }
  cmArchiveWrite::Compress compress = cmArchiveWrite::CompressNone;
  switch (compressType) {
    case TarCompressGZip:
      compress = cmArchiveWrite::CompressGZip;
      break;
    case TarCompressBZip2:
      compress = cmArchiveWrite::CompressBZip2;
      break;
    case TarCompressXZ:
      compress = cmArchiveWrite::CompressXZ;
      break;
    case TarCompressZstd:
      compress = cmArchiveWrite::CompressZstd;
      break;
    case TarCompressLZMA:
      compress = cmArchiveWrite::CompressLZMA;
      break;
    case TarCompressNone:
      compress = cmArchiveWrite::CompressNone;
      break;
  }

  cmArchiveWrite a(fout, compress, format.empty() ? "paxr" : format,
                   compressionLevel, numThreads);

  if (!a.Open()) {
    cmSystemTools::Error(a.GetError());
    return false;
  }
  a.SetMTime(mtime);
  a.SetVerbose(verbose);
  bool tarCreatedSuccessfully = true;
  for (auto path : files) {
    if (cmSystemTools::FileIsFullPath(path)) {
      // Get the relative path to the file.
      path = cmSystemTools::RelativePath(cwd, path);
    }
    if (!a.Add(path)) {
      cmSystemTools::Error(a.GetError());
      tarCreatedSuccessfully = false;
    }
  }
  return tarCreatedSuccessfully;
#else
  (void)outFileName;
  (void)files;
  (void)verbose;
  return false;
#endif
}

#if !defined(CMAKE_BOOTSTRAP)
namespace {
#  define BSDTAR_FILESIZE_PRINTF "%lu"
#  define BSDTAR_FILESIZE_TYPE unsigned long
void list_item_verbose(FILE* out, struct archive_entry* entry)
{
  char tmp[100];
  size_t w;
  char const* p;
  char const* fmt;
  time_t tim;
  static time_t now;
  size_t u_width = 6;
  size_t gs_width = 13;

  /*
   * We avoid collecting the entire list in memory at once by
   * listing things as we see them.  However, that also means we can't
   * just pre-compute the field widths.  Instead, we start with guesses
   * and just widen them as necessary.  These numbers are completely
   * arbitrary.
   */
  if (!now) {
    time(&now);
  }
  fprintf(out, "%s %u ", archive_entry_strmode(entry),
          archive_entry_nlink(entry));

  /* Use uname if it's present, else uid. */
  p = archive_entry_uname(entry);
  if (!p || (*p == '\0')) {
    snprintf(tmp, sizeof(tmp), "%lu ",
             static_cast<unsigned long>(archive_entry_uid(entry)));
    p = tmp;
  }
  w = strlen(p);
  if (w > u_width) {
    u_width = w;
  }
  fprintf(out, "%-*s ", static_cast<int>(u_width), p);
  /* Use gname if it's present, else gid. */
  p = archive_entry_gname(entry);
  if (p && p[0] != '\0') {
    fprintf(out, "%s", p);
    w = strlen(p);
  } else {
    snprintf(tmp, sizeof(tmp), "%lu",
             static_cast<unsigned long>(archive_entry_gid(entry)));
    w = strlen(tmp);
    fprintf(out, "%s", tmp);
  }

  /*
   * Print device number or file size, right-aligned so as to make
   * total width of group and devnum/filesize fields be gs_width.
   * If gs_width is too small, grow it.
   */
  if (archive_entry_filetype(entry) == AE_IFCHR ||
      archive_entry_filetype(entry) == AE_IFBLK) {
    unsigned long rdevmajor = archive_entry_rdevmajor(entry);
    unsigned long rdevminor = archive_entry_rdevminor(entry);
    snprintf(tmp, sizeof(tmp), "%lu,%lu", rdevmajor, rdevminor);
  } else {
    /*
     * Note the use of platform-dependent macros to format
     * the filesize here.  We need the format string and the
     * corresponding type for the cast.
     */
    snprintf(tmp, sizeof(tmp), BSDTAR_FILESIZE_PRINTF,
             static_cast<BSDTAR_FILESIZE_TYPE>(archive_entry_size(entry)));
  }
  if (w + strlen(tmp) >= gs_width) {
    gs_width = w + strlen(tmp) + 1;
  }
  fprintf(out, "%*s", static_cast<int>(gs_width - w), tmp);

  /* Format the time using 'ls -l' conventions. */
  tim = archive_entry_mtime(entry);
#  define HALF_YEAR ((time_t)365 * 86400 / 2)
#  if defined(_WIN32) && !defined(__CYGWIN__)
/* Windows' strftime function does not support %e format. */
#    define DAY_FMT "%d"
#  else
#    define DAY_FMT "%e" /* Day number without leading zeros */
#  endif
  if (tim < now - HALF_YEAR || tim > now + HALF_YEAR) {
    fmt = DAY_FMT " %b  %Y";
  } else {
    fmt = DAY_FMT " %b %H:%M";
  }
  strftime(tmp, sizeof(tmp), fmt, localtime(&tim));
  fprintf(out, " %s ", tmp);
  fprintf(out, "%s", cm_archive_entry_pathname(entry).c_str());

  /* Extra information for links. */
  if (archive_entry_hardlink(entry)) /* Hard link */
  {
    fprintf(out, " link to %s", archive_entry_hardlink(entry));
  } else if (archive_entry_symlink(entry)) /* Symbolic link */
  {
    fprintf(out, " -> %s", archive_entry_symlink(entry));
  }
  fflush(out);
}

void ArchiveError(char const* m1, struct archive* a)
{
  std::string message(m1);
  char const* m2 = archive_error_string(a);
  if (m2) {
    message += m2;
  }
  cmSystemTools::Error(message);
}

bool la_diagnostic(struct archive* ar, __LA_SSIZE_T r)
{
  // See archive.h definition of ARCHIVE_OK for return values.

  if (r >= ARCHIVE_OK) {
    return true;
  }

  if (r >= ARCHIVE_WARN) {
    char const* warn = archive_error_string(ar);
    if (!warn) {
      warn = "unknown warning";
    }
    std::cerr << "cmake -E tar: warning: " << warn << '\n';
    return true;
  }

  // Error.
  char const* err = archive_error_string(ar);
  if (!err) {
    err = "unknown error";
  }
  std::cerr << "cmake -E tar: error: " << err << '\n';
  return false;
}

// Return 'true' on success
bool copy_data(struct archive* ar, struct archive* aw)
{
  long r;
  void const* buff;
  size_t size;
#  if defined(ARCHIVE_VERSION_NUMBER) && ARCHIVE_VERSION_NUMBER >= 3000000
  __LA_INT64_T offset;
#  else
  off_t offset;
#  endif

  for (;;) {
    // See archive.h definition of ARCHIVE_OK for return values.
    r = archive_read_data_block(ar, &buff, &size, &offset);
    if (r == ARCHIVE_EOF) {
      return true;
    }
    if (!la_diagnostic(ar, r)) {
      return false;
    }
    // See archive.h definition of ARCHIVE_OK for return values.
    __LA_SSIZE_T const w = archive_write_data_block(aw, buff, size, offset);
    if (!la_diagnostic(ar, w)) {
      return false;
    }
  }
#  if !defined(__clang__) && !defined(__NVCOMPILER) && !defined(__HP_aCC)
  return false; /* this should not happen but it quiets some compilers */
#  endif
}

bool extract_tar(std::string const& outFileName,
                 std::vector<std::string> const& files, bool verbose,
                 cmSystemTools::cmTarExtractTimestamps extractTimestamps,
                 bool extract)
{
  cmLocaleRAII localeRAII;
  static_cast<void>(localeRAII);
  struct archive* a = archive_read_new();
  struct archive* ext = archive_write_disk_new();
  archive_read_support_filter_all(a);
  archive_read_support_format_all(a);
  struct archive_entry* entry;

  struct archive* matching = archive_match_new();
  if (!matching) {
    cmSystemTools::Error("Out of memory");
    return false;
  }

  for (auto const& filename : files) {
    if (archive_match_include_pattern(matching, filename.c_str()) !=
        ARCHIVE_OK) {
      cmSystemTools::Error("Failed to add to inclusion list: " + filename);
      return false;
    }
  }

  int r = cm_archive_read_open_file(a, outFileName.c_str(), 10240);
  if (r) {
    ArchiveError("Problem with archive_read_open_file(): ", a);
    archive_write_free(ext);
    archive_read_close(a);
    return false;
  }
  for (;;) {
    r = archive_read_next_header(a, &entry);
    if (r == ARCHIVE_EOF) {
      break;
    }
    if (r != ARCHIVE_OK) {
      ArchiveError("Problem with archive_read_next_header(): ", a);
      break;
    }

    if (archive_match_excluded(matching, entry)) {
      continue;
    }

    if (verbose) {
      if (extract) {
        cmSystemTools::Stdout(
          cmStrCat("x ", cm_archive_entry_pathname(entry)));
      } else {
        list_item_verbose(stdout, entry);
      }
      cmSystemTools::Stdout("\n");
    } else if (!extract) {
      cmSystemTools::Stdout(cmStrCat(cm_archive_entry_pathname(entry), '\n'));
    }
    if (extract) {
      if (extractTimestamps == cmSystemTools::cmTarExtractTimestamps::Yes) {
        r = archive_write_disk_set_options(ext, ARCHIVE_EXTRACT_TIME);
        if (r != ARCHIVE_OK) {
          ArchiveError("Problem with archive_write_disk_set_options(): ", ext);
          break;
        }
      }

      r = archive_write_header(ext, entry);
      if (r == ARCHIVE_OK) {
        if (!copy_data(a, ext)) {
          break;
        }
        r = archive_write_finish_entry(ext);
        if (r != ARCHIVE_OK) {
          ArchiveError("Problem with archive_write_finish_entry(): ", ext);
          break;
        }
      }
#  ifdef _WIN32
      else if (char const* linktext = archive_entry_symlink(entry)) {
        std::cerr << "cmake -E tar: warning: skipping symbolic link \""
                  << cm_archive_entry_pathname(entry) << "\" -> \"" << linktext
                  << "\"." << std::endl;
      }
#  endif
      else {
        ArchiveError("Problem with archive_write_header(): ", ext);
        cmSystemTools::Error("Current file: " +
                             cm_archive_entry_pathname(entry));
        break;
      }
    }
  }

  bool error_occurred = false;
  if (matching) {
    char const* p;
    int ar;

    while ((ar = archive_match_path_unmatched_inclusions_next(matching, &p)) ==
           ARCHIVE_OK) {
      cmSystemTools::Error("tar: " + std::string(p) +
                           ": Not found in archive");
      error_occurred = true;
    }
    if (error_occurred) {
      return false;
    }
    if (ar == ARCHIVE_FATAL) {
      cmSystemTools::Error("tar: Out of memory");
      return false;
    }
  }
  archive_match_free(matching);
  archive_write_free(ext);
  archive_read_close(a);
  archive_read_free(a);
  return r == ARCHIVE_EOF || r == ARCHIVE_OK;
}
}
#endif

bool cmSystemTools::ExtractTar(std::string const& outFileName,
                               std::vector<std::string> const& files,
                               cmTarExtractTimestamps extractTimestamps,
                               bool verbose)
{
#if !defined(CMAKE_BOOTSTRAP)
  return extract_tar(outFileName, files, verbose, extractTimestamps, true);
#else
  (void)outFileName;
  (void)files;
  (void)extractTimestamps;
  (void)verbose;
  return false;
#endif
}

bool cmSystemTools::ListTar(std::string const& outFileName,
                            std::vector<std::string> const& files,
                            bool verbose)
{
#if !defined(CMAKE_BOOTSTRAP)
  return extract_tar(outFileName, files, verbose, cmTarExtractTimestamps::Yes,
                     false);
#else
  (void)outFileName;
  (void)files;
  (void)verbose;
  return false;
#endif
}

cmSystemTools::WaitForLineResult cmSystemTools::WaitForLine(
  uv_loop_t* loop, uv_stream_t* outPipe, uv_stream_t* errPipe,
  std::string& line, cmDuration timeout, std::vector<char>& out,
  std::vector<char>& err)
{
  line.clear();
  auto outiter = out.begin();
  auto erriter = err.begin();
  cmProcessOutput processOutput;
  std::string strdata;
  while (true) {
    // Check for a newline in stdout.
    for (; outiter != out.end(); ++outiter) {
      if ((*outiter == '\r') && ((outiter + 1) == out.end())) {
        break;
      }
      if (*outiter == '\n' || *outiter == '\0') {
        std::vector<char>::size_type length = outiter - out.begin();
        if (length > 1 && *(outiter - 1) == '\r') {
          --length;
        }
        if (length > 0) {
          line.append(out.data(), length);
        }
        out.erase(out.begin(), outiter + 1);
        return WaitForLineResult::STDOUT;
      }
    }

    // Check for a newline in stderr.
    for (; erriter != err.end(); ++erriter) {
      if ((*erriter == '\r') && ((erriter + 1) == err.end())) {
        break;
      }
      if (*erriter == '\n' || *erriter == '\0') {
        std::vector<char>::size_type length = erriter - err.begin();
        if (length > 1 && *(erriter - 1) == '\r') {
          --length;
        }
        if (length > 0) {
          line.append(err.data(), length);
        }
        err.erase(err.begin(), erriter + 1);
        return WaitForLineResult::STDERR;
      }
    }

    // No newlines found.  Wait for more data from the process.
    struct ReadData
    {
      uv_stream_t* Stream;
      std::vector<char> Buffer;
      bool Read = false;
      bool Finished = false;
    };
    auto startRead =
      [](uv_stream_t* stream,
         ReadData& data) -> std::unique_ptr<cmUVStreamReadHandle> {
      data.Stream = stream;
      return cmUVStreamRead(
        stream,
        [&data](std::vector<char> buf) {
          data.Buffer = std::move(buf);
          data.Read = true;
          uv_read_stop(data.Stream);
        },
        [&data]() { data.Finished = true; });
    };
    ReadData outData;
    auto outHandle = startRead(outPipe, outData);
    ReadData errData;
    auto errHandle = startRead(errPipe, errData);

    cm::uv_timer_ptr timer;
    bool timedOut = false;
    timer.init(*loop, &timedOut);
    timer.start(
      [](uv_timer_t* handle) {
        auto* timedOutPtr = static_cast<bool*>(handle->data);
        *timedOutPtr = true;
      },
      static_cast<uint64_t>(timeout.count() * 1000.0), 0,
      cm::uv_update_time::no);

    uv_run(loop, UV_RUN_ONCE);
    if (timedOut) {
      // Timeout has been exceeded.
      return WaitForLineResult::Timeout;
    }
    if (outData.Read) {
      processOutput.DecodeText(outData.Buffer.data(), outData.Buffer.size(),
                               strdata, 1);
      // Append to the stdout buffer.
      std::vector<char>::size_type size = out.size();
      cm::append(out, strdata);
      outiter = out.begin() + size;
    } else if (errData.Read) {
      processOutput.DecodeText(errData.Buffer.data(), errData.Buffer.size(),
                               strdata, 2);
      // Append to the stderr buffer.
      std::vector<char>::size_type size = err.size();
      cm::append(err, strdata);
      erriter = err.begin() + size;
    } else if (outData.Finished && errData.Finished) {
      // Both stdout and stderr pipes have broken.  Return leftover data.
      processOutput.DecodeText(std::string(), strdata, 1);
      if (!strdata.empty()) {
        std::vector<char>::size_type size = out.size();
        cm::append(out, strdata);
        outiter = out.begin() + size;
      }
      processOutput.DecodeText(std::string(), strdata, 2);
      if (!strdata.empty()) {
        std::vector<char>::size_type size = err.size();
        cm::append(err, strdata);
        erriter = err.begin() + size;
      }
      if (!out.empty()) {
        line.append(out.data(), outiter - out.begin());
        out.erase(out.begin(), out.end());
        return WaitForLineResult::STDOUT;
      }
      if (!err.empty()) {
        line.append(err.data(), erriter - err.begin());
        err.erase(err.begin(), err.end());
        return WaitForLineResult::STDERR;
      }
      return WaitForLineResult::None;
    }
    if (!outData.Finished) {
      uv_read_stop(outPipe);
    }
    if (!errData.Finished) {
      uv_read_stop(errPipe);
    }
  }
}

#ifdef _WIN32
#  ifndef CRYPT_SILENT
#    define CRYPT_SILENT 0x40 /* Not defined by VS 6 version of header.  */
#  endif
static int WinCryptRandom(void* data, size_t size)
{
  int result = 0;
  HCRYPTPROV hProvider = 0;
  if (CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL,
                           CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
    result = CryptGenRandom(hProvider, (DWORD)size, (BYTE*)data) ? 1 : 0;
    CryptReleaseContext(hProvider, 0);
  }
  return result;
}
#endif

unsigned int cmSystemTools::RandomSeed()
{
#if defined(_WIN32) && !defined(__CYGWIN__)
  unsigned int seed = 0;

  // Try using a real random source.
  if (WinCryptRandom(&seed, sizeof(seed))) {
    return seed;
  }

  // Fall back to the time and pid.
  FILETIME ft;
  GetSystemTimeAsFileTime(&ft);
  unsigned int t1 = static_cast<unsigned int>(ft.dwHighDateTime);
  unsigned int t2 = static_cast<unsigned int>(ft.dwLowDateTime);
  unsigned int pid = static_cast<unsigned int>(GetCurrentProcessId());
  return t1 ^ t2 ^ pid;
#else
  union
  {
    unsigned int integer;
    char bytes[sizeof(unsigned int)];
  } seed;

  // Try using a real random source.
  cmsys::ifstream fin;
  fin.rdbuf()->pubsetbuf(nullptr, 0); // Unbuffered read.
  fin.open("/dev/urandom");
  if (fin.good() && fin.read(seed.bytes, sizeof(seed)) &&
      fin.gcount() == sizeof(seed)) {
    return seed.integer;
  }

  // Fall back to the time and pid.
  struct timeval t;
  gettimeofday(&t, nullptr);
  unsigned int pid = static_cast<unsigned int>(getpid());
  unsigned int tv_sec = static_cast<unsigned int>(t.tv_sec);
  unsigned int tv_usec = static_cast<unsigned int>(t.tv_usec);
  // Since tv_usec never fills more than 11 bits we shift it to fill
  // in the slow-changing high-order bits of tv_sec.
  return tv_sec ^ (tv_usec << 21) ^ pid;
#endif
}

unsigned int cmSystemTools::RandomNumber()
{
#ifndef CM_HAVE_THREAD_LOCAL
  static std::mutex gen_mutex;
  std::lock_guard<std::mutex> gen_mutex_lock(gen_mutex);
#else
  thread_local
#endif
  static std::mt19937 gen{ cmSystemTools::RandomSeed() };
  return static_cast<unsigned int>(gen());
}

std::string cmSystemTools::FindProgram(std::string const& name,
                                       std::vector<std::string> const& path)
{
  std::string exe = cmsys::SystemTools::FindProgram(name, path);
  if (!exe.empty()) {
    exe = cmSystemTools::ToNormalizedPathOnDisk(std::move(exe));
  }
  return exe;
}

namespace {
std::string InitLogicalWorkingDirectory()
{
  std::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory();
  std::string pwd;
  if (cmSystemTools::GetEnv("PWD", pwd) &&
      cmSystemTools::FileIsFullPath(pwd)) {
    std::string const pwd_real = cmSystemTools::GetRealPath(pwd);
    if (pwd_real == cwd) {
      cwd = cmSystemTools::ToNormalizedPathOnDisk(std::move(pwd));
    }
  }
  return cwd;
}

std::string cmSystemToolsLogicalWorkingDirectory =
  InitLogicalWorkingDirectory();

std::string cmSystemToolsCMakeCommand;
std::string cmSystemToolsCTestCommand;
std::string cmSystemToolsCPackCommand;
std::string cmSystemToolsCMakeCursesCommand;
std::string cmSystemToolsCMakeGUICommand;
std::string cmSystemToolsCMClDepsCommand;
std::string cmSystemToolsCMakeRoot;
std::string cmSystemToolsHTMLDoc;

#if defined(__APPLE__)
bool IsCMakeAppBundleExe(std::string const& exe)
{
  return cmHasLiteralSuffix(cmSystemTools::LowerCase(exe), "/macos/cmake");
}
#endif

std::string FindOwnExecutable(char const* argv0)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
  static_cast<void>(argv0);
  wchar_t modulepath[_MAX_PATH];
  ::GetModuleFileNameW(nullptr, modulepath, sizeof(modulepath));
  std::string exe = cmsys::Encoding::ToNarrow(modulepath);
#elif defined(__APPLE__)
  static_cast<void>(argv0);
#  define CM_EXE_PATH_LOCAL_SIZE 16384
  char exe_path_local[CM_EXE_PATH_LOCAL_SIZE];
#  if defined(MAC_OS_X_VERSION_10_3) && !defined(MAC_OS_X_VERSION_10_4)
  unsigned long exe_path_size = CM_EXE_PATH_LOCAL_SIZE;
#  else
  uint32_t exe_path_size = CM_EXE_PATH_LOCAL_SIZE;
#  endif
#  undef CM_EXE_PATH_LOCAL_SIZE
  char* exe_path = exe_path_local;
  if (_NSGetExecutablePath(exe_path, &exe_path_size) < 0) {
    exe_path = static_cast<char*>(malloc(exe_path_size));
    _NSGetExecutablePath(exe_path, &exe_path_size);
  }
  std::string exe = exe_path;
  if (exe_path != exe_path_local) {
    free(exe_path);
  }
  if (IsCMakeAppBundleExe(exe)) {
    // The executable is inside an application bundle.
    // The install tree has "..<CMAKE_BIN_DIR>/cmake-gui".
    // The build tree has '../../../cmake-gui".
    std::string dir = cmSystemTools::GetFilenamePath(exe);
    dir = cmSystemTools::GetFilenamePath(dir);
    exe = cmStrCat(dir, CMAKE_BIN_DIR "/cmake-gui");
    if (!cmSystemTools::PathExists(exe)) {
      dir = cmSystemTools::GetFilenamePath(dir);
      dir = cmSystemTools::GetFilenamePath(dir);
      exe = cmStrCat(dir, "/cmake-gui");
    }
  }
#else
  std::string exe = cmsys::SystemTools::FindProgram(argv0);
#endif
  exe = cmSystemTools::ToNormalizedPathOnDisk(std::move(exe));
  return exe;
}

#ifndef CMAKE_BOOTSTRAP
bool ResolveSymlinkToOwnExecutable(std::string& exe, std::string& exe_dir)
{
  std::string linked_exe;
  if (!cmSystemTools::ReadSymlink(exe, linked_exe)) {
    return false;
  }
#  if defined(__APPLE__)
  // Ignore "cmake-gui -> ../MacOS/CMake".
  if (IsCMakeAppBundleExe(linked_exe)) {
    return false;
  }
#  endif
  if (cmSystemTools::FileIsFullPath(linked_exe)) {
    exe = std::move(linked_exe);
  } else {
    exe = cmStrCat(exe_dir, '/', std::move(linked_exe));
  }
  exe = cmSystemTools::ToNormalizedPathOnDisk(std::move(exe));
  exe_dir = cmSystemTools::GetFilenamePath(exe);
  return true;
}

bool FindCMakeResourcesInInstallTree(std::string const& exe_dir)
{
  // Install tree has
  // - "<prefix><CMAKE_BIN_DIR>/cmake"
  // - "<prefix><CMAKE_DATA_DIR>"
  // - "<prefix><CMAKE_DOC_DIR>"
  if (cmHasLiteralSuffix(exe_dir, CMAKE_BIN_DIR)) {
    std::string const prefix =
      exe_dir.substr(0, exe_dir.size() - cmStrLen(CMAKE_BIN_DIR));
    // Set cmSystemToolsCMakeRoot set to the location expected in an
    // install tree, even if it does not exist, so that
    // cmake::AddCMakePaths can print the location in its error message.
    cmSystemToolsCMakeRoot = cmStrCat(prefix, CMAKE_DATA_DIR);
    if (cmSystemTools::FileExists(
          cmStrCat(cmSystemToolsCMakeRoot, "/Modules/CMake.cmake"))) {
      if (cmSystemTools::FileExists(
            cmStrCat(prefix, CMAKE_DOC_DIR "/html/index.html"))) {
        cmSystemToolsHTMLDoc = cmStrCat(prefix, CMAKE_DOC_DIR "/html");
      }
      return true;
    }
  }
  return false;
}

void FindCMakeResourcesInBuildTree(std::string const& exe_dir)
{
  // Build tree has "<build>/bin[/<config>]/cmake" and
  // "<build>/CMakeFiles/CMakeSourceDir.txt".
  std::string dir = cmSystemTools::GetFilenamePath(exe_dir);
  std::string src_dir_txt = cmStrCat(dir, "/CMakeFiles/CMakeSourceDir.txt");
  cmsys::ifstream fin(src_dir_txt.c_str());
  std::string src_dir;
  if (fin && cmSystemTools::GetLineFromStream(fin, src_dir) &&
      cmSystemTools::FileIsDirectory(src_dir)) {
    cmSystemToolsCMakeRoot = src_dir;
  } else {
    dir = cmSystemTools::GetFilenamePath(dir);
    src_dir_txt = cmStrCat(dir, "/CMakeFiles/CMakeSourceDir.txt");
    cmsys::ifstream fin2(src_dir_txt.c_str());
    if (fin2 && cmSystemTools::GetLineFromStream(fin2, src_dir) &&
        cmSystemTools::FileIsDirectory(src_dir)) {
      cmSystemToolsCMakeRoot = src_dir;
    }
  }
  if (!cmSystemToolsCMakeRoot.empty() && cmSystemToolsHTMLDoc.empty() &&
      cmSystemTools::FileExists(
        cmStrCat(dir, "/Utilities/Sphinx/html/index.html"))) {
    cmSystemToolsHTMLDoc = cmStrCat(dir, "/Utilities/Sphinx/html");
  }
}
#endif
}

void cmSystemTools::FindCMakeResources(char const* argv0)
{
  std::string exe = FindOwnExecutable(argv0);
#ifdef CMAKE_BOOTSTRAP
  // The bootstrap cmake knows its resource locations.
  cmSystemToolsCMakeRoot = CMAKE_BOOTSTRAP_SOURCE_DIR;
  cmSystemToolsCMakeCommand = exe;
  // The bootstrap cmake does not provide the other tools,
  // so use the directory where they are about to be built.
  std::string exe_dir = CMAKE_BOOTSTRAP_BINARY_DIR "/bin";
#else
  // Find resources relative to our own executable.
  std::string exe_dir = cmSystemTools::GetFilenamePath(exe);
  bool found = false;
  // When running through a symlink to our own executable,
  // preserve symlinks in directory components if possible.
  do {
    found = FindCMakeResourcesInInstallTree(exe_dir);
  } while (!found && ResolveSymlinkToOwnExecutable(exe, exe_dir));
  // If we have not yet found the resources, the above loop will
  // have left 'exe' referring to a real file, not a symlink, so
  // all our binaries should exist under 'exe_dir'.  However, the
  // resources may be discoverable only in the real path.
  if (!found) {
    found =
      FindCMakeResourcesInInstallTree(cmSystemTools::GetRealPath(exe_dir));
  }
  if (!found) {
    FindCMakeResourcesInBuildTree(exe_dir);
  }
  cmSystemToolsCMakeCommand =
    cmStrCat(exe_dir, "/cmake", cmSystemTools::GetExecutableExtension());
#endif
  cmSystemToolsCTestCommand =
    cmStrCat(exe_dir, "/ctest", cmSystemTools::GetExecutableExtension());
  cmSystemToolsCPackCommand =
    cmStrCat(exe_dir, "/cpack", cmSystemTools::GetExecutableExtension());
  cmSystemToolsCMakeGUICommand =
    cmStrCat(exe_dir, "/cmake-gui", cmSystemTools::GetExecutableExtension());
  if (!cmSystemTools::FileExists(cmSystemToolsCMakeGUICommand)) {
    cmSystemToolsCMakeGUICommand.clear();
  }
  cmSystemToolsCMakeCursesCommand =
    cmStrCat(exe_dir, "/ccmake", cmSystemTools::GetExecutableExtension());
  if (!cmSystemTools::FileExists(cmSystemToolsCMakeCursesCommand)) {
    cmSystemToolsCMakeCursesCommand.clear();
  }
  cmSystemToolsCMClDepsCommand =
    cmStrCat(exe_dir, "/cmcldeps", cmSystemTools::GetExecutableExtension());
  if (!cmSystemTools::FileExists(cmSystemToolsCMClDepsCommand)) {
    cmSystemToolsCMClDepsCommand.clear();
  }
}

std::string const& cmSystemTools::GetCMakeCommand()
{
  return cmSystemToolsCMakeCommand;
}

std::string const& cmSystemTools::GetCTestCommand()
{
  return cmSystemToolsCTestCommand;
}

std::string const& cmSystemTools::GetCPackCommand()
{
  return cmSystemToolsCPackCommand;
}

std::string const& cmSystemTools::GetCMakeCursesCommand()
{
  return cmSystemToolsCMakeCursesCommand;
}

std::string const& cmSystemTools::GetCMakeGUICommand()
{
  return cmSystemToolsCMakeGUICommand;
}

std::string const& cmSystemTools::GetCMClDepsCommand()
{
  return cmSystemToolsCMClDepsCommand;
}

std::string const& cmSystemTools::GetCMakeRoot()
{
  return cmSystemToolsCMakeRoot;
}

std::string const& cmSystemTools::GetHTMLDoc()
{
  return cmSystemToolsHTMLDoc;
}

cm::optional<std::string> cmSystemTools::GetSystemConfigDirectory()
{
#if defined(_WIN32)
  LPWSTR lpwstr;
  if (FAILED(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &lpwstr))) {
    return cm::nullopt;
  }
  std::wstring wstr = std::wstring(lpwstr);
  CoTaskMemFree(lpwstr);
  std::string config = cmsys::Encoding::ToNarrow(wstr);
  cmSystemTools::ConvertToUnixSlashes(config);
  return config;
#else
  auto config = cmSystemTools::GetEnvVar("XDG_CONFIG_HOME");
  if (!config.has_value()) {
    config = cmSystemTools::GetEnvVar("HOME");
    if (config.has_value()) {
#  if defined(__APPLE__)
      config = cmStrCat(config.value(), "/Library/Application Support");
#  else
      config = cmStrCat(config.value(), "/.config");
#  endif
    }
  }
  return config;
#endif
}

cm::optional<std::string> cmSystemTools::GetCMakeConfigDirectory()
{
  auto config = cmSystemTools::GetEnvVar("CMAKE_CONFIG_DIR");
  if (!config.has_value()) {
    config = cmSystemTools::GetSystemConfigDirectory();
    if (config.has_value()) {
#if defined(_WIN32) || defined(__APPLE__)
      config = cmStrCat(config.value(), "/CMake");
#else
      config = cmStrCat(config.value(), "/cmake");
#endif
    }
  }
  return config;
}

std::string const& cmSystemTools::GetLogicalWorkingDirectory()
{
  return cmSystemToolsLogicalWorkingDirectory;
}

cmsys::Status cmSystemTools::SetLogicalWorkingDirectory(std::string const& lwd)
{
  cmsys::Status status = cmSystemTools::ChangeDirectory(lwd);
  if (status) {
    cmSystemToolsLogicalWorkingDirectory = lwd;
  }
  return status;
}

bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath,
                                       std::string& soname)
{
  // For ELF shared libraries use a real parser to get the correct
  // soname.
  cmELF elf(fullPath.c_str());
  if (elf) {
    return elf.GetSOName(soname);
  }

  // If the file is not a symlink we have no guess for its soname.
  if (!cmSystemTools::FileIsSymlink(fullPath)) {
    return false;
  }
  if (!cmSystemTools::ReadSymlink(fullPath, soname)) {
    return false;
  }

  // If the symlink has a path component we have no guess for the soname.
  if (!cmSystemTools::GetFilenamePath(soname).empty()) {
    return false;
  }

  // If the symlink points at an extended version of the same name
  // assume it is the soname.
  std::string name = cmSystemTools::GetFilenameName(fullPath);
  return soname.length() > name.length() &&
    soname.compare(0, name.length(), name) == 0;
}

bool cmSystemTools::GuessLibraryInstallName(std::string const& fullPath,
                                            std::string& soname)
{
#if defined(CMake_USE_MACH_PARSER)
  cmMachO macho(fullPath.c_str());
  if (macho) {
    return macho.GetInstallName(soname);
  }
#else
  (void)fullPath;
  (void)soname;
#endif

  return false;
}

static std::string::size_type cmSystemToolsFindRPath(cm::string_view have,
                                                     cm::string_view want)
{
  std::string::size_type pos = 0;
  while (pos < have.size()) {
    // Look for an occurrence of the string.
    std::string::size_type const beg = have.find(want, pos);
    if (beg == std::string::npos) {
      return std::string::npos;
    }

    // Make sure it is separated from preceding entries.
    if (beg > 0 && have[beg - 1] != ':') {
      pos = beg + 1;
      continue;
    }

    // Make sure it is separated from following entries.
    std::string::size_type const end = beg + want.size();
    if (end < have.size() && have[end] != ':') {
      pos = beg + 1;
      continue;
    }

    // Return the position of the path portion.
    return beg;
  }

  // The desired rpath was not found.
  return std::string::npos;
}

namespace {
struct cmSystemToolsRPathInfo
{
  unsigned long Position;
  unsigned long Size;
  std::string Name;
  std::string Value;
};

using EmptyCallback = std::function<bool(std::string*, cmELF const&)>;
using AdjustCallback = std::function<bool(
  cm::optional<std::string>&, std::string const&, char const*, std::string*)>;

cm::optional<bool> AdjustRPathELF(std::string const& file,
                                  EmptyCallback const& emptyCallback,
                                  AdjustCallback const& adjustCallback,
                                  std::string* emsg, bool* changed)
{
  if (changed) {
    *changed = false;
  }
  int rp_count = 0;
  bool remove_rpath = true;
  cmSystemToolsRPathInfo rp[2];
  {
    // Parse the ELF binary.
    cmELF elf(file.c_str());
    if (!elf) {
      return cm::nullopt; // Not a valid ELF file.
    }

    if (!elf.HasDynamicSection()) {
      return true; // No dynamic section to update.
    }

    // Get the RPATH and RUNPATH entries from it.
    int se_count = 0;
    cmELF::StringEntry const* se[2] = { nullptr, nullptr };
    char const* se_name[2] = { nullptr, nullptr };
    if (cmELF::StringEntry const* se_rpath = elf.GetRPath()) {
      se[se_count] = se_rpath;
      se_name[se_count] = "RPATH";
      ++se_count;
    }
    if (cmELF::StringEntry const* se_runpath = elf.GetRunPath()) {
      se[se_count] = se_runpath;
      se_name[se_count] = "RUNPATH";
      ++se_count;
    }
    if (se_count == 0) {
      return emptyCallback(emsg, elf);
    }

    for (int i = 0; i < se_count; ++i) {
      // If both RPATH and RUNPATH refer to the same string literal it
      // needs to be changed only once.
      if (rp_count && rp[0].Position == se[i]->Position) {
        continue;
      }

      // Store information about the entry in the file.
      rp[rp_count].Position = se[i]->Position;
      rp[rp_count].Size = se[i]->Size;
      rp[rp_count].Name = se_name[i];

      // Adjust the rpath.
      cm::optional<std::string> outRPath;
      if (!adjustCallback(outRPath, se[i]->Value, se_name[i], emsg)) {
        return false;
      }

      if (outRPath) {
        if (!outRPath->empty()) {
          remove_rpath = false;
        }

        // Make sure there is enough room to store the new rpath and at
        // least one null terminator.
        if (rp[rp_count].Size < outRPath->length() + 1) {
          if (emsg) {
            *emsg = cmStrCat("The replacement path is too long for the ",
                             se_name[i], " entry.");
          }
          return false;
        }

        // This entry is ready for update.
        rp[rp_count].Value = std::move(*outRPath);
        ++rp_count;
      } else {
        remove_rpath = false;
      }
    }
  }

  // If no runtime path needs to be changed, we are done.
  if (rp_count == 0) {
    return true;
  }

  // If the resulting rpath is empty, just remove the entire entry instead.
  if (remove_rpath) {
    return cmSystemTools::RemoveRPath(file, emsg, changed);
  }

  FileModeGuard file_mode_guard(file, emsg);
  if (file_mode_guard.HasErrors()) {
    return false;
  }

  {
    // Open the file for update.
    cmsys::ofstream f(file.c_str(),
                      std::ios::in | std::ios::out | std::ios::binary);
    if (!f) {
      if (emsg) {
        *emsg = "Error opening file for update.";
      }
      return false;
    }

    // Store the new RPATH and RUNPATH strings.
    for (int i = 0; i < rp_count; ++i) {
      // Seek to the RPATH position.
      if (!f.seekp(rp[i].Position)) {
        if (emsg) {
          *emsg = cmStrCat("Error seeking to ", rp[i].Name, " position.");
        }
        return false;
      }

      // Write the new rpath.  Follow it with enough null terminators to
      // fill the string table entry.
      f << rp[i].Value;
      for (unsigned long j = rp[i].Value.length(); j < rp[i].Size; ++j) {
        f << '\0';
      }

      // Make sure it wrote correctly.
      if (!f) {
        if (emsg) {
          *emsg = cmStrCat("Error writing the new ", rp[i].Name,
                           " string to the file.");
        }
        return false;
      }
    }
  }

  if (!file_mode_guard.Restore(emsg)) {
    return false;
  }

  // Everything was updated successfully.
  if (changed) {
    *changed = true;
  }
  return true;
}

std::function<bool(std::string*, cmELF const&)> MakeEmptyCallback(
  std::string const& newRPath)
{
  return [newRPath](std::string* emsg, cmELF const& elf) -> bool {
    if (newRPath.empty()) {
      // The new rpath is empty and there is no rpath anyway so it is
      // okay.
      return true;
    }
    if (emsg) {
      *emsg =
        cmStrCat("No valid ELF RPATH or RUNPATH entry exists in the file; ",
                 elf.GetErrorMessage());
    }
    return false;
  };
}
}

static cm::optional<bool> ChangeRPathELF(std::string const& file,
                                         std::string const& oldRPath,
                                         std::string const& newRPath,
                                         bool removeEnvironmentRPath,
                                         std::string* emsg, bool* changed)
{
  auto adjustCallback = [oldRPath, newRPath, removeEnvironmentRPath](
                          cm::optional<std::string>& outRPath,
                          std::string const& inRPath, char const* se_name,
                          std::string* emsg2) -> bool {
    // Make sure the current rpath contains the old rpath.
    std::string::size_type pos = cmSystemToolsFindRPath(inRPath, oldRPath);
    if (pos == std::string::npos) {
      // If it contains the new rpath instead then it is okay.
      if (cmSystemToolsFindRPath(inRPath, newRPath) != std::string::npos) {
        return true;
      }
      if (emsg2) {
        std::ostringstream e;
        /* clang-format off */
        e << "The current " << se_name << " is:\n"
             "  " << inRPath << "\n"
             "which does not contain:\n"
             "  " << oldRPath << "\n"
             "as was expected.";
        /* clang-format on */
        *emsg2 = e.str();
      }
      return false;
    }

    std::string::size_type prefix_len = pos;

    // If oldRPath was at the end of the file's RPath, and newRPath is empty,
    // we should remove the unnecessary ':' at the end.
    if (newRPath.empty() && pos > 0 && inRPath[pos - 1] == ':' &&
        pos + oldRPath.length() == inRPath.length()) {
      prefix_len--;
    }

    // Construct the new value which preserves the part of the path
    // not being changed.
    outRPath.emplace();
    if (!removeEnvironmentRPath) {
      *outRPath += inRPath.substr(0, prefix_len);
    }
    *outRPath += newRPath;
    *outRPath += inRPath.substr(pos + oldRPath.length());

    return true;
  };

  return AdjustRPathELF(file, MakeEmptyCallback(newRPath), adjustCallback,
                        emsg, changed);
}

static cm::optional<bool> SetRPathELF(std::string const& file,
                                      std::string const& newRPath,
                                      std::string* emsg, bool* changed)
{
  auto adjustCallback = [newRPath](cm::optional<std::string>& outRPath,
                                   std::string const& inRPath,
                                   char const* /*se_name*/, std::string*
                                   /*emsg*/) -> bool {
    if (inRPath != newRPath) {
      outRPath = newRPath;
    }
    return true;
  };

  return AdjustRPathELF(file, MakeEmptyCallback(newRPath), adjustCallback,
                        emsg, changed);
}
static cm::optional<bool> ChangeRPathXCOFF(std::string const& file,
                                           std::string const& oldRPath,
                                           std::string const& newRPath,
                                           bool removeEnvironmentRPath,
                                           std::string* emsg, bool* changed)
{
  if (changed) {
    *changed = false;
  }
#if !defined(CMake_USE_XCOFF_PARSER)
  (void)file;
  (void)oldRPath;
  (void)newRPath;
  (void)removeEnvironmentRPath;
  (void)emsg;
  return cm::nullopt;
#else
  bool chg = false;
  cmXCOFF xcoff(file.c_str(), cmXCOFF::Mode::ReadWrite);
  if (!xcoff) {
    return cm::nullopt; // Not a valid XCOFF file
  }
  if (cm::optional<cm::string_view> maybeLibPath = xcoff.GetLibPath()) {
    cm::string_view libPath = *maybeLibPath;
    // Make sure the current rpath contains the old rpath.
    std::string::size_type pos = cmSystemToolsFindRPath(libPath, oldRPath);
    if (pos == std::string::npos) {
      // If it contains the new rpath instead then it is okay.
      if (cmSystemToolsFindRPath(libPath, newRPath) != std::string::npos) {
        return true;
      }
      if (emsg) {
        std::ostringstream e;
        /* clang-format off */
        e << "The current RPATH is:\n"
             "  " << libPath << "\n"
             "which does not contain:\n"
             "  " << oldRPath << "\n"
             "as was expected.";
        /* clang-format on */
        *emsg = e.str();
      }
      return false;
    }

    // The prefix is either empty or ends in a ':'.
    cm::string_view prefix = libPath.substr(0, pos);
    if (newRPath.empty() && !prefix.empty()) {
      prefix.remove_suffix(1);
    }

    // The suffix is either empty or starts in a ':'.
    cm::string_view suffix = libPath.substr(pos + oldRPath.length());

    // Construct the new value which preserves the part of the path
    // not being changed.
    std::string newLibPath;
    if (!removeEnvironmentRPath) {
      newLibPath = std::string(prefix);
    }
    newLibPath += newRPath;
    newLibPath += suffix;

    chg = xcoff.SetLibPath(newLibPath);
  }
  if (!xcoff) {
    if (emsg) {
      *emsg = xcoff.GetErrorMessage();
    }
    return false;
  }

  // Everything was updated successfully.
  if (changed) {
    *changed = chg;
  }
  return true;
#endif
}

static cm::optional<bool> SetRPathXCOFF(std::string const& /*file*/,
                                        std::string const& /*newRPath*/,
                                        std::string* /*emsg*/,
                                        bool* /*changed*/)
{
  return cm::nullopt; // Not implemented.
}

bool cmSystemTools::ChangeRPath(std::string const& file,
                                std::string const& oldRPath,
                                std::string const& newRPath,
                                bool removeEnvironmentRPath, std::string* emsg,
                                bool* changed)
{
  if (cm::optional<bool> result = ChangeRPathELF(
        file, oldRPath, newRPath, removeEnvironmentRPath, emsg, changed)) {
    return result.value();
  }
  if (cm::optional<bool> result = ChangeRPathXCOFF(
        file, oldRPath, newRPath, removeEnvironmentRPath, emsg, changed)) {
    return result.value();
  }
  // The file format is not recognized.  Assume it has no RPATH.
  if (newRPath.empty()) {
    // The caller wanted no RPATH anyway.
    return true;
  }
  if (emsg) {
    *emsg = "The file format is not recognized.";
  }
  return false;
}

bool cmSystemTools::SetRPath(std::string const& file,
                             std::string const& newRPath, std::string* emsg,
                             bool* changed)
{
  if (cm::optional<bool> result = SetRPathELF(file, newRPath, emsg, changed)) {
    return result.value();
  }
  if (cm::optional<bool> result =
        SetRPathXCOFF(file, newRPath, emsg, changed)) {
    return result.value();
  }
  // The file format is not recognized.  Assume it has no RPATH.
  if (newRPath.empty()) {
    // The caller wanted no RPATH anyway.
    return true;
  }
  if (emsg) {
    *emsg = "The file format is not recognized.";
  }
  return false;
}

namespace {
bool VersionCompare(cmSystemTools::CompareOp op, char const* lhss,
                    char const* rhss)
{
  char const* endl = lhss;
  char const* endr = rhss;

  while (((*endl >= '0') && (*endl <= '9')) ||
         ((*endr >= '0') && (*endr <= '9'))) {
    // Do component-wise comparison, ignoring leading zeros
    // (components are treated as integers, not as mantissas)
    while (*endl == '0') {
      endl++;
    }
    while (*endr == '0') {
      endr++;
    }

    char const* beginl = endl;
    char const* beginr = endr;

    // count significant digits
    while ((*endl >= '0') && (*endl <= '9')) {
      endl++;
    }
    while ((*endr >= '0') && (*endr <= '9')) {
      endr++;
    }

    // compare number of digits first
    ptrdiff_t r = ((endl - beginl) - (endr - beginr));
    if (r == 0) {
      // compare the digits if number of digits is equal
      r = strncmp(beginl, beginr, endl - beginl);
    }

    if (r < 0) {
      // lhs < rhs, so true if operation is LESS
      return (op & cmSystemTools::OP_LESS) != 0;
    }
    if (r > 0) {
      // lhs > rhs, so true if operation is GREATER
      return (op & cmSystemTools::OP_GREATER) != 0;
    }

    if (*endr == '.') {
      endr++;
    }

    if (*endl == '.') {
      endl++;
    }
  }
  // lhs == rhs, so true if operation is EQUAL
  return (op & cmSystemTools::OP_EQUAL) != 0;
}
}

bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op,
                                   std::string const& lhs,
                                   std::string const& rhs)
{
  return ::VersionCompare(op, lhs.c_str(), rhs.c_str());
}
bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op,
                                   std::string const& lhs, char const rhs[])
{
  return ::VersionCompare(op, lhs.c_str(), rhs);
}

bool cmSystemTools::VersionCompareEqual(std::string const& lhs,
                                        std::string const& rhs)
{
  return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL, lhs, rhs);
}

bool cmSystemTools::VersionCompareGreater(std::string const& lhs,
                                          std::string const& rhs)
{
  return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER, lhs, rhs);
}

bool cmSystemTools::VersionCompareGreaterEq(std::string const& lhs,
                                            std::string const& rhs)
{
  return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER_EQUAL, lhs,
                                       rhs);
}

static size_t cm_strverscmp_find_first_difference_or_end(char const* lhs,
                                                         char const* rhs)
{
  size_t i = 0;
  /* Step forward until we find a difference or both strings end together.
     The difference may lie on the null-terminator of one string.  */
  while (lhs[i] == rhs[i] && lhs[i] != 0) {
    ++i;
  }
  return i;
}

static size_t cm_strverscmp_find_digits_begin(char const* s, size_t i)
{
  /* Step back until we are not preceded by a digit.  */
  while (i > 0 && isdigit(s[i - 1])) {
    --i;
  }
  return i;
}

static size_t cm_strverscmp_find_digits_end(char const* s, size_t i)
{
  /* Step forward over digits.  */
  while (isdigit(s[i])) {
    ++i;
  }
  return i;
}

static size_t cm_strverscmp_count_leading_zeros(char const* s, size_t b)
{
  size_t i = b;
  /* Step forward over zeros that are followed by another digit.  */
  while (s[i] == '0' && isdigit(s[i + 1])) {
    ++i;
  }
  return i - b;
}

static int cm_strverscmp(char const* lhs, char const* rhs)
{
  size_t const i = cm_strverscmp_find_first_difference_or_end(lhs, rhs);
  if (lhs[i] != rhs[i]) {
    /* The strings differ starting at 'i'.  Check for a digit sequence.  */
    size_t const b = cm_strverscmp_find_digits_begin(lhs, i);
    if (b != i || (isdigit(lhs[i]) && isdigit(rhs[i]))) {
      /* A digit sequence starts at 'b', preceding or at 'i'.  */

      /* Look for leading zeros, implying a leading decimal point.  */
      size_t const lhs_zeros = cm_strverscmp_count_leading_zeros(lhs, b);
      size_t const rhs_zeros = cm_strverscmp_count_leading_zeros(rhs, b);
      if (lhs_zeros != rhs_zeros) {
        /* The side with more leading zeros orders first.  */
        return rhs_zeros > lhs_zeros ? 1 : -1;
      }
      if (lhs_zeros == 0) {
        /* No leading zeros; compare digit sequence lengths.  */
        size_t const lhs_end = cm_strverscmp_find_digits_end(lhs, i);
        size_t const rhs_end = cm_strverscmp_find_digits_end(rhs, i);
        if (lhs_end != rhs_end) {
          /* The side with fewer digits orders first.  */
          return lhs_end > rhs_end ? 1 : -1;
        }
      }
    }
  }

  /* Ordering was not decided by digit sequence lengths; compare bytes.  */
  return lhs[i] - rhs[i];
}

int cmSystemTools::strverscmp(std::string const& lhs, std::string const& rhs)
{
  return cm_strverscmp(lhs.c_str(), rhs.c_str());
}

static cm::optional<bool> RemoveRPathELF(std::string const& file,
                                         std::string* emsg, bool* removed)
{
  if (removed) {
    *removed = false;
  }
  int zeroCount = 0;
  unsigned long zeroPosition[2] = { 0, 0 };
  unsigned long zeroSize[2] = { 0, 0 };
  unsigned long bytesBegin = 0;
  std::vector<char> bytes;
  {
    // Parse the ELF binary.
    cmELF elf(file.c_str());
    if (!elf) {
      return cm::nullopt; // Not a valid ELF file.
    }

    // Get the RPATH and RUNPATH entries from it and sort them by index
    // in the dynamic section header.
    int se_count = 0;
    cmELF::StringEntry const* se[2] = { nullptr, nullptr };
    if (cmELF::StringEntry const* se_rpath = elf.GetRPath()) {
      se[se_count++] = se_rpath;
    }
    if (cmELF::StringEntry const* se_runpath = elf.GetRunPath()) {
      se[se_count++] = se_runpath;
    }
    if (se_count == 0) {
      // There is no RPATH or RUNPATH anyway.
      return true;
    }
    if (se_count == 2 && se[1]->IndexInSection < se[0]->IndexInSection) {
      std::swap(se[0], se[1]);
    }

    // Obtain a copy of the dynamic entries
    cmELF::DynamicEntryList dentries = elf.GetDynamicEntries();
    if (dentries.empty()) {
      // This should happen only for invalid ELF files where a DT_NULL
      // appears before the end of the table.
      if (emsg) {
        *emsg = "DYNAMIC section contains a DT_NULL before the end.";
      }
      return false;
    }

    // Save information about the string entries to be zeroed.
    zeroCount = se_count;
    for (int i = 0; i < se_count; ++i) {
      zeroPosition[i] = se[i]->Position;
      zeroSize[i] = se[i]->Size;
    }

    // Get size of one DYNAMIC entry
    unsigned long const sizeof_dentry =
      elf.GetDynamicEntryPosition(1) - elf.GetDynamicEntryPosition(0);

    // Adjust the entry list as necessary to remove the run path
    unsigned long entriesErased = 0;
    for (auto it = dentries.begin(); it != dentries.end();) {
      if (it->first == cmELF::TagRPath || it->first == cmELF::TagRunPath) {
        it = dentries.erase(it);
        entriesErased++;
        continue;
      }
      if (it->first == cmELF::TagMipsRldMapRel && elf.IsMIPS()) {
        // Background: debuggers need to know the "linker map" which contains
        // the addresses each dynamic object is loaded at. Most arches use
        // the DT_DEBUG tag which the dynamic linker writes to (directly) and
        // contain the location of the linker map, however on MIPS the
        // .dynamic section is always read-only so this is not possible. MIPS
        // objects instead contain a DT_MIPS_RLD_MAP tag which contains the
        // address where the dynamic linker will write to (an indirect
        // version of DT_DEBUG). Since this doesn't work when using PIE, a
        // relative equivalent was created - DT_MIPS_RLD_MAP_REL. Since this
        // version contains a relative offset, moving it changes the
        // calculated address. This may cause the dynamic linker to write
        // into memory it should not be changing.
        //
        // To fix this, we adjust the value of DT_MIPS_RLD_MAP_REL here. If
        // we move it up by n bytes, we add n bytes to the value of this tag.
        it->second += entriesErased * sizeof_dentry;
      }

      it++;
    }

    // Encode new entries list
    bytes = elf.EncodeDynamicEntries(dentries);
    bytesBegin = elf.GetDynamicEntryPosition(0);
  }

  FileModeGuard file_mode_guard(file, emsg);
  if (file_mode_guard.HasErrors()) {
    return false;
  }

  // Open the file for update.
  cmsys::ofstream f(file.c_str(),
                    std::ios::in | std::ios::out | std::ios::binary);
  if (!f) {
    if (emsg) {
      *emsg = "Error opening file for update.";
    }
    return false;
  }

  // Write the new DYNAMIC table header.
  if (!f.seekp(bytesBegin)) {
    if (emsg) {
      *emsg = "Error seeking to DYNAMIC table header for RPATH.";
    }
    return false;
  }
  if (!f.write(bytes.data(), bytes.size())) {
    if (emsg) {
      *emsg = "Error replacing DYNAMIC table header.";
    }
    return false;
  }

  // Fill the RPATH and RUNPATH strings with zero bytes.
  for (int i = 0; i < zeroCount; ++i) {
    if (!f.seekp(zeroPosition[i])) {
      if (emsg) {
        *emsg = "Error seeking to RPATH position.";
      }
      return false;
    }
    for (unsigned long j = 0; j < zeroSize[i]; ++j) {
      f << '\0';
    }
    if (!f) {
      if (emsg) {
        *emsg = "Error writing the empty rpath string to the file.";
      }
      return false;
    }
  }

  // Close the handle to allow further operations on the file
  f.close();

  if (!file_mode_guard.Restore(emsg)) {
    return false;
  }

  // Everything was updated successfully.
  if (removed) {
    *removed = true;
  }
  return true;
}

static cm::optional<bool> RemoveRPathXCOFF(std::string const& file,
                                           std::string* emsg, bool* removed)
{
  if (removed) {
    *removed = false;
  }
#if !defined(CMake_USE_XCOFF_PARSER)
  (void)file;
  (void)emsg;
  return cm::nullopt; // Cannot handle XCOFF files.
#else
  bool rm = false;

  FileModeGuard file_mode_guard(file, emsg);
  if (file_mode_guard.HasErrors()) {
    return false;
  }

  {
    cmXCOFF xcoff(file.c_str(), cmXCOFF::Mode::ReadWrite);
    if (!xcoff) {
      return cm::nullopt; // Not a valid XCOFF file.
    }
    rm = xcoff.RemoveLibPath();
    if (!xcoff) {
      if (emsg) {
        *emsg = xcoff.GetErrorMessage();
      }
      return false;
    }
  }

  if (!file_mode_guard.Restore(emsg)) {
    return false;
  }

  if (removed) {
    *removed = rm;
  }
  return true;
#endif
}
bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
                                bool* removed)
{
  if (cm::optional<bool> result = RemoveRPathELF(file, emsg, removed)) {
    return result.value();
  }
  if (cm::optional<bool> result = RemoveRPathXCOFF(file, emsg, removed)) {
    return result.value();
  }
  // The file format is not recognized.  Assume it has no RPATH.
  return true;
}

bool cmSystemTools::CheckRPath(std::string const& file,
                               std::string const& newRPath)
{
  // Parse the ELF binary.
  cmELF elf(file.c_str());
  if (elf) {
    // Get the RPATH or RUNPATH entry from it.
    cmELF::StringEntry const* se = elf.GetRPath();
    if (!se) {
      se = elf.GetRunPath();
    }

    // Make sure the current rpath contains the new rpath.
    if (newRPath.empty()) {
      if (!se) {
        return true;
      }
    } else {
      if (se &&
          cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos) {
        return true;
      }
    }
    return false;
  }
#if defined(CMake_USE_XCOFF_PARSER)
  // Parse the XCOFF binary.
  cmXCOFF xcoff(file.c_str());
  if (xcoff) {
    if (cm::optional<cm::string_view> libPath = xcoff.GetLibPath()) {
      if (cmSystemToolsFindRPath(*libPath, newRPath) != std::string::npos) {
        return true;
      }
    }
    return false;
  }
#endif
  // The file format is not recognized.  Assume it has no RPATH.
  // Therefore we succeed if the new rpath is empty anyway.
  return newRPath.empty();
}

cmsys::Status cmSystemTools::RepeatedRemoveDirectory(std::string const& dir)
{
#ifdef _WIN32
  // Windows sometimes locks files temporarily so try a few times.
  WindowsFileRetry retry = cmSystemTools::GetWindowsFileRetry();

  cmsys::Status status;
  unsigned int tries = 0;
  while (!(status = cmSystemTools::RemoveADirectory(dir)) &&
         ++tries < retry.Count) {
    cmSystemTools::Delay(retry.Delay);
  }
  return status;
#else
  return cmSystemTools::RemoveADirectory(dir);
#endif
}

std::string cmSystemTools::EncodeURL(std::string const& in, bool escapeSlashes)
{
  std::string out;
  for (char c : in) {
    char hexCh[4] = { 0, 0, 0, 0 };
    hexCh[0] = c;
    switch (c) {
      case '+':
      case '?':
      case '\\':
      case '&':
      case ' ':
      case '=':
      case '%':
        snprintf(hexCh, sizeof(hexCh), "%%%02X", static_cast<unsigned int>(c));
        break;
      case '/':
        if (escapeSlashes) {
          strcpy(hexCh, "%2F");
        }
        break;
      default:
        break;
    }
    out.append(hexCh);
  }
  return out;
}

cm::optional<cmSystemTools::DirCase> cmSystemTools::GetDirCase(
  std::string const& dir)
{
  if (!cmSystemTools::FileIsDirectory(dir)) {
    return cm::nullopt;
  }
#if defined(_WIN32) || defined(__APPLE__)
  return DirCase::Insensitive;
#elif defined(__linux__)
  int fd = open(dir.c_str(), O_RDONLY);
  if (fd == -1) {
    // cannot open dir but it exists, assume dir is case sensitive.
    return DirCase::Sensitive;
  }
  int attr = 0;
  int ioctl_res = ioctl(fd, FS_IOC_GETFLAGS, &attr);
  close(fd);

  if (ioctl_res == -1) {
    return DirCase::Sensitive;
  }

  // FS_CASEFOLD_FD from linux/fs.h, in Linux libc-dev 5.4+
  // For compat with old libc-dev, define it here.
  int const CMAKE_FS_CASEFOLD_FL = 0x40000000;
  return (attr & CMAKE_FS_CASEFOLD_FL) != 0 ? DirCase::Insensitive
                                            : DirCase::Sensitive;
#else
  return DirCase::Sensitive;
#endif
}

cmsys::Status cmSystemTools::CreateSymlink(std::string const& origName,
                                           std::string const& newName)
{
  cmsys::Status status =
    cmSystemTools::CreateSymlinkQuietly(origName, newName);
  if (!status) {
    cmSystemTools::Error(cmStrCat("failed to create symbolic link '", newName,
                                  "': ", status.GetString()));
  }
  return status;
}

cmsys::Status cmSystemTools::CreateSymlinkQuietly(std::string const& origName,
                                                  std::string const& newName)
{
  uv_fs_t req;
  int flags = 0;
#if defined(_WIN32)
  if (cmsys::SystemTools::FileIsDirectory(origName)) {
    flags |= UV_FS_SYMLINK_DIR;
  }
#endif
  int err = uv_fs_symlink(nullptr, &req, origName.c_str(), newName.c_str(),
                          flags, nullptr);
  cmsys::Status status;
  if (err) {
#if defined(_WIN32)
    status = cmsys::Status::Windows(uv_fs_get_system_error(&req));
#elif UV_VERSION_MAJOR > 1 || (UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR >= 38)
    status = cmsys::Status::POSIX(uv_fs_get_system_error(&req));
#else
    status = cmsys::Status::POSIX(-err);
#endif
  }
  return status;
}

cmsys::Status cmSystemTools::CreateLink(std::string const& origName,
                                        std::string const& newName)
{
  cmsys::Status status = cmSystemTools::CreateLinkQuietly(origName, newName);
  if (!status) {
    cmSystemTools::Error(
      cmStrCat("failed to create link '", newName, "': ", status.GetString()));
  }
  return status;
}

cmsys::Status cmSystemTools::CreateLinkQuietly(std::string const& origName,
                                               std::string const& newName)
{
  uv_fs_t req;
  int err =
    uv_fs_link(nullptr, &req, origName.c_str(), newName.c_str(), nullptr);
  cmsys::Status status;
  if (err) {
#if defined(_WIN32)
    status = cmsys::Status::Windows(uv_fs_get_system_error(&req));
#elif UV_VERSION_MAJOR > 1 || (UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR >= 38)
    status = cmsys::Status::POSIX(uv_fs_get_system_error(&req));
#else
    status = cmsys::Status::POSIX(-err);
#endif
  }
  return status;
}

cm::string_view cmSystemTools::GetSystemName()
{
#if defined(_WIN32)
  return "Windows";
#elif defined(__MSYS__)
  return "MSYS";
#elif defined(__CYGWIN__)
  return "CYGWIN";
#elif defined(__ANDROID__)
  return "Android";
#else
  static struct utsname uts_name;
  static bool initialized = false;
  static cm::string_view systemName;
  if (initialized) {
    return systemName;
  }
  if (uname(&uts_name) >= 0) {
    initialized = true;
    systemName = uts_name.sysname;

    if (cmIsOff(systemName)) {
      systemName = "UnknownOS";
    }

    // fix for BSD/OS, remove the /
    static cmsys::RegularExpression const bsdOsRegex("BSD.OS");
    cmsys::RegularExpressionMatch match;
    if (bsdOsRegex.find(uts_name.sysname, match)) {
      systemName = "BSDOS";
    }

    return systemName;
  }
  return "";
#endif
}

char cmSystemTools::GetSystemPathlistSeparator()
{
#if defined(_WIN32)
  return ';';
#else
  return ':';
#endif
}
