mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 03:47:34 +00:00
Userland+AK: Stop using getopt() for ArgsParser
This commit moves the implementation of getopt into AK, and converts its API to understand and use StringView instead of char*. Everything else is caught in the crossfire of making Option::accept_value() take a StringView instead of a char const*. With this, we must now pass a Span<StringView> to ArgsParser::parse(), applications using LibMain are unaffected, but anything not using that or taking its own argc/argv has to construct a Vector<StringView> for this method.
This commit is contained in:
parent
b2b851b361
commit
db886fe18b
43 changed files with 673 additions and 584 deletions
|
@ -31,15 +31,15 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
"preserve",
|
||||
'p',
|
||||
"attributes",
|
||||
[&preserve](char const* s) {
|
||||
if (!s) {
|
||||
[&preserve](StringView s) {
|
||||
if (s.is_empty()) {
|
||||
preserve = Core::DeprecatedFile::PreserveMode::Permissions | Core::DeprecatedFile::PreserveMode::Ownership | Core::DeprecatedFile::PreserveMode::Timestamps;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool values_ok = true;
|
||||
|
||||
StringView { s, strlen(s) }.for_each_split_view(',', SplitBehavior::Nothing, [&](StringView value) {
|
||||
s.for_each_split_view(',', SplitBehavior::Nothing, [&](StringView value) {
|
||||
if (value == "mode"sv) {
|
||||
preserve |= Core::DeprecatedFile::PreserveMode::Permissions;
|
||||
} else if (value == "ownership"sv) {
|
||||
|
|
|
@ -169,19 +169,19 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
|
||||
if (selected_options_count == 0) {
|
||||
warnln("cut: you must specify a list of bytes, or fields");
|
||||
args_parser.print_usage(stderr, arguments.strings[0].characters_without_null_termination());
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (selected_options_count > 1) {
|
||||
warnln("cut: you must specify only one of bytes, or fields");
|
||||
args_parser.print_usage(stderr, arguments.strings[0].characters_without_null_termination());
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (delimiter.length() != 1) {
|
||||
warnln("cut: the delimiter must be a single character");
|
||||
args_parser.print_usage(stderr, arguments.strings[0].characters_without_null_termination());
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
auto expansion_successful = expand_list(ranges_list, ranges_vector);
|
||||
|
||||
if (!expansion_successful) {
|
||||
args_parser.print_usage(stderr, arguments.strings[0].characters_without_null_termination());
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,8 +66,7 @@ ErrorOr<void> parse_args(Main::Arguments arguments, Vector<DeprecatedString>& fi
|
|||
"time",
|
||||
0,
|
||||
"time-type",
|
||||
[&du_option](auto const* option_ptr) {
|
||||
StringView option { option_ptr, strlen(option_ptr) };
|
||||
[&du_option](StringView option) {
|
||||
if (option == "mtime"sv || option == "modification"sv)
|
||||
du_option.time_type = DuOption::TimeType::Modification;
|
||||
else if (option == "ctime"sv || option == "status"sv || option == "use"sv)
|
||||
|
@ -87,7 +86,7 @@ ErrorOr<void> parse_args(Main::Arguments arguments, Vector<DeprecatedString>& fi
|
|||
nullptr,
|
||||
'k',
|
||||
nullptr,
|
||||
[&du_option](auto const*) {
|
||||
[&du_option](StringView) {
|
||||
du_option.block_size = 1024;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
|
|||
.long_name = "regexp",
|
||||
.short_name = 'e',
|
||||
.value_name = "Pattern",
|
||||
.accept_value = [&](auto* str) {
|
||||
.accept_value = [&](StringView str) {
|
||||
patterns.append(str);
|
||||
return true;
|
||||
},
|
||||
|
@ -97,7 +97,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
|
|||
.argument_mode = Core::ArgsParser::OptionArgumentMode::Required,
|
||||
.help_string = "Action to take for binary files ([binary], text, skip)",
|
||||
.long_name = "binary-mode",
|
||||
.accept_value = [&](auto* str) {
|
||||
.accept_value = [&](StringView str) {
|
||||
if ("text"sv == str)
|
||||
binary_mode = BinaryFileMode::Text;
|
||||
else if ("binary"sv == str)
|
||||
|
@ -135,7 +135,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
|
|||
.long_name = "color",
|
||||
.short_name = 0,
|
||||
.value_name = "WHEN",
|
||||
.accept_value = [&](auto* str) {
|
||||
.accept_value = [&](StringView str) {
|
||||
if ("never"sv == str)
|
||||
colored_output = false;
|
||||
else if ("always"sv == str)
|
||||
|
|
|
@ -45,8 +45,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
"monochrome",
|
||||
'm',
|
||||
nullptr,
|
||||
[](char const* s) {
|
||||
VERIFY(s == nullptr);
|
||||
[](StringView s) {
|
||||
VERIFY(s.is_empty());
|
||||
use_color = false;
|
||||
return true;
|
||||
},
|
||||
|
|
|
@ -227,7 +227,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
return 0;
|
||||
}
|
||||
|
||||
args_parser.print_usage(stderr, arguments.argv[0]);
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
args_parser.parse(arguments);
|
||||
|
||||
if (paths.size() < 2) {
|
||||
args_parser.print_usage(stderr, arguments.argv[0]);
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,12 +35,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
"body-numbering",
|
||||
'b',
|
||||
"style",
|
||||
[&number_style](char const* s) {
|
||||
if (!strcmp(s, "t"))
|
||||
[&number_style](StringView s) {
|
||||
if (s == "t"sv)
|
||||
number_style = NumberNonEmptyLines;
|
||||
else if (!strcmp(s, "a"))
|
||||
else if (s == "a"sv)
|
||||
number_style = NumberAllLines;
|
||||
else if (!strcmp(s, "n"))
|
||||
else if (s == "n"sv)
|
||||
number_style = NumberNoLines;
|
||||
else
|
||||
return false;
|
||||
|
|
|
@ -63,7 +63,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
|
|||
auto number = StringView { omit_pid_value, strlen(omit_pid_value) }.to_uint();
|
||||
if (!number.has_value()) {
|
||||
warnln("Invalid value for -o");
|
||||
args_parser.print_usage(stderr, args.argv[0]);
|
||||
args_parser.print_usage(stderr, args.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
pid_to_omit = number.value();
|
||||
|
|
|
@ -172,8 +172,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
.long_name = "header",
|
||||
.short_name = 'H',
|
||||
.value_name = "key:value",
|
||||
.accept_value = [&](auto* s) {
|
||||
StringView header { s, strlen(s) };
|
||||
.accept_value = [&](StringView header) {
|
||||
auto split = header.find(':');
|
||||
if (!split.has_value())
|
||||
return false;
|
||||
|
@ -186,8 +185,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
.long_name = "auth",
|
||||
.short_name = 'u',
|
||||
.value_name = "username:password",
|
||||
.accept_value = [&](auto* s) {
|
||||
StringView input { s, strlen(s) };
|
||||
.accept_value = [&](StringView input) {
|
||||
if (!input.contains(':'))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
}
|
||||
|
||||
if (pid_argument.is_empty() && command.is_empty() && !all_processes) {
|
||||
args_parser.print_usage(stdout, arguments.argv[0]);
|
||||
args_parser.print_usage(stdout, arguments.strings[0]);
|
||||
print_types();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -242,7 +242,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
args_parser.parse(arguments);
|
||||
|
||||
if (arguments.argc < 3) {
|
||||
args_parser.print_usage(stderr, arguments.argv[0]);
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return Error::from_errno(EINVAL);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
args_parser.parse(arguments);
|
||||
|
||||
if (!force && paths.is_empty()) {
|
||||
args_parser.print_usage(stderr, arguments.argv[0]);
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -326,7 +326,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
.help_string = "Show progress with OSC 9 (true, false)",
|
||||
.long_name = "show-progress",
|
||||
.short_name = 'p',
|
||||
.accept_value = [&](auto* str) {
|
||||
.accept_value = [&](StringView str) {
|
||||
if ("true"sv == str)
|
||||
print_progress = true;
|
||||
else if ("false"sv == str)
|
||||
|
|
|
@ -108,8 +108,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
nullptr,
|
||||
't',
|
||||
"format",
|
||||
[&string_offset_format](char const* s) {
|
||||
StringView value = { s, strlen(s) };
|
||||
[&string_offset_format](StringView value) {
|
||||
if (value == "d") {
|
||||
string_offset_format = StringOffsetFormat::Decimal;
|
||||
} else if (value == "o") {
|
||||
|
|
|
@ -69,7 +69,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
}
|
||||
|
||||
if (syscall_arguments.is_empty()) {
|
||||
args_parser.print_usage(stderr, arguments.argv[0]);
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
args_parser.parse(arguments);
|
||||
|
||||
if (!show_all && variables.is_empty()) {
|
||||
args_parser.print_usage(stdout, arguments.argv[0]);
|
||||
args_parser.print_usage(stdout, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
args_parser.parse(arguments);
|
||||
|
||||
if (arguments.strings.size() <= 2 && arguments.strings[1] != "list"sv) {
|
||||
args_parser.print_usage_terminal(stderr, arguments.argv[0]);
|
||||
args_parser.print_usage_terminal(stderr, arguments.strings[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
.long_name = "unveil",
|
||||
.short_name = 'u',
|
||||
.value_name = "path",
|
||||
.accept_value = [&](auto* s) {
|
||||
StringView path { s, strlen(s) };
|
||||
.accept_value = [&](StringView path) {
|
||||
if (path.is_empty())
|
||||
return false;
|
||||
auto maybe_error = Core::System::unveil(path, permissions);
|
||||
|
@ -41,7 +40,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
.help_string = "Lock the veil",
|
||||
.long_name = "lock",
|
||||
.short_name = 'l',
|
||||
.accept_value = [&](auto*) {
|
||||
.accept_value = [&](StringView) {
|
||||
auto maybe_error = Core::System::unveil(nullptr, nullptr);
|
||||
if (maybe_error.is_error()) {
|
||||
warnln("unveil(nullptr, nullptr): {}", maybe_error.error());
|
||||
|
@ -54,8 +53,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
.name = "path",
|
||||
.min_values = 0,
|
||||
.max_values = INT_MAX,
|
||||
.accept_value = [&](auto* s) {
|
||||
auto maybe_error = Core::System::access({ s, strlen(s) }, X_OK);
|
||||
.accept_value = [&](StringView s) {
|
||||
auto maybe_error = Core::System::access(s, X_OK);
|
||||
if (maybe_error.is_error())
|
||||
warnln("'{}' - fail: {}", s, maybe_error.error());
|
||||
else
|
||||
|
|
|
@ -141,8 +141,7 @@ static void parse_args(Main::Arguments arguments, TopOption& top_option)
|
|||
"sort-by",
|
||||
's',
|
||||
nullptr,
|
||||
[&top_option](char const* s) {
|
||||
StringView sort_by_option { s, strlen(s) };
|
||||
[&top_option](StringView sort_by_option) {
|
||||
if (sort_by_option == "pid"sv)
|
||||
top_option.sort_by = TopOption::SortBy::Pid;
|
||||
else if (sort_by_option == "tid"sv)
|
||||
|
|
|
@ -111,19 +111,19 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
|
||||
if (!transform_flag && !delete_flag && !squeeze_flag) {
|
||||
warnln("tr: Missing operand");
|
||||
args_parser.print_usage(stderr, arguments.argv[0]);
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (delete_flag && squeeze_flag && to_chars.is_empty()) {
|
||||
warnln("tr: Combined delete and squeeze operations need two sets of characters");
|
||||
args_parser.print_usage(stderr, arguments.argv[0]);
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (delete_flag && !squeeze_flag && !to_chars.is_empty()) {
|
||||
warnln("tr: Only one set of characters may be given when deleting without squeezing");
|
||||
args_parser.print_usage(stderr, arguments.argv[0]);
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,12 +33,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
args_parser.parse(arguments);
|
||||
|
||||
if (resize.is_empty() && reference.is_empty()) {
|
||||
args_parser.print_usage(stderr, arguments.argv[0]);
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!resize.is_empty() && !reference.is_empty()) {
|
||||
args_parser.print_usage(stderr, arguments.argv[0]);
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
|
||||
auto size_opt = str.to_int<off_t>();
|
||||
if (!size_opt.has_value()) {
|
||||
args_parser.print_usage(stderr, arguments.argv[0]);
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
size = size_opt.value();
|
||||
|
|
|
@ -48,7 +48,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
if (*test_name == 'k')
|
||||
return kill_test();
|
||||
if (*test_name != 'n') {
|
||||
args_parser.print_usage(stdout, arguments.argv[0]);
|
||||
args_parser.print_usage(stdout, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
}
|
||||
|
||||
if (!s_disassembly_attempted) {
|
||||
args_parser.print_usage(stderr, arguments.argv[0]);
|
||||
args_parser.print_usage(stderr, arguments.strings[0]);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -296,9 +296,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
.long_name = "link",
|
||||
.short_name = 'l',
|
||||
.value_name = "file",
|
||||
.accept_value = [&](char const* str) {
|
||||
if (auto v = StringView { str, strlen(str) }; !v.is_empty()) {
|
||||
modules_to_link_in.append(v);
|
||||
.accept_value = [&](StringView str) {
|
||||
if (!str.is_empty()) {
|
||||
modules_to_link_in.append(str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -310,8 +310,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
.long_name = "arg",
|
||||
.short_name = 0,
|
||||
.value_name = "u64",
|
||||
.accept_value = [&](char const* str) -> bool {
|
||||
if (auto v = StringView { str, strlen(str) }.to_uint<u64>(); v.has_value()) {
|
||||
.accept_value = [&](StringView str) -> bool {
|
||||
if (auto v = str.to_uint<u64>(); v.has_value()) {
|
||||
values_to_push.append(v.value());
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue