浏览代码

LibCore+Userland: Remove ArgsParser::add*(Vector<char const*>&)

This finally makes ArgsParser's value API free of silly char*'s!
Ali Mohammad Pur 2 年之前
父节点
当前提交
23c514cda3

+ 0 - 16
Userland/Libraries/LibCore/ArgsParser.cpp

@@ -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 {

+ 0 - 1
Userland/Libraries/LibCore/ArgsParser.h

@@ -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);
 

+ 9 - 8
Userland/Utilities/seq.cpp

@@ -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");

+ 12 - 14
Userland/Utilities/syscall.cpp

@@ -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;
 }

+ 10 - 8
Userland/Utilities/watch.cpp

@@ -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 = [&] {