You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
3.8 KiB
95 lines
3.8 KiB
#ifndef ARG_PARSER_H |
|
#define ARG_PARSER_H |
|
|
|
#include <cstddef> // size_t |
|
#include <functional> // function |
|
#include <string> |
|
#include <string_view> |
|
#include <vector> |
|
|
|
namespace Util { |
|
|
|
class ArgParser final { |
|
public: |
|
ArgParser(); |
|
virtual ~ArgParser(); |
|
|
|
enum class Required { |
|
No, |
|
Yes, |
|
Optional, |
|
}; |
|
|
|
enum class Error { |
|
None, |
|
InvalidOption, // For short options |
|
UnrecognizedOption, // For long options |
|
DoesntAllowArgument, |
|
RequiresArgument, |
|
}; |
|
|
|
struct Option { |
|
char shortName { 0 }; |
|
const char* longName { nullptr }; |
|
const char* argumentName { nullptr }; |
|
const char* usageString { nullptr }; |
|
const char* manString { nullptr }; |
|
Required requiresArgument; |
|
std::function<bool(const char*)> acceptValue; |
|
|
|
Error error = Error::None; |
|
}; |
|
|
|
struct Argument { |
|
const char* name { nullptr }; |
|
const char* usageString { nullptr }; |
|
const char* manString { nullptr }; |
|
size_t minValues { 0 }; |
|
size_t maxValues { 1 }; |
|
size_t addedValues { 0 }; |
|
std::function<bool(const char*)> acceptValue; |
|
}; |
|
|
|
bool parse(int argc, const char* argv[]); |
|
|
|
void addOption(Option&& option); |
|
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_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>& values, char shortName, const char* longName, const char* usageString, const char* manString, const char* argumentName = "", Required requiresArgument = Required::No); |
|
|
|
void addArgument(Argument&& argument); |
|
void addArgument(std::string& value, const char* name, const char* usageString, const char* manString, Required required = Required::No); |
|
void addArgument(std::vector<std::string>& values, const char* name, const char* usageString, const char* manString, Required required = Required::No); |
|
|
|
void setErrorReporting(bool state) { m_errorReporting = state; } |
|
void setExitOnFirstError(bool state) { m_exitOnFirstError = state; } |
|
void setStopParsingOnFirstNonOption(bool state) { m_stopParsingOnFirstNonOption = state; } |
|
|
|
private: |
|
void printOptionError(char name, Error error); |
|
void printOptionError(const char* name, Error error, bool longName = true); |
|
bool parseShortOption(std::string_view option, std::string_view next); |
|
bool parseLongOption(std::string_view option, std::string_view next); |
|
bool parseArgument(std::string_view argument); |
|
|
|
bool m_errorReporting { true }; |
|
bool m_exitOnFirstError { true }; |
|
bool m_stopParsingOnFirstNonOption { false }; |
|
|
|
size_t m_optionIndex { 1 }; |
|
size_t m_argumentIndex { 0 }; |
|
bool m_nonOptionMode { false }; |
|
|
|
const char* m_name { nullptr }; |
|
std::vector<Option> m_options; |
|
std::vector<Argument> m_arguments; |
|
}; |
|
|
|
} // namespace Util |
|
|
|
#endif // ARG_PARSER_H
|
|
|