diff options
-rw-r--r-- | Userland/Libraries/LibCore/ArgsParser.cpp | 21 | ||||
-rw-r--r-- | Userland/Libraries/LibCore/ArgsParser.h | 9 | ||||
-rw-r--r-- | Userland/Shell/Builtin.cpp | 36 | ||||
-rw-r--r-- | Userland/Utilities/profile.cpp | 2 |
4 files changed, 38 insertions, 30 deletions
diff --git a/Userland/Libraries/LibCore/ArgsParser.cpp b/Userland/Libraries/LibCore/ArgsParser.cpp index 3c8e3597a0..5dbec84b7e 100644 --- a/Userland/Libraries/LibCore/ArgsParser.cpp +++ b/Userland/Libraries/LibCore/ArgsParser.cpp @@ -30,11 +30,12 @@ ArgsParser::ArgsParser() add_option(m_show_help, "Display this message", "help", 0); } -bool ArgsParser::parse(int argc, char** argv, bool exit_on_failure) +bool ArgsParser::parse(int argc, char* const* argv, FailureBehavior failure_behavior) { - auto print_usage_and_exit = [this, argv, exit_on_failure] { - print_usage(stderr, argv[0]); - if (exit_on_failure) + auto fail = [this, argv, failure_behavior] { + if (failure_behavior == FailureBehavior::PrintUsage || failure_behavior == FailureBehavior::PrintUsageAndExit) + print_usage(stderr, argv[0]); + if (failure_behavior == FailureBehavior::Exit || failure_behavior == FailureBehavior::PrintUsageAndExit) exit(1); }; @@ -76,7 +77,7 @@ bool ArgsParser::parse(int argc, char** argv, bool exit_on_failure) } else if (c == '?') { // There was an error, and getopt() has already // printed its error message. - print_usage_and_exit(); + fail(); return false; } @@ -98,7 +99,7 @@ bool ArgsParser::parse(int argc, char** argv, bool exit_on_failure) const char* arg = found_option->requires_argument ? optarg : nullptr; if (!found_option->accept_value(arg)) { warnln("\033[31mInvalid value for option \033[1m{}\033[22m, dude\033[0m", found_option->name_for_display()); - print_usage_and_exit(); + fail(); return false; } } @@ -116,7 +117,7 @@ bool ArgsParser::parse(int argc, char** argv, bool exit_on_failure) } if (total_values_required > values_left) { - print_usage_and_exit(); + fail(); return false; } int extra_values_to_distribute = values_left - total_values_required; @@ -132,7 +133,7 @@ bool ArgsParser::parse(int argc, char** argv, bool exit_on_failure) if (extra_values_to_distribute > 0) { // We still have too many values :( - print_usage_and_exit(); + fail(); return false; } @@ -142,7 +143,7 @@ bool ArgsParser::parse(int argc, char** argv, bool exit_on_failure) const char* value = argv[optind++]; if (!arg.accept_value(value)) { warnln("Invalid value for argument {}", arg.name); - print_usage_and_exit(); + fail(); return false; } } @@ -152,7 +153,7 @@ bool ArgsParser::parse(int argc, char** argv, bool exit_on_failure) // Now let's show help if requested. if (m_show_help) { print_usage(stdout, argv[0]); - if (exit_on_failure) + if (failure_behavior == FailureBehavior::Exit || failure_behavior == FailureBehavior::PrintUsageAndExit) exit(0); return false; } diff --git a/Userland/Libraries/LibCore/ArgsParser.h b/Userland/Libraries/LibCore/ArgsParser.h index 5c73437064..4e88e8af06 100644 --- a/Userland/Libraries/LibCore/ArgsParser.h +++ b/Userland/Libraries/LibCore/ArgsParser.h @@ -22,6 +22,13 @@ public: No }; + enum class FailureBehavior { + PrintUsageAndExit, + PrintUsage, + Exit, + Ignore, + }; + struct Option { bool requires_argument { true }; const char* help_string { nullptr }; @@ -46,7 +53,7 @@ public: Function<bool(const char*)> accept_value; }; - bool parse(int argc, char** argv, bool exit_on_failure = true); + bool parse(int argc, char* const* argv, FailureBehavior failure_behavior = FailureBehavior::PrintUsageAndExit); // *Without* trailing newline! void set_general_help(const char* help_string) { m_general_help = help_string; }; void print_usage(FILE*, const char* argv0); diff --git a/Userland/Shell/Builtin.cpp b/Userland/Shell/Builtin.cpp index d03b47a56f..55b2b5ef2d 100644 --- a/Userland/Shell/Builtin.cpp +++ b/Userland/Shell/Builtin.cpp @@ -39,7 +39,7 @@ int Shell::builtin_alias(int argc, const char** argv) Core::ArgsParser parser; parser.add_positional_argument(arguments, "List of name[=values]'s", "name[=value]", Core::ArgsParser::Required::No); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; if (arguments.is_empty()) { @@ -96,7 +96,7 @@ int Shell::builtin_bg(int argc, const char** argv) return false; } }); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; if (job_id == -1 && !jobs.is_empty()) @@ -141,7 +141,7 @@ int Shell::builtin_type(int argc, const char** argv) parser.add_positional_argument(commands, "Command(s) to list info about", "command"); parser.add_option(dont_show_function_source, "Do not show functions source.", "no-fn-source", 'f'); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; bool something_not_found = false; @@ -207,7 +207,7 @@ int Shell::builtin_cd(int argc, const char** argv) Core::ArgsParser parser; parser.add_positional_argument(arg_path, "Path to change to", "path", Core::ArgsParser::Required::No); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; String new_path; @@ -258,7 +258,7 @@ int Shell::builtin_cdh(int argc, const char** argv) Core::ArgsParser parser; parser.add_positional_argument(index, "Index of the cd history entry (leave out for a list)", "index", Core::ArgsParser::Required::No); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; if (index == -1) { @@ -300,7 +300,7 @@ int Shell::builtin_dirs(int argc, const char** argv) parser.add_option(number_when_printing, "Number the directories in the stack when printing", "number", 'v'); parser.add_positional_argument(paths, "Extra paths to put on the stack", "path", Core::ArgsParser::Required::No); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; // -v implies -p @@ -382,7 +382,7 @@ int Shell::builtin_export(int argc, const char** argv) Core::ArgsParser parser; parser.add_positional_argument(vars, "List of variable[=value]'s", "values", Core::ArgsParser::Required::No); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; if (vars.is_empty()) { @@ -427,7 +427,7 @@ int Shell::builtin_glob(int argc, const char** argv) Core::ArgsParser parser; parser.add_positional_argument(globs, "Globs to resolve", "glob"); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; for (auto& glob : globs) { @@ -467,7 +467,7 @@ int Shell::builtin_fg(int argc, const char** argv) return false; } }); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; if (job_id == -1 && !jobs.is_empty()) @@ -538,7 +538,7 @@ int Shell::builtin_disown(int argc, const char** argv) return false; } }); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; if (job_ids.is_empty()) { @@ -593,7 +593,7 @@ int Shell::builtin_jobs(int argc, const char** argv) parser.add_option(list, "List all information about jobs", "list", 'l'); parser.add_option(show_pid, "Display the PID of the jobs", "pid", 'p'); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; Job::PrintStatusMode mode = Job::PrintStatusMode::Basic; @@ -625,7 +625,7 @@ int Shell::builtin_popd(int argc, const char** argv) Core::ArgsParser parser; parser.add_option(should_not_switch, "Do not switch dirs", "no-switch", 'n'); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; bool should_switch = !should_not_switch; @@ -792,7 +792,7 @@ int Shell::builtin_setopt(int argc, const char** argv) #undef __ENUMERATE_SHELL_OPTION - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; #define __ENUMERATE_SHELL_OPTION(name, default_, description) \ @@ -815,7 +815,7 @@ int Shell::builtin_shift(int argc, const char** argv) Core::ArgsParser parser; parser.add_positional_argument(count, "Shift count", "count", Core::ArgsParser::Required::No); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; if (count < 1) @@ -880,7 +880,7 @@ int Shell::builtin_time(int argc, const char** argv) Core::ArgsParser parser; parser.add_positional_argument(args, "Command to execute with arguments", "command", Core::ArgsParser::Required::Yes); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; AST::Command command; @@ -907,7 +907,7 @@ int Shell::builtin_umask(int argc, const char** argv) Core::ArgsParser parser; parser.add_positional_argument(mask_text, "New mask (omit to get current mask)", "octal-mask", Core::ArgsParser::Required::No); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; if (!mask_text) { @@ -957,7 +957,7 @@ int Shell::builtin_wait(int argc, const char** argv) return false; } }); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; Vector<NonnullRefPtr<Job>> jobs_to_wait_for; @@ -992,7 +992,7 @@ int Shell::builtin_unset(int argc, const char** argv) Core::ArgsParser parser; parser.add_positional_argument(vars, "List of variables", "variables", Core::ArgsParser::Required::Yes); - if (!parser.parse(argc, const_cast<char**>(argv), false)) + if (!parser.parse(argc, const_cast<char**>(argv), Core::ArgsParser::FailureBehavior::PrintUsage)) return 1; for (auto& value : vars) { diff --git a/Userland/Utilities/profile.cpp b/Userland/Utilities/profile.cpp index 46c7fc8b3f..69b6d03e1f 100644 --- a/Userland/Utilities/profile.cpp +++ b/Userland/Utilities/profile.cpp @@ -58,7 +58,7 @@ int main(int argc, char** argv) outln("Event type can be one of: sample, context_switch, page_fault, kmalloc and kfree."); }; - if (!args_parser.parse(argc, argv, false)) { + if (!args_parser.parse(argc, argv, Core::ArgsParser::FailureBehavior::PrintUsage)) { print_types(); exit(1); } |