add more features to argparse

can now add git [name] [args] type calls
v1
Brett 2023-09-10 15:33:11 -04:00
parent 215220f98b
commit 9e4bfad087
3 changed files with 71 additions and 15 deletions

View File

@ -77,7 +77,7 @@ namespace blt
} }
// returns the first flag that starts with '--' otherwise return the first '-' flag // returns the first flag that starts with '--' otherwise return the first '-' flag
[[nodiscard]] std::string getFirstFullFlag(); [[nodiscard]] std::string getFirstFullFlag() const;
}; };
class arg_nargs_t class arg_nargs_t
@ -127,13 +127,22 @@ namespace blt
std::string a_version{}; std::string a_version{};
std::string a_metavar{}; std::string a_metavar{};
bool a_required = true; bool a_required = true;
bool a_disable_help = false;
}; };
class arg_builder class arg_builder
{ {
private:
arg_properties_t properties; arg_properties_t properties;
public: public:
arg_builder(const arg_vector_t& flags): properties(flags) explicit arg_builder(const arg_vector_t& flags): properties(flags)
{}
arg_builder(const std::initializer_list<std::string>& flags): properties(flags)
{}
template<typename... string_args>
explicit arg_builder(string_args... flags): properties({flags...})
{} {}
inline arg_properties_t build() inline arg_properties_t build()
@ -171,6 +180,12 @@ namespace blt
return *this; return *this;
} }
inline arg_builder& disableHelp()
{
properties.a_disable_help = true;
return *this;
}
inline arg_builder& setHelp(const std::string& help) inline arg_builder& setHelp(const std::string& help)
{ {
properties.a_help = help; properties.a_help = help;
@ -203,7 +218,7 @@ namespace blt
std::vector<std::string> args; std::vector<std::string> args;
size_t currentIndex = 0; size_t currentIndex = 0;
public: public:
arg_tokenizer(std::vector<std::string> args): args(std::move(args)) explicit arg_tokenizer(std::vector<std::string> args): args(std::move(args))
{} {}
// returns the current arg // returns the current arg
@ -265,11 +280,11 @@ namespace blt
friend arg_parse; friend arg_parse;
private: private:
// stores dest value not the flag/name! // stores dest value not the flag/name!
HASHSET<std::string> found_args; HASHSET <std::string> found_args;
std::vector<std::string> unrecognized_args; std::vector<std::string> unrecognized_args;
public: public:
std::string program_name; std::string program_name;
HASHMAP<std::string, arg_data_t> data; HASHMAP <std::string, arg_data_t> data;
inline arg_data_t& operator[](const std::string& key) inline arg_data_t& operator[](const std::string& key)
{ {
@ -296,8 +311,11 @@ namespace blt
} }
} loaded_args; } loaded_args;
bool help_disabled = false;
std::string help_inclusion;
private: private:
static std::string getMetavar(const arg_properties_t* const& arg); static std::string getMetavar(const arg_properties_t* const& arg);
static std::string getFlagHelp(const arg_properties_t* const& arg); static std::string getFlagHelp(const arg_properties_t* const& arg);
static bool takesArgs(const arg_properties_t* const& arg); static bool takesArgs(const arg_properties_t* const& arg);
@ -311,7 +329,7 @@ namespace blt
// expects that the current flag has already been consumed (advanced past), leaves tokenizer in a state where the next element is 'current' // expects that the current flag has already been consumed (advanced past), leaves tokenizer in a state where the next element is 'current'
bool consumeArguments( bool consumeArguments(
arg_tokenizer& tokenizer, const std::string& flag, const arg_properties_t& properties, std::vector<arg_data_internal_t>& v_out arg_tokenizer& tokenizer, const std::string& flag, const arg_properties_t& properties, std::vector<arg_data_internal_t>& v_out
) const; ) const;
void handlePositionalArgument(arg_tokenizer& tokenizer, size_t& last_pos); void handlePositionalArgument(arg_tokenizer& tokenizer, size_t& last_pos);
@ -319,6 +337,8 @@ namespace blt
void processFlag(arg_tokenizer& tokenizer, const std::string& flag); void processFlag(arg_tokenizer& tokenizer, const std::string& flag);
void handleFlag(arg_tokenizer& tokenizer, const std::string& flag, const arg_properties_t* properties);
public: public:
template<typename T> template<typename T>
@ -398,6 +418,11 @@ namespace blt
user_args.max_line_length = size; user_args.max_line_length = size;
} }
inline void setHelpExtras(std::string str)
{
help_inclusion = std::move(str);
}
static std::string filename(const std::string& path); static std::string filename(const std::string& path);
~arg_parse() ~arg_parse()

@ -1 +1 @@
Subproject commit 93201da2ba5a6aba0a6e57ada64973555629b3e3 Subproject commit 77cab8192a879e5d27188f97e8f2080dd7e36ca8

View File

@ -68,7 +68,7 @@ namespace blt
name = str; name = str;
} }
std::string arg_vector_t::getFirstFullFlag() std::string arg_vector_t::getFirstFullFlag() const
{ {
// assign flag so it always exists, will be first '-' flag if we fail to find a '--' flag // assign flag so it always exists, will be first '-' flag if we fail to find a '--' flag
std::string flag = flags[0]; std::string flag = flags[0];
@ -156,7 +156,7 @@ namespace blt
bool arg_parse::consumeArguments( bool arg_parse::consumeArguments(
arg_tokenizer& tokenizer, const std::string& flag, const arg_properties_t& properties, std::vector<arg_data_internal_t>& v_out arg_tokenizer& tokenizer, const std::string& flag, const arg_properties_t& properties, std::vector<arg_data_internal_t>& v_out
) const ) const
{ {
switch (properties.a_nargs.flags) switch (properties.a_nargs.flags)
{ {
@ -231,8 +231,26 @@ namespace blt
loaded_args.unrecognized_args.push_back(tokenizer.get()); loaded_args.unrecognized_args.push_back(tokenizer.get());
else else
{ {
loaded_args.data[user_args.name_associations[index]->a_dest] = tokenizer.get(); bool found = false;
loaded_args.found_args.insert(user_args.name_associations[index]->a_dest); for (const auto& pos_properties : user_args.name_associations)
{
const auto& flag = tokenizer.get();
if (pos_properties->a_flags.contains(flag))
{
tokenizer.advance();
handleFlag(tokenizer, flag, pos_properties);
found = true;
break;
}
}
if (!found)
{
const auto& arg_property = user_args.name_associations[index];
if (arg_property->a_disable_help)
help_disabled = true;
loaded_args.data[arg_property->a_dest] = tokenizer.get();
loaded_args.found_args.insert(arg_property->a_dest);
}
} }
tokenizer.advance(); tokenizer.advance();
} }
@ -282,6 +300,11 @@ namespace blt
const auto* const properties = user_args.flag_associations.at(flag); const auto* const properties = user_args.flag_associations.at(flag);
handleFlag(tokenizer, flag, properties);
}
void arg_parse::handleFlag(arg_tokenizer& tokenizer, const std::string& flag, const arg_properties_t* properties)
{
if (properties->a_dest.empty()) if (properties->a_dest.empty())
{ {
loaded_args.unrecognized_args.push_back(flag); loaded_args.unrecognized_args.push_back(flag);
@ -291,6 +314,9 @@ namespace blt
loaded_args.found_args.insert(dest); loaded_args.found_args.insert(dest);
if (properties->a_disable_help)
help_disabled = true;
switch (properties->a_action) switch (properties->a_action)
{ {
case arg_action_t::HELP: case arg_action_t::HELP:
@ -438,6 +464,8 @@ namespace blt
void arg_parse::printHelp() const void arg_parse::printHelp() const
{ {
if (help_disabled)
return;
if (!user_args.prefix.empty()) if (!user_args.prefix.empty())
{ {
std::cout << "\n"; std::cout << "\n";
@ -452,7 +480,8 @@ namespace blt
{ {
if (!arg->a_flags.isFlag()) if (!arg->a_flags.isFlag())
max_length = std::max(arg->a_flags.name.size(), max_length); max_length = std::max(arg->a_flags.name.size(), max_length);
else { else
{
auto tmp = getFlagHelp(arg); auto tmp = getFlagHelp(arg);
max_length = std::max(tmp.size(), max_length); max_length = std::max(tmp.size(), max_length);
} }
@ -495,7 +524,9 @@ namespace blt
void arg_parse::printUsage() const void arg_parse::printUsage() const
{ {
std::string usage = "Usage: " + filename(loaded_args.program_name) + " "; if (help_disabled)
return;
std::string usage = "Usage: " + filename(loaded_args.program_name) + " " + help_inclusion + " ";
std::cout << usage; std::cout << usage;
size_t current_line_length = 0; size_t current_line_length = 0;
@ -566,7 +597,7 @@ namespace blt
} }
tmp += ", "; tmp += ", ";
} }
tmp = tmp.substr(0, tmp.size()-2); tmp = tmp.substr(0, tmp.size() - 2);
return tmp; return tmp;
} }
} }