args
parent
e702a651df
commit
a0492df393
|
@ -12,10 +12,11 @@
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <blt/std/hashmap.h>
|
#include <blt/std/hashmap.h>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
namespace blt::parser {
|
namespace blt::parser {
|
||||||
|
|
||||||
enum class arg_action {
|
enum class arg_action_t {
|
||||||
STORE,
|
STORE,
|
||||||
STORE_CONST,
|
STORE_CONST,
|
||||||
STORE_TRUE,
|
STORE_TRUE,
|
||||||
|
@ -28,14 +29,13 @@ namespace blt::parser {
|
||||||
EXTEND
|
EXTEND
|
||||||
};
|
};
|
||||||
|
|
||||||
class arg_t {
|
enum class arg_result_t {
|
||||||
private:
|
BOOL,
|
||||||
|
VALUE,
|
||||||
public:
|
VECTOR
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class arg_vector {
|
class arg_vector_t {
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> names;
|
||||||
std::vector<std::string> flags;
|
std::vector<std::string> flags;
|
||||||
|
@ -43,23 +43,23 @@ namespace blt::parser {
|
||||||
void insertAndSort(const std::string& str);
|
void insertAndSort(const std::string& str);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
arg_vector() = default;
|
arg_vector_t() = default;
|
||||||
|
|
||||||
arg_vector(const std::vector<std::string>& args);
|
arg_vector_t(const std::vector<std::string>& args);
|
||||||
|
|
||||||
arg_vector(std::initializer_list<std::string> args);
|
arg_vector_t(std::initializer_list<std::string> args);
|
||||||
|
|
||||||
arg_vector(const std::string& arg);
|
arg_vector_t(const std::string& arg);
|
||||||
|
|
||||||
arg_vector(const char* arg);
|
arg_vector_t(const char* arg);
|
||||||
|
|
||||||
arg_vector& operator=(const std::string& arg);
|
arg_vector_t& operator=(const std::string& arg);
|
||||||
|
|
||||||
arg_vector& operator=(const char* arg);
|
arg_vector_t& operator=(const char* arg);
|
||||||
|
|
||||||
arg_vector& operator=(std::initializer_list<std::string>& args);
|
arg_vector_t& operator=(std::initializer_list<std::string>& args);
|
||||||
|
|
||||||
arg_vector& operator=(std::vector<std::string>& args);
|
arg_vector_t& operator=(std::vector<std::string>& args);
|
||||||
|
|
||||||
[[nodiscard]] inline std::vector<std::string>& getNames() {
|
[[nodiscard]] inline std::vector<std::string>& getNames() {
|
||||||
return names;
|
return names;
|
||||||
|
@ -76,44 +76,84 @@ namespace blt::parser {
|
||||||
[[nodiscard]] inline const std::vector<std::string>& getFlags() const {
|
[[nodiscard]] inline const std::vector<std::string>& getFlags() const {
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct equals {
|
||||||
|
bool operator()(const arg_vector_t& a1, const arg_vector_t& a2) const {
|
||||||
|
// arg cannot have both
|
||||||
|
if (!a1.names.empty()) {
|
||||||
|
// match all pos arg
|
||||||
|
return std::ranges::all_of(a1.names, [&a2](const auto& n) -> bool {
|
||||||
|
if (std::find(a2.names.begin(), a2.names.end(), n) == a2.names.end())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// match any flag (--foo or -f)
|
||||||
|
return std::ranges::all_of(a1.flags, [&a2](const auto& f) -> bool {
|
||||||
|
if (std::find(a2.flags.begin(), a2.flags.end(), f) != a2.flags.end())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hash {
|
||||||
|
size_t operator()(const arg_vector_t& a) const {
|
||||||
|
size_t v = 0;
|
||||||
|
std::hash<std::string> hash;
|
||||||
|
for (const auto& n : a.names) {
|
||||||
|
v >>= 8;
|
||||||
|
v += hash(n);
|
||||||
|
}
|
||||||
|
for (const auto& f : a.flags) {
|
||||||
|
v >>= 8;
|
||||||
|
v += hash(f);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class arg_nargs {
|
class arg_nargs_t {
|
||||||
private:
|
private:
|
||||||
|
friend class argparse;
|
||||||
static constexpr int UNKNOWN = 0x1;
|
static constexpr int UNKNOWN = 0x1;
|
||||||
static constexpr int ALL = 0x2;
|
static constexpr int ALL = 0x2;
|
||||||
static constexpr int ALL_REQUIRED = 0x4;
|
static constexpr int ALL_REQUIRED = 0x4;
|
||||||
|
// 0 means default behaviour (consume 1 if presented otherwise ignore)
|
||||||
int args = 0;
|
int args = 0;
|
||||||
|
// 0 indicates args is used
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
void decode(char c);
|
void decode(char c);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
arg_nargs() = default;
|
arg_nargs_t() = default;
|
||||||
|
|
||||||
arg_nargs(int args): args(args) {}
|
arg_nargs_t(int args): args(args) {}
|
||||||
|
|
||||||
arg_nargs(char c);
|
arg_nargs_t(char c);
|
||||||
|
|
||||||
arg_nargs(std::string s);
|
arg_nargs_t(std::string s);
|
||||||
|
|
||||||
arg_nargs(const char* s);
|
arg_nargs_t(const char* s);
|
||||||
|
|
||||||
arg_nargs& operator=(const std::string& s);
|
arg_nargs_t& operator=(const std::string& s);
|
||||||
|
|
||||||
arg_nargs& operator=(const char* s);
|
arg_nargs_t& operator=(const char* s);
|
||||||
|
|
||||||
arg_nargs& operator=(char c);
|
arg_nargs_t& operator=(char c);
|
||||||
|
|
||||||
arg_nargs& operator=(int args);
|
arg_nargs_t& operator=(int args);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct arg_properties {
|
struct arg_properties_t {
|
||||||
private:
|
private:
|
||||||
public:
|
public:
|
||||||
arg_vector a_flags;
|
arg_vector_t a_flags;
|
||||||
arg_action a_action = arg_action::STORE;
|
arg_action_t a_action = arg_action_t::STORE;
|
||||||
arg_nargs a_nargs = 0;
|
arg_nargs_t a_nargs = 0;
|
||||||
std::optional<std::string> a_const{};
|
std::optional<std::string> a_const{};
|
||||||
std::string a_default{};
|
std::string a_default{};
|
||||||
std::string a_def{};
|
std::string a_def{};
|
||||||
|
@ -122,22 +162,24 @@ namespace blt::parser {
|
||||||
bool a_required = false;
|
bool a_required = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class arg_tokenizer {
|
class arg_tokenizer_t {
|
||||||
private:
|
private:
|
||||||
static constexpr char FLAG = '-';
|
static constexpr char FLAG = '-';
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
size_t nextIndex = 0;
|
size_t nextIndex = 0;
|
||||||
|
|
||||||
inline const std::string& get(size_t i){
|
inline const std::string& get(size_t i) {
|
||||||
return args[i];
|
return args[i];
|
||||||
}
|
}
|
||||||
inline bool hasNext(size_t i){
|
|
||||||
return (size_t)i < args.size();
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
arg_tokenizer() = default;
|
|
||||||
|
|
||||||
arg_tokenizer(size_t argc, const char** argv);
|
inline bool hasNext(size_t i) {
|
||||||
|
return (size_t) i < args.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
arg_tokenizer_t() = default;
|
||||||
|
|
||||||
|
arg_tokenizer_t(size_t argc, const char** argv);
|
||||||
|
|
||||||
inline void forward() {
|
inline void forward() {
|
||||||
nextIndex++;
|
nextIndex++;
|
||||||
|
@ -155,7 +197,7 @@ namespace blt::parser {
|
||||||
return hasNext(nextIndex);
|
return hasNext(nextIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isFlag(size_t i){
|
inline bool isFlag(size_t i) {
|
||||||
return get(i).starts_with(FLAG);
|
return get(i).starts_with(FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,27 +207,41 @@ namespace blt::parser {
|
||||||
};
|
};
|
||||||
|
|
||||||
class argparse {
|
class argparse {
|
||||||
|
public:
|
||||||
|
typedef std::variant<std::string, bool, std::vector<std::string>> arg_data_t;
|
||||||
private:
|
private:
|
||||||
arg_tokenizer tokenizer;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
std::vector<arg_properties> argStorage;
|
friend argparse;
|
||||||
HASHMAP<std::string, arg_properties*> flagAssociations;
|
private:
|
||||||
std::vector<std::pair<std::string, arg_properties*>> nameAssociations;
|
std::vector<arg_properties_t> arg_storage;
|
||||||
|
public:
|
||||||
|
std::vector<std::pair<std::string, arg_properties_t*>> name_associations;
|
||||||
|
HASHMAP<std::string, arg_properties_t*> flag_associations;
|
||||||
|
HASHSET<arg_vector_t, arg_vector_t::hash, arg_vector_t::equals> required_vars;
|
||||||
} user_args;
|
} user_args;
|
||||||
|
|
||||||
struct arg_results {
|
struct arg_results {
|
||||||
std::string programName;
|
friend argparse;
|
||||||
HASHMAP<std::string, std::string> positionalArgs;
|
private:
|
||||||
|
HASHSET<arg_vector_t, arg_vector_t::hash, arg_vector_t::equals> found_required;
|
||||||
|
public:
|
||||||
|
std::string program_name;
|
||||||
|
HASHMAP <arg_vector_t, arg_data_t, arg_vector_t::hash, arg_vector_t::equals> positional_args;
|
||||||
|
HASHMAP <arg_vector_t, arg_data_t, arg_vector_t::hash, arg_vector_t::equals> flag_args;
|
||||||
} loaded_args;
|
} loaded_args;
|
||||||
|
private:
|
||||||
static bool validateArgument(const arg_properties& args);
|
static bool validateArgument(const arg_properties_t& args);
|
||||||
|
bool consumeFlagArguments(arg_tokenizer_t& arg_tokenizer, const arg_properties_t& properties, arg_data_t& arg_data);
|
||||||
|
void handlePositionalArgument(arg_tokenizer_t& arg_tokenizer, size_t& last_pos);
|
||||||
|
void handleFlagArgument(arg_tokenizer_t& arg_tokenizer);
|
||||||
public:
|
public:
|
||||||
argparse() = default;
|
argparse() = default;
|
||||||
|
|
||||||
void addArgument(const arg_properties& args);
|
void addArgument(const arg_properties_t& args);
|
||||||
|
|
||||||
const arg_results& parse_args(int argc, const char** argv);
|
const arg_results& parse_args(int argc, const char** argv);
|
||||||
|
|
||||||
|
void printHelp();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,140 +8,215 @@
|
||||||
|
|
||||||
namespace blt::parser {
|
namespace blt::parser {
|
||||||
|
|
||||||
arg_vector::arg_vector(const std::vector<std::string>& args) {
|
arg_vector_t::arg_vector_t(const std::vector<std::string>& args) {
|
||||||
for (auto& arg : args)
|
for (auto& arg : args)
|
||||||
insertAndSort(arg);
|
insertAndSort(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_vector::arg_vector(std::initializer_list<std::string> args) {
|
arg_vector_t::arg_vector_t(std::initializer_list<std::string> args) {
|
||||||
for (auto& arg : args)
|
for (auto& arg : args)
|
||||||
insertAndSort(arg);
|
insertAndSort(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_vector::arg_vector(const std::string& arg) {
|
arg_vector_t::arg_vector_t(const std::string& arg) {
|
||||||
insertAndSort(arg);
|
insertAndSort(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_vector::arg_vector(const char* arg) {
|
arg_vector_t::arg_vector_t(const char* arg) {
|
||||||
insertAndSort(arg);
|
insertAndSort(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_vector& arg_vector::operator=(const std::string& arg) {
|
arg_vector_t& arg_vector_t::operator=(const std::string& arg) {
|
||||||
insertAndSort(arg);
|
insertAndSort(arg);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_vector& arg_vector::operator=(const char* arg) {
|
arg_vector_t& arg_vector_t::operator=(const char* arg) {
|
||||||
insertAndSort(arg);
|
insertAndSort(arg);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_vector& arg_vector::operator=(std::initializer_list<std::string>& args) {
|
arg_vector_t& arg_vector_t::operator=(std::initializer_list<std::string>& args) {
|
||||||
for (auto& arg : args)
|
for (auto& arg : args)
|
||||||
insertAndSort(arg);
|
insertAndSort(arg);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_vector& arg_vector::operator=(std::vector<std::string>& args) {
|
arg_vector_t& arg_vector_t::operator=(std::vector<std::string>& args) {
|
||||||
for (auto& arg : args)
|
for (auto& arg : args)
|
||||||
insertAndSort(arg);
|
insertAndSort(arg);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void arg_vector::insertAndSort(const std::string& str) {
|
void arg_vector_t::insertAndSort(const std::string& str) {
|
||||||
if (str.starts_with('-'))
|
if (str.starts_with('-'))
|
||||||
flags.push_back(str);
|
flags.push_back(str);
|
||||||
else
|
else
|
||||||
names.push_back(str);
|
names.push_back(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_nargs::arg_nargs(char c) {
|
arg_nargs_t::arg_nargs_t(char c) {
|
||||||
decode(c);
|
decode(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_nargs::arg_nargs(std::string s) {
|
arg_nargs_t::arg_nargs_t(std::string s) {
|
||||||
decode(s[0]);
|
decode(s[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_nargs::arg_nargs(const char* s) {
|
arg_nargs_t::arg_nargs_t(const char* s) {
|
||||||
decode(*s);
|
decode(*s);
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_nargs& arg_nargs::operator=(const std::string& s) {
|
arg_nargs_t& arg_nargs_t::operator=(const std::string& s) {
|
||||||
decode(s[0]);
|
decode(s[0]);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_nargs& arg_nargs::operator=(char c) {
|
arg_nargs_t& arg_nargs_t::operator=(char c) {
|
||||||
decode(c);
|
decode(c);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_nargs& arg_nargs::operator=(int a) {
|
arg_nargs_t& arg_nargs_t::operator=(int a) {
|
||||||
args = a;
|
args = a;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_nargs& arg_nargs::operator=(const char* s) {
|
arg_nargs_t& arg_nargs_t::operator=(const char* s) {
|
||||||
decode(*s);
|
decode(*s);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void arg_nargs::decode(char c) {
|
void arg_nargs_t::decode(char c) {
|
||||||
if (c == '?')
|
if (c == '?')
|
||||||
flags |= UNKNOWN;
|
flags = UNKNOWN;
|
||||||
if (c == '+')
|
else if (c == '+')
|
||||||
flags |= ALL_REQUIRED;
|
flags = ALL_REQUIRED;
|
||||||
if (c == '*')
|
else if (c == '*')
|
||||||
flags |= ALL;
|
flags = ALL;
|
||||||
|
else
|
||||||
|
flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_tokenizer::arg_tokenizer(size_t argc, const char** argv) {
|
arg_tokenizer_t::arg_tokenizer_t(size_t argc, const char** argv) {
|
||||||
for (size_t i = 0; i < argc; i++)
|
for (size_t i = 0; i < argc; i++)
|
||||||
args.emplace_back(argv[i]);
|
args.emplace_back(argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool argparse::validateArgument(const arg_properties& args) {
|
bool argparse::validateArgument(const arg_properties_t& args) {
|
||||||
return !args.a_flags.getFlags().empty() ^ !args.a_flags.getNames().empty();
|
return !args.a_flags.getFlags().empty() ^ !args.a_flags.getNames().empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void argparse::addArgument(const arg_properties& args) {
|
void argparse::addArgument(const arg_properties_t& args) {
|
||||||
if (!validateArgument(args)) {
|
if (!validateArgument(args)) {
|
||||||
BLT_WARN("Argument contains both flags and positional names, this is not allowed!");
|
BLT_WARN("Argument contains both flags and positional names, this is not allowed!");
|
||||||
BLT_WARN("(Discarding argument)");
|
BLT_WARN("(Discarding argument)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// store one copy of the properties (arg properties could in theory be very large!)
|
// store one copy of the properties (arg properties could in theory be very large!)
|
||||||
auto pos = user_args.argStorage.size();
|
auto pos = user_args.arg_storage.size();
|
||||||
user_args.argStorage.push_back(args);
|
user_args.arg_storage.push_back(args);
|
||||||
auto& arg = user_args.argStorage[pos];
|
auto& arg = user_args.arg_storage[pos];
|
||||||
// associate the arg properties per name and flag to allow for quick access when parsing
|
// associate the arg properties per name and flag to allow for quick access when parsing
|
||||||
auto& names = args.a_flags.getNames();
|
auto& names = args.a_flags.getNames();
|
||||||
for (const auto& name : names)
|
for (const auto& name : names)
|
||||||
user_args.nameAssociations.emplace_back(name, &arg);
|
user_args.name_associations.emplace_back(name, &arg);
|
||||||
|
|
||||||
auto& flags = args.a_flags.getFlags();
|
auto& flags = args.a_flags.getFlags();
|
||||||
for (const auto& flag : flags)
|
for (const auto& flag : flags)
|
||||||
user_args.flagAssociations[flag] = &arg;
|
user_args.flag_associations[flag] = &arg;
|
||||||
|
|
||||||
|
if (args.a_required)
|
||||||
|
user_args.required_vars.insert(args.a_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
const argparse::arg_results& argparse::parse_args(int argc, const char** argv) {
|
const argparse::arg_results& argparse::parse_args(int argc, const char** argv) {
|
||||||
loaded_args = {};
|
loaded_args = {};
|
||||||
arg_tokenizer asToken(argc, argv);
|
arg_tokenizer_t arg_tokenizer(argc, argv);
|
||||||
loaded_args.programName = asToken.next();
|
loaded_args.program_name = arg_tokenizer.next();
|
||||||
BLT_TRACE("Loading args for %s", loaded_args.programName.c_str());
|
BLT_TRACE("Loading args for %s", loaded_args.program_name.c_str());
|
||||||
|
|
||||||
size_t lastPositional;
|
size_t last_positional;
|
||||||
while (asToken.hasNext()) {
|
while (arg_tokenizer.hasNext()) {
|
||||||
if (!asToken.isFlag()){
|
// a token isn't a flag it must be a positional arg as flags will consume nargs
|
||||||
loaded_args.positionalArgs[user_args.nameAssociations[lastPositional].first] = asToken.next();
|
if (!arg_tokenizer.isFlag()){
|
||||||
|
handlePositionalArgument(arg_tokenizer, last_positional);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
handleFlagArgument(arg_tokenizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return loaded_args;
|
return loaded_args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void argparse::printHelp() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void argparse::handlePositionalArgument(arg_tokenizer_t& arg_tokenizer, size_t& last_pos) {
|
||||||
|
// TODO:
|
||||||
|
loaded_args.positional_args[user_args.name_associations[last_pos++].first] = arg_tokenizer.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
void argparse::handleFlagArgument(arg_tokenizer_t& arg_tokenizer) {
|
||||||
|
// token is a flag, find out special information about it
|
||||||
|
auto flag = arg_tokenizer.next();
|
||||||
|
|
||||||
|
auto loc = user_args.flag_associations.find(flag);
|
||||||
|
if (loc == user_args.flag_associations.end()){
|
||||||
|
BLT_WARN("Flag '%s' not an option!");
|
||||||
|
printHelp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto flag_properties = loc->second;
|
||||||
|
|
||||||
|
arg_data_t data;
|
||||||
|
switch(flag_properties->a_action){
|
||||||
|
case arg_action_t::HELP:
|
||||||
|
printHelp();
|
||||||
|
break;
|
||||||
|
case arg_action_t::STORE:
|
||||||
|
break;
|
||||||
|
case arg_action_t::STORE_CONST:
|
||||||
|
data = flag_properties->a_const;
|
||||||
|
break;
|
||||||
|
case arg_action_t::STORE_FALSE:
|
||||||
|
data = false;
|
||||||
|
break;
|
||||||
|
case arg_action_t::STORE_TRUE:
|
||||||
|
data = true;
|
||||||
|
break;
|
||||||
|
case arg_action_t::APPEND:
|
||||||
|
if (holds_alternative<std::vector<std::string>>(data)){
|
||||||
|
auto& l = get<std::vector<std::string>>(data);
|
||||||
|
|
||||||
|
} else
|
||||||
|
BLT_WARN("Requested append to data which doesn't contain a list!");
|
||||||
|
break;
|
||||||
|
case arg_action_t::APPEND_CONST:
|
||||||
|
break;
|
||||||
|
case arg_action_t::COUNT:
|
||||||
|
break;
|
||||||
|
case arg_action_t::EXTEND:
|
||||||
|
break;
|
||||||
|
case arg_action_t::VERSION:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
loaded_args.flag_args[flag_properties->a_flags] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool argparse::consumeFlagArguments(arg_tokenizer_t& arg_tokenizer, const arg_properties_t& properties, arg_data_t& arg_data) {
|
||||||
|
// since the function is called after the flag is consumed, isFlag()/ will return information about the next arg
|
||||||
|
if (properties.a_nargs.flags) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (arg_tokenizer.isFlag())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue