LibCore+Userland: Remove ArgsParser::add*(Vector<char const*>&)
This finally makes ArgsParser's value API free of silly char*'s!
This commit is contained in:
parent
500044906d
commit
23c514cda3
Notes:
sideshowbarker
2024-07-17 17:49:11 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/23c514cda3 Pull-request: https://github.com/SerenityOS/serenity/pull/17674 Reviewed-by: https://github.com/AtkinsSJ ✅ Reviewed-by: https://github.com/kleinesfilmroellchen
5 changed files with 31 additions and 47 deletions
Userland
|
@ -649,22 +649,6 @@ void ArgsParser::add_positional_argument(double& value, char const* help_string,
|
|||
add_positional_argument(move(arg));
|
||||
}
|
||||
|
||||
void ArgsParser::add_positional_argument(Vector<char const*>& values, char const* help_string, char const* name, Required required)
|
||||
{
|
||||
Arg arg {
|
||||
help_string,
|
||||
name,
|
||||
required == Required::Yes ? 1 : 0,
|
||||
INT_MAX,
|
||||
[&values](StringView s) {
|
||||
VERIFY(s.length() == strlen(s.characters_without_null_termination()));
|
||||
values.append(s.characters_without_null_termination());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
add_positional_argument(move(arg));
|
||||
}
|
||||
|
||||
void ArgsParser::add_positional_argument(Vector<DeprecatedString>& values, char const* help_string, char const* name, Required required)
|
||||
{
|
||||
Arg arg {
|
||||
|
|
|
@ -105,7 +105,6 @@ public:
|
|||
void add_positional_argument(int& value, char const* help_string, char const* name, Required required = Required::Yes);
|
||||
void add_positional_argument(unsigned& value, char const* help_string, char const* name, Required required = Required::Yes);
|
||||
void add_positional_argument(double& value, char const* help_string, char const* name, Required required = Required::Yes);
|
||||
void add_positional_argument(Vector<char const*>& value, char const* help_string, char const* name, Required required = Required::Yes);
|
||||
void add_positional_argument(Vector<DeprecatedString>& value, char const* help_string, char const* name, Required required = Required::Yes);
|
||||
void add_positional_argument(Vector<StringView>& value, char const* help_string, char const* name, Required required = Required::Yes);
|
||||
|
||||
|
|
|
@ -27,20 +27,21 @@ static void print_usage(FILE* stream)
|
|||
fputs(g_usage, stream);
|
||||
}
|
||||
|
||||
static double get_double(char const* name, char const* d_string, size_t* number_of_decimals)
|
||||
static double get_double(char const* name, StringView d_string, size_t* number_of_decimals)
|
||||
{
|
||||
char* end;
|
||||
double d = strtod(d_string, &end);
|
||||
if (d == 0 && end == d_string) {
|
||||
auto d = d_string.to_double();
|
||||
if (!d.has_value()) {
|
||||
warnln("{}: invalid argument \"{}\"", name, d_string);
|
||||
print_usage(stderr);
|
||||
exit(1);
|
||||
}
|
||||
if (char const* dot = strchr(d_string, '.'))
|
||||
*number_of_decimals = strlen(dot + 1);
|
||||
|
||||
if (auto dot = d_string.find('.'); dot.has_value())
|
||||
*number_of_decimals = d_string.length() - *dot - 1;
|
||||
else
|
||||
*number_of_decimals = 0;
|
||||
return d;
|
||||
|
||||
return *d;
|
||||
}
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
|
@ -50,7 +51,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
|
||||
StringView separator = "\n"sv;
|
||||
StringView terminator = ""sv;
|
||||
Vector<char const*> parameters;
|
||||
Vector<StringView> parameters;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_option(separator, "Characters to print after each number (default: \\n)", "separator", 's', "separator");
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
FlatPtr arg[SC_NARG];
|
||||
char outbuf[BUFSIZ];
|
||||
|
||||
using Arguments = Vector<char const*>;
|
||||
using Arguments = Vector<DeprecatedString>;
|
||||
using ArgIter = Arguments::Iterator;
|
||||
|
||||
static FlatPtr parse_from(ArgIter&);
|
||||
|
@ -41,7 +41,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
{
|
||||
bool output_buffer = false;
|
||||
bool list_syscalls = false;
|
||||
Vector<char const*> syscall_arguments;
|
||||
Arguments syscall_arguments;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.set_general_help(
|
||||
|
@ -140,7 +140,7 @@ static FlatPtr parse_parameter_buffer(ArgIter& iter)
|
|||
{
|
||||
Vector<FlatPtr> params_vec;
|
||||
while (!iter.is_end()) {
|
||||
if (strcmp(*iter, "]") == 0) {
|
||||
if (*iter == "]"sv) {
|
||||
++iter;
|
||||
return as_buf(params_vec);
|
||||
}
|
||||
|
@ -155,36 +155,34 @@ static FlatPtr parse_parameter_buffer(ArgIter& iter)
|
|||
|
||||
static FlatPtr parse_from(ArgIter& iter)
|
||||
{
|
||||
char const* this_arg = *iter;
|
||||
auto const& this_arg_string = *iter;
|
||||
auto* this_arg = this_arg_string.characters();
|
||||
++iter;
|
||||
|
||||
// Is it a forced literal?
|
||||
if (this_arg[0] == ',') {
|
||||
this_arg += 1;
|
||||
dbgln_if(SYSCALL_1_DEBUG, "Using (forced) string >>{}<< at {:p}", this_arg, (FlatPtr)this_arg);
|
||||
dbgln_if(SYSCALL_1_DEBUG, "Using (forced) string >>{}<< at {:p}", this_arg_string, (FlatPtr)this_arg);
|
||||
return (FlatPtr)this_arg;
|
||||
}
|
||||
|
||||
// Is it the output buffer?
|
||||
if (strcmp(this_arg, "buf") == 0)
|
||||
if (this_arg_string == "buf"sv)
|
||||
return (FlatPtr)outbuf;
|
||||
|
||||
// Is it a parameter buffer?
|
||||
if (strcmp(this_arg, "[") == 0)
|
||||
if (this_arg_string == "["sv)
|
||||
return parse_parameter_buffer(iter);
|
||||
|
||||
// Is it a number?
|
||||
char* endptr = nullptr;
|
||||
FlatPtr l = strtoul(this_arg, &endptr, 0);
|
||||
if (*endptr == 0) {
|
||||
return l;
|
||||
}
|
||||
if (auto l = this_arg_string.to_uint(); l.has_value())
|
||||
return *l;
|
||||
|
||||
// Then it must be a string:
|
||||
if (strcmp(this_arg, "]") == 0)
|
||||
if (this_arg_string == "]"sv)
|
||||
fprintf(stderr, "Warning: Treating unmatched ']' as literal string\n");
|
||||
|
||||
dbgln_if(SYSCALL_1_DEBUG, "Using (detected) string >>{}<< at {:p}", this_arg, (FlatPtr)this_arg);
|
||||
dbgln_if(SYSCALL_1_DEBUG, "Using (detected) string >>{}<< at {:p}", this_arg_string, (FlatPtr)this_arg);
|
||||
|
||||
return (FlatPtr)this_arg;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ static bool flag_beep_on_fail = false;
|
|||
static int volatile exit_code = 0;
|
||||
static volatile pid_t child_pid = -1;
|
||||
|
||||
static DeprecatedString build_header_string(Vector<char const*> const& command, struct timeval const& interval)
|
||||
static DeprecatedString build_header_string(Vector<DeprecatedString> const& command, struct timeval const& interval)
|
||||
{
|
||||
StringBuilder builder;
|
||||
builder.appendff("Every {}.{}s: \x1b[1m", interval.tv_sec, interval.tv_usec / 100000);
|
||||
|
@ -37,7 +37,7 @@ static DeprecatedString build_header_string(Vector<char const*> const& command,
|
|||
return builder.to_deprecated_string();
|
||||
}
|
||||
|
||||
static DeprecatedString build_header_string(Vector<char const*> const& command, Vector<DeprecatedString> const& filenames)
|
||||
static DeprecatedString build_header_string(Vector<DeprecatedString> const& command, Vector<DeprecatedString> const& filenames)
|
||||
{
|
||||
StringBuilder builder;
|
||||
builder.appendff("Every time any of {} changes: \x1b[1m", filenames);
|
||||
|
@ -78,11 +78,15 @@ static void handle_signal(int signal)
|
|||
exit(exit_code);
|
||||
}
|
||||
|
||||
static int run_command(Vector<char const*> const& command)
|
||||
static int run_command(Vector<DeprecatedString> const& command)
|
||||
{
|
||||
VERIFY(command[command.size() - 1] == nullptr);
|
||||
Vector<char const*> argv;
|
||||
argv.ensure_capacity(command.size() + 1);
|
||||
for (auto& arg : command)
|
||||
argv.unchecked_append(arg.characters());
|
||||
argv.unchecked_append(nullptr);
|
||||
|
||||
if ((errno = posix_spawnp(const_cast<pid_t*>(&child_pid), command[0], nullptr, nullptr, const_cast<char**>(command.data()), environ))) {
|
||||
if ((errno = posix_spawnp(const_cast<pid_t*>(&child_pid), argv[0], nullptr, nullptr, const_cast<char**>(argv.data()), environ))) {
|
||||
exit_code = 1;
|
||||
perror("posix_spawn");
|
||||
return errno;
|
||||
|
@ -113,7 +117,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
TRY(Core::System::pledge("stdio proc exec rpath"));
|
||||
|
||||
Vector<DeprecatedString> files_to_watch;
|
||||
Vector<char const*> command;
|
||||
Vector<DeprecatedString> command;
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.set_stop_on_first_non_option(true);
|
||||
args_parser.set_general_help("Execute a command repeatedly, and watch its output over time.");
|
||||
|
@ -135,8 +139,6 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
args_parser.add_positional_argument(command, "Command to run", "command");
|
||||
args_parser.parse(arguments);
|
||||
|
||||
command.append(nullptr);
|
||||
|
||||
DeprecatedString header;
|
||||
|
||||
auto watch_callback = [&] {
|
||||
|
|
Loading…
Add table
Reference in a new issue