Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
cmake-build-release
cmake-build-debug
build
29 changes: 14 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
22 changes: 11 additions & 11 deletions include/argparse/argparse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string> implicit_value=std::nullopt) :
type(type),
Entry(ARG_TYPE type_str, const std::string& key, std::string help, std::optional<std::string> implicit_value=std::nullopt) :
type(type_str),
keys_(split(key)),
help(std::move(help)),
help_(std::move(help)),
implicit_value_(std::move(implicit_value)) {
}

Expand Down Expand Up @@ -239,7 +239,7 @@ namespace argparse {

private:
std::vector<std::string> keys_;
std::string help;
std::string help_;
std::optional<std::string> value_;
std::optional<std::string> implicit_value_;
std::optional<std::string> default_str_;
Expand All @@ -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();
}
}

Expand All @@ -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_ + ")";
}
}

Expand All @@ -294,7 +294,7 @@ namespace argparse {
std::shared_ptr<Args> 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<typename T> operator T &() {
static_assert(std::is_base_of_v<Args, T>, "Subcommand type must be a derivative of argparse::Args");
Expand Down Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -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;
}

Expand Down
22 changes: 11 additions & 11 deletions tests/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ struct Custom {
std::pair<int, char**> get_argc_argv(std::string &str) {
std::string key;
std::vector<char*> 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];
}

Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -241,7 +241,7 @@ void TEST_SUBCOMMANDS() {
}
}

int main(int argc, char* argv[]) {
int main() {
TEST_ALL();
TEST_MULTI();
TEST_MULTI2();
Expand Down