diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..afc21b5 --- /dev/null +++ b/.clang-format @@ -0,0 +1,5 @@ +NamespaceIndentation: All +PointerAlignment: Left +IndentWidth: 4 +ColumnLimit: 120 +BasedOnStyle: Google diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..4d00d9a --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,109 @@ +Checks: + abseil-*, + altera-*, + android-*, + bugprone-*, + cert-*, + clang-*analyzer-*, + concurrency-*, + cppcoreguidelines-*, + darwin-*, + fuchsia-*, + google-*, + hicpp-*, + linuxkernel-*, + llvm-*, + misc-*, + modernize-*, + mpi-*, + objc-*, + openmp-*, + performance-*, + portability-*, + readability-*, + zircon-*, + -boost-*, + -llvmlibc-*, + -altera-unroll-loops, + -hicpp-vararg, + -hicpp-signed-bitwise, + -hicpp-no-array-decay, + -hicpp-explicit-conversions, + -cppcoreguidelines-pro-type-vararg, + -cppcoreguidelines-macro-usage, + -cppcoreguidelines-avoid-do-while, + -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-avoid-magic-numbers, + -cppcoreguidelines-pro-bounds-array-to-pointer-decay, + -google-readability-todo, + -google-explicit-constructor, + -google-build-using-namespace, + -fuchsia-overloaded-operator, + -fuchsia-statically-constructed-objects, + -fuchsia-default-arguments-declarations, + -fuchsia-default-arguments-calls, + -modernize-use-trailing-return-type, + -readability-identifier-length, + -readability-magic-numbers, + -altera-struct-pack-align, + -misc-non-private-member-variables-in-classes, + -misc-use-anonymous-namespace, + -misc-use-internal-linkage, + -concurrency-mt-unsafe, + -cert-env33-c, + -cert-err58-cpp, + -bugprone-easily-swappable-parameters, + + # -abseil-cleanup-ctad + # -abseil-duration-addition + # -abseil-duration-comparison + # -abseil-duration-conversion-cast + # -abseil-duration-division + # -abseil-duration-factory-float + # -abseil-duration-factory-scale + # -abseil-duration-subtraction + # -abseil-duration-unnecessary-conversion + # -abseil-faster-strsplit-delimiter + # -abseil-no-internal-dependencies + # -abseil-no-namespace + # -abseil-redundant-strcat-calls + # -abseil-str-cat-append + # -abseil-string-find-startswith + # -abseil-string-find-str-contains + # -abseil-time-comparison + # -abseil-time-subtraction + # -abseil-upgrade-duration-conversions + # -altera-id-dependent-backward-branch + # -altera-struct-pack-align + # -altera-unroll-loops + # -bugprone-easily-swappable-parameters + # -cppcoreguidelines-avoid-c-arrays + # -cppcoreguidelines-avoid-magic-numbers + # -cppcoreguidelines-avoid-non-const-global-variables + # -cppcoreguidelines-pro-bounds-array-to-pointer-decay + # -cppcoreguidelines-pro-bounds-constant-array-index + # -cppcoreguidelines-pro-bounds-pointer-arithmetic + # -cppcoreguidelines-special-member-functions + # -fuchsia-default-arguments-calls + # -fuchsia-default-arguments-declarations + # -fuchsia-overloaded-operator + # -fuchsia-trailing-return + # -google-default-arguments + # -google-explicit-constructor + # -google-global-names-in-headers + # -google-objc-function-naming + # -google-objc-global-variable-declaration + # -google-runtime-int + # -hicpp-avoid-c-arrays + # -hicpp-explicit-conversions + # -hicpp-no-array-decay + # -hicpp-special-member-functions + # -llvmlibc-callee-namespace + # -llvmlibc-implementation-in-namespace + # -llvmlibc-restrict-system-libc-headers + # -modernize-avoid-c-arrays + # -modernize-use-nodiscard + # -modernize-use-trailing-return-type + # -readability-identifier-length + # -readability-isolate-declaration + # -readability-magic-numbers diff --git a/include/Arg.hpp b/include/Arg.hpp index 593b2a7..49b3275 100644 --- a/include/Arg.hpp +++ b/include/Arg.hpp @@ -1,15 +1,15 @@ #pragma once -#include "Macros.hpp" - -#include #include #include +#include #include +#include "Macros.hpp" + class Arg { - public: - Arg(const std::string& name); + public: + Arg(std::string name); Arg& short_name(const std::string& short_name); Arg& long_name(const std::string& long_name); @@ -24,7 +24,7 @@ class Arg { static void print_arg(std::ostream& os, const Arg& arg, int indent); friend std::ostream& operator<<(std::ostream& os, const Arg& arg); - private: + private: friend class ClapParser; std::string name_; @@ -51,14 +51,14 @@ class Arg { DEFINE_GETTER_SETTER(auto_env, bool) DEFINE_GETTER_SETTER(default_value, std::string) DEFINE_GETTER_SETTER(value, std::optional) - + // ----| Checkers |---- // has_env_ - [[nodiscard]] inline bool has_env() const { return !this->env_name_.empty(); } - + [[nodiscard]] bool has_env() const { return !this->env_name_.empty(); } + // has_default_ - [[nodiscard]] inline bool has_default() const { return !this->default_value_.empty(); } + [[nodiscard]] bool has_default() const { return !this->default_value_.empty(); } // has_value_ - [[nodiscard]] inline bool has_value() const { return this->value_.has_value(); } + [[nodiscard]] bool has_value() const { return this->value_.has_value(); } }; diff --git a/include/Macros.hpp b/include/Macros.hpp index 85f8df1..49e1049 100644 --- a/include/Macros.hpp +++ b/include/Macros.hpp @@ -1,27 +1,29 @@ #pragma once -#define DEFINE_PARSABLE_BASIC_TYPE(TYPE) \ -template<> \ -struct Parse { \ - static std::optional parse(std::string_view s) { \ - TYPE value; \ - auto [ptr, ec] = std::from_chars(s.data(), s.data() + s.size(), value); \ - if (ec == std::errc()) return value; \ - return std::nullopt; \ - } \ -}; +#define DEFINE_PARSABLE_BASIC_TYPE(TYPE) \ + template <> \ + struct Parse { \ + static std::optional parse(std::string_view s) { \ + TYPE value; \ + auto [ptr, ec] = std::from_chars(s.data(), s.data() + s.size(), value); \ + if (ec == std::errc()) return value; \ + return std::nullopt; \ + } \ + }; -#define DEFINE_PARSABLE_FLOAT_TYPE(TYPE, CONVERT_FN) \ -template<> \ -struct Parse { \ - static std::optional parse(std::string_view s) { \ - char* end = nullptr; \ - TYPE value = CONVERT_FN(s.data(), &end); \ - if (end == s.data() + s.size()) return value; \ - return std::nullopt; \ - } \ -}; +#define DEFINE_PARSABLE_FLOAT_TYPE(TYPE, CONVERT_FN) \ + template <> \ + struct Parse { \ + static std::optional parse(std::string_view s) { \ + char* end = nullptr; \ + TYPE value = CONVERT_FN(s.data(), &end); \ + if (end == s.data() + s.size()) { \ + return value; \ + } \ + return std::nullopt; \ + } \ + }; -#define DEFINE_GETTER_SETTER(NAME, TYPE) \ - [[nodiscard]] inline const TYPE& get__##NAME() const { return this->NAME##_; } \ - inline void set__##NAME(const TYPE& NAME) { this->NAME##_ = NAME; } +#define DEFINE_GETTER_SETTER(NAME, TYPE) \ + [[nodiscard]] inline const TYPE& get__##NAME() const { return this->NAME##_; } \ + inline void set__##NAME(const TYPE& NAME) { this->NAME##_ = NAME; } diff --git a/include/Parsables.hpp b/include/Parsables.hpp index d8b3ccc..343545f 100644 --- a/include/Parsables.hpp +++ b/include/Parsables.hpp @@ -1,7 +1,5 @@ #pragma once -#include "Macros.hpp" - #include #include #include @@ -9,12 +7,14 @@ #include #include -template +#include "Macros.hpp" + +template struct Parse { static_assert(sizeof(T) == 0, "No Parse specialization defined for this type"); }; -template +template concept Parseable = requires(std::string_view s) { { Parse::parse(s) } -> std::convertible_to>; }; @@ -34,17 +34,15 @@ DEFINE_PARSABLE_FLOAT_TYPE(float, std::strtof) DEFINE_PARSABLE_FLOAT_TYPE(double, std::strtod) DEFINE_PARSABLE_FLOAT_TYPE(long double, std::strtold) -template<> +template <> struct Parse { - static std::optional parse(std::string_view s) { - return std::string(s.data()); - } + static std::optional parse(std::string_view s) { return std::string(s.data()); } }; -template<> +template <> struct Parse { static std::optional parse(std::string_view s) { - auto as_int = Parse::parse(s).value(); - return as_int; + auto as_int = Parse::parse(s).value(); + return as_int; } }; diff --git a/include/Parser.hpp b/include/Parser.hpp index bc45e95..2c29de0 100644 --- a/include/Parser.hpp +++ b/include/Parser.hpp @@ -1,32 +1,32 @@ #pragma once -#include "Arg.hpp" -#include "utils.hpp" -#include "Parsables.hpp" - -#include #include #include #include #include #include +#include "Arg.hpp" +#include "Parsables.hpp" +#include "utils.hpp" + class ClapParser { - public: + public: void add_arg(const Arg& arg); void parse(const int& argc, char* argv[]); void print_help() const; template - requires Parseable - inline std::optional get_one_as(const std::string& name) { - Arg* arg = ok_or(ClapParser::find_arg(*this, "--" + name), []{ return std::nullopt; }); + requires Parseable + std::optional get_one_as(const std::string& name) { + Arg* arg = ok_or(ClapParser::find_arg(*this, "--" + name), [] { return std::nullopt; }); return Parse::parse(arg->get__value().value()); } static void print_parser(std::ostream& os, const ClapParser& parser, int indent); friend std::ostream& operator<<(std::ostream& os, const ClapParser& parser); - private: + + private: std::vector args_; std::string program_name_; @@ -35,7 +35,6 @@ class ClapParser { static bool is_long_option(const std::string& token); static bool is_short_option(const std::string& token); static std::optional find_arg(ClapParser& parser, const std::string& name); - std::vector get_positional_args() const; void apply_defaults(); void parse_cli_args(const std::vector& args); diff --git a/include/utils.hpp b/include/utils.hpp index 387a618..73e4093 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -8,44 +8,52 @@ template inline T ok_or(std::optional opt, E&& err) { - if (!opt) std::forward(err)(); + if (!opt) { + std::forward(err)(); + } return *opt; } template inline T ok_or_throw_str(std::optional opt, const std::string& err) { - if (!opt) throw std::runtime_error(err); + if (!opt) { + throw std::runtime_error(err); + } return *opt; } template inline T ptr_ok_or_throw_str(T pointer, const std::string& err) { - if (!pointer) throw std::runtime_error(err); + if (!pointer) { + throw std::runtime_error(err); + } return pointer; } template -inline E ptr_unwrap_or(P pointer, const E other) { - if (!pointer) return other; +inline E ptr_unwrap_or(P pointer, const E other) { + if (!pointer) { + return other; + } } - + // variadic template function to concatenate any number of arguments -template inline std::string concat(Args&&... args) { +template +inline std::string concat(Args&&... args) { std::ostringstream oss; (void)std::initializer_list{ - (oss << std::forward(args), 0)...}; // using initializer_list for fold-like behavior + (oss << std::forward(args), 0)...}; // using initializer_list for fold-like behavior return oss.str(); } -inline const std::string quote(const std::string& name) { - return '\'' + name + '\''; -} +inline std::string quote(const std::string& name) { return '\'' + name + '\''; } inline void print_indent(std::ostream& os, int indent_level) { - for (int i = 0; i < indent_level; ++i) + for (int i = 0; i < indent_level; ++i) { os << '\t'; + } } -inline void to_upper(std::string &s) { +inline void to_upper(std::string& s) { std::ranges::transform(s, s.begin(), [](const unsigned char& c) { return std::toupper(c); }); } diff --git a/src/Arg.cpp b/src/Arg.cpp index 5ed46d4..b4b3811 100644 --- a/src/Arg.cpp +++ b/src/Arg.cpp @@ -1,23 +1,20 @@ #include "Arg.hpp" -#include "utils.hpp" -#include #include + +#include #include -Arg::Arg(const std::string& name) : - name_(name), - short_name_(""), - long_name_(this->name_), - help_(""), - is_required_(false), - is_flag_(false), - accepts_many_(false), - env_name_(""), - auto_env_(false), - default_value_(""), - value_(std::nullopt) -{} +#include "utils.hpp" + +Arg::Arg(std::string name) + : name_(std::move(name)), + long_name_(this->name_), + is_required_(false), + is_flag_(false), + accepts_many_(false), + auto_env_(false), + value_(std::nullopt) {} // Setters Arg& Arg::short_name(const std::string& short_name) { @@ -47,43 +44,44 @@ Arg& Arg::default_value(const std::string& default_value) { } Arg& Arg::from_env(const char* env_var_name) { this->env_name_ = env_var_name; - // std::string value_from_env = ptr_unwrap_or(std::getenv(env_var_name), concat("value \'", env_var_name, "\' not present in env for: ", this->name_)); - // std::optional value_from_env = ptr_unwrap_or(std::getenv(env_var_name), std::nullopt); - // this->value_ = ptr_unwrap_or(std::getenv(env_var_name), std::nullopt); -/* - auto ptr = std::getenv(env_var_name); - if (!ptr) { - this->value_ = std::nullopt; - } else { - this->value_ = ptr; - } -*/ - return *this; + return *this; }; Arg& Arg::auto_env() { - this -> auto_env_ = true; + this->auto_env_ = true; return *this; }; void Arg::print_arg(std::ostream& os, const Arg& arg, int indent) { - print_indent(os, indent); os << "Arg {\n"; + print_indent(os, indent); + os << "Arg {\n"; - print_indent(os, indent + 1); os << "name: \"" << arg.name_ << "\",\n"; - print_indent(os, indent + 1); os << "short: \"" << arg.short_name_ << "\",\n"; - print_indent(os, indent + 1); os << "long: \"" << arg.long_name_ << "\",\n"; - print_indent(os, indent + 1); os << "help: \"" << arg.help_ << "\",\n"; - print_indent(os, indent + 1); os << "required: " << std::boolalpha << arg.is_required_ << ",\n"; - print_indent(os, indent + 1); os << "is_flag: " << std::boolalpha << arg.is_flag_ << ",\n"; - print_indent(os, indent + 1); os << "accepts_many: " << std::boolalpha << arg.accepts_many_ << ",\n"; - print_indent(os, indent + 1); os << "default: \"" << arg.default_value_ << "\",\n"; - print_indent(os, indent + 1); os << "value: "; - if (arg.value_) + print_indent(os, indent + 1); + os << "name: \"" << arg.name_ << "\",\n"; + print_indent(os, indent + 1); + os << "short: \"" << arg.short_name_ << "\",\n"; + print_indent(os, indent + 1); + os << "long: \"" << arg.long_name_ << "\",\n"; + print_indent(os, indent + 1); + os << "help: \"" << arg.help_ << "\",\n"; + print_indent(os, indent + 1); + os << "required: " << std::boolalpha << arg.is_required_ << ",\n"; + print_indent(os, indent + 1); + os << "is_flag: " << std::boolalpha << arg.is_flag_ << ",\n"; + print_indent(os, indent + 1); + os << "accepts_many: " << std::boolalpha << arg.accepts_many_ << ",\n"; + print_indent(os, indent + 1); + os << "default: \"" << arg.default_value_ << "\",\n"; + print_indent(os, indent + 1); + os << "value: "; + if (arg.value_) { os << "\"" << arg.value_.value() << "\""; - else + } else { os << "std::nullopt"; + } os << '\n'; - print_indent(os, indent); os << "}"; + print_indent(os, indent); + os << "}"; } std::ostream& operator<<(std::ostream& os, const Arg& arg) { diff --git a/src/Parser.cpp b/src/Parser.cpp index dcaf32c..cdfb31c 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -1,16 +1,16 @@ #include "Parser.hpp" -#include "Arg.hpp" -#include "utils.hpp" -#include +#include #include #include #include #include #include -#include #include +#include "Arg.hpp" +#include "utils.hpp" + void ClapParser::parse(const int& argc, char* argv[]) { const std::string& raw_program_name = argv[0]; #ifdef _WIN32 @@ -24,7 +24,7 @@ void ClapParser::parse(const int& argc, char* argv[]) { this->apply_defaults(); this->check_env(); - this->parse_cli_args(args); // parse from cli (argc, argv) + this->parse_cli_args(args); // parse from cli (argc, argv) // Validate all arguments that need values received them for (const auto& arg : args_) { @@ -46,7 +46,7 @@ void ClapParser::parse_cli_args(const std::vector& args) { exit(0); } - auto arg = ok_or_throw_str(ClapParser::find_arg(*this, token), "unknown option: \'" + token); + auto* arg = ok_or_throw_str(ClapParser::find_arg(*this, token), "unknown option: \'" + token); if (!arg->get__is_flag()) { ClapParser::parse_value_for_non_flag(arg, i, args); @@ -67,9 +67,9 @@ void ClapParser::parse_value_for_non_flag(Arg* arg, size_t& cli_index, const std arg->set__value(value); } else { arg->set__value(args.at(cli_index + 1)); - cli_index++; // Skip the value in the next iteration + cli_index++; // Skip the value in the next iteration } - } else { + } else { throw std::runtime_error("option '" + arg->get__name() + "' requires a value but none was provided"); } } @@ -79,14 +79,14 @@ void ClapParser::check_env() { if (arg.get__auto_env()) { std::string env_name = this->program_name_ + '_' + arg.get__name(); to_upper(env_name); - auto value_from_env = std::getenv(env_name.c_str()); - if (value_from_env) { + auto* value_from_env = std::getenv(env_name.c_str()); + if (value_from_env != nullptr) { arg.set__value(value_from_env); } } if (arg.has_env()) { - auto value_from_env = std::getenv(arg.get__env_name().c_str()); - if (value_from_env) { + auto* value_from_env = std::getenv(arg.get__env_name().c_str()); + if (value_from_env != nullptr) { arg.set__value(value_from_env); } } @@ -94,15 +94,13 @@ void ClapParser::check_env() { }; bool ClapParser::is_option(const std::string& token) { - return token.substr(0, 2) == "--" || (token[0] == '-' && token.size() > 1); -} - -bool ClapParser::is_long_option(const std::string& token) { - return token.substr(0, 2) == "--"; + return token.starts_with("--") || (token.starts_with('-') && token.size() > 1); } - + +bool ClapParser::is_long_option(const std::string& token) { return token.starts_with("--"); } + bool ClapParser::is_short_option(const std::string& token) { - return token[0] == '-' && token.size() > 1 && token[1] != '-'; + return token.starts_with("-") && token.size() > 1 && token.at(1) != '-'; } void ClapParser::print_help() const { @@ -110,7 +108,7 @@ void ClapParser::print_help() const { std::cout << "\n\nOptions:\n"; for (const auto& arg : args_) { - arg.get__short_name().empty()? std::cout << " " : std::cout << " -" << arg.get__short_name() << ", "; + arg.get__short_name().empty() ? std::cout << " " : std::cout << " -" << arg.get__short_name() << ", "; std::cout << "--" << arg.get__long_name(); std::cout << "\t" << arg.get__help(); if (arg.has_default()) { @@ -121,7 +119,7 @@ void ClapParser::print_help() const { } if (arg.get__auto_env()) { std::string env_name = this->program_name_ + '_' + arg.get__name(); - std::transform(env_name.begin(), env_name.end(), env_name.begin(), [](const unsigned char& c) { return std::toupper(c); }); + to_upper(env_name); std::cout << " [def.env: " << env_name << "]"; } std::cout << "\n"; @@ -135,8 +133,8 @@ void ClapParser::print_help() const { // Helper methods std::optional ClapParser::find_arg(ClapParser& parser, const std::string& arg_name) { - auto it = std::find_if(parser.args_.begin(), parser.args_.end(), [&](Arg& arg) { - return ( "--" + arg.get__long_name() == arg_name || "-" + arg.get__short_name() == arg_name ); + auto it = std::ranges::find_if(parser.args_, [&](Arg& arg) { + return ("--" + arg.get__long_name() == arg_name || "-" + arg.get__short_name() == arg_name); }); if (it == parser.args_.end()) { @@ -154,20 +152,26 @@ void ClapParser::apply_defaults() { } void ClapParser::print_parser(std::ostream& os, const ClapParser& parser, int indent) { - print_indent(os, indent); os << "ClapParser {\n"; + print_indent(os, indent); + os << "ClapParser {\n"; - print_indent(os, indent + 1); os << "program_name: \"" << parser.program_name_ << "\",\n"; + print_indent(os, indent + 1); + os << "program_name: \"" << parser.program_name_ << "\",\n"; - print_indent(os, indent + 1); os << "args: [\n"; + print_indent(os, indent + 1); + os << "args: [\n"; for (const auto& arg : parser.args_) { Arg::print_arg(os, arg, indent + 2); os << ",\n"; } - print_indent(os, indent + 1); os << "],\n"; + print_indent(os, indent + 1); + os << "],\n"; - print_indent(os, indent + 1); os << "}\n"; + print_indent(os, indent + 1); + os << "}\n"; - print_indent(os, indent); os << "}"; + print_indent(os, indent); + os << "}"; } std::ostream& operator<<(std::ostream& os, const ClapParser& parser) { diff --git a/src/example.cpp b/src/example.cpp index 89b609f..b16ce2a 100644 --- a/src/example.cpp +++ b/src/example.cpp @@ -1,42 +1,40 @@ -#include "Parser.hpp" +#include + #include "Arg.hpp" +#include "Parser.hpp" #include "utils.hpp" -#include -#include - -void run(ClapParser& parsed_args); +void run(ClapParser& arg_parser); int main(const int argc, char* argv[]) { - ClapParser arg_parser; - auto num1 = Arg("num1").from_env("ASDF").auto_env().required(true); - // std::cerr << num1 << "\n"; - arg_parser.add_arg(num1); - auto num2 = Arg("num2").short_name("N").from_env("TES").default_value("99"); - arg_parser.add_arg(num2); - - arg_parser.add_arg(Arg("test").is_flag()); - // arg_parser.add_arg(Arg("test").is_flag(true)); - - try { - arg_parser.parse(argc, argv); - // std::cerr << arg_parser; - run(arg_parser); - } - catch (const std::exception& e) { - std::cerr << "\n\n\nerror: " << e.what() << "\n\n\n"; - // arg_parser.print_help(); - } + ClapParser arg_parser; + auto num1 = Arg("num1").from_env("ASDF").auto_env().required(true); + // std::cerr << num1 << "\n"; + arg_parser.add_arg(num1); + auto num2 = Arg("num2").short_name("N").from_env("TES").default_value("99"); + arg_parser.add_arg(num2); + + arg_parser.add_arg(Arg("test").is_flag()); + // arg_parser.add_arg(Arg("test").is_flag(true)); + + try { + arg_parser.parse(argc, argv); + // std::cerr << arg_parser; + run(arg_parser); + } catch (const std::exception& e) { + std::cerr << "\n\n\nerror: " << e.what() << "\n\n\n"; + // arg_parser.print_help(); + } } void run(ClapParser& arg_parser) { - // std::cerr << "running\n"; - auto num1 = ok_or_throw_str(arg_parser.get_one_as("num1"), "num1 not defined"); - auto num2 = ok_or_throw_str(arg_parser.get_one_as("num2"), "num2 not defined"); + // std::cerr << "running\n"; + auto num1 = ok_or_throw_str(arg_parser.get_one_as("num1"), "num1 not defined"); + auto num2 = ok_or_throw_str(arg_parser.get_one_as("num2"), "num2 not defined"); - std::cout << "num1: " << num1 << '\n'; - std::cout.precision(5); - std::cout << std::fixed << "num2: " << num2 << '\n'; + std::cout << "num1: " << num1 << '\n'; + std::cout.precision(5); + std::cout << std::fixed << "num2: " << num2 << '\n'; - // std::cerr << arg_parser; + // std::cerr << arg_parser; } diff --git a/tests/test_combo.cpp b/tests/test_combo.cpp index 9aa7ab0..6ad23e6 100644 --- a/tests/test_combo.cpp +++ b/tests/test_combo.cpp @@ -1,34 +1,35 @@ // tests/test_combo.cpp -#include "Parser.hpp" -#include "Arg.hpp" -#include "utils.hpp" -#include #include +#include #include +#include "Arg.hpp" +#include "Parser.hpp" +#include "utils.hpp" + int main(int argc, char* argv[]) { - ClapParser p; - // a value arg with full priority stack: - auto val = Arg("val").from_env("VAL").auto_env().default_value("10"); - auto boolean = Arg("flag").is_flag(); - p.add_arg(val); - p.add_arg(boolean); - p.parse(argc, argv); + ClapParser p; + // a value arg with full priority stack: + auto val = Arg("val").from_env("VAL").auto_env().default_value("10"); + auto boolean = Arg("flag").is_flag(); + p.add_arg(val); + p.add_arg(boolean); + p.parse(argc, argv); - // EXPECTED_V -> any int - // EXPECTED_B -> "1" or "0" - const auto ev = std::getenv("EXPECTED_V"); - const auto eb = std::getenv("EXPECTED_B"); - assert(ev && eb && "EXPECTED_V/B must be set"); + // EXPECTED_V -> any int + // EXPECTED_B -> "1" or "0" + auto *const ev = std::getenv("EXPECTED_V"); + auto *const eb = std::getenv("EXPECTED_B"); + assert(ev && eb && "EXPECTED_V/B must be set"); - int expected_val = std::stoi(ev); - bool expected_boolean = std::stoi(eb); + int expected_val = std::stoi(ev); + bool expected_boolean = std::stoi(eb) != 0; - auto actual_val = ok_or_throw_str(p.get_one_as("val"), "test argument: 'val' is missing"); - auto actual_boolean = ok_or_throw_str(p.get_one_as("flag"), "test argument: 'flag' is missing"); + auto actual_val = ok_or_throw_str(p.get_one_as("val"), "test argument: 'val' is missing"); + auto actual_boolean = ok_or_throw_str(p.get_one_as("flag"), "test argument: 'flag' is missing"); - std::cerr << p << '\n'; - assert(actual_val == expected_val); - assert(actual_boolean == expected_boolean); - return 0; + std::cerr << p << '\n'; + assert(actual_val == expected_val); + assert(actual_boolean == expected_boolean); + return 0; } diff --git a/tests/test_flag.cpp b/tests/test_flag.cpp index 9c2676d..69fe8c7 100644 --- a/tests/test_flag.cpp +++ b/tests/test_flag.cpp @@ -1,24 +1,25 @@ // tests/test_flag.cpp -#include "Parser.hpp" -#include "Arg.hpp" -#include "utils.hpp" -#include #include +#include #include +#include "Arg.hpp" +#include "Parser.hpp" +#include "utils.hpp" + int main(int argc, char* argv[]) { - ClapParser p; - auto f = Arg("opt").is_flag(); - p.add_arg(f); - p.parse(argc, argv); + ClapParser p; + auto f = Arg("opt").is_flag(); + p.add_arg(f); + p.parse(argc, argv); - // EXPECTED should be "1" or "0" (present or absent) - const auto e = std::getenv("EXPECTED"); - assert(e && "EXPECTED must be set"); - bool expected = std::string(e) == "1"; + // EXPECTED should be "1" or "0" (present or absent) + auto *const e = std::getenv("EXPECTED"); + assert(e && "EXPECTED must be set"); + bool expected = std::string(e) == "1"; - auto actual = ok_or_throw_str(p.get_one_as("opt"), "test argument: 'opt' is missing"); - std::cerr << p << '\n'; - assert(actual == expected); - return 0; + auto actual = ok_or_throw_str(p.get_one_as("opt"), "test argument: 'opt' is missing"); + std::cerr << p << '\n'; + assert(actual == expected); + return 0; } diff --git a/tests/test_priority.cpp b/tests/test_priority.cpp index 722a4a6..4d900ef 100644 --- a/tests/test_priority.cpp +++ b/tests/test_priority.cpp @@ -1,33 +1,34 @@ // tests/test_priority.cpp -#include "Parser.hpp" -#include "Arg.hpp" -#include "utils.hpp" -#include #include +#include #include #include +#include "Arg.hpp" +#include "Parser.hpp" +#include "utils.hpp" + /* VALUE PRIORITY: 1. cli arg: '--val' 2. env var: 'VAL' 3. auto env var: 'PRIORITY_MANUAL_VAL' - 4. default value: '1' + 4. default value: '1' */ int main(const int argc, char* argv[]) { - ClapParser p; + ClapParser p; - auto a = Arg("val").from_env("VAL").auto_env().default_value("1"); - p.add_arg(a); - p.parse(argc, argv); + auto a = Arg("val").from_env("VAL").auto_env().default_value("1"); + p.add_arg(a); + p.parse(argc, argv); - // gets read from meson test env - const auto e = std::getenv("EXPECTED"); - assert(e && "EXPECTED must be set"); - int expected = std::stoi(e); + // gets read from meson test env + auto *const e = std::getenv("EXPECTED"); + assert(e && "EXPECTED must be set"); + int expected = std::stoi(e); - auto actual = ok_or_throw_str(p.get_one_as("val"), "test argument: 'val' is missing"); - std::cerr << p << '\n'; - assert(actual == expected); - return 0; + auto actual = ok_or_throw_str(p.get_one_as("val"), "test argument: 'val' is missing"); + std::cerr << p << '\n'; + assert(actual == expected); + return 0; }