浏览代码

Update Taywee/args and fix a subcommand bug

default_compile_flags
vector-of-bool 5 年前
父节点
当前提交
67d426685a
共有 2 个文件被更改,包括 58 次插入35 次删除
  1. +57
    -34
      external/taywee-args/include/args.hxx
  2. +1
    -1
      peru.yaml

+ 57
- 34
external/taywee-args/include/args.hxx 查看文件

/* Copyright (c) 2016-2017 Taylor C. Richberger <taywee@gmx.com> and Pavel
/* A simple header-only C++ argument parser library.
*
* https://github.com/Taywee/args
*
* Copyright (c) 2016-2019 Taylor C. Richberger <taywee@gmx.com> and Pavel
* Belikov * Belikov
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to * of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the * deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is * sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <type_traits> #include <type_traits>
#include <cstddef>


#ifdef ARGS_TESTNAMESPACE #ifdef ARGS_TESTNAMESPACE
namespace argstest namespace argstest
*/ */
std::vector<Base *>::size_type MatchedChildren() const std::vector<Base *>::size_type MatchedChildren() const
{ {
return std::count_if(std::begin(Children()), std::end(Children()), [](const Base *child){return child->Matched();});
// Cast to avoid warnings from -Wsign-conversion
return static_cast<std::vector<Base *>::size_type>(
std::count_if(std::begin(Children()), std::end(Children()), [](const Base *child){return child->Matched();}));
} }


/** Whether or not this group matches validation /** Whether or not this group matches validation


public: public:
Subparser(std::vector<std::string> args_, ArgumentParser &parser_, const Command &command_, const HelpParams &helpParams_) Subparser(std::vector<std::string> args_, ArgumentParser &parser_, const Command &command_, const HelpParams &helpParams_)
: args(std::move(args_)), parser(&parser_), helpParams(helpParams_), command(command_)
: Group({}, Validators::AllChildGroups), args(std::move(args_)), parser(&parser_), helpParams(helpParams_), command(command_)
{ {
} }


Subparser(const Command &command_, const HelpParams &helpParams_) : helpParams(helpParams_), command(command_)
Subparser(const Command &command_, const HelpParams &helpParams_) : Group({}, Validators::AllChildGroups), helpParams(helpParams_), command(command_)
{ {
} }


return; return;
} }


for (Base *child: Children())
auto onValidationError = [&]
{ {
if (child->IsGroup() && !child->Matched())
{
std::ostringstream problem;
problem << "Group validation failed somewhere!";
std::ostringstream problem;
problem << "Group validation failed somewhere!";
#ifdef ARGS_NOEXCEPT #ifdef ARGS_NOEXCEPT
error = Error::Validation;
errorMsg = problem.str();
error = Error::Validation;
errorMsg = problem.str();
#else #else
throw ValidationError(problem.str());
throw ValidationError(problem.str());
#endif #endif
};

for (Base *child: Children())
{
if (child->IsGroup() && !child->Matched())
{
onValidationError();
} }


child->Validate(shortprefix, longprefix); child->Validate(shortprefix, longprefix);
if (subparser != nullptr) if (subparser != nullptr)
{ {
subparser->Validate(shortprefix, longprefix); subparser->Validate(shortprefix, longprefix);
if (!subparser->Matched())
{
onValidationError();
}
} }


if (selectedCommand == nullptr && commandIsRequired && (Group::HasCommand() || subparserHasCommand)) if (selectedCommand == nullptr && commandIsRequired && (Group::HasCommand() || subparserHasCommand))
#endif #endif
} }


SelectCommand(*itCommand);
SelectedCommand().SelectCommand(*itCommand);


if (const auto &coroutine = GetCoroutine()) if (const auto &coroutine = GetCoroutine())
{ {
#endif #endif
readCompletion = true; readCompletion = true;
++it; ++it;
size_t argsLeft = std::distance(it, end);
const auto argsLeft = static_cast<size_t>(std::distance(it, end));
if (completion->cword == 0 || argsLeft <= 1 || completion->cword >= argsLeft) if (completion->cword == 0 || argsLeft <= 1 || completion->cword >= argsLeft)
{ {
#ifndef ARGS_NOEXCEPT #ifndef ARGS_NOEXCEPT
if (idx > 0 && curArgs[idx] == "=") if (idx > 0 && curArgs[idx] == "=")
{ {
curArgs[idx - 1] += "="; curArgs[idx - 1] += "=";
// Avoid warnings from -Wsign-conversion
const auto signedIdx = static_cast<std::ptrdiff_t>(idx);
if (idx + 1 < curArgs.size()) if (idx + 1 < curArgs.size())
{ {
curArgs[idx - 1] += curArgs[idx + 1]; curArgs[idx - 1] += curArgs[idx + 1];
curArgs.erase(curArgs.begin() + idx, curArgs.begin() + idx + 2);
curArgs.erase(curArgs.begin() + signedIdx, curArgs.begin() + signedIdx + 2);
} else } else
{ {
curArgs.erase(curArgs.begin() + idx);
curArgs.erase(curArgs.begin() + signedIdx);
} }
} else } else
{ {
const std::vector<std::string> args(argv + 1, argv + argc); const std::vector<std::string> args(argv + 1, argv + argc);
return ParseArgs(args) == std::end(args); return ParseArgs(args) == std::end(args);
} }
template <typename T> template <typename T>
bool ParseCLI(const T &args) bool ParseCLI(const T &args)
{ {
operator ()(const std::string &name, const std::string &value, T &destination) operator ()(const std::string &name, const std::string &value, T &destination)
{ {
std::istringstream ss(value); std::istringstream ss(value);
ss >> destination >> std::ws;
bool failed = !(ss >> destination);

if (!failed)
{
ss >> std::ws;
}


if (ss.rdbuf()->in_avail() > 0)
if (ss.rdbuf()->in_avail() > 0 || failed)
{ {
#ifdef ARGS_NOEXCEPT #ifdef ARGS_NOEXCEPT
(void)name; (void)name;
}; };


/** An argument-accepting flag class /** An argument-accepting flag class
*
*
* \tparam T the type to extract the argument as * \tparam T the type to extract the argument as
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined) * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
*/ */
return values.end(); return values.end();
} }


const_iterator end() const noexcept
const_iterator end() const noexcept
{ {
return values.end(); return values.end();
} }
}; };


/** An argument-accepting flag class that pushes the found values into a list /** An argument-accepting flag class that pushes the found values into a list
*
*
* \tparam T the type to extract the argument as * \tparam T the type to extract the argument as
* \tparam List the list type that houses the values * \tparam List the list type that houses the values
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined) * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
return values.end(); return values.end();
} }


const_iterator end() const noexcept
const_iterator end() const noexcept
{ {
return values.end(); return values.end();
} }
}; };


/** A mapping value flag class /** A mapping value flag class
*
*
* \tparam K the type to extract the argument as * \tparam K the type to extract the argument as
* \tparam T the type to store the result as * \tparam T the type to store the result as
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined) * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
}; };


/** A mapping value flag list class /** A mapping value flag list class
*
*
* \tparam K the type to extract the argument as * \tparam K the type to extract the argument as
* \tparam T the type to store the result as * \tparam T the type to store the result as
* \tparam List the list type that houses the values * \tparam List the list type that houses the values
return values.end(); return values.end();
} }


const_iterator end() const noexcept
const_iterator end() const noexcept
{ {
return values.end(); return values.end();
} }
}; };


/** A positional argument class that pushes the found values into a list /** A positional argument class that pushes the found values into a list
*
*
* \tparam T the type to extract the argument as * \tparam T the type to extract the argument as
* \tparam List the list type that houses the values * \tparam List the list type that houses the values
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined) * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
return values.end(); return values.end();
} }


const_iterator end() const noexcept
const_iterator end() const noexcept
{ {
return values.end(); return values.end();
} }
}; };


/** A positional argument mapping class /** A positional argument mapping class
*
*
* \tparam K the type to extract the argument as * \tparam K the type to extract the argument as
* \tparam T the type to store the result as * \tparam T the type to store the result as
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined) * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
}; };


/** A positional argument mapping list class /** A positional argument mapping list class
*
*
* \tparam K the type to extract the argument as * \tparam K the type to extract the argument as
* \tparam T the type to store the result as * \tparam T the type to store the result as
* \tparam List the list type that houses the values * \tparam List the list type that houses the values
return values.end(); return values.end();
} }


const_iterator end() const noexcept
const_iterator end() const noexcept
{ {
return values.end(); return values.end();
} }

+ 1
- 1
peru.yaml 查看文件



git module taywee-args: git module taywee-args:
url: https://github.com/Taywee/args.git url: https://github.com/Taywee/args.git
rev: 6.2.2
rev: 78e27faf75ff7d20f232f11ffcef65cde43c449d
move: move:
args.hxx: include/args.hxx args.hxx: include/args.hxx
pick: include pick: include

正在加载...
取消
保存