mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-04 07:04:39 +00:00
Updated formatting
This commit is contained in:
parent
8df0a878ac
commit
cb04248cfa
@ -28,44 +28,43 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <list>
|
|
||||||
#include <functional>
|
|
||||||
#include <any>
|
|
||||||
#include <memory>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <any>
|
||||||
|
#include <functional>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <numeric>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <numeric>
|
#include <string>
|
||||||
#include <iomanip>
|
#include <type_traits>
|
||||||
#include <iterator>
|
#include <vector>
|
||||||
|
|
||||||
namespace argparse {
|
namespace argparse {
|
||||||
|
|
||||||
namespace { // anonymous namespace for helper methods - not visible outside this header file
|
namespace { // anonymous namespace for helper methods - not visible outside this
|
||||||
|
// header file
|
||||||
|
|
||||||
template<typename... Ts>
|
template <typename... Ts> struct is_container_helper {};
|
||||||
struct is_container_helper {};
|
|
||||||
|
|
||||||
template <typename T, typename _ = void>
|
template <typename T, typename _ = void>
|
||||||
struct is_container : std::false_type {};
|
struct is_container : std::false_type {};
|
||||||
|
|
||||||
template<>
|
template <> struct is_container<std::string> : std::false_type {};
|
||||||
struct is_container<std::string> : std::false_type {};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_container<T, std::conditional_t<
|
struct is_container<
|
||||||
false, is_container_helper<
|
T,
|
||||||
typename T::value_type,
|
std::conditional_t<false,
|
||||||
|
is_container_helper<typename T::value_type,
|
||||||
decltype(std::declval<T>().begin()),
|
decltype(std::declval<T>().begin()),
|
||||||
decltype(std::declval<T>().end()),
|
decltype(std::declval<T>().end()),
|
||||||
decltype(std::declval<T>().size())
|
decltype(std::declval<T>().size())>,
|
||||||
>, void>> : public std::true_type {
|
void>> : public std::true_type {};
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static constexpr bool is_container_v = is_container<T>::value;
|
static constexpr bool is_container_v = is_container<T>::value;
|
||||||
@ -75,19 +74,19 @@ using enable_if_container = std::enable_if_t<is_container_v<T>, T>;
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using enable_if_not_container = std::enable_if_t<!is_container_v<T>, T>;
|
using enable_if_not_container = std::enable_if_t<!is_container_v<T>, T>;
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
class Argument {
|
class Argument {
|
||||||
friend class ArgumentParser;
|
friend class ArgumentParser;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Argument() = default;
|
Argument() = default;
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
explicit Argument(Args... args)
|
explicit Argument(Args... args)
|
||||||
: mNames({std::move(args)...})
|
: mNames({std::move(args)...}), mIsOptional((is_optional(args) || ...)) {
|
||||||
, mIsOptional((is_optional(args) || ...))
|
std::sort(
|
||||||
{
|
mNames.begin(), mNames.end(), [](const auto &lhs, const auto &rhs) {
|
||||||
std::sort(mNames.begin(), mNames.end(), [](const auto& lhs, const auto& rhs) {
|
|
||||||
return lhs.size() == rhs.size() ? lhs < rhs : lhs.size() < rhs.size();
|
return lhs.size() == rhs.size() ? lhs < rhs : lhs.size() < rhs.size();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -133,19 +132,16 @@ public:
|
|||||||
if (mNumArgs == 0) {
|
if (mNumArgs == 0) {
|
||||||
mValues.emplace_back(mImplicitValue);
|
mValues.emplace_back(mImplicitValue);
|
||||||
return start;
|
return start;
|
||||||
}
|
} else if (mNumArgs <= static_cast<size_t>(std::distance(start, end))) {
|
||||||
else if (mNumArgs <= static_cast<size_t>(std::distance(start, end))) {
|
|
||||||
end = std::next(start, mNumArgs);
|
end = std::next(start, mNumArgs);
|
||||||
if (std::any_of(start, end, Argument::is_optional)) {
|
if (std::any_of(start, end, Argument::is_optional)) {
|
||||||
throw std::runtime_error("optional argument in parameter sequence");
|
throw std::runtime_error("optional argument in parameter sequence");
|
||||||
}
|
}
|
||||||
std::transform(start, end, std::back_inserter(mValues), mAction);
|
std::transform(start, end, std::back_inserter(mValues), mAction);
|
||||||
return end;
|
return end;
|
||||||
}
|
} else if (mDefaultValue.has_value()) {
|
||||||
else if (mDefaultValue.has_value()) {
|
|
||||||
return start;
|
return start;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
throw std::runtime_error("Too few arguments");
|
throw std::runtime_error("Too few arguments");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,11 +153,10 @@ public:
|
|||||||
if (mIsOptional) {
|
if (mIsOptional) {
|
||||||
if (mIsUsed && mValues.size() != mNumArgs && !mDefaultValue.has_value()) {
|
if (mIsUsed && mValues.size() != mNumArgs && !mDefaultValue.has_value()) {
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
stream << "error: " << mUsedName << ": expected " << mNumArgs << " argument(s). "
|
stream << "error: " << mUsedName << ": expected " << mNumArgs
|
||||||
<< mValues.size() << " provided.";
|
<< " argument(s). " << mValues.size() << " provided.";
|
||||||
throw std::runtime_error(stream.str());
|
throw std::runtime_error(stream.str());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// TODO: check if an implicit value was programmed for this argument
|
// TODO: check if an implicit value was programmed for this argument
|
||||||
if (!mIsUsed && !mDefaultValue.has_value() && mIsRequired) {
|
if (!mIsUsed && !mDefaultValue.has_value() && mIsRequired) {
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
@ -174,26 +169,29 @@ public:
|
|||||||
throw std::runtime_error(stream.str());
|
throw std::runtime_error(stream.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (mValues.size() != mNumArgs && !mDefaultValue.has_value()) {
|
if (mValues.size() != mNumArgs && !mDefaultValue.has_value()) {
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
stream << "error: " << mUsedName << ": expected " << mNumArgs << " argument(s). "
|
stream << "error: " << mUsedName << ": expected " << mNumArgs
|
||||||
<< mValues.size() << " provided.";
|
<< " argument(s). " << mValues.size() << " provided.";
|
||||||
throw std::runtime_error(stream.str());
|
throw std::runtime_error(stream.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t get_arguments_length() const {
|
size_t get_arguments_length() const {
|
||||||
return std::accumulate(std::begin(mNames), std::end(mNames), size_t(0), [](const auto& sum, const auto& s) {
|
return std::accumulate(std::begin(mNames), std::end(mNames), size_t(0),
|
||||||
return sum + s.size() + 1; // +1 for space between names
|
[](const auto &sum, const auto &s) {
|
||||||
|
return sum + s.size() +
|
||||||
|
1; // +1 for space between names
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& stream, const Argument& argument) {
|
friend std::ostream &operator<<(std::ostream &stream,
|
||||||
|
const Argument &argument) {
|
||||||
std::stringstream nameStream;
|
std::stringstream nameStream;
|
||||||
std::copy(std::begin(argument.mNames), std::end(argument.mNames), std::ostream_iterator<std::string>(nameStream, " "));
|
std::copy(std::begin(argument.mNames), std::end(argument.mNames),
|
||||||
|
std::ostream_iterator<std::string>(nameStream, " "));
|
||||||
stream << nameStream.str() << "\t" << argument.mHelp;
|
stream << nameStream.str() << "\t" << argument.mHelp;
|
||||||
if (argument.mIsRequired)
|
if (argument.mIsRequired)
|
||||||
stream << "[Required]";
|
stream << "[Required]";
|
||||||
@ -201,9 +199,7 @@ public:
|
|||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> bool operator!=(const T &aRhs) const {
|
||||||
template <typename T>
|
|
||||||
bool operator!=(const T& aRhs) const {
|
|
||||||
return !(*this == aRhs);
|
return !(*this == aRhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,8 +208,7 @@ public:
|
|||||||
* @throws std::logic_error in case of incompatible types
|
* @throws std::logic_error in case of incompatible types
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::enable_if_t <!is_container_v<T>, bool>
|
std::enable_if_t<!is_container_v<T>, bool> operator==(const T &aRhs) const {
|
||||||
operator==(const T& aRhs) const {
|
|
||||||
return get<T>() == aRhs;
|
return get<T>() == aRhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,21 +217,20 @@ public:
|
|||||||
* @throws std::logic_error in case of incompatible types
|
* @throws std::logic_error in case of incompatible types
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::enable_if_t <is_container_v<T>, bool>
|
std::enable_if_t<is_container_v<T>, bool> operator==(const T &aRhs) const {
|
||||||
operator==(const T& aRhs) const {
|
|
||||||
using ValueType = typename T::value_type;
|
using ValueType = typename T::value_type;
|
||||||
auto tLhs = get<T>();
|
auto tLhs = get<T>();
|
||||||
if (tLhs.size() != aRhs.size())
|
if (tLhs.size() != aRhs.size())
|
||||||
return false;
|
return false;
|
||||||
else {
|
else {
|
||||||
return std::equal(std::begin(tLhs), std::end(tLhs), std::begin(aRhs), [](const auto& lhs, const auto& rhs) {
|
return std::equal(std::begin(tLhs), std::end(tLhs), std::begin(aRhs),
|
||||||
|
[](const auto &lhs, const auto &rhs) {
|
||||||
return std::any_cast<const ValueType &>(lhs) == rhs;
|
return std::any_cast<const ValueType &>(lhs) == rhs;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static bool is_integer(const std::string &aValue) {
|
static bool is_integer(const std::string &aValue) {
|
||||||
if (aValue.empty() ||
|
if (aValue.empty() ||
|
||||||
((!isdigit(aValue[0])) && (aValue[0] != '-') && (aValue[0] != '+')))
|
((!isdigit(aValue[0])) && (aValue[0] != '-') && (aValue[0] != '+')))
|
||||||
@ -258,8 +252,8 @@ public:
|
|||||||
|
|
||||||
// If an argument starts with "-" or "--", then it's optional
|
// If an argument starts with "-" or "--", then it's optional
|
||||||
static bool is_optional(const std::string &aName) {
|
static bool is_optional(const std::string &aName) {
|
||||||
return (!aName.empty() && aName[0] == '-' &&
|
return (!aName.empty() && aName[0] == '-' && !is_integer(aName) &&
|
||||||
!is_integer(aName) && !is_float(aName));
|
!is_float(aName));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_positional(const std::string &aName) {
|
static bool is_positional(const std::string &aName) {
|
||||||
@ -270,9 +264,7 @@ public:
|
|||||||
* Getter for template non-container types
|
* Getter for template non-container types
|
||||||
* @throws std::logic_error in case of incompatible types
|
* @throws std::logic_error in case of incompatible types
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T> enable_if_not_container<T> get() const {
|
||||||
enable_if_not_container<T>
|
|
||||||
get() const {
|
|
||||||
if (!mValues.empty()) {
|
if (!mValues.empty()) {
|
||||||
return std::any_cast<T>(mValues.front());
|
return std::any_cast<T>(mValues.front());
|
||||||
}
|
}
|
||||||
@ -286,20 +278,20 @@ public:
|
|||||||
* Getter for container types
|
* Getter for container types
|
||||||
* @throws std::logic_error in case of incompatible types
|
* @throws std::logic_error in case of incompatible types
|
||||||
*/
|
*/
|
||||||
template <typename CONTAINER>
|
template <typename CONTAINER> enable_if_container<CONTAINER> get() const {
|
||||||
enable_if_container<CONTAINER>
|
|
||||||
get() const {
|
|
||||||
using ValueType = typename CONTAINER::value_type;
|
using ValueType = typename CONTAINER::value_type;
|
||||||
CONTAINER tResult;
|
CONTAINER tResult;
|
||||||
if (!mValues.empty()) {
|
if (!mValues.empty()) {
|
||||||
std::transform(std::begin(mValues), std::end(mValues), std::back_inserter(tResult), [](const auto & value) {
|
std::transform(
|
||||||
return std::any_cast<ValueType>(value);
|
std::begin(mValues), std::end(mValues), std::back_inserter(tResult),
|
||||||
});
|
[](const auto &value) { return std::any_cast<ValueType>(value); });
|
||||||
return tResult;
|
return tResult;
|
||||||
}
|
}
|
||||||
if (mDefaultValue.has_value()) {
|
if (mDefaultValue.has_value()) {
|
||||||
const auto& tDefaultValues = std::any_cast<const CONTAINER&>(mDefaultValue);
|
const auto &tDefaultValues =
|
||||||
std::transform(std::begin(tDefaultValues), std::end(tDefaultValues), std::back_inserter(tResult), [](const auto & value) {
|
std::any_cast<const CONTAINER &>(mDefaultValue);
|
||||||
|
std::transform(std::begin(tDefaultValues), std::end(tDefaultValues),
|
||||||
|
std::back_inserter(tResult), [](const auto &value) {
|
||||||
return std::any_cast<ValueType>(value);
|
return std::any_cast<ValueType>(value);
|
||||||
});
|
});
|
||||||
return tResult;
|
return tResult;
|
||||||
@ -312,7 +304,8 @@ public:
|
|||||||
std::string mHelp;
|
std::string mHelp;
|
||||||
std::any mDefaultValue;
|
std::any mDefaultValue;
|
||||||
std::any mImplicitValue;
|
std::any mImplicitValue;
|
||||||
std::function<std::any(const std::string&)> mAction = [](const std::string& aValue) { return aValue; };
|
std::function<std::any(const std::string &)> mAction =
|
||||||
|
[](const std::string &aValue) { return aValue; };
|
||||||
std::vector<std::any> mValues;
|
std::vector<std::any> mValues;
|
||||||
std::vector<std::string> mRawValues;
|
std::vector<std::string> mRawValues;
|
||||||
size_t mNumArgs = 1;
|
size_t mNumArgs = 1;
|
||||||
@ -327,9 +320,8 @@ public:
|
|||||||
|
|
||||||
class ArgumentParser {
|
class ArgumentParser {
|
||||||
public:
|
public:
|
||||||
explicit ArgumentParser(std::string aProgramName = {}) :
|
explicit ArgumentParser(std::string aProgramName = {})
|
||||||
mProgramName(std::move(aProgramName))
|
: mProgramName(std::move(aProgramName)) {
|
||||||
{
|
|
||||||
add_argument(Argument::mHelpOption, Argument::mHelpOptionLong)
|
add_argument(Argument::mHelpOption, Argument::mHelpOptionLong)
|
||||||
.help("show this help message and exit")
|
.help("show this help message and exit")
|
||||||
.nargs(0)
|
.nargs(0)
|
||||||
@ -339,9 +331,9 @@ class ArgumentParser {
|
|||||||
|
|
||||||
// Parameter packing
|
// Parameter packing
|
||||||
// Call add_argument with variadic number of string arguments
|
// Call add_argument with variadic number of string arguments
|
||||||
template<typename... Targs>
|
template <typename... Targs> Argument &add_argument(Targs... Fargs) {
|
||||||
Argument& add_argument(Targs... Fargs) {
|
std::shared_ptr<Argument> tArgument =
|
||||||
std::shared_ptr<Argument> tArgument = std::make_shared<Argument>(std::move(Fargs)...);
|
std::make_shared<Argument>(std::move(Fargs)...);
|
||||||
|
|
||||||
if (tArgument->mIsOptional)
|
if (tArgument->mIsOptional)
|
||||||
mOptionalArguments.emplace_back(tArgument);
|
mOptionalArguments.emplace_back(tArgument);
|
||||||
@ -356,22 +348,25 @@ class ArgumentParser {
|
|||||||
|
|
||||||
// Parameter packed add_parents method
|
// Parameter packed add_parents method
|
||||||
// Accepts a variadic number of ArgumentParser objects
|
// Accepts a variadic number of ArgumentParser objects
|
||||||
template<typename... Targs>
|
template <typename... Targs> void add_parents(Targs... Fargs) {
|
||||||
void add_parents(Targs... Fargs) {
|
|
||||||
const auto tNewParentParsers = {Fargs...};
|
const auto tNewParentParsers = {Fargs...};
|
||||||
for (const auto &tParentParser : tNewParentParsers) {
|
for (const auto &tParentParser : tNewParentParsers) {
|
||||||
const auto &tPositionalArguments = tParentParser.mPositionalArguments;
|
const auto &tPositionalArguments = tParentParser.mPositionalArguments;
|
||||||
std::copy(std::begin(tPositionalArguments), std::end(tPositionalArguments), std::back_inserter(mPositionalArguments));
|
std::copy(std::begin(tPositionalArguments),
|
||||||
|
std::end(tPositionalArguments),
|
||||||
|
std::back_inserter(mPositionalArguments));
|
||||||
|
|
||||||
const auto &tOptionalArguments = tParentParser.mOptionalArguments;
|
const auto &tOptionalArguments = tParentParser.mOptionalArguments;
|
||||||
std::copy(std::begin(tOptionalArguments), std::end(tOptionalArguments), std::back_inserter(mOptionalArguments));
|
std::copy(std::begin(tOptionalArguments), std::end(tOptionalArguments),
|
||||||
|
std::back_inserter(mOptionalArguments));
|
||||||
|
|
||||||
const auto &tArgumentMap = tParentParser.mArgumentMap;
|
const auto &tArgumentMap = tParentParser.mArgumentMap;
|
||||||
for (const auto &[tKey, tValue] : tArgumentMap) {
|
for (const auto &[tKey, tValue] : tArgumentMap) {
|
||||||
mArgumentMap.insert_or_assign(tKey, tValue);
|
mArgumentMap.insert_or_assign(tKey, tValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::move(std::begin(tNewParentParsers), std::end(tNewParentParsers), std::back_inserter(mParentParsers));
|
std::move(std::begin(tNewParentParsers), std::end(tNewParentParsers),
|
||||||
|
std::back_inserter(mParentParsers));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call parse_args_internal - which does all the work
|
/* Call parse_args_internal - which does all the work
|
||||||
@ -384,7 +379,8 @@ class ArgumentParser {
|
|||||||
parse_args_validate();
|
parse_args_validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main entry point for parsing command-line arguments using this ArgumentParser
|
/* Main entry point for parsing command-line arguments using this
|
||||||
|
* ArgumentParser
|
||||||
* @throws std::runtime_error in case of any invalid argument
|
* @throws std::runtime_error in case of any invalid argument
|
||||||
*/
|
*/
|
||||||
void parse_args(int argc, const char *const argv[]) {
|
void parse_args(int argc, const char *const argv[]) {
|
||||||
@ -397,8 +393,7 @@ class ArgumentParser {
|
|||||||
* @throws std::logic_error in case of an invalid argument name
|
* @throws std::logic_error in case of an invalid argument name
|
||||||
* @throws std::logic_error in case of incompatible types
|
* @throws std::logic_error in case of incompatible types
|
||||||
*/
|
*/
|
||||||
template <typename T = std::string>
|
template <typename T = std::string> T get(const std::string &aArgumentName) {
|
||||||
T get(const std::string& aArgumentName) {
|
|
||||||
auto tIterator = mArgumentMap.find(aArgumentName);
|
auto tIterator = mArgumentMap.find(aArgumentName);
|
||||||
if (tIterator != mArgumentMap.end()) {
|
if (tIterator != mArgumentMap.end()) {
|
||||||
return tIterator->second->get<T>();
|
return tIterator->second->get<T>();
|
||||||
@ -441,7 +436,8 @@ class ArgumentParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!mOptionalArguments.empty())
|
if (!mOptionalArguments.empty())
|
||||||
stream << (mPositionalArguments.empty() ? "" : "\n") << "Optional arguments:\n";
|
stream << (mPositionalArguments.empty() ? "" : "\n")
|
||||||
|
<< "Optional arguments:\n";
|
||||||
|
|
||||||
for (const auto &mOptionalArgument : mOptionalArguments) {
|
for (const auto &mOptionalArgument : mOptionalArguments) {
|
||||||
stream.width(tLongestArgumentLength);
|
stream.width(tLongestArgumentLength);
|
||||||
@ -464,37 +460,36 @@ class ArgumentParser {
|
|||||||
auto positionalArgumentIt = std::begin(mPositionalArguments);
|
auto positionalArgumentIt = std::begin(mPositionalArguments);
|
||||||
for (auto it = std::next(std::begin(aArguments)); it != end;) {
|
for (auto it = std::next(std::begin(aArguments)); it != end;) {
|
||||||
const auto &tCurrentArgument = *it;
|
const auto &tCurrentArgument = *it;
|
||||||
if (tCurrentArgument == Argument::mHelpOption || tCurrentArgument == Argument::mHelpOptionLong) {
|
if (tCurrentArgument == Argument::mHelpOption ||
|
||||||
|
tCurrentArgument == Argument::mHelpOptionLong) {
|
||||||
throw std::runtime_error("help called");
|
throw std::runtime_error("help called");
|
||||||
}
|
}
|
||||||
if (Argument::is_positional(tCurrentArgument)) {
|
if (Argument::is_positional(tCurrentArgument)) {
|
||||||
if (positionalArgumentIt == std::end(mPositionalArguments)) {
|
if (positionalArgumentIt == std::end(mPositionalArguments)) {
|
||||||
throw std::runtime_error("Maximum number of positional arguments exceeded");
|
throw std::runtime_error(
|
||||||
|
"Maximum number of positional arguments exceeded");
|
||||||
}
|
}
|
||||||
auto tArgument = *(positionalArgumentIt++);
|
auto tArgument = *(positionalArgumentIt++);
|
||||||
it = tArgument->consume(it, end);
|
it = tArgument->consume(it, end);
|
||||||
}
|
} else if (auto tIterator = mArgumentMap.find(tCurrentArgument);
|
||||||
else if (auto tIterator = mArgumentMap.find(tCurrentArgument); tIterator != mArgumentMap.end()) {
|
tIterator != mArgumentMap.end()) {
|
||||||
auto tArgument = tIterator->second;
|
auto tArgument = tIterator->second;
|
||||||
it = tArgument->consume(std::next(it), end, tCurrentArgument);
|
it = tArgument->consume(std::next(it), end, tCurrentArgument);
|
||||||
}
|
} else if (const auto &tCompoundArgument = tCurrentArgument;
|
||||||
else if (const auto& tCompoundArgument = tCurrentArgument;
|
tCompoundArgument.size() > 1 && tCompoundArgument[0] == '-' &&
|
||||||
tCompoundArgument.size() > 1 &&
|
|
||||||
tCompoundArgument[0] == '-' &&
|
|
||||||
tCompoundArgument[1] != '-') {
|
tCompoundArgument[1] != '-') {
|
||||||
++it;
|
++it;
|
||||||
for (size_t j = 1; j < tCompoundArgument.size(); j++) {
|
for (size_t j = 1; j < tCompoundArgument.size(); j++) {
|
||||||
auto tCurrentArgument = std::string{'-', tCompoundArgument[j]};
|
auto tCurrentArgument = std::string{'-', tCompoundArgument[j]};
|
||||||
if (auto tIterator = mArgumentMap.find(tCurrentArgument); tIterator != mArgumentMap.end()) {
|
if (auto tIterator = mArgumentMap.find(tCurrentArgument);
|
||||||
|
tIterator != mArgumentMap.end()) {
|
||||||
auto tArgument = tIterator->second;
|
auto tArgument = tIterator->second;
|
||||||
it = tArgument->consume(it, end, tCurrentArgument);
|
it = tArgument->consume(it, end, tCurrentArgument);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
throw std::runtime_error("Unknown argument");
|
throw std::runtime_error("Unknown argument");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
throw std::runtime_error("Unknown argument");
|
throw std::runtime_error("Unknown argument");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -542,4 +537,4 @@ try { \
|
|||||||
exit(0); \
|
exit(0); \
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace argparse
|
||||||
|
Loading…
Reference in New Issue
Block a user