BLT/include/blt/parse/argparse.h

194 lines
5.2 KiB
C
Raw Normal View History

/*
* Created by Brett on 28/07/23.
* Licensed under GNU General Public License V3.0
* See LICENSE file for license detail
*/
#ifndef BLT_TESTS_ARGPARSE_H
#define BLT_TESTS_ARGPARSE_H
#include <vector>
#include <string>
#include <initializer_list>
#include <optional>
#include <blt/std/hashmap.h>
2023-07-29 13:38:19 -04:00
namespace blt::parser {
enum class arg_action {
2023-07-29 13:38:19 -04:00
STORE,
STORE_CONST,
STORE_TRUE,
STORE_FALSE,
APPEND,
APPEND_CONST,
COUNT,
HELP,
VERSION,
EXTEND
};
class arg_t {
private:
public:
};
class arg_vector {
private:
std::vector<std::string> names;
std::vector<std::string> flags;
void insertAndSort(const std::string& str);
2023-07-29 13:38:19 -04:00
public:
arg_vector() = default;
2023-07-29 13:38:19 -04:00
arg_vector(const std::vector<std::string>& args);
arg_vector(std::initializer_list<std::string> args);
2023-07-29 13:38:19 -04:00
arg_vector(const std::string& arg);
2023-07-29 13:38:19 -04:00
arg_vector(const char* arg);
arg_vector& operator=(const std::string& arg);
2023-07-29 13:38:19 -04:00
arg_vector& operator=(const char* arg);
2023-07-29 13:38:19 -04:00
arg_vector& operator=(std::initializer_list<std::string>& args);
2023-07-29 13:38:19 -04:00
arg_vector& operator=(std::vector<std::string>& args);
2023-07-29 13:38:19 -04:00
[[nodiscard]] inline std::vector<std::string>& getNames() {
return names;
}
2023-07-29 13:38:19 -04:00
[[nodiscard]] inline std::vector<std::string>& getFlags() {
return flags;
}
2023-07-29 14:04:46 -04:00
[[nodiscard]] inline const std::vector<std::string>& getNames() const {
return names;
}
[[nodiscard]] inline const std::vector<std::string>& getFlags() const {
return flags;
}
};
class arg_nargs {
private:
static constexpr int UNKNOWN = 0x1;
static constexpr int ALL = 0x2;
static constexpr int ALL_REQUIRED = 0x4;
int args = 0;
int flags = 0;
2023-07-29 13:38:19 -04:00
void decode(char c);
2023-07-29 13:38:19 -04:00
public:
arg_nargs() = default;
2023-07-29 13:38:19 -04:00
arg_nargs(int args): args(args) {}
2023-07-29 13:38:19 -04:00
arg_nargs(char c);
2023-07-29 13:38:19 -04:00
arg_nargs(std::string s);
2023-07-29 13:38:19 -04:00
arg_nargs(const char* s);
2023-07-29 13:38:19 -04:00
arg_nargs& operator=(const std::string& s);
2023-07-29 13:38:19 -04:00
arg_nargs& operator=(const char* s);
2023-07-29 13:38:19 -04:00
arg_nargs& operator=(char c);
2023-07-29 13:38:19 -04:00
arg_nargs& operator=(int args);
};
2023-07-29 13:38:19 -04:00
struct arg_properties {
private:
public:
arg_vector a_flags;
arg_action a_action = arg_action::STORE;
arg_nargs a_nargs = 0;
std::optional<std::string> a_const{};
std::string a_default{};
std::string a_def{};
std::string a_help{};
std::string a_metavar{};
bool a_required = false;
};
2023-07-29 13:38:19 -04:00
class arg_tokenizer {
private:
static constexpr char FLAG = '-';
std::vector<std::string> args;
size_t nextIndex = 0;
inline const std::string& get(size_t 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);
2023-07-29 13:38:19 -04:00
inline void forward() {
nextIndex++;
}
inline const std::string& get() {
return get(nextIndex);
}
inline const std::string& next() {
2023-07-31 13:53:10 -04:00
return get(nextIndex++);
2023-07-29 13:38:19 -04:00
}
inline bool hasNext() {
return hasNext(nextIndex);
}
2023-07-31 13:53:10 -04:00
inline bool isFlag(size_t i){
return get(i).starts_with(FLAG);
}
2023-07-29 13:38:19 -04:00
inline bool isFlag() {
return isFlag(nextIndex);
}
};
class argparse {
private:
arg_tokenizer tokenizer;
2023-07-29 14:04:46 -04:00
struct {
std::vector<arg_properties> argStorage;
HASHMAP<std::string, arg_properties*> flagAssociations;
2023-07-31 13:53:10 -04:00
std::vector<std::pair<std::string, arg_properties*>> nameAssociations;
} user_args;
struct arg_results {
std::string programName;
HASHMAP<std::string, std::string> positionalArgs;
} loaded_args;
2023-07-29 14:04:46 -04:00
static bool validateArgument(const arg_properties& args);
2023-07-29 13:38:19 -04:00
public:
argparse() = default;
2023-07-29 13:38:19 -04:00
void addArgument(const arg_properties& args);
const arg_results& parse_args(int argc, const char** argv);
};
}
#endif //BLT_TESTS_ARGPARSE_H