Util+Test: Add more ArgParser option types
This commit is contained in:
+111
-1
@@ -1,5 +1,7 @@
|
|||||||
#include <algorithm> // std::find_if
|
#include <algorithm> // find_if
|
||||||
#include <cstdio> // printf
|
#include <cstdio> // printf
|
||||||
|
#include <limits> // numeric_limits
|
||||||
|
#include <string> // stod, stoi, stoul
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
#include "util/argparser.h"
|
#include "util/argparser.h"
|
||||||
@@ -276,6 +278,23 @@ void ArgParser::addOption(bool& value, char shortName, const char* longName, con
|
|||||||
addOption(std::move(option));
|
addOption(std::move(option));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArgParser::addOption(const char*& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName, Required requiresArgument)
|
||||||
|
{
|
||||||
|
Option option {
|
||||||
|
shortName,
|
||||||
|
longName,
|
||||||
|
argumentName,
|
||||||
|
usageString,
|
||||||
|
manString,
|
||||||
|
requiresArgument,
|
||||||
|
[&value](const char* a) -> bool {
|
||||||
|
value = a;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
addOption(std::move(option));
|
||||||
|
}
|
||||||
|
|
||||||
void ArgParser::addOption(std::string& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName, Required requiresArgument)
|
void ArgParser::addOption(std::string& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName, Required requiresArgument)
|
||||||
{
|
{
|
||||||
Option option {
|
Option option {
|
||||||
@@ -293,6 +312,97 @@ void ArgParser::addOption(std::string& value, char shortName, const char* longNa
|
|||||||
addOption(std::move(option));
|
addOption(std::move(option));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArgParser::addOption(std::string_view& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName, Required requiresArgument)
|
||||||
|
{
|
||||||
|
Option option {
|
||||||
|
shortName,
|
||||||
|
longName,
|
||||||
|
argumentName,
|
||||||
|
usageString,
|
||||||
|
manString,
|
||||||
|
requiresArgument,
|
||||||
|
[&value](const char* a) -> bool {
|
||||||
|
value = a;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
addOption(std::move(option));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArgParser::addOption(int& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName, Required requiresArgument)
|
||||||
|
{
|
||||||
|
Option option {
|
||||||
|
shortName,
|
||||||
|
longName,
|
||||||
|
argumentName,
|
||||||
|
usageString,
|
||||||
|
manString,
|
||||||
|
requiresArgument,
|
||||||
|
[&value](const char* a) -> bool {
|
||||||
|
try {
|
||||||
|
value = std::stoi(a);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
addOption(std::move(option));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArgParser::addOption(unsigned int& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName, Required requiresArgument)
|
||||||
|
{
|
||||||
|
Option option {
|
||||||
|
shortName,
|
||||||
|
longName,
|
||||||
|
argumentName,
|
||||||
|
usageString,
|
||||||
|
manString,
|
||||||
|
requiresArgument,
|
||||||
|
[&value](const char* a) -> bool {
|
||||||
|
unsigned long convert = 0;
|
||||||
|
try {
|
||||||
|
convert = std::stoul(a);
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (convert <= std::numeric_limits<unsigned int>::max())
|
||||||
|
{
|
||||||
|
value = static_cast<unsigned int>(convert);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
addOption(std::move(option));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArgParser::addOption(double& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName, Required requiresArgument)
|
||||||
|
{
|
||||||
|
Option option {
|
||||||
|
shortName,
|
||||||
|
longName,
|
||||||
|
argumentName,
|
||||||
|
usageString,
|
||||||
|
manString,
|
||||||
|
requiresArgument,
|
||||||
|
[&value](const char* a) -> bool {
|
||||||
|
try {
|
||||||
|
value = std::stod(a);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
addOption(std::move(option));
|
||||||
|
}
|
||||||
|
|
||||||
void ArgParser::addOption(std::vector<std::string>& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName, Required requiresArgument)
|
void ArgParser::addOption(std::vector<std::string>& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName, Required requiresArgument)
|
||||||
{
|
{
|
||||||
Option option {
|
Option option {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef ARG_PARSER_H
|
#ifndef ARG_PARSER_H
|
||||||
#define ARG_PARSER_H
|
#define ARG_PARSER_H
|
||||||
|
|
||||||
#include <functional>
|
#include <functional> // function
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -46,7 +46,12 @@ public:
|
|||||||
|
|
||||||
void addOption(Option&& option);
|
void addOption(Option&& option);
|
||||||
void addOption(bool& value, char shortName, const char* longName, const char* usageString, const char* manString);
|
void addOption(bool& value, char shortName, const char* longName, const char* usageString, const char* manString);
|
||||||
|
void addOption(const char*& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName = "", Required requiresArgument = Required::No);
|
||||||
void addOption(std::string& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName = "", Required requiresArgument = Required::No);
|
void addOption(std::string& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName = "", Required requiresArgument = Required::No);
|
||||||
|
void addOption(std::string_view& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName = "", Required requiresArgument = Required::No);
|
||||||
|
void addOption(int& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName = "", Required requiresArgument = Required::No);
|
||||||
|
void addOption(unsigned int& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName = "", Required requiresArgument = Required::No);
|
||||||
|
void addOption(double& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName = "", Required requiresArgument = Required::No);
|
||||||
void addOption(std::vector<std::string>& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName = "", Required requiresArgument = Required::No);
|
void addOption(std::vector<std::string>& value, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName = "", Required requiresArgument = Required::No);
|
||||||
|
|
||||||
void setOptionIndex(int index) { m_optionIndex = index; }
|
void setOptionIndex(int index) { m_optionIndex = index; }
|
||||||
|
|||||||
@@ -300,6 +300,75 @@ TEST_CASE(SingleNonRequiredStringOptions)
|
|||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
|
TEST_CASE(NumberOptions)
|
||||||
|
{
|
||||||
|
// Required int short option
|
||||||
|
int intOpt1 = 0;
|
||||||
|
auto result = runParser({ "-i", "2147483647" }, [&](auto& parser) {
|
||||||
|
parser.addOption(intOpt1, 'i', nullptr, nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
|
||||||
|
});
|
||||||
|
EXPECT_EQ(result, true);
|
||||||
|
EXPECT_EQ(intOpt1, 2147483647);
|
||||||
|
|
||||||
|
// Required int short option, overflown value given
|
||||||
|
intOpt1 = 0;
|
||||||
|
result = runParser({ "-i", "2147483648" }, [&](auto& parser) {
|
||||||
|
parser.addOption(intOpt1, 'i', nullptr, nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
|
||||||
|
});
|
||||||
|
EXPECT_EQ(result, false);
|
||||||
|
EXPECT_EQ(intOpt1, 0);
|
||||||
|
|
||||||
|
// Required int short option, empty given
|
||||||
|
intOpt1 = 0;
|
||||||
|
result = runParser({ "-i" }, [&](auto& parser) {
|
||||||
|
parser.addOption(intOpt1, 'i', nullptr, nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
|
||||||
|
});
|
||||||
|
EXPECT_EQ(result, false);
|
||||||
|
EXPECT_EQ(intOpt1, 0);
|
||||||
|
|
||||||
|
// Required unsigned int short option
|
||||||
|
unsigned int unsignedIntOpt1 = 0;
|
||||||
|
result = runParser({ "-u", "4294967295" }, [&](auto& parser) {
|
||||||
|
parser.addOption(unsignedIntOpt1, 'u', nullptr, nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
|
||||||
|
});
|
||||||
|
EXPECT_EQ(result, true);
|
||||||
|
EXPECT_EQ(unsignedIntOpt1, 4294967295);
|
||||||
|
|
||||||
|
// Required unsigned int short option, overflown value given
|
||||||
|
unsignedIntOpt1 = 0;
|
||||||
|
result = runParser({ "-u", "4294967296" }, [&](auto& parser) {
|
||||||
|
parser.addOption(unsignedIntOpt1, 'u', nullptr, nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
|
||||||
|
});
|
||||||
|
EXPECT_EQ(result, false);
|
||||||
|
EXPECT_EQ(unsignedIntOpt1, 0);
|
||||||
|
|
||||||
|
// Required unsigned int short option, empty given
|
||||||
|
unsignedIntOpt1 = 0;
|
||||||
|
result = runParser({ "-u" }, [&](auto& parser) {
|
||||||
|
parser.addOption(unsignedIntOpt1, 'u', nullptr, nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
|
||||||
|
});
|
||||||
|
EXPECT_EQ(result, false);
|
||||||
|
EXPECT_EQ(unsignedIntOpt1, 0);
|
||||||
|
|
||||||
|
// Required double short option
|
||||||
|
double doubleOpt1 = 0;
|
||||||
|
result = runParser({ "-d", "999.999" }, [&](auto& parser) {
|
||||||
|
parser.addOption(doubleOpt1, 'd', nullptr, nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
|
||||||
|
});
|
||||||
|
EXPECT_EQ(result, true);
|
||||||
|
EXPECT_EQ(doubleOpt1, 999.999);
|
||||||
|
|
||||||
|
// Required double short option, empty given
|
||||||
|
doubleOpt1 = 0;
|
||||||
|
result = runParser({ "-d" }, [&](auto& parser) {
|
||||||
|
parser.addOption(doubleOpt1, 'd', nullptr, nullptr, nullptr, nullptr, Util::ArgParser::Required::Yes);
|
||||||
|
});
|
||||||
|
EXPECT_EQ(result, false);
|
||||||
|
EXPECT_EQ(doubleOpt1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
TEST_CASE(VectorStringOptions)
|
TEST_CASE(VectorStringOptions)
|
||||||
{
|
{
|
||||||
// Required vector string short option, not given
|
// Required vector string short option, not given
|
||||||
|
|||||||
Reference in New Issue
Block a user