mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-04 15:14:39 +00:00
Implemented support for parsing both positional and optional arguments
This commit is contained in:
parent
d7d1880fe6
commit
996f7882ca
@ -140,7 +140,8 @@ struct Argument {
|
|||||||
class ArgumentParser {
|
class ArgumentParser {
|
||||||
public:
|
public:
|
||||||
ArgumentParser(const std::string& aProgramName) :
|
ArgumentParser(const std::string& aProgramName) :
|
||||||
mProgramName(aProgramName) {}
|
mProgramName(aProgramName),
|
||||||
|
mNextPositionalArgument(0) {}
|
||||||
|
|
||||||
template<typename T, typename... Targs>
|
template<typename T, typename... Targs>
|
||||||
Argument& add_argument(T value, Targs... Fargs) {
|
Argument& add_argument(T value, Targs... Fargs) {
|
||||||
@ -196,6 +197,25 @@ class ArgumentParser {
|
|||||||
else {
|
else {
|
||||||
// This is a positional argument.
|
// This is a positional argument.
|
||||||
// Parse and save into mPositionalArguments vector
|
// Parse and save into mPositionalArguments vector
|
||||||
|
auto tArgument = mPositionalArguments[mNextPositionalArgument];
|
||||||
|
auto tCount = tArgument->mNumArgs;
|
||||||
|
while (tCount > 0) {
|
||||||
|
if (i < argc) {
|
||||||
|
tArgument->mRawValues.push_back(argv[i]);
|
||||||
|
if (tArgument->mAction != nullptr)
|
||||||
|
tArgument->mValues.push_back(tArgument->mAction(argv[i]));
|
||||||
|
else {
|
||||||
|
if (tArgument->mDefaultValue.has_value())
|
||||||
|
tArgument->mValues.push_back(tArgument->mDefaultValue);
|
||||||
|
else
|
||||||
|
tArgument->mValues.push_back(std::string(argv[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tCount -= 1;
|
||||||
|
if (tCount > 0) i += 1;
|
||||||
|
}
|
||||||
|
if (tCount == 0)
|
||||||
|
mNextPositionalArgument += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,6 +258,7 @@ class ArgumentParser {
|
|||||||
|
|
||||||
std::string mProgramName;
|
std::string mProgramName;
|
||||||
std::vector<std::shared_ptr<Argument>> mPositionalArguments;
|
std::vector<std::shared_ptr<Argument>> mPositionalArguments;
|
||||||
|
size_t mNextPositionalArgument;
|
||||||
std::map<std::string, std::shared_ptr<Argument>> mArgumentMap;
|
std::map<std::string, std::shared_ptr<Argument>> mArgumentMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,3 +3,4 @@
|
|||||||
#include <argparse.hpp>
|
#include <argparse.hpp>
|
||||||
#include <test_add_argument.hpp>
|
#include <test_add_argument.hpp>
|
||||||
#include <test_parse_args.hpp>
|
#include <test_parse_args.hpp>
|
||||||
|
#include <test_positional_arguments.hpp>
|
||||||
|
45
tests/test_positional_arguments.hpp
Normal file
45
tests/test_positional_arguments.hpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <catch.hpp>
|
||||||
|
#include <argparse.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("Parse positional arguments", "[parse_args]") {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
program.add_argument("input");
|
||||||
|
program.add_argument("output");
|
||||||
|
program.parse_args({ "test", "rocket.mesh", "thrust_profile.csv" });
|
||||||
|
auto arguments = program.get_arguments();
|
||||||
|
REQUIRE(arguments.size() == 2);
|
||||||
|
REQUIRE(program.get("input") == "rocket.mesh");
|
||||||
|
REQUIRE(program.get("output") == "thrust_profile.csv");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Parse positional arguments with fixed nargs", "[parse_args]") {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
program.add_argument("input");
|
||||||
|
program.add_argument("output").nargs(2);
|
||||||
|
program.parse_args({ "test", "rocket.mesh", "thrust_profile.csv", "output.mesh" });
|
||||||
|
auto arguments = program.get_arguments();
|
||||||
|
REQUIRE(arguments.size() == 2);
|
||||||
|
REQUIRE(program.get("input") == "rocket.mesh");
|
||||||
|
auto outputs = program.get<std::vector<std::string>>("output");
|
||||||
|
REQUIRE(outputs.size() == 2);
|
||||||
|
REQUIRE(outputs[0] == "thrust_profile.csv");
|
||||||
|
REQUIRE(outputs[1] == "output.mesh");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Parse positional arguments with optional arguments", "[parse_args]") {
|
||||||
|
argparse::ArgumentParser program("test");
|
||||||
|
program.add_argument("input");
|
||||||
|
program.add_argument("output").nargs(2);
|
||||||
|
program.add_argument("--num_iterations")
|
||||||
|
.action([](const std::string& value) { return std::stoi(value); });
|
||||||
|
program.parse_args({ "test", "rocket.mesh", "--num_iterations", "15", "thrust_profile.csv", "output.mesh" });
|
||||||
|
auto arguments = program.get_arguments();
|
||||||
|
REQUIRE(arguments.size() == 3);
|
||||||
|
REQUIRE(program.get<int>("--num_iterations") == 15);
|
||||||
|
REQUIRE(program.get("input") == "rocket.mesh");
|
||||||
|
auto outputs = program.get<std::vector<std::string>>("output");
|
||||||
|
REQUIRE(outputs.size() == 2);
|
||||||
|
REQUIRE(outputs[0] == "thrust_profile.csv");
|
||||||
|
REQUIRE(outputs[1] == "output.mesh");
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user