diff --git a/include/blt/parse/argparse.h b/include/blt/parse/argparse.h index b49ae82..5d72f3b 100644 --- a/include/blt/parse/argparse.h +++ b/include/blt/parse/argparse.h @@ -280,7 +280,7 @@ namespace blt static std::string filename(const std::string& path); // expects that the current flag has already been consumed (advanced past), leaves tokenizer in a state where the next element is 'current' - static bool consumeArguments(arg_tokenizer& tokenizer, const arg_properties_t& properties, std::vector& v_out); + bool consumeArguments(arg_tokenizer& tokenizer, const std::string& flag, const arg_properties_t& properties, std::vector& v_out) const; void handlePositionalArgument(arg_tokenizer& tokenizer, size_t& last_pos); @@ -314,7 +314,8 @@ namespace blt arg_results parse_args(const std::vector& args); - void printHelp(); + void printUsage() const; + void printHelp() const; ~arg_parse() { diff --git a/include/blt/std/string.h b/include/blt/std/string.h index ae4a56f..4f9d65a 100755 --- a/include/blt/std/string.h +++ b/include/blt/std/string.h @@ -12,7 +12,6 @@ #include #include #include -#include namespace blt::string { diff --git a/src/blt/parse/argparse.cpp b/src/blt/parse/argparse.cpp index c1a7ca6..00c4ff1 100644 --- a/src/blt/parse/argparse.cpp +++ b/src/blt/parse/argparse.cpp @@ -4,7 +4,7 @@ * See LICENSE file for license detail */ #include -#include +#include #include namespace blt @@ -51,14 +51,17 @@ namespace blt throw invalid_argument_exception("Flag '" + flag + "' must start with - or --"); } - arg_vector_t::arg_vector_t(const char* str) { + arg_vector_t::arg_vector_t(const char* str) + { std::string as_string(str); if (as_string.starts_with('-')) flags.emplace_back(as_string); else name = as_string; } - arg_vector_t::arg_vector_t(const std::string& str) { + + arg_vector_t::arg_vector_t(const std::string& str) + { if (str.starts_with('-')) flags.emplace_back(str); else @@ -89,9 +92,11 @@ namespace blt std::string to_string(const arg_data_internal_t& v) { - if (std::holds_alternative(v)){ + if (std::holds_alternative(v)) + { return std::get(v); - } else if (std::holds_alternative(v)) { + } else if (std::holds_alternative(v)) + { return std::get(v) ? "True" : "False"; } return std::to_string(std::get(v)); @@ -146,7 +151,9 @@ namespace blt user_args.arg_properties_storage.push_back(properties); } - bool arg_parse::consumeArguments(arg_tokenizer& tokenizer, const arg_properties_t& properties, std::vector& v_out) + bool arg_parse::consumeArguments( + arg_tokenizer& tokenizer, const std::string& flag, const arg_properties_t& properties, std::vector& v_out + ) const { switch (properties.a_nargs.flags) { @@ -156,13 +163,19 @@ namespace blt // if we don't have another arg to consume we have a problem! if (!tokenizer.hasCurrent()) { - BLT_WARN("Expected %d arguments got %d instead!", properties.a_nargs.args, i); + // TODO: S + printUsage(); + std::cout << filename(loaded_args.program_name) << ": error: flag '" << flag << "' expected " << properties.a_nargs.args + << " argument(s) got " << i << " argument(s) instead!\n"; return false; } // if we do have one, but it is a flag then we also have a problem! if (tokenizer.isFlag()) { - BLT_WARN("Expected %d arguments, found flag instead!", properties.a_nargs.args); + printUsage(); + std::cout << filename(loaded_args.program_name) << ": error: flag '" << flag << "' expected " << properties.a_nargs.args + << " argument(s) but found '" << tokenizer.get() << "' instead!\n"; + //BLT_WARN("Expected %d arguments, found flag instead!", properties.a_nargs.args); return false; } // get the value and advance @@ -194,7 +207,8 @@ namespace blt case arg_nargs_t::ALL_REQUIRED: if (tokenizer.hasCurrent() && tokenizer.isFlag()) { - BLT_WARN("At least one argument is required!"); + printUsage(); + std::cout << loaded_args.program_name << ": at least one argument is required for '" << flag << "'\n"; return false; } while (tokenizer.hasCurrent() && !tokenizer.isFlag()) @@ -232,14 +246,15 @@ namespace blt { // handle special args like -vvv if (!flag.starts_with('-')) - BLT_ERROR("Flag processed but does not start with '-'"); + std::cerr << "Flag processed but does not start with '-' (this is a serious error!)\n"; // make sure the flag only contains the same character auto type = flag[1]; for (char c : flag.substr(1)) { if (c != type) { - BLT_ERROR("Processed flag '%s' expected %c found %c", flag.c_str(), type, c); + printUsage(); + std::cout << "found different characters in flag '" << flag.c_str() << "' expected '" << type << "' but found '" << c << "'\n"; return; } } @@ -282,12 +297,14 @@ namespace blt { arg_data_t& data = loaded_args.data[dest]; arg_data_vec_t v; - if (!consumeArguments(tokenizer, *properties, v)) + if (!consumeArguments(tokenizer, flag, *properties, v)) { printHelp(); return; } - if (v.size() == 1) + if (v.empty()) + data = ""; + else if (v.size() == 1) data = v[0]; else data = v; @@ -318,7 +335,7 @@ namespace blt case arg_action_t::VERSION: { auto file = filename(loaded_args.program_name); - BLT_INFO("%s, %s", file.c_str(), properties->a_version.c_str()); + std::cout << file.c_str() << " " << properties->a_version << "\n"; break; } case arg_action_t::APPEND_CONST: @@ -338,7 +355,7 @@ namespace blt if (!holds_alternative(data)) data = arg_data_vec_t(); auto& l = get(data); - consumeArguments(tokenizer, *properties, l); + consumeArguments(tokenizer, flag, *properties, l); break; } } @@ -369,7 +386,8 @@ namespace blt } // load defaults for args which were not found - for (const auto* arg : user_args.arg_properties_storage) { + for (const auto* arg : user_args.arg_properties_storage) + { if (!to_string(arg->a_default).empty() && !loaded_args.contains(arg->a_dest)) loaded_args.data[arg->a_dest] = arg->a_default; } @@ -389,16 +407,22 @@ namespace blt } // remove the last space caused by the for loop unrec = unrec.substr(0, unrec.size() - 1); - // TODO: use exceptions? - BLT_WARN("Unrecognized args: %s", unrec.c_str()); + printUsage(); + std::cout << loaded_args.program_name << ": error: unrecognized args: " << unrec << "\n"; printHelp(); return loaded_args; } - void arg_parse::printHelp() + void arg_parse::printHelp() const { - BLT_TRACE("I am helpful!"); + std::cout << ("I am helpful!\n"); std::exit(0); } + + void arg_parse::printUsage() const + { + + + } } \ No newline at end of file diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 822b91e..43955fe 100755 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -70,7 +70,7 @@ int (*func_func_in)(int) = &test_as_func; int main(int argc, const char** argv) { blt::arg_parse parser; parser.addArgument(blt::arg_builder({"--poo", "-p"}).build()); - parser.addArgument(blt::arg_builder({"--foo", "-f"}).setAction(blt::arg_action_t::STORE_TRUE).setDefault(false).build()); + parser.addArgument(blt::arg_builder("--foo").setAction(blt::arg_action_t::STORE_TRUE).setDefault(false).build()); parser.addArgument(blt::arg_builder({"--goo", "-g"}).build()); parser.addArgument(blt::arg_builder({"--oop", "-o"}).build()); parser.addArgument(blt::arg_builder("Sexy_pos").build());