Compare commits
3 Commits
Prerelease
...
main
Author | SHA1 | Date | |
---|---|---|---|
8ddf7d182a | |||
224e0bd397 | |||
0ac5d8bd4f |
13
README.md
13
README.md
@@ -1,3 +1,16 @@
|
||||
# ArgsParser
|
||||
|
||||
A C++ library for parsing command arguments.
|
||||
|
||||
## Brief
|
||||
|
||||
The library in it's current state performs only the parsing of tokens from a command string.
|
||||
Implementing the functionality of flags, options, subcommands, etc is left up to the user.
|
||||
Plans for a more comprehensive parsing suite are in the works, however.
|
||||
|
||||
## API Overview
|
||||
|
||||
## Usage
|
||||
|
||||
## Known Bugs
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -9,34 +10,52 @@ struct FlagInfo {
|
||||
std::optional<std::string> arg;
|
||||
};
|
||||
|
||||
struct ShortFlag {
|
||||
|
||||
};
|
||||
|
||||
struct LongFlag {};
|
||||
|
||||
struct Subcommand {};
|
||||
|
||||
struct ArgFlag {};
|
||||
|
||||
|
||||
/// A class that provides a convenient interface for parsing commands.
|
||||
class ArgsParser {
|
||||
public:
|
||||
/// Constructor from traditional argc, argv
|
||||
/// Constructor from traditional argc, argv.
|
||||
ArgsParser(int argc, char** argv, bool keep_program_name = false);
|
||||
|
||||
/// @return True if there is another unconsumed token in the argument list.
|
||||
bool has_next() const;
|
||||
|
||||
/// Retrieves then next unconsumed token in the argument list.
|
||||
/// @return The next token in the argument list.
|
||||
std::string get_next() const;
|
||||
|
||||
std::string consume_next();
|
||||
|
||||
/// Constructor from an existing vector of strings,
|
||||
explicit ArgsParser(const std::vector<std::string>& value): args(value) {}
|
||||
|
||||
/// @return Whether the unconsumed-arguments list is empty.
|
||||
[[nodiscard]] bool empty() const;
|
||||
|
||||
/// @return True if there is another unconsumed token in the argument list.
|
||||
[[nodiscard]] bool has_next() const;
|
||||
|
||||
/// Retrieves the next unconsumed token in the argument list.
|
||||
/// @return The next token in the argument list.
|
||||
[[nodiscard]] std::string get_next() const;
|
||||
|
||||
/// Retrieves the next unconsumed token in the argument list, returns the value, and removes it from the list.
|
||||
std::string consume_next();
|
||||
|
||||
/// Searches the arguments for the given option flag, and returns whether it was found.
|
||||
/// @return True if the flag is present, false otherwise.
|
||||
bool has_flag(const std::string& option);
|
||||
|
||||
/// Searches the arguments for an option flag that matches the given strings, and returns whether any were found.
|
||||
bool has_flag(const std::initializer_list<std::string>& flags);
|
||||
|
||||
/// Searches the arguments for all given flag tokens, and removes all occurrences of it.
|
||||
/// Searches the arguments for the given flag token, and removes all occurrences of it.
|
||||
/// @return true if the flag was found in the arguments.
|
||||
bool consume_flag(const std::string& option);
|
||||
|
||||
|
||||
/// Searches the arguments for all given flag tokens, and removes them.
|
||||
/// Searches the arguments for any of the given flag tokens, and removes them.
|
||||
/// @note All strings in the list will be removed from the arguments.
|
||||
/// @return True if the flag was found in the arguments.
|
||||
bool consume_flag(const std::initializer_list<std::string>& flags);
|
||||
|
||||
@@ -49,32 +68,28 @@ public:
|
||||
/// Searches for a specific flag and its argument, removes both, and returns the argument.
|
||||
std::optional<std::string> consume_flag_arg(const std::string& flag);
|
||||
|
||||
std::tuple<bool, std::string> consume_flag_arg(const std::initializer_list<std::string>& flags);
|
||||
std::optional<std::string> consume_flag_arg(const std::initializer_list<std::string>& flags);
|
||||
|
||||
std::vector<std::string> get_remaining_args() const;
|
||||
|
||||
std::vector<std::string> get_unmatched() const { return get_remaining_args(); }
|
||||
|
||||
|
||||
|
||||
bool contains(const std::string& token) const;
|
||||
bool has_flag_contains(const std::string& match);
|
||||
|
||||
std::optional<std::string> get_flag_contains(std::string& match) {
|
||||
for (auto& token : args) {
|
||||
if (token.find(match) != std::string::npos)
|
||||
return token;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool has_flag_starts_with(const std::string& value) const;
|
||||
std::string get_flag_starts_with(const std::string& prefix) const;
|
||||
/// @return all tokens that have not yet been matched and consumed by other methods.
|
||||
[[nodiscard]] std::vector<std::string> get_remaining_args() const;
|
||||
|
||||
/// Searches for a given string in the arguments list.
|
||||
/// @return true if found, false otherwise.
|
||||
[[nodiscard]] bool contains(const std::string& token) const;
|
||||
|
||||
/// Searches for an argument that contains the given string.
|
||||
[[nodiscard]] bool has_flag_contains(const std::string& match) const;
|
||||
|
||||
/// Searches for an argument that contains the given string.
|
||||
std::optional<std::string> get_flag_contains(std::string& match);
|
||||
|
||||
[[nodiscard]] bool has_flag_starts_with(const std::string& value) const;
|
||||
[[nodiscard]] std::string get_flag_starts_with(const std::string& prefix) const;
|
||||
|
||||
|
||||
std::vector<std::string> consume_flag_arg_multiple(const std::string& flag);
|
||||
|
||||
std::vector<std::string> consume_flag_arg_multiple(const std::initializer_list<std::string>& flag_aliases);
|
||||
|
||||
protected:
|
||||
/// The list of arguments that have yet to be consumed.
|
||||
|
33
main.cpp
33
main.cpp
@@ -11,14 +11,43 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
ArgsParser args(argc, argv);
|
||||
args.consume_next(); // Consume file-name.
|
||||
std::vector<std::string> fakeArgs {"--output", "console", "hello!!", "--color", "#FFFFFF", "what's up?", "--color", "#420690", "Damn jit", "--color", "#FFFFFF"}; //{"--verbose", "--file", "thf", "bruhbruh"};
|
||||
|
||||
|
||||
ArgsParser args(fakeArgs);
|
||||
|
||||
auto output = args.consume_flag_arg("--output");
|
||||
|
||||
|
||||
if (args.has_flag("--help")) {
|
||||
|
||||
std::cout << "Help information displayed here!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//for (auto args.)
|
||||
|
||||
for (auto& arg : args.get_remaining_args()) {
|
||||
if (arg == "--color") {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> color_codes = args.consume_flag_arg_multiple("--color");
|
||||
|
||||
|
||||
if (args.has_flag("--file")) {
|
||||
if (args.has_flag_arg("--file")) {
|
||||
auto filename = args.consume_flag_arg("--file");
|
||||
|
||||
if (filename.has_value()) {
|
||||
std::cout << "Filename: " << filename.value() << std::endl;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& entry : args.get_remaining_args()) {
|
||||
std::cout << entry << " ";
|
||||
}
|
||||
|
@@ -5,6 +5,8 @@ ArgsParser::ArgsParser(int argc, char **argv, bool keep_program_name) {
|
||||
args = std::vector<std::string>(argv, argv+argc);
|
||||
}
|
||||
|
||||
bool ArgsParser::empty() const { return args.empty();}
|
||||
|
||||
bool ArgsParser::has_next() const {
|
||||
return !args.empty();
|
||||
}
|
||||
@@ -57,6 +59,8 @@ bool ArgsParser::has_flag_arg(const std::string &option) {
|
||||
auto it = std::ranges::find(args, option);
|
||||
return it!=args.end() && ++it!=args.end();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,18 +72,37 @@ std::optional<std::string> ArgsParser::get_flag_arg(const std::string &option) {
|
||||
}
|
||||
|
||||
std::optional<std::string> ArgsParser::consume_flag_arg(const std::string &flag) {
|
||||
if (has_flag_arg(flag)) {
|
||||
auto it = std::ranges::find(args, flag);
|
||||
|
||||
++it;
|
||||
|
||||
std::string ret_val = std::string(*it);
|
||||
args.erase(std::remove(args.begin(), args.end(), flag), args.end());
|
||||
args.erase(std::remove(args.begin(), args.end(), ret_val), args.end());
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::tuple<bool, std::string> ArgsParser::consume_flag_arg(const std::initializer_list<std::string> &flags) {
|
||||
|
||||
std::optional<std::string> ArgsParser::consume_flag_arg(const std::initializer_list<std::string> &flags) {
|
||||
for (auto& flag : flags) {
|
||||
if (has_flag_arg(flag))
|
||||
return consume_flag_arg(flag);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> ArgsParser::get_remaining_args() const {
|
||||
return args;
|
||||
}
|
||||
|
||||
bool ArgsParser::has_flag_contains(const std::string &match) {
|
||||
bool ArgsParser::contains(const std::string &token) const {
|
||||
return std::ranges::find(args, token) != args.end();
|
||||
}
|
||||
|
||||
bool ArgsParser::has_flag_contains(const std::string &match) const {
|
||||
for (auto& token : args) {
|
||||
if (token.find(match) != std::string::npos)
|
||||
return true;
|
||||
@@ -88,6 +111,15 @@ bool ArgsParser::has_flag_contains(const std::string &match) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<std::string> ArgsParser::get_flag_contains(std::string &match) {
|
||||
for (auto& token : args) {
|
||||
if (token.find(match) != std::string::npos)
|
||||
return token;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool ArgsParser::has_flag_starts_with(const std::string &value) const {
|
||||
for (auto& token : args) {
|
||||
if (token.starts_with(value))
|
||||
@@ -104,3 +136,33 @@ std::string ArgsParser::get_flag_starts_with(const std::string &prefix) const {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> ArgsParser::consume_flag_arg_multiple(const std::string &flag) {
|
||||
std::vector<std::string> ret_val;
|
||||
|
||||
for (auto it = args.begin(); it != args.end();) {
|
||||
if (*it == flag) {
|
||||
if (it != args.end()) {
|
||||
ret_val.push_back(*std::next(it, 1).base());
|
||||
it = args.erase(it, it+1);
|
||||
|
||||
//args.erase(it);
|
||||
}
|
||||
} else
|
||||
++it;
|
||||
|
||||
//++it;
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
std::vector<std::string> ArgsParser::consume_flag_arg_multiple(const std::initializer_list<std::string> &flag_aliases) {
|
||||
std::vector<std::string> ret_val;
|
||||
for (auto& flag : flag_aliases) {
|
||||
std::vector<std::string> pass = consume_flag_arg_multiple(flag);
|
||||
for (auto& val : pass) {
|
||||
ret_val.push_back(val);
|
||||
}
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user