From 5075533581748b89281db3c479098305fe5b3f8a Mon Sep 17 00:00:00 2001 From: csboo Date: Thu, 15 May 2025 01:40:03 +0200 Subject: [PATCH 1/7] fix(Arg): remove unused code --- src/Arg.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/Arg.cpp b/src/Arg.cpp index 5ed46d4..2bec9c9 100644 --- a/src/Arg.cpp +++ b/src/Arg.cpp @@ -47,17 +47,6 @@ 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; }; Arg& Arg::auto_env() { From 5d18b5ab9c982f7a4468074d7ee6ea3222669b70 Mon Sep 17 00:00:00 2001 From: csboo Date: Thu, 15 May 2025 01:40:50 +0200 Subject: [PATCH 2/7] feat: add .clang-tidy file --- .clang-tidy | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 .clang-tidy 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 From 7309d775e44cc005fe87c5ab7ebfddbc440e98f4 Mon Sep 17 00:00:00 2001 From: csboo Date: Thu, 15 May 2025 02:12:47 +0200 Subject: [PATCH 3/7] misc: listen to clang-tidy --- include/Arg.hpp | 10 ++++---- include/Macros.hpp | 2 +- include/Parser.hpp | 6 ++--- include/utils.hpp | 57 +++++++++++++++++++++++++++------------------- src/Arg.cpp | 13 ++++------- src/Parser.cpp | 23 +++++++++---------- src/example.cpp | 3 +-- 7 files changed, 58 insertions(+), 56 deletions(-) diff --git a/include/Arg.hpp b/include/Arg.hpp index 593b2a7..5da27e1 100644 --- a/include/Arg.hpp +++ b/include/Arg.hpp @@ -2,14 +2,14 @@ #include "Macros.hpp" -#include #include #include +#include #include class Arg { public: - Arg(const std::string& name); + Arg(std::string name); Arg& short_name(const std::string& short_name); Arg& long_name(const std::string& long_name); @@ -54,11 +54,11 @@ class Arg { // ----| 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..a9f8973 100644 --- a/include/Macros.hpp +++ b/include/Macros.hpp @@ -17,7 +17,7 @@ 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; \ + if (end == s.data() + s.size()) { return value; }\ return std::nullopt; \ } \ }; diff --git a/include/Parser.hpp b/include/Parser.hpp index bc45e95..eb057cc 100644 --- a/include/Parser.hpp +++ b/include/Parser.hpp @@ -1,10 +1,9 @@ #pragma once #include "Arg.hpp" -#include "utils.hpp" #include "Parsables.hpp" +#include "utils.hpp" -#include #include #include #include @@ -19,7 +18,7 @@ class ClapParser { template requires Parseable - inline std::optional get_one_as(const std::string& name) { + 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()); } @@ -35,7 +34,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..ae998d7 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -7,45 +7,54 @@ #include template -inline T ok_or(std::optional opt, E&& err) { - if (!opt) std::forward(err)(); - return *opt; +inline T ok_or(std::optional opt, E &&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); - return *opt; +inline T ok_or_throw_str(std::optional opt, const std::string &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); - return pointer; +inline T ptr_ok_or_throw_str(T pointer, const std::string &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) { - std::ostringstream oss; - (void)std::initializer_list{ - (oss << std::forward(args), 0)...}; // using initializer_list for fold-like behavior - return oss.str(); +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 + 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) - os << '\t'; +inline void print_indent(std::ostream &os, int indent_level) { + for (int i = 0; i < indent_level; ++i) { + os << '\t'; + } } inline void to_upper(std::string &s) { - std::ranges::transform(s, s.begin(), [](const unsigned char& c) { return std::toupper(c); }); + 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 2bec9c9..f911a04 100644 --- a/src/Arg.cpp +++ b/src/Arg.cpp @@ -5,17 +5,13 @@ #include #include -Arg::Arg(const std::string& name) : - name_(name), - short_name_(""), +Arg::Arg(std::string name) : + name_(std::move(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) {} @@ -66,10 +62,11 @@ void Arg::print_arg(std::ostream& os, const Arg& arg, int indent) { 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_) + if (arg.value_) { os << "\"" << arg.value_.value() << "\""; - else + } else { os << "std::nullopt"; + } os << '\n'; print_indent(os, indent); os << "}"; diff --git a/src/Parser.cpp b/src/Parser.cpp index dcaf32c..06a085a 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -2,13 +2,12 @@ #include "Arg.hpp" #include "utils.hpp" -#include +#include #include #include #include #include #include -#include #include void ClapParser::parse(const int& argc, char* argv[]) { @@ -46,7 +45,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); @@ -79,14 +78,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 +93,15 @@ void ClapParser::check_env() { }; bool ClapParser::is_option(const std::string& token) { - return token.substr(0, 2) == "--" || (token[0] == '-' && token.size() > 1); + return token.starts_with("--") || (token.starts_with('-') && token.size() > 1); } bool ClapParser::is_long_option(const std::string& token) { - return token.substr(0, 2) == "--"; + 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 { @@ -121,7 +120,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,7 +134,7 @@ 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) { + auto it = std::ranges::find_if(parser.args_, [&](Arg& arg) { return ( "--" + arg.get__long_name() == arg_name || "-" + arg.get__short_name() == arg_name ); }); diff --git a/src/example.cpp b/src/example.cpp index 89b609f..52e3da3 100644 --- a/src/example.cpp +++ b/src/example.cpp @@ -2,10 +2,9 @@ #include "Arg.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; From 788fb51ea193e02981e8f7098db953ed9a047bf0 Mon Sep 17 00:00:00 2001 From: csboo Date: Thu, 15 May 2025 02:24:21 +0200 Subject: [PATCH 4/7] feat: add .clang-format file --- .clang-format | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .clang-format 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 From ffb74c09955706a4bf1623a50ffe56ea50d2d27f Mon Sep 17 00:00:00 2001 From: csboo Date: Thu, 15 May 2025 02:24:45 +0200 Subject: [PATCH 5/7] misc: clang-format everything --- include/Arg.hpp | 10 +++---- include/Macros.hpp | 47 +++++++++++++++--------------- include/Parsables.hpp | 19 +++++------- include/Parser.hpp | 5 ++-- include/utils.hpp | 68 ++++++++++++++++++++----------------------- src/Arg.cpp | 49 +++++++++++++++++-------------- src/Parser.cpp | 40 +++++++++++++------------ src/example.cpp | 53 +++++++++++++++++---------------- 8 files changed, 145 insertions(+), 146 deletions(-) diff --git a/include/Arg.hpp b/include/Arg.hpp index 5da27e1..d99170d 100644 --- a/include/Arg.hpp +++ b/include/Arg.hpp @@ -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]] bool has_env() const { return !this->env_name_.empty(); } - + [[nodiscard]] bool has_env() const { return !this->env_name_.empty(); } + // has_default_ - [[nodiscard]] bool has_default() const { return !this->default_value_.empty(); } + [[nodiscard]] bool has_default() const { return !this->default_value_.empty(); } // has_value_ - [[nodiscard]] 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 a9f8973..7e43219 100644 --- a/include/Macros.hpp +++ b/include/Macros.hpp @@ -1,27 +1,28 @@ #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..143e2bc 100644 --- a/include/Parsables.hpp +++ b/include/Parsables.hpp @@ -9,12 +9,11 @@ #include #include -template -struct Parse { +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 +33,13 @@ DEFINE_PARSABLE_FLOAT_TYPE(float, std::strtof) DEFINE_PARSABLE_FLOAT_TYPE(double, std::strtod) DEFINE_PARSABLE_FLOAT_TYPE(long double, std::strtold) -template<> -struct Parse { - static std::optional parse(std::string_view s) { - return std::string(s.data()); - } +template <> struct Parse { + static std::optional parse(std::string_view s) { return std::string(s.data()); } }; -template<> -struct Parse { +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 eb057cc..27921e9 100644 --- a/include/Parser.hpp +++ b/include/Parser.hpp @@ -17,14 +17,15 @@ class ClapParser { void print_help() const; template - requires Parseable + requires Parseable std::optional get_one_as(const std::string& name) { - Arg* arg = ok_or(ClapParser::find_arg(*this, "--" + name), []{ return std::nullopt; }); + 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: std::vector args_; std::string program_name_; diff --git a/include/utils.hpp b/include/utils.hpp index ae998d7..2f0a5a2 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -6,55 +6,49 @@ #include #include -template -inline T ok_or(std::optional opt, E &&err) { - if (!opt) { - std::forward(err)(); - } - return *opt; +template inline T ok_or(std::optional opt, E&& 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); - } - return *opt; +template inline T ok_or_throw_str(std::optional opt, const std::string& 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); - } - return pointer; +template inline T ptr_ok_or_throw_str(T pointer, const std::string& 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; - } +template 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) { - std::ostringstream oss; - (void)std::initializer_list{ - (oss << std::forward(args), - 0)...}; // using initializer_list for fold-like behavior - return oss.str(); +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 + return oss.str(); } -inline 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) { - os << '\t'; - } +inline void print_indent(std::ostream& os, int indent_level) { + for (int i = 0; i < indent_level; ++i) { + os << '\t'; + } } -inline void to_upper(std::string &s) { - std::ranges::transform( - s, s.begin(), [](const unsigned char &c) { return std::toupper(c); }); +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 f911a04..b1a31ad 100644 --- a/src/Arg.cpp +++ b/src/Arg.cpp @@ -5,15 +5,9 @@ #include #include -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) -{} +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) { @@ -43,25 +37,35 @@ Arg& Arg::default_value(const std::string& default_value) { } Arg& Arg::from_env(const char* env_var_name) { this->env_name_ = env_var_name; - 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: "; + 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 { @@ -69,7 +73,8 @@ void Arg::print_arg(std::ostream& os, const Arg& arg, int indent) { } 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 06a085a..b9fab50 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -45,7 +45,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); @@ -68,7 +68,7 @@ void ClapParser::parse_value_for_non_flag(Arg* arg, size_t& cli_index, const std arg->set__value(args.at(cli_index + 1)); 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"); } } @@ -78,13 +78,13 @@ 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()); + 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()); + auto* value_from_env = std::getenv(arg.get__env_name().c_str()); if (value_from_env != nullptr) { arg.set__value(value_from_env); } @@ -95,11 +95,9 @@ void ClapParser::check_env() { bool ClapParser::is_option(const std::string& token) { 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_long_option(const std::string& token) { return token.starts_with("--"); } + bool ClapParser::is_short_option(const std::string& token) { return token.starts_with("-") && token.size() > 1 && token.at(1) != '-'; } @@ -109,7 +107,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()) { @@ -134,8 +132,8 @@ void ClapParser::print_help() const { // Helper methods std::optional ClapParser::find_arg(ClapParser& parser, const std::string& 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 ); + 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()) { @@ -153,20 +151,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 52e3da3..cc21ba8 100644 --- a/src/example.cpp +++ b/src/example.cpp @@ -1,5 +1,5 @@ -#include "Parser.hpp" #include "Arg.hpp" +#include "Parser.hpp" #include "utils.hpp" #include @@ -7,35 +7,34 @@ 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; } From 7f6a3803c006866cce167cbef2512dcc38056f41 Mon Sep 17 00:00:00 2001 From: csboo Date: Thu, 15 May 2025 02:29:47 +0200 Subject: [PATCH 6/7] misc: clang-format everything (Google style) --- include/Arg.hpp | 8 +++---- include/Macros.hpp | 43 ++++++++++++++++++------------------ include/Parsables.hpp | 13 ++++++----- include/Parser.hpp | 12 +++++----- include/utils.hpp | 17 +++++++++----- src/Arg.cpp | 15 +++++++++---- src/Parser.cpp | 9 ++++---- src/example.cpp | 4 ++-- tests/test_combo.cpp | 49 +++++++++++++++++++++-------------------- tests/test_flag.cpp | 33 +++++++++++++-------------- tests/test_priority.cpp | 35 +++++++++++++++-------------- 11 files changed, 129 insertions(+), 109 deletions(-) diff --git a/include/Arg.hpp b/include/Arg.hpp index d99170d..49b3275 100644 --- a/include/Arg.hpp +++ b/include/Arg.hpp @@ -1,14 +1,14 @@ #pragma once -#include "Macros.hpp" - #include #include #include #include +#include "Macros.hpp" + class Arg { - public: + public: Arg(std::string name); Arg& short_name(const std::string& short_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_; diff --git a/include/Macros.hpp b/include/Macros.hpp index 7e43219..49e1049 100644 --- a/include/Macros.hpp +++ b/include/Macros.hpp @@ -1,28 +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##_; } \ +#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 143e2bc..343545f 100644 --- a/include/Parsables.hpp +++ b/include/Parsables.hpp @@ -1,7 +1,5 @@ #pragma once -#include "Macros.hpp" - #include #include #include @@ -9,7 +7,10 @@ #include #include -template struct Parse { +#include "Macros.hpp" + +template +struct Parse { static_assert(sizeof(T) == 0, "No Parse specialization defined for this type"); }; @@ -33,11 +34,13 @@ DEFINE_PARSABLE_FLOAT_TYPE(float, std::strtof) DEFINE_PARSABLE_FLOAT_TYPE(double, std::strtod) DEFINE_PARSABLE_FLOAT_TYPE(long double, std::strtold) -template <> struct Parse { +template <> +struct Parse { static std::optional parse(std::string_view s) { return std::string(s.data()); } }; -template <> struct Parse { +template <> +struct Parse { static std::optional parse(std::string_view s) { auto as_int = Parse::parse(s).value(); return as_int; diff --git a/include/Parser.hpp b/include/Parser.hpp index 27921e9..2c29de0 100644 --- a/include/Parser.hpp +++ b/include/Parser.hpp @@ -1,17 +1,17 @@ #pragma once -#include "Arg.hpp" -#include "Parsables.hpp" -#include "utils.hpp" - #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; @@ -26,7 +26,7 @@ class ClapParser { 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_; diff --git a/include/utils.hpp b/include/utils.hpp index 2f0a5a2..73e4093 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -6,38 +6,43 @@ #include #include -template inline T ok_or(std::optional opt, E&& err) { +template +inline T ok_or(std::optional opt, E&& err) { if (!opt) { std::forward(err)(); } return *opt; } -template inline T ok_or_throw_str(std::optional opt, const std::string& err) { +template +inline T ok_or_throw_str(std::optional opt, const std::string& err) { if (!opt) { throw std::runtime_error(err); } return *opt; } -template inline T ptr_ok_or_throw_str(T pointer, const std::string& err) { +template +inline T ptr_ok_or_throw_str(T pointer, const std::string& err) { if (!pointer) { throw std::runtime_error(err); } return pointer; } -template inline E ptr_unwrap_or(P pointer, const E other) { +template +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(); } diff --git a/src/Arg.cpp b/src/Arg.cpp index b1a31ad..b4b3811 100644 --- a/src/Arg.cpp +++ b/src/Arg.cpp @@ -1,13 +1,20 @@ #include "Arg.hpp" -#include "utils.hpp" -#include #include + +#include #include +#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) {} + : 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) { diff --git a/src/Parser.cpp b/src/Parser.cpp index b9fab50..cdfb31c 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -1,6 +1,4 @@ #include "Parser.hpp" -#include "Arg.hpp" -#include "utils.hpp" #include #include @@ -10,6 +8,9 @@ #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 @@ -23,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_) { @@ -66,7 +67,7 @@ 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 { throw std::runtime_error("option '" + arg->get__name() + "' requires a value but none was provided"); diff --git a/src/example.cpp b/src/example.cpp index cc21ba8..b16ce2a 100644 --- a/src/example.cpp +++ b/src/example.cpp @@ -1,9 +1,9 @@ +#include + #include "Arg.hpp" #include "Parser.hpp" #include "utils.hpp" -#include - void run(ClapParser& arg_parser); int main(const int argc, char* argv[]) { diff --git a/tests/test_combo.cpp b/tests/test_combo.cpp index 9aa7ab0..c70c91b 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" + const auto ev = std::getenv("EXPECTED_V"); + const auto 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); - 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..9ffb2cc 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) + const auto 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..2d3f104 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 + const auto 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; } From 95776e0a5cd031acc50f5da3277b5ca33bba3346 Mon Sep 17 00:00:00 2001 From: csboo Date: Thu, 15 May 2025 02:32:33 +0200 Subject: [PATCH 7/7] misc(tests): listen to clang-tidy --- tests/test_combo.cpp | 6 +++--- tests/test_flag.cpp | 2 +- tests/test_priority.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_combo.cpp b/tests/test_combo.cpp index c70c91b..6ad23e6 100644 --- a/tests/test_combo.cpp +++ b/tests/test_combo.cpp @@ -18,12 +18,12 @@ int main(int argc, char* argv[]) { // EXPECTED_V -> any int // EXPECTED_B -> "1" or "0" - const auto ev = std::getenv("EXPECTED_V"); - const auto eb = std::getenv("EXPECTED_B"); + 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); + 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"); diff --git a/tests/test_flag.cpp b/tests/test_flag.cpp index 9ffb2cc..69fe8c7 100644 --- a/tests/test_flag.cpp +++ b/tests/test_flag.cpp @@ -14,7 +14,7 @@ int main(int argc, char* argv[]) { p.parse(argc, argv); // EXPECTED should be "1" or "0" (present or absent) - const auto e = std::getenv("EXPECTED"); + auto *const e = std::getenv("EXPECTED"); assert(e && "EXPECTED must be set"); bool expected = std::string(e) == "1"; diff --git a/tests/test_priority.cpp b/tests/test_priority.cpp index 2d3f104..4d900ef 100644 --- a/tests/test_priority.cpp +++ b/tests/test_priority.cpp @@ -23,7 +23,7 @@ int main(const int argc, char* argv[]) { p.parse(argc, argv); // gets read from meson test env - const auto e = std::getenv("EXPECTED"); + auto *const e = std::getenv("EXPECTED"); assert(e && "EXPECTED must be set"); int expected = std::stoi(e);