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

#include <functional>
#include <iomanip>
#include <map>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

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

#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
#include "cmCMakePath.h"
#include "cmExecutionStatus.h"
#include "cmList.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
#include "cmValue.h"

namespace {
// Helper classes for argument parsing
template <typename Result>
class CMakePathArgumentParser : public cmArgumentParser<Result>
{
public:
  CMakePathArgumentParser()
    : cmArgumentParser<Result>()
  {
  }

  template <typename T>
  CMakePathArgumentParser& Bind(cm::static_string_view name, T Result::*member)
  {
    this->cmArgumentParser<Result>::Bind(name, member);
    return *this;
  }

  template <int Advance = 2>
  Result Parse(std::vector<std::string> const& args) const
  {
    this->Inputs.clear();

    return this->cmArgumentParser<Result>::Parse(
      cmMakeRange(args).advance(Advance), &this->Inputs);
  }

  std::vector<std::string> const& GetInputs() const { return this->Inputs; }

protected:
  mutable std::vector<std::string> Inputs;
};

// OUTPUT_VARIABLE is expected
template <typename Result>
class ArgumentParserWithOutputVariable : public CMakePathArgumentParser<Result>
{
public:
  ArgumentParserWithOutputVariable()
    : CMakePathArgumentParser<Result>()
  {
    this->Bind("OUTPUT_VARIABLE"_s, &Result::Output);
  }

  template <typename T>
  ArgumentParserWithOutputVariable& Bind(cm::static_string_view name,
                                         T Result::*member)
  {
    this->cmArgumentParser<Result>::Bind(name, member);
    return *this;
  }

  template <int Advance = 2>
  Result Parse(std::vector<std::string> const& args) const
  {
    return this->CMakePathArgumentParser<Result>::template Parse<Advance>(
      args);
  }
};

struct OutputVariable : public ArgumentParser::ParseResult
{
  cm::optional<ArgumentParser::NonEmpty<std::string>> Output;
};
// Usable when OUTPUT_VARIABLE is the only option
class OutputVariableParser
  : public ArgumentParserWithOutputVariable<OutputVariable>
{
};

struct NormalizeOption
{
  bool Normalize = false;
};
// Usable when NORMALIZE is the only option
class NormalizeParser : public CMakePathArgumentParser<NormalizeOption>
{
public:
  NormalizeParser() { this->Bind("NORMALIZE"_s, &NormalizeOption::Normalize); }
};

// retrieve value of input path from specified variable
bool getInputPath(std::string const& arg, cmExecutionStatus& status,
                  std::string& path)
{
  cmValue def = status.GetMakefile().GetDefinition(arg);
  if (!def) {
    status.SetError("undefined variable for input path.");
    return false;
  }

  path = *def;
  return true;
}

bool HandleGetCommand(std::vector<std::string> const& args,
                      cmExecutionStatus& status)
{
  static std::map<cm::string_view,
                  std::function<cmCMakePath(cmCMakePath const&, bool)>> const
    actions{ { "ROOT_NAME"_s,
               [](cmCMakePath const& path, bool) -> cmCMakePath {
                 return path.GetRootName();
               } },
             { "ROOT_DIRECTORY"_s,
               [](cmCMakePath const& path, bool) -> cmCMakePath {
                 return path.GetRootDirectory();
               } },
             { "ROOT_PATH"_s,
               [](cmCMakePath const& path, bool) -> cmCMakePath {
                 return path.GetRootPath();
               } },
             { "FILENAME"_s,
               [](cmCMakePath const& path, bool) -> cmCMakePath {
                 return path.GetFileName();
               } },
             { "EXTENSION"_s,
               [](cmCMakePath const& path, bool last_only) -> cmCMakePath {
                 if (last_only) {
                   return path.GetExtension();
                 }
                 return path.GetWideExtension();
               } },
             { "STEM"_s,
               [](cmCMakePath const& path, bool last_only) -> cmCMakePath {
                 if (last_only) {
                   return path.GetStem();
                 }
                 return path.GetNarrowStem();
               } },
             { "RELATIVE_PART"_s,
               [](cmCMakePath const& path, bool) -> cmCMakePath {
                 return path.GetRelativePath();
               } },
             { "PARENT_PATH"_s,
               [](cmCMakePath const& path, bool) -> cmCMakePath {
                 return path.GetParentPath();
               } } };

  if (args.size() < 4) {
    status.SetError("GET must be called with at least three arguments.");
    return false;
  }

  auto const& action = args[2];

  if (actions.find(action) == actions.end()) {
    status.SetError(
      cmStrCat("GET called with an unknown action: ", action, '.'));
    return false;
  }

  struct Arguments
  {
    bool LastOnly = false;
  };

  CMakePathArgumentParser<Arguments> parser;
  if ((action == "EXTENSION"_s || action == "STEM"_s)) {
    parser.Bind("LAST_ONLY"_s, &Arguments::LastOnly);
  }

  Arguments const arguments = parser.Parse<3>(args);

  if (parser.GetInputs().size() != 1) {
    status.SetError("GET called with unexpected arguments.");
    return false;
  }
  if (parser.GetInputs().front().empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  std::string path;
  if (!getInputPath(args[1], status, path)) {
    return false;
  }

  auto result = actions.at(action)(path, arguments.LastOnly);

  status.GetMakefile().AddDefinition(parser.GetInputs().front(),
                                     result.String());

  return true;
}

bool HandleSetCommand(std::vector<std::string> const& args,
                      cmExecutionStatus& status)
{
  if (args.size() < 3 || args.size() > 4) {
    status.SetError("SET must be called with two or three arguments.");
    return false;
  }

  if (args[1].empty()) {
    status.SetError("Invalid name for path variable.");
    return false;
  }

  static NormalizeParser const parser;

  auto const arguments = parser.Parse(args);

  if (parser.GetInputs().size() != 1) {
    status.SetError("SET called with unexpected arguments.");
    return false;
  }

  auto path =
    cmCMakePath(parser.GetInputs().front(), cmCMakePath::native_format);

  if (arguments.Normalize) {
    path = path.Normal();
  }

  status.GetMakefile().AddDefinition(args[1], path.GenericString());

  return true;
}

bool HandleAppendCommand(std::vector<std::string> const& args,
                         cmExecutionStatus& status)
{
  if (args[1].empty()) {
    status.SetError("Invalid name for path variable.");
    return false;
  }

  static OutputVariableParser const parser{};

  auto const arguments = parser.Parse(args);

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

  cmCMakePath path(status.GetMakefile().GetSafeDefinition(args[1]));
  for (auto const& input : parser.GetInputs()) {
    path /= input;
  }

  status.GetMakefile().AddDefinition(
    arguments.Output ? *arguments.Output : args[1], path.String());

  return true;
}

bool HandleAppendStringCommand(std::vector<std::string> const& args,
                               cmExecutionStatus& status)
{
  static OutputVariableParser const parser{};

  auto const arguments = parser.Parse(args);

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

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  cmCMakePath path(inputPath);
  for (auto const& input : parser.GetInputs()) {
    path += input;
  }

  status.GetMakefile().AddDefinition(
    arguments.Output ? *arguments.Output : args[1], path.String());

  return true;
}

bool HandleRemoveFilenameCommand(std::vector<std::string> const& args,
                                 cmExecutionStatus& status)
{
  static OutputVariableParser const parser{};

  auto const arguments = parser.Parse(args);

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

  if (!parser.GetInputs().empty()) {
    status.SetError("REMOVE_FILENAME called with unexpected arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  cmCMakePath path(inputPath);
  path.RemoveFileName();

  status.GetMakefile().AddDefinition(
    arguments.Output ? *arguments.Output : args[1], path.String());

  return true;
}

bool HandleReplaceFilenameCommand(std::vector<std::string> const& args,
                                  cmExecutionStatus& status)
{
  static OutputVariableParser const parser{};

  auto const arguments = parser.Parse(args);

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

  if (parser.GetInputs().size() > 1) {
    status.SetError("REPLACE_FILENAME called with unexpected arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  cmCMakePath path(inputPath);
  path.ReplaceFileName(
    parser.GetInputs().empty() ? "" : parser.GetInputs().front());

  status.GetMakefile().AddDefinition(
    arguments.Output ? *arguments.Output : args[1], path.String());

  return true;
}

bool HandleRemoveExtensionCommand(std::vector<std::string> const& args,
                                  cmExecutionStatus& status)
{
  struct Arguments : public ArgumentParser::ParseResult
  {
    cm::optional<ArgumentParser::NonEmpty<std::string>> Output;
    bool LastOnly = false;
  };

  static auto const parser =
    ArgumentParserWithOutputVariable<Arguments>{}.Bind("LAST_ONLY"_s,
                                                       &Arguments::LastOnly);

  Arguments const arguments = parser.Parse(args);

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

  if (!parser.GetInputs().empty()) {
    status.SetError("REMOVE_EXTENSION called with unexpected arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  cmCMakePath path(inputPath);

  if (arguments.LastOnly) {
    path.RemoveExtension();
  } else {
    path.RemoveWideExtension();
  }

  status.GetMakefile().AddDefinition(
    arguments.Output ? *arguments.Output : args[1], path.String());

  return true;
}

bool HandleReplaceExtensionCommand(std::vector<std::string> const& args,
                                   cmExecutionStatus& status)
{
  struct Arguments : public ArgumentParser::ParseResult
  {
    cm::optional<ArgumentParser::NonEmpty<std::string>> Output;
    bool LastOnly = false;
  };

  static auto const parser =
    ArgumentParserWithOutputVariable<Arguments>{}.Bind("LAST_ONLY"_s,
                                                       &Arguments::LastOnly);

  Arguments const arguments = parser.Parse(args);

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

  if (parser.GetInputs().size() > 1) {
    status.SetError("REPLACE_EXTENSION called with unexpected arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  cmCMakePath path(inputPath);
  cmCMakePath extension(
    parser.GetInputs().empty() ? "" : parser.GetInputs().front());

  if (arguments.LastOnly) {
    path.ReplaceExtension(extension);
  } else {
    path.ReplaceWideExtension(extension);
  }

  status.GetMakefile().AddDefinition(
    arguments.Output ? *arguments.Output : args[1], path.String());

  return true;
}

bool HandleNormalPathCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
{
  static OutputVariableParser const parser{};

  auto const arguments = parser.Parse(args);

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

  if (!parser.GetInputs().empty()) {
    status.SetError("NORMAL_PATH called with unexpected arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  auto path = cmCMakePath(inputPath).Normal();

  status.GetMakefile().AddDefinition(
    arguments.Output ? *arguments.Output : args[1], path.String());

  return true;
}

bool HandleTransformPathCommand(
  std::vector<std::string> const& args, cmExecutionStatus& status,
  std::function<cmCMakePath(cmCMakePath const&,
                            std::string const& base)> const& transform,
  bool normalizeOption = false)
{
  struct Arguments : public ArgumentParser::ParseResult
  {
    cm::optional<ArgumentParser::NonEmpty<std::string>> Output;
    cm::optional<std::string> BaseDirectory;
    bool Normalize = false;
  };

  auto parser = ArgumentParserWithOutputVariable<Arguments>{}.Bind(
    "BASE_DIRECTORY"_s, &Arguments::BaseDirectory);
  if (normalizeOption) {
    parser.Bind("NORMALIZE"_s, &Arguments::Normalize);
  }

  Arguments arguments = parser.Parse(args);

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

  if (!parser.GetInputs().empty()) {
    status.SetError(cmStrCat(args[0], " called with unexpected arguments."));
    return false;
  }

  std::string baseDirectory;
  if (arguments.BaseDirectory) {
    baseDirectory = *arguments.BaseDirectory;
  } else {
    baseDirectory = status.GetMakefile().GetCurrentSourceDirectory();
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  auto path = transform(cmCMakePath(inputPath), baseDirectory);
  if (arguments.Normalize) {
    path = path.Normal();
  }

  status.GetMakefile().AddDefinition(
    arguments.Output ? *arguments.Output : args[1], path.String());

  return true;
}

bool HandleRelativePathCommand(std::vector<std::string> const& args,
                               cmExecutionStatus& status)
{
  return HandleTransformPathCommand(
    args, status,
    [](cmCMakePath const& path, std::string const& base) -> cmCMakePath {
      return path.Relative(base);
    });
}

bool HandleAbsolutePathCommand(std::vector<std::string> const& args,
                               cmExecutionStatus& status)
{
  return HandleTransformPathCommand(
    args, status,
    [](cmCMakePath const& path, std::string const& base) -> cmCMakePath {
      return path.Absolute(base);
    },
    true);
}

bool HandleNativePathCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
{
  if (args.size() < 3 || args.size() > 4) {
    status.SetError("NATIVE_PATH must be called with two or three arguments.");
    return false;
  }

  static NormalizeParser const parser;

  auto const arguments = parser.Parse(args);

  if (parser.GetInputs().size() != 1) {
    status.SetError("NATIVE_PATH called with unexpected arguments.");
    return false;
  }
  if (parser.GetInputs().front().empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  cmCMakePath path(inputPath);
  if (arguments.Normalize) {
    path = path.Normal();
  }

  status.GetMakefile().AddDefinition(parser.GetInputs().front(),
                                     path.NativeString());

  return true;
}

bool HandleConvertCommand(std::vector<std::string> const& args,
                          cmExecutionStatus& status)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
  auto const pathSep = ";"_s;
#else
  auto const pathSep = ":"_s;
#endif
  auto const cmakePath = "TO_CMAKE_PATH_LIST"_s;
  auto const nativePath = "TO_NATIVE_PATH_LIST"_s;

  if (args.size() < 4 || args.size() > 5) {
    status.SetError("CONVERT must be called with three or four arguments.");
    return false;
  }

  auto const& action = args[2];

  if (action != cmakePath && action != nativePath) {
    status.SetError(
      cmStrCat("CONVERT called with an unknown action: ", action, '.'));
    return false;
  }

  if (args[3].empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  static NormalizeParser const parser;

  auto const arguments = parser.Parse<4>(args);

  if (!parser.GetInputs().empty()) {
    status.SetError("CONVERT called with unexpected arguments.");
    return false;
  }

  cmList paths;

  if (action == cmakePath) {
    paths = cmSystemTools::SplitString(args[1], pathSep.front());
  } else {
    paths.assign(args[1]);
  }

  for (auto& path : paths) {
    auto p = cmCMakePath(path,
                         action == cmakePath ? cmCMakePath::native_format
                                             : cmCMakePath::generic_format);
    if (arguments.Normalize) {
      p = p.Normal();
    }
    if (action == cmakePath) {
      path = p.GenericString();
    } else {
      path = p.NativeString();
    }
  }

  auto value = action == cmakePath ? paths.to_string() : paths.join(pathSep);
  status.GetMakefile().AddDefinition(args[3], value);

  return true;
}

bool HandleCompareCommand(std::vector<std::string> const& args,
                          cmExecutionStatus& status)
{
  if (args.size() != 5) {
    status.SetError("COMPARE must be called with four arguments.");
    return false;
  }

  static std::map<cm::string_view,
                  std::function<bool(cmCMakePath const&,
                                     cmCMakePath const&)>> const operators{
    { "EQUAL"_s,
      [](cmCMakePath const& path1, cmCMakePath const& path2) -> bool {
        return path1 == path2;
      } },
    { "NOT_EQUAL"_s,
      [](cmCMakePath const& path1, cmCMakePath const& path2) -> bool {
        return path1 != path2;
      } }
  };

  auto const op = operators.find(args[2]);
  if (op == operators.end()) {
    status.SetError(cmStrCat(
      "COMPARE called with an unknown comparison operator: ", args[2], '.'));
    return false;
  }

  if (args[4].empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  cmCMakePath path1(args[1]);
  cmCMakePath path2(args[3]);
  auto result = op->second(path1, path2);

  status.GetMakefile().AddDefinitionBool(args[4], result);

  return true;
}

bool HandleHasItemCommand(
  std::vector<std::string> const& args, cmExecutionStatus& status,
  std::function<bool(cmCMakePath const&)> const& has_item)
{
  if (args.size() != 3) {
    status.SetError(
      cmStrCat(args.front(), " must be called with two arguments."));
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  if (args[2].empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  cmCMakePath path(inputPath);
  auto result = has_item(path);

  status.GetMakefile().AddDefinitionBool(args[2], result);

  return true;
}

bool HandleHasRootNameCommand(std::vector<std::string> const& args,
                              cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](cmCMakePath const& path) -> bool { return path.HasRootName(); });
}

bool HandleHasRootDirectoryCommand(std::vector<std::string> const& args,
                                   cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](cmCMakePath const& path) -> bool { return path.HasRootDirectory(); });
}

bool HandleHasRootPathCommand(std::vector<std::string> const& args,
                              cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](cmCMakePath const& path) -> bool { return path.HasRootPath(); });
}

bool HandleHasFilenameCommand(std::vector<std::string> const& args,
                              cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](cmCMakePath const& path) -> bool { return path.HasFileName(); });
}

bool HandleHasExtensionCommand(std::vector<std::string> const& args,
                               cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](cmCMakePath const& path) -> bool { return path.HasExtension(); });
}

bool HandleHasStemCommand(std::vector<std::string> const& args,
                          cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](cmCMakePath const& path) -> bool { return path.HasStem(); });
}

bool HandleHasRelativePartCommand(std::vector<std::string> const& args,
                                  cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](cmCMakePath const& path) -> bool { return path.HasRelativePath(); });
}

bool HandleHasParentPathCommand(std::vector<std::string> const& args,
                                cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](cmCMakePath const& path) -> bool { return path.HasParentPath(); });
}

bool HandleIsAbsoluteCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
{
  if (args.size() != 3) {
    status.SetError("IS_ABSOLUTE must be called with two arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  if (args[2].empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  bool isAbsolute = cmCMakePath(inputPath).IsAbsolute();

  status.GetMakefile().AddDefinitionBool(args[2], isAbsolute);

  return true;
}

bool HandleIsRelativeCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
{
  if (args.size() != 3) {
    status.SetError("IS_RELATIVE must be called with two arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  if (args[2].empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  bool isRelative = cmCMakePath(inputPath).IsRelative();

  status.GetMakefile().AddDefinitionBool(args[2], isRelative);

  return true;
}

bool HandleIsPrefixCommand(std::vector<std::string> const& args,
                           cmExecutionStatus& status)
{
  if (args.size() < 4 || args.size() > 5) {
    status.SetError("IS_PREFIX must be called with three or four arguments.");
    return false;
  }

  static NormalizeParser const parser;

  auto const arguments = parser.Parse(args);

  if (parser.GetInputs().size() != 2) {
    status.SetError("IS_PREFIX called with unexpected arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  auto const& input = parser.GetInputs().front();
  auto const& output = parser.GetInputs().back();

  if (output.empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  bool isPrefix;
  if (arguments.Normalize) {
    isPrefix =
      cmCMakePath(inputPath).Normal().IsPrefix(cmCMakePath(input).Normal());
  } else {
    isPrefix = cmCMakePath(inputPath).IsPrefix(input);
  }

  status.GetMakefile().AddDefinitionBool(output, isPrefix);

  return true;
}

bool HandleHashCommand(std::vector<std::string> const& args,
                       cmExecutionStatus& status)
{
  if (args.size() != 3) {
    status.SetError("HASH must be called with two arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  auto const& output = args[2];

  if (output.empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  auto hash = hash_value(cmCMakePath(inputPath).Normal());

  std::ostringstream out;
  out << std::setbase(16) << hash;

  status.GetMakefile().AddDefinition(output, out.str());

  return true;
}
} // anonymous namespace

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

  static cmSubcommandTable const subcommand{
    { "GET"_s, HandleGetCommand },
    { "SET"_s, HandleSetCommand },
    { "APPEND"_s, HandleAppendCommand },
    { "APPEND_STRING"_s, HandleAppendStringCommand },
    { "REMOVE_FILENAME"_s, HandleRemoveFilenameCommand },
    { "REPLACE_FILENAME"_s, HandleReplaceFilenameCommand },
    { "REMOVE_EXTENSION"_s, HandleRemoveExtensionCommand },
    { "REPLACE_EXTENSION"_s, HandleReplaceExtensionCommand },
    { "NORMAL_PATH"_s, HandleNormalPathCommand },
    { "RELATIVE_PATH"_s, HandleRelativePathCommand },
    { "ABSOLUTE_PATH"_s, HandleAbsolutePathCommand },
    { "NATIVE_PATH"_s, HandleNativePathCommand },
    { "CONVERT"_s, HandleConvertCommand },
    { "COMPARE"_s, HandleCompareCommand },
    { "HAS_ROOT_NAME"_s, HandleHasRootNameCommand },
    { "HAS_ROOT_DIRECTORY"_s, HandleHasRootDirectoryCommand },
    { "HAS_ROOT_PATH"_s, HandleHasRootPathCommand },
    { "HAS_FILENAME"_s, HandleHasFilenameCommand },
    { "HAS_EXTENSION"_s, HandleHasExtensionCommand },
    { "HAS_STEM"_s, HandleHasStemCommand },
    { "HAS_RELATIVE_PART"_s, HandleHasRelativePartCommand },
    { "HAS_PARENT_PATH"_s, HandleHasParentPathCommand },
    { "IS_ABSOLUTE"_s, HandleIsAbsoluteCommand },
    { "IS_RELATIVE"_s, HandleIsRelativeCommand },
    { "IS_PREFIX"_s, HandleIsPrefixCommand },
    { "HASH"_s, HandleHashCommand }
  };

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