Userland: Convert command line arguments to String/StringView

StringView was used where possible. Some utilities still use libc
functions which expect null-terminated strings, so String objects were
used there instead.
This commit is contained in:
sin-ack 2022-07-11 20:42:03 +00:00 committed by Andreas Kling
parent fded8f861d
commit 60f6bc902b
25 changed files with 101 additions and 100 deletions

View file

@ -267,16 +267,16 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::pledge("stdio recvfd sendfd proc exec rpath"));
char const* cpu = nullptr;
char const* memory = nullptr;
char const* network = nullptr;
StringView cpu {};
StringView memory {};
StringView network {};
Core::ArgsParser args_parser;
args_parser.add_option(cpu, "Create CPU graph", "cpu", 'C', "cpu");
args_parser.add_option(memory, "Create memory graph", "memory", 'M', "memory");
args_parser.add_option(network, "Create network graph", "network", 'N', "network");
args_parser.parse(arguments);
if (!cpu && !memory && !network) {
if (cpu.is_empty() && memory.is_empty() && network.is_empty()) {
printf("At least one of --cpu, --memory, or --network must be used");
return 1;
}
@ -306,11 +306,11 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
return {};
};
if (cpu)
if (!cpu.is_empty())
TRY(create_applet(GraphType::CPU, cpu));
if (memory)
if (!memory.is_empty())
TRY(create_applet(GraphType::Memory, memory));
if (network)
if (!network.is_empty())
TRY(create_applet(GraphType::Network, network));
TRY(Core::System::unveil("/res", "r"));

View file

@ -140,7 +140,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto app = TRY(GUI::Application::try_create(arguments));
char const* coredump_path = nullptr;
String coredump_path {};
bool unlink_on_exit = false;
StringBuilder full_backtrace;
@ -265,7 +265,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto& debug_button = *widget->find_descendant_of_type_named<GUI::Button>("debug_button");
debug_button.set_icon(TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/app-hack-studio.png")));
debug_button.on_click = [&](int) {
GUI::Process::spawn_or_show_error(window, "/bin/HackStudio", Array { "-c", coredump_path });
GUI::Process::spawn_or_show_error(window, "/bin/HackStudio", Array { "-c", coredump_path.characters() });
};
auto& save_backtrace_button = *widget->find_descendant_of_type_named<GUI::Button>("save_backtrace_button");

View file

@ -157,8 +157,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
};
};
char const* command_to_run = nullptr;
char const* file_to_read_from = nullptr;
StringView command_to_run = {};
StringView file_to_read_from = {};
Vector<String> script_args;
bool skip_rc_files = false;
char const* format = nullptr;
@ -201,10 +201,10 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
}
}
auto execute_file = file_to_read_from && "-"sv != file_to_read_from;
auto execute_file = !file_to_read_from.is_empty() && "-"sv != file_to_read_from;
attempt_interactive = !execute_file;
if (keep_open && !command_to_run && !execute_file) {
if (keep_open && command_to_run.is_empty() && !execute_file) {
warnln("Option --keep-open can only be used in combination with -c or when specifying a file to execute.");
return 1;
}
@ -230,7 +230,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
shell->set_local_variable("ARGV", adopt_ref(*new Shell::AST::ListValue(move(script_args))));
if (command_to_run) {
if (!command_to_run.is_empty()) {
dbgln("sh -c '{}'\n", command_to_run);
auto result = shell->run_command(command_to_run);
if (!keep_open)

View file

@ -19,7 +19,7 @@ static constexpr size_t MAX_CHUNK_SIZE = 1 * MiB / 2;
ErrorOr<int> serenity_main(Main::Arguments args)
{
char const* path = nullptr;
StringView path {};
int sample_count = -1;
Core::ArgsParser args_parser;

View file

@ -24,7 +24,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
{
TRY(Core::System::pledge("stdio rpath sendfd unix thread"));
char const* path = nullptr;
StringView path {};
bool should_loop = false;
bool show_sample_progress = false;

View file

@ -16,7 +16,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::pledge("stdio rpath chown"));
char const* gid_arg = nullptr;
char const* path = nullptr;
StringView path {};
bool dont_follow_symlinks = false;
Core::ArgsParser args_parser;

View file

@ -19,7 +19,7 @@
ErrorOr<int> serenity_main(Main::Arguments args)
{
char const* path = nullptr;
StringView path {};
Core::ArgsParser args_parser;
args_parser.set_general_help(

View file

@ -16,7 +16,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::pledge("stdio rpath exec"));
bool ignore_env = false;
char const* split_string = nullptr;
StringView split_string {};
Vector<String> values;
Core::ArgsParser args_parser;
@ -41,8 +41,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
}
Vector<StringView> new_argv;
if (split_string) {
for (auto view : StringView(split_string).split_view(' ')) {
if (!split_string.is_empty()) {
for (auto view : split_string.split_view(' ')) {
new_argv.append(view);
}
}

View file

@ -17,7 +17,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
{
TRY(Core::System::pledge("stdio unix"));
char const* name_or_ip = nullptr;
String name_or_ip {};
Core::ArgsParser args_parser;
args_parser.set_general_help("Convert between domain name and IPv4 address.");
args_parser.add_positional_argument(name_or_ip, "Domain name or IPv4 address", "name");
@ -37,7 +37,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
return 0;
}
auto* hostent = gethostbyname(name_or_ip);
auto* hostent = gethostbyname(name_or_ip.characters());
if (!hostent) {
warnln("Lookup failed for '{}'", name_or_ip);
return 1;

View file

@ -14,16 +14,16 @@
ErrorOr<int> serenity_main(Main::Arguments args)
{
char const* hostname = nullptr;
StringView hostname {};
Core::ArgsParser args_parser;
args_parser.add_positional_argument(hostname, "Hostname to set", "hostname", Core::ArgsParser::Required::No);
args_parser.parse(args);
if (!hostname) {
if (hostname.is_empty()) {
outln("{}", TRY(Core::System::gethostname()));
} else {
if (strlen(hostname) >= HOST_NAME_MAX) {
if (hostname.length() >= HOST_NAME_MAX) {
warnln("Hostname must be less than {} characters", HOST_NAME_MAX);
return 1;
}

View file

@ -25,9 +25,9 @@
ErrorOr<int> serenity_main(Main::Arguments arguments)
{
char const* value_ipv4 = nullptr;
char const* value_adapter = nullptr;
char const* value_mask = nullptr;
StringView value_ipv4 {};
StringView value_adapter {};
StringView value_mask {};
Core::ArgsParser args_parser;
args_parser.set_general_help("Display or modify the configuration of each network interface.");
@ -36,7 +36,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
args_parser.add_option(value_mask, "Set the network mask of the selected network", "mask", 'm', "mask");
args_parser.parse(arguments);
if (!value_ipv4 && !value_adapter && !value_mask) {
if (value_ipv4.is_empty() && value_adapter.is_empty() && value_mask.is_empty()) {
auto file = TRY(Core::File::open("/proc/net/adapters", Core::OpenMode::ReadOnly));
auto json = TRY(JsonValue::from_string(file->read_all()));
@ -66,14 +66,14 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
});
} else {
if (!value_adapter) {
if (value_adapter.is_empty()) {
warnln("No network adapter was specified.");
return 1;
}
String ifname = value_adapter;
if (value_ipv4) {
if (!value_ipv4.is_empty()) {
auto address = IPv4Address::from_string(value_ipv4);
if (!address.has_value()) {
@ -105,7 +105,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
}
}
if (value_mask) {
if (!value_mask.is_empty()) {
auto address = IPv4Address::from_string(value_mask);
if (!address.has_value()) {

View file

@ -526,8 +526,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
{
TRY(Core::System::pledge("stdio rpath tty sigaction"));
char const* filename = "-";
char const* prompt = "?f%f :.(line %l)?e (END):.";
// FIXME: Make these into StringViews once we stop using fopen below.
String filename = "-";
String prompt = "?f%f :.(line %l)?e (END):.";
bool dont_switch_buffer = false;
bool quit_at_eof = false;
bool emulate_more = false;
@ -546,7 +547,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
FILE* file;
if (String("-") == filename) {
file = stdin;
} else if ((file = fopen(filename, "r")) == nullptr) {
} else if ((file = fopen(filename.characters(), "r")) == nullptr) {
perror("fopen");
exit(1);
}

View file

@ -59,9 +59,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::unveil("/bin", "x"));
TRY(Core::System::unveil(nullptr, nullptr));
char const* section = nullptr;
char const* name = nullptr;
char const* pager = nullptr;
StringView section {};
StringView name {};
StringView pager {};
Core::ArgsParser args_parser;
args_parser.set_general_help("Read manual pages. Try 'man man' to get started.");
@ -70,19 +70,19 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
args_parser.add_option(pager, "Pager to pipe the man page to", "pager", 'P', "pager");
args_parser.parse(arguments);
auto make_path = [name](char const* section) {
auto make_path = [name](StringView section) {
return String::formatted("/usr/share/man/man{}/{}.md", section, name);
};
if (!section) {
char const* sections[] = {
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8"
if (section.is_empty()) {
constexpr StringView sections[] = {
"1"sv,
"2"sv,
"3"sv,
"4"sv,
"5"sv,
"6"sv,
"7"sv,
"8"sv
};
for (auto s : sections) {
String path = make_path(s);
@ -102,10 +102,10 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
}
String pager_command;
if (pager)
if (!pager.is_empty())
pager_command = pager;
else
pager_command = String::formatted("less -P 'Manual Page {}({}) line %l?e (END):.'", StringView(name).replace("'", "'\\''", ReplaceMode::FirstOnly), StringView(section).replace("'", "'\\''", ReplaceMode::FirstOnly));
pager_command = String::formatted("less -P 'Manual Page {}({}) line %l?e (END):.'", StringView(name).replace("'"sv, "'\\''"sv, ReplaceMode::FirstOnly), StringView(section).replace("'"sv, "'\\''"sv, ReplaceMode::FirstOnly));
pid_t pager_pid = TRY(pipe_to_pager(pager_command));
auto file = TRY(Core::File::open(filename, Core::OpenMode::ReadOnly));

View file

@ -15,9 +15,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto app = TRY(GUI::Application::try_create(arguments));
Core::ArgsParser args_parser;
char const* title = nullptr;
char const* message = nullptr;
char const* icon_path = nullptr;
StringView title {};
StringView message {};
StringView icon_path {};
args_parser.add_positional_argument(title, "Title of the notification", "title");
args_parser.add_positional_argument(message, "Message to display in the notification", "message");
args_parser.add_positional_argument(icon_path, "Path of icon to display in the notification", "icon-path", Core::ArgsParser::Required::No);
@ -26,7 +26,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto notification = TRY(GUI::Notification::try_create());
notification->set_text(message);
notification->set_title(title);
if (icon_path) {
if (!icon_path.is_empty()) {
notification->set_icon(TRY(Gfx::Bitmap::try_load_from_file(icon_path)));
}
notification->show();

View file

@ -30,7 +30,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
bool del = false;
bool lock = false;
bool unlock = false;
char const* username = nullptr;
// FIXME: Replace with StringView once Core::Account::from_name stops taking a char const*.
String username {};
auto args_parser = Core::ArgsParser();
args_parser.set_general_help("Modify an account password.");
@ -44,8 +45,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
uid_t current_uid = getuid();
// target_account is the account we are changing the password of.
auto target_account = TRY((username)
? Core::Account::from_name(username)
auto target_account = TRY(!username.is_empty()
? Core::Account::from_name(username.characters())
: Core::Account::from_uid(current_uid));
setpwent();

View file

@ -15,8 +15,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
{
Core::ArgsParser args_parser;
char const* pid_argument = nullptr;
char const* cmd_argument = nullptr;
StringView pid_argument {};
StringView cmd_argument {};
bool wait = false;
bool free = false;
bool enable = false;
@ -69,7 +69,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
exit(0);
}
if (!pid_argument && !cmd_argument && !all_processes) {
if (pid_argument.is_empty() && cmd_argument.is_empty() && !all_processes) {
args_parser.print_usage(stdout, arguments.argv[0]);
print_types();
return 0;
@ -78,13 +78,14 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!seen_event_type_arg)
event_mask |= PERF_EVENT_SAMPLE;
if (pid_argument || all_processes) {
if (!pid_argument.is_empty() || all_processes) {
if (!(enable ^ disable ^ wait ^ free)) {
warnln("-p <PID> requires -e xor -d xor -w xor -f.");
return 1;
}
pid_t pid = all_processes ? -1 : atoi(pid_argument);
// FIXME: Handle error case.
pid_t pid = all_processes ? -1 : pid_argument.to_int().release_value();
if (wait || enable) {
TRY(Core::System::profiling_enable(pid, event_mask));

View file

@ -232,7 +232,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
{
TRY(Core::System::pledge("stdio rpath"));
char const* path;
StringView path {};
static bool display_all = false;
static bool display_elf_header = false;
static bool display_program_headers = false;

View file

@ -33,7 +33,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
bool gzip = false;
bool no_auto_compress = false;
StringView archive_file;
char const* directory = nullptr;
StringView directory;
Vector<String> paths;
Core::ArgsParser args_parser;
@ -64,7 +64,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!archive_file.is_empty())
file = TRY(Core::File::open(archive_file, Core::OpenMode::ReadOnly));
if (directory)
if (!directory.is_empty())
TRY(Core::System::chdir(directory));
Core::InputFileStream file_stream(file);
@ -213,7 +213,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!archive_file.is_empty())
file = TRY(Core::File::open(archive_file, Core::OpenMode::WriteOnly));
if (directory)
if (!directory.is_empty())
TRY(Core::System::chdir(directory));
Core::OutputFileStream file_stream(file);

View file

@ -96,8 +96,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
bool complement_flag = false;
bool delete_flag = false;
bool squeeze_flag = false;
char const* from_chars = nullptr;
char const* to_chars = nullptr;
StringView from_chars;
StringView to_chars;
Core::ArgsParser args_parser;
args_parser.add_option(complement_flag, "Take the complement of the first set", "complement", 'c');
@ -107,7 +107,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
args_parser.add_positional_argument(to_chars, "Set of characters to translate to", "to", Core::ArgsParser::Required::No);
args_parser.parse(arguments);
bool transform_flag = to_chars && !delete_flag;
bool transform_flag = !to_chars.is_empty() && !delete_flag;
if (!transform_flag && !delete_flag && !squeeze_flag) {
warnln("tr: Missing operand");
@ -115,13 +115,13 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
return 1;
}
if (delete_flag && squeeze_flag && !to_chars) {
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]);
return 1;
}
if (delete_flag && !squeeze_flag && to_chars) {
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]);
return 1;
@ -138,7 +138,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
}
auto to_str = TRY(build_set(to_chars));
auto squeeze_string = TRY(build_set(to_chars ? to_chars : from_chars));
auto squeeze_string = TRY(build_set(!to_chars.is_empty() ? to_chars : from_chars));
Optional<char> last_char;
for (;;) {

View file

@ -22,9 +22,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
{
TRY(Core::System::pledge("stdio rpath wpath cpath"));
char const* resize = nullptr;
char const* reference = nullptr;
char const* file = nullptr;
StringView resize;
StringView reference;
StringView file;
Core::ArgsParser args_parser;
args_parser.add_option(resize, "Resize the target file to (or by) this size. Prefix with + or - to expand or shrink the file, or a bare number to set the size exactly", "size", 's', "size");
@ -32,12 +32,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
args_parser.add_positional_argument(file, "File path", "file");
args_parser.parse(arguments);
if (!resize && !reference) {
if (resize.is_empty() && reference.is_empty()) {
args_parser.print_usage(stderr, arguments.argv[0]);
return 1;
}
if (resize && reference) {
if (!resize.is_empty() && !reference.is_empty()) {
args_parser.print_usage(stderr, arguments.argv[0]);
return 1;
}
@ -45,7 +45,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto op = OP_Set;
off_t size = 0;
if (resize) {
if (!resize.is_empty()) {
String str = resize;
switch (str[0]) {
@ -67,7 +67,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
size = size_opt.value();
}
if (reference) {
if (!reference.is_empty()) {
auto stat = TRY(Core::System::stat(reference));
size = stat.st_size;
}

View file

@ -35,10 +35,10 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
int uid = 0;
int gid = USERS_GID;
bool create_home_dir = false;
char const* password = "";
char const* shell = DEFAULT_SHELL;
char const* gecos = "";
char const* username = nullptr;
String password = "";
String shell = DEFAULT_SHELL;
String gecos = "";
String username;
Core::ArgsParser args_parser;
args_parser.add_option(home_path, "Home directory for the new user", "home-dir", 'd', "path");
@ -53,7 +53,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
args_parser.parse(arguments);
// Let's run a quick sanity check on username
if (strpbrk(username, "\\/!@#$%^&*()~+=`:\n")) {
if (strpbrk(username.characters(), "\\/!@#$%^&*()~+=`:\n")) {
warnln("invalid character in username, {}", username);
return 1;
}
@ -145,19 +145,19 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
return builder.build();
};
char* hash = crypt(password, get_salt().characters());
char* hash = crypt(password.characters(), get_salt().characters());
struct passwd p;
p.pw_name = const_cast<char*>(username);
p.pw_name = const_cast<char*>(username.characters());
p.pw_passwd = const_cast<char*>("!");
p.pw_dir = const_cast<char*>(home.characters());
p.pw_uid = static_cast<uid_t>(uid);
p.pw_gid = static_cast<gid_t>(gid);
p.pw_shell = const_cast<char*>(shell);
p.pw_gecos = const_cast<char*>(gecos);
p.pw_shell = const_cast<char*>(shell.characters());
p.pw_gecos = const_cast<char*>(gecos.characters());
struct spwd s;
s.sp_namp = const_cast<char*>(username);
s.sp_namp = const_cast<char*>(username.characters());
s.sp_pwdp = const_cast<char*>(hash);
s.sp_lstchg = 18727;
s.sp_min = 0;

View file

@ -24,8 +24,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
pid_t pid = 0;
bool flag_create = false;
bool flag_delete = false;
char const* tty_name = nullptr;
char const* from = nullptr;
StringView tty_name;
StringView from;
Core::ArgsParser args_parser;
args_parser.add_option(flag_create, "Create entry", "create", 'c');

View file

@ -269,7 +269,7 @@ static void print_link_error(Wasm::LinkError const& error)
ErrorOr<int> serenity_main(Main::Arguments arguments)
{
char const* filename = nullptr;
StringView filename;
bool print = false;
bool attempt_instantiate = false;
bool debug = false;

View file

@ -42,7 +42,7 @@ ErrorOr<int> serenity_main(Main::Arguments main_arguments)
{
TRY(Core::System::pledge("stdio rpath proc exec"));
char const* placeholder = nullptr;
StringView placeholder;
bool split_with_nulls = false;
char const* specified_delimiter = "\n";
Vector<String> arguments;
@ -74,15 +74,13 @@ ErrorOr<int> serenity_main(Main::Arguments main_arguments)
char entry_separator = split_with_nulls ? '\0' : *specified_delimiter;
StringView placeholder_view { placeholder };
if (!placeholder_view.is_empty())
if (!placeholder.is_empty())
max_lines = 1;
if (arguments.is_empty())
arguments.append("echo");
ParsedInitialArguments initial_arguments(arguments, placeholder_view);
ParsedInitialArguments initial_arguments(arguments, placeholder);
FILE* fp = stdin;
bool is_stdin = true;

View file

@ -16,7 +16,7 @@
ErrorOr<int> serenity_main(Main::Arguments arguments)
{
char const* zip_path;
StringView zip_path;
Vector<StringView> source_paths;
bool recurse = false;
bool force = false;