diff --git a/.gitignore b/.gitignore index 2ff5481..7ea20f7 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ cmake-build-release cmake-build-debug +build \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index da38e41..fd8b0d5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,31 +26,30 @@ export(EXPORT argparseConfig option(ARGPARSE_BUILD_EXAMPLES OFF) option(ARGPARSE_BUILD_TESTS OFF) if(ARGPARSE_BUILD_EXAMPLES) + # we want to add these compile options to the main library, so that we can let the compiler warn us about issues in code the tests may not cover + set(COMPILE_OPTIONS -Wall -Werror -Wpedantic -Wshadow -Wdouble-promotion -Wextra) + target_compile_options(argparse INTERFACE ${COMPILE_OPTIONS}) + add_executable(argparse_example examples/argparse_example.cpp) - target_include_directories(argparse_example PUBLIC include) - target_link_libraries(argparse_example PUBLIC morrisfranken::argparse) - target_compile_options(argparse_example PRIVATE -Wall -Werror -Wpedantic) + target_include_directories(argparse_example PRIVATE include) + target_link_libraries(argparse_example PRIVATE morrisfranken::argparse) add_executable(hello_world examples/hello_world.cpp) - target_include_directories(hello_world PUBLIC include) - target_link_libraries(hello_world PUBLIC morrisfranken::argparse) - target_compile_options(hello_world PRIVATE -Wall -Werror -Wpedantic) + target_include_directories(hello_world PRIVATE include) + target_link_libraries(hello_world PRIVATE morrisfranken::argparse) add_executable(multiple_arguments examples/multiple_arguments.cpp) - target_include_directories(multiple_arguments PUBLIC include) - target_link_libraries(multiple_arguments PUBLIC morrisfranken::argparse) - target_compile_options(multiple_arguments PRIVATE -Wall -Werror -Wpedantic) + target_include_directories(multiple_arguments PRIVATE include) + target_link_libraries(multiple_arguments PRIVATE morrisfranken::argparse) set(EXE_NAME argparse_subcommands) add_executable(${EXE_NAME} examples/${EXE_NAME}.cpp) - target_include_directories(${EXE_NAME} PUBLIC include) - target_link_libraries(${EXE_NAME} PUBLIC morrisfranken::argparse) - target_compile_options(${EXE_NAME} PRIVATE -Wall -Werror -Wpedantic) + target_include_directories(${EXE_NAME} PRIVATE include) + target_link_libraries(${EXE_NAME} PRIVATE morrisfranken::argparse) add_executable(enums examples/enums.cpp) - target_include_directories(enums PUBLIC include) - target_link_libraries(enums PUBLIC morrisfranken::argparse) - target_compile_options(enums PRIVATE -Wall -Werror -Wpedantic) + target_include_directories(enums PRIVATE include) + target_link_libraries(enums PRIVATE morrisfranken::argparse) #target_compile_options(argparse_test PUBLIC -ftime-report) #target_precompile_headers(argparse_test PUBLIC include/argparse.h) --> should be enabled on release endif() diff --git a/include/argparse/argparse.hpp b/include/argparse/argparse.hpp index 31b54db..a0166d3 100755 --- a/include/argparse/argparse.hpp +++ b/include/argparse/argparse.hpp @@ -195,10 +195,10 @@ namespace argparse { struct Entry { enum ARG_TYPE {ARG, KWARG, FLAG} type; - Entry(ARG_TYPE type, const std::string& key, std::string help, std::optional implicit_value=std::nullopt) : - type(type), + Entry(ARG_TYPE type_str, const std::string& key, std::string help, std::optional implicit_value=std::nullopt) : + type(type_str), keys_(split(key)), - help(std::move(help)), + help_(std::move(help)), implicit_value_(std::move(implicit_value)) { } @@ -239,7 +239,7 @@ namespace argparse { private: std::vector keys_; - std::string help; + std::string help_; std::optional value_; std::optional implicit_value_; std::optional default_str_; @@ -261,9 +261,9 @@ namespace argparse { this->value_ = value; datap->convert(value); } catch (const std::invalid_argument &e) { - error = "Invalid argument, could not convert \"" + value + "\" for " + _get_keys() + " (" + help + ")"; + error = "Invalid argument, could not convert \"" + value + "\" for " + _get_keys() + " (" + help_ + ")"; } catch (const std::runtime_error &e) { - error = "Invalid argument \"" + value + "\" for " + _get_keys() + " (" + help + "). Error: " + e.what(); + error = "Invalid argument \"" + value + "\" for " + _get_keys() + " (" + help_ + "). Error: " + e.what(); } } @@ -275,7 +275,7 @@ namespace argparse { } else if (default_str_.has_value()) { // in cases where a string is provided to the `set_default` function _convert(default_str_.value()); } else { - error = "Argument missing: " + _get_keys() + " (" + help + ")"; + error = "Argument missing: " + _get_keys() + " (" + help_ + ")"; } } @@ -294,7 +294,7 @@ namespace argparse { std::shared_ptr subargs; std::string subcommand_name; - explicit SubcommandEntry(std::string subcommand_name) : subcommand_name(std::move(subcommand_name)) {} + explicit SubcommandEntry(std::string subcommand) : subcommand_name(std::move(subcommand)) {} template operator T &() { static_assert(std::is_base_of_v, "Subcommand type must be a derivative of argparse::Args"); @@ -405,13 +405,13 @@ namespace argparse { } cout << endl; for (const auto &entry : arg_entries) { - cout << setw(17) << entry->keys_[0] << " : " << entry->help << entry->info() << endl; + cout << setw(17) << entry->keys_[0] << " : " << entry->help_ << entry->info() << endl; } if (has_options()) cout << endl << "Options:" << endl; for (const auto &entry : all_entries) { if (entry->type != Entry::ARG) { - cout << setw(17) << entry->_get_keys() << " : " << entry->help << entry->info() << endl; + cout << setw(17) << entry->_get_keys() << " : " << entry->help_ << entry->info() << endl; } } @@ -557,7 +557,7 @@ namespace argparse { void print() const { for (const auto &entry : all_entries) { - std::string snip = entry->type == Entry::ARG ? "(" + (entry->help.size() > 10 ? entry->help.substr(0, 7) + "..." : entry->help) + ")" : ""; + std::string snip = entry->type == Entry::ARG ? "(" + (entry->help_.size() > 10 ? entry->help_.substr(0, 7) + "..." : entry->help_) + ")" : ""; cout << setw(21) << entry->_get_keys() + snip << " : " << (entry->is_set_by_user? bold(entry->value_.value_or("null")) : entry->value_.value_or("null")) << endl; } diff --git a/tests/tests.cpp b/tests/tests.cpp index ef63908..4afd7d8 100755 --- a/tests/tests.cpp +++ b/tests/tests.cpp @@ -23,14 +23,14 @@ struct Custom { std::pair get_argc_argv(std::string &str) { std::string key; std::vector splits = {(char *)str.c_str()}; - for (int i = 1; i < str.size(); i++) { + for (size_t i = 1; i < str.size(); i++) { if (str[i] == ' ') { str[i] = '\0'; splits.emplace_back(&str[++i]); } } char** argv = new char*[splits.size()]; - for (int i = 0; i < splits.size(); i++) { + for (size_t i = 0; i < splits.size(); i++) { argv[i] = splits[i]; } @@ -134,14 +134,14 @@ void TEST_ALL() { assert(args.named_arg == "named_arg_input"); assert(args.dst_path == "destination"); assert(args.k == 5); - assert(args.alpha != nullptr && std::abs(*args.alpha - 1) < 0.0001); - assert(std::abs(args.beta - 3.3) < 0.0001); - assert(std::abs(args.beta2 - 0.6) < 0.0001); - assert(args.gamma != nullptr && std::abs(*args.gamma - 0.5) < 0.0001); + assert(args.alpha != nullptr && std::abs(*args.alpha - 1) < 0.0001f); + assert(std::abs(args.beta - 3.3f) < 0.0001f); + assert(std::abs(args.beta2 - 0.6f) < 0.0001f); + assert(args.gamma != nullptr && std::abs(*args.gamma - 0.5f) < 0.0001f); assert(args.numbers.size() == 5 && args.numbers[2] == 3); assert(args.numbers2.size() == 3 && args.numbers2[2] == 8); assert(args.files.size() == 3 && args.files[2] == "f3"); - assert(std::abs(args.opt.value() - 1.0f) < 0.0001); + assert(std::abs(args.opt.value() - 1.0f) < 0.0001f); assert(args.custom.message == "hello_custom"); assert(args.flag1 == false); assert(args.verbose); @@ -155,13 +155,13 @@ void TEST_ALL() { assert(args.dst_path == "world"); assert(args.k == 3); assert(args.alpha == nullptr); - assert(std::abs(args.beta - 0.6) < 0.0001); - assert(std::abs(args.beta2 - 0.6) < 0.0001); + assert(std::abs(args.beta - 0.6f) < 0.0001f); + assert(std::abs(args.beta2 - 0.6f) < 0.0001f); assert(args.gamma == nullptr); assert(args.numbers.size() == 2 && args.numbers[1] == 2); assert(args.numbers2.size() == 3 && args.numbers2[2] == 5); assert(args.files.empty()); - assert(std::abs(args.opt.value() - 1.0f) < 0.0001); + assert(std::abs(args.opt.value() - 1.0f) < 0.0001f); assert(args.custom.message == "hello_custom"); assert(args.flag1 == false); assert(args.verbose); @@ -241,7 +241,7 @@ void TEST_SUBCOMMANDS() { } } -int main(int argc, char* argv[]) { +int main() { TEST_ALL(); TEST_MULTI(); TEST_MULTI2();