Replace StringPiece with std::string_view in profman.

And in dexoptanalyzer and hiddenapi, see below.

The parsing helpers in utils.h were mostly unused, only
profman was calling one of them, so move that helper to
profman and rewrite and fix it, remove the other helpers.
This exposed dependency of dexoptanalyzer and hiddenapi
on StringPiece indirectly included from utils.h, thus we
replace it with std::string_view also in those tools.

During the rewrite, avoid using std::string_view::data()
as a null terminated string, prefer to fall back to the
original null terminated raw option instead.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 123750182
Change-Id: Ibeec8069a5d82ea556e03e4577812f94dca6f387
diff --git a/dexoptanalyzer/dexoptanalyzer.cc b/dexoptanalyzer/dexoptanalyzer.cc
index 92850f7..988c612 100644
--- a/dexoptanalyzer/dexoptanalyzer.cc
+++ b/dexoptanalyzer/dexoptanalyzer.cc
@@ -15,14 +15,16 @@
  */
 
 #include <string>
+#include <string_view>
 
-#include "base/logging.h"  // For InitLogging.
-#include "base/mutex.h"
-#include "base/os.h"
-#include "base/utils.h"
 #include "android-base/stringprintf.h"
 #include "android-base/strings.h"
 #include "base/file_utils.h"
+#include "base/logging.h"  // For InitLogging.
+#include "base/mutex.h"
+#include "base/os.h"
+#include "base/string_view_cpp20.h"
+#include "base/utils.h"
 #include "compiler_filter.h"
 #include "class_loader_context.h"
 #include "dex/dex_file.h"
@@ -155,56 +157,57 @@
     }
 
     for (int i = 0; i < argc; ++i) {
-      const StringPiece option(argv[i]);
+      const char* raw_option = argv[i];
+      const std::string_view option(raw_option);
       if (option == "--assume-profile-changed") {
         assume_profile_changed_ = true;
-      } else if (option.starts_with("--dex-file=")) {
-        dex_file_ = option.substr(strlen("--dex-file=")).ToString();
-      } else if (option.starts_with("--compiler-filter=")) {
-        std::string filter_str = option.substr(strlen("--compiler-filter=")).ToString();
-        if (!CompilerFilter::ParseCompilerFilter(filter_str.c_str(), &compiler_filter_)) {
-          Usage("Invalid compiler filter '%s'", option.data());
+      } else if (StartsWith(option, "--dex-file=")) {
+        dex_file_ = std::string(option.substr(strlen("--dex-file=")));
+      } else if (StartsWith(option, "--compiler-filter=")) {
+        const char* filter_str = raw_option + strlen("--compiler-filter=");
+        if (!CompilerFilter::ParseCompilerFilter(filter_str, &compiler_filter_)) {
+          Usage("Invalid compiler filter '%s'", raw_option);
         }
-      } else if (option.starts_with("--isa=")) {
-        std::string isa_str = option.substr(strlen("--isa=")).ToString();
-        isa_ = GetInstructionSetFromString(isa_str.c_str());
+      } else if (StartsWith(option, "--isa=")) {
+        const char* isa_str = raw_option + strlen("--isa=");
+        isa_ = GetInstructionSetFromString(isa_str);
         if (isa_ == InstructionSet::kNone) {
-          Usage("Invalid isa '%s'", option.data());
+          Usage("Invalid isa '%s'", raw_option);
         }
-      } else if (option.starts_with("--image=")) {
-        image_ = option.substr(strlen("--image=")).ToString();
+      } else if (StartsWith(option, "--image=")) {
+        image_ = std::string(option.substr(strlen("--image=")));
       } else if (option == "--runtime-arg") {
         if (i + 1 == argc) {
           Usage("Missing argument for --runtime-arg\n");
         }
         ++i;
         runtime_args_.push_back(argv[i]);
-      } else if (option.starts_with("--android-data=")) {
+      } else if (StartsWith(option, "--android-data=")) {
         // Overwrite android-data if needed (oat file assistant relies on a valid directory to
         // compute dalvik-cache folder). This is mostly used in tests.
-        std::string new_android_data = option.substr(strlen("--android-data=")).ToString();
-        setenv("ANDROID_DATA", new_android_data.c_str(), 1);
-      } else if (option.starts_with("--downgrade")) {
+        const char* new_android_data = raw_option + strlen("--android-data=");
+        setenv("ANDROID_DATA", new_android_data, 1);
+      } else if (option == "--downgrade") {
         downgrade_ = true;
-      } else if (option.starts_with("--oat-fd")) {
-        oat_fd_ = std::stoi(option.substr(strlen("--oat-fd=")).ToString(), nullptr, 0);
+      } else if (StartsWith(option, "--oat-fd=")) {
+        oat_fd_ = std::stoi(std::string(option.substr(strlen("--oat-fd="))), nullptr, 0);
         if (oat_fd_ < 0) {
           Usage("Invalid --oat-fd %d", oat_fd_);
         }
-      } else if (option.starts_with("--vdex-fd")) {
-        vdex_fd_ = std::stoi(option.substr(strlen("--vdex-fd=")).ToString(), nullptr, 0);
+      } else if (StartsWith(option, "--vdex-fd=")) {
+        vdex_fd_ = std::stoi(std::string(option.substr(strlen("--vdex-fd="))), nullptr, 0);
         if (vdex_fd_ < 0) {
           Usage("Invalid --vdex-fd %d", vdex_fd_);
         }
-      } else if (option.starts_with("--zip-fd")) {
-          zip_fd_ = std::stoi(option.substr(strlen("--zip-fd=")).ToString(), nullptr, 0);
-          if (zip_fd_ < 0) {
-            Usage("Invalid --zip-fd %d", zip_fd_);
-          }
-      } else if (option.starts_with("--class-loader-context=")) {
-        context_str_ = option.substr(strlen("--class-loader-context=")).ToString();
+      } else if (StartsWith(option, "--zip-fd=")) {
+        zip_fd_ = std::stoi(std::string(option.substr(strlen("--zip-fd="))), nullptr, 0);
+        if (zip_fd_ < 0) {
+          Usage("Invalid --zip-fd %d", zip_fd_);
+        }
+      } else if (StartsWith(option, "--class-loader-context=")) {
+        context_str_ = std::string(option.substr(strlen("--class-loader-context=")));
       } else {
-        Usage("Unknown argument '%s'", option.data());
+        Usage("Unknown argument '%s'", raw_option);
       }
     }
 
diff --git a/libartbase/base/utils.cc b/libartbase/base/utils.cc
index b989d9e..30423a4 100644
--- a/libartbase/base/utils.cc
+++ b/libartbase/base/utils.cc
@@ -190,45 +190,6 @@
 #endif
 }
 
-static void ParseStringAfterChar(const std::string& s,
-                                 char c,
-                                 std::string* parsed_value,
-                                 UsageFn Usage) {
-  std::string::size_type colon = s.find(c);
-  if (colon == std::string::npos) {
-    Usage("Missing char %c in option %s\n", c, s.c_str());
-  }
-  // Add one to remove the char we were trimming until.
-  *parsed_value = s.substr(colon + 1);
-}
-
-void ParseDouble(const std::string& option,
-                 char after_char,
-                 double min,
-                 double max,
-                 double* parsed_value,
-                 UsageFn Usage) {
-  std::string substring;
-  ParseStringAfterChar(option, after_char, &substring, Usage);
-  bool sane_val = true;
-  double value;
-  if ((false)) {
-    // TODO: this doesn't seem to work on the emulator.  b/15114595
-    std::stringstream iss(substring);
-    iss >> value;
-    // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range.
-    sane_val = iss.eof() && (value >= min) && (value <= max);
-  } else {
-    char* end = nullptr;
-    value = strtod(substring.c_str(), &end);
-    sane_val = *end == '\0' && value >= min && value <= max;
-  }
-  if (!sane_val) {
-    Usage("Invalid double value %s for option %s\n", substring.c_str(), option.c_str());
-  }
-  *parsed_value = value;
-}
-
 void SleepForever() {
   while (true) {
     usleep(1000000);
diff --git a/libartbase/base/utils.h b/libartbase/base/utils.h
index 11472a8..9284950 100644
--- a/libartbase/base/utils.h
+++ b/libartbase/base/utils.h
@@ -30,7 +30,6 @@
 #include "enums.h"
 #include "globals.h"
 #include "macros.h"
-#include "stringpiece.h"
 
 namespace art {
 
@@ -91,44 +90,6 @@
   return reinterpret_cast<const void*>(code);
 }
 
-using UsageFn = void (*)(const char*, ...);
-
-template <typename T>
-static void ParseIntOption(const StringPiece& option,
-                            const std::string& option_name,
-                            T* out,
-                            UsageFn usage,
-                            bool is_long_option = true) {
-  std::string option_prefix = option_name + (is_long_option ? "=" : "");
-  DCHECK(option.starts_with(option_prefix)) << option << " " << option_prefix;
-  const char* value_string = option.substr(option_prefix.size()).data();
-  int64_t parsed_integer_value = 0;
-  if (!android::base::ParseInt(value_string, &parsed_integer_value)) {
-    usage("Failed to parse %s '%s' as an integer", option_name.c_str(), value_string);
-  }
-  *out = dchecked_integral_cast<T>(parsed_integer_value);
-}
-
-template <typename T>
-static void ParseUintOption(const StringPiece& option,
-                            const std::string& option_name,
-                            T* out,
-                            UsageFn usage,
-                            bool is_long_option = true) {
-  ParseIntOption(option, option_name, out, usage, is_long_option);
-  if (*out < 0) {
-    usage("%s passed a negative value %d", option_name.c_str(), *out);
-    *out = 0;
-  }
-}
-
-void ParseDouble(const std::string& option,
-                 char after_char,
-                 double min,
-                 double max,
-                 double* parsed_value,
-                 UsageFn Usage);
-
 #if defined(__BIONIC__)
 struct Arc4RandomGenerator {
   typedef uint32_t result_type;
diff --git a/profman/profman.cc b/profman/profman.cc
index 82d9df0..b29e743 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -25,6 +25,7 @@
 #include <iostream>
 #include <set>
 #include <string>
+#include <string_view>
 #include <unordered_set>
 #include <vector>
 
@@ -36,7 +37,7 @@
 #include "base/mem_map.h"
 #include "base/scoped_flock.h"
 #include "base/stl_util.h"
-#include "base/stringpiece.h"
+#include "base/string_view_cpp20.h"
 #include "base/time_utils.h"
 #include "base/unix_file/fd_file.h"
 #include "base/utils.h"
@@ -188,6 +189,33 @@
   exit(1);
 }
 
+template <typename T>
+static void ParseUintOption(const char* raw_option,
+                            std::string_view option_prefix,
+                            T* out) {
+  DCHECK(EndsWith(option_prefix, "="));
+  DCHECK(StartsWith(raw_option, option_prefix)) << raw_option << " " << option_prefix;
+  const char* value_string = raw_option + option_prefix.size();
+  int64_t parsed_integer_value = 0;
+  if (!android::base::ParseInt(value_string, &parsed_integer_value)) {
+    std::string option_name(option_prefix.substr(option_prefix.size() - 1u));
+    Usage("Failed to parse %s '%s' as an integer", option_name.c_str(), value_string);
+  }
+  if (parsed_integer_value < 0) {
+    std::string option_name(option_prefix.substr(option_prefix.size() - 1u));
+    Usage("%s passed a negative value %" PRId64, option_name.c_str(), parsed_integer_value);
+  }
+  if (static_cast<uint64_t>(parsed_integer_value) >
+      static_cast<std::make_unsigned_t<T>>(std::numeric_limits<T>::max())) {
+    std::string option_name(option_prefix.substr(option_prefix.size() - 1u));
+    Usage("%s passed a value %" PRIu64 " above max (%" PRIu64 ")",
+          option_name.c_str(),
+          static_cast<uint64_t>(parsed_integer_value),
+          static_cast<uint64_t>(std::numeric_limits<T>::max()));
+  }
+  *out = dchecked_integral_cast<T>(parsed_integer_value);
+}
+
 // TODO(calin): This class has grown too much from its initial design. Split the functionality
 // into smaller, more contained pieces.
 class ProfMan final {
@@ -226,7 +254,8 @@
     }
 
     for (int i = 0; i < argc; ++i) {
-      const StringPiece option(argv[i]);
+      const char* raw_option = argv[i];
+      const std::string_view option(raw_option);
       const bool log_options = false;
       if (log_options) {
         LOG(INFO) << "profman: option[" << i << "]=" << argv[i];
@@ -235,66 +264,60 @@
         dump_only_ = true;
       } else if (option == "--dump-classes-and-methods") {
         dump_classes_and_methods_ = true;
-      } else if (option.starts_with("--create-profile-from=")) {
-        create_profile_from_file_ = option.substr(strlen("--create-profile-from=")).ToString();
-      } else if (option.starts_with("--dump-output-to-fd=")) {
-        ParseUintOption(option, "--dump-output-to-fd", &dump_output_to_fd_, Usage);
+      } else if (StartsWith(option, "--create-profile-from=")) {
+        create_profile_from_file_ = std::string(option.substr(strlen("--create-profile-from=")));
+      } else if (StartsWith(option, "--dump-output-to-fd=")) {
+        ParseUintOption(raw_option, "--dump-output-to-fd=", &dump_output_to_fd_);
       } else if (option == "--generate-boot-image-profile") {
         generate_boot_image_profile_ = true;
-      } else if (option.starts_with("--boot-image-class-threshold=")) {
-        ParseUintOption(option,
-                        "--boot-image-class-threshold",
-                        &boot_image_options_.image_class_theshold,
-                        Usage);
-      } else if (option.starts_with("--boot-image-clean-class-threshold=")) {
-        ParseUintOption(option,
-                        "--boot-image-clean-class-threshold",
-                        &boot_image_options_.image_class_clean_theshold,
-                        Usage);
-      } else if (option.starts_with("--boot-image-sampled-method-threshold=")) {
-        ParseUintOption(option,
-                        "--boot-image-sampled-method-threshold",
-                        &boot_image_options_.compiled_method_threshold,
-                        Usage);
-      } else if (option.starts_with("--profile-file=")) {
-        profile_files_.push_back(option.substr(strlen("--profile-file=")).ToString());
-      } else if (option.starts_with("--profile-file-fd=")) {
-        ParseFdForCollection(option, "--profile-file-fd", &profile_files_fd_);
-      } else if (option.starts_with("--reference-profile-file=")) {
-        reference_profile_file_ = option.substr(strlen("--reference-profile-file=")).ToString();
-      } else if (option.starts_with("--reference-profile-file-fd=")) {
-        ParseUintOption(option, "--reference-profile-file-fd", &reference_profile_file_fd_, Usage);
-      } else if (option.starts_with("--dex-location=")) {
-        dex_locations_.push_back(option.substr(strlen("--dex-location=")).ToString());
-      } else if (option.starts_with("--apk-fd=")) {
-        ParseFdForCollection(option, "--apk-fd", &apks_fd_);
-      } else if (option.starts_with("--apk=")) {
-        apk_files_.push_back(option.substr(strlen("--apk=")).ToString());
-      } else if (option.starts_with("--generate-test-profile=")) {
-        test_profile_ = option.substr(strlen("--generate-test-profile=")).ToString();
-      } else if (option.starts_with("--generate-test-profile-num-dex=")) {
-        ParseUintOption(option,
-                        "--generate-test-profile-num-dex",
-                        &test_profile_num_dex_,
-                        Usage);
-      } else if (option.starts_with("--generate-test-profile-method-percentage")) {
-        ParseUintOption(option,
-                        "--generate-test-profile-method-percentage",
-                        &test_profile_method_percerntage_,
-                        Usage);
-      } else if (option.starts_with("--generate-test-profile-class-percentage")) {
-        ParseUintOption(option,
-                        "--generate-test-profile-class-percentage",
-                        &test_profile_class_percentage_,
-                        Usage);
-      } else if (option.starts_with("--generate-test-profile-seed=")) {
-        ParseUintOption(option, "--generate-test-profile-seed", &test_profile_seed_, Usage);
-      } else if (option.starts_with("--copy-and-update-profile-key")) {
+      } else if (StartsWith(option, "--boot-image-class-threshold=")) {
+        ParseUintOption(raw_option,
+                        "--boot-image-class-threshold=",
+                        &boot_image_options_.image_class_theshold);
+      } else if (StartsWith(option, "--boot-image-clean-class-threshold=")) {
+        ParseUintOption(raw_option,
+                        "--boot-image-clean-class-threshold=",
+                        &boot_image_options_.image_class_clean_theshold);
+      } else if (StartsWith(option, "--boot-image-sampled-method-threshold=")) {
+        ParseUintOption(raw_option,
+                        "--boot-image-sampled-method-threshold=",
+                        &boot_image_options_.compiled_method_threshold);
+      } else if (StartsWith(option, "--profile-file=")) {
+        profile_files_.push_back(std::string(option.substr(strlen("--profile-file="))));
+      } else if (StartsWith(option, "--profile-file-fd=")) {
+        ParseFdForCollection(raw_option, "--profile-file-fd=", &profile_files_fd_);
+      } else if (StartsWith(option, "--reference-profile-file=")) {
+        reference_profile_file_ = std::string(option.substr(strlen("--reference-profile-file=")));
+      } else if (StartsWith(option, "--reference-profile-file-fd=")) {
+        ParseUintOption(raw_option, "--reference-profile-file-fd=", &reference_profile_file_fd_);
+      } else if (StartsWith(option, "--dex-location=")) {
+        dex_locations_.push_back(std::string(option.substr(strlen("--dex-location="))));
+      } else if (StartsWith(option, "--apk-fd=")) {
+        ParseFdForCollection(raw_option, "--apk-fd=", &apks_fd_);
+      } else if (StartsWith(option, "--apk=")) {
+        apk_files_.push_back(std::string(option.substr(strlen("--apk="))));
+      } else if (StartsWith(option, "--generate-test-profile=")) {
+        test_profile_ = std::string(option.substr(strlen("--generate-test-profile=")));
+      } else if (StartsWith(option, "--generate-test-profile-num-dex=")) {
+        ParseUintOption(raw_option,
+                        "--generate-test-profile-num-dex=",
+                        &test_profile_num_dex_);
+      } else if (StartsWith(option, "--generate-test-profile-method-percentage=")) {
+        ParseUintOption(raw_option,
+                        "--generate-test-profile-method-percentage=",
+                        &test_profile_method_percerntage_);
+      } else if (StartsWith(option, "--generate-test-profile-class-percentage=")) {
+        ParseUintOption(raw_option,
+                        "--generate-test-profile-class-percentage=",
+                        &test_profile_class_percentage_);
+      } else if (StartsWith(option, "--generate-test-profile-seed=")) {
+        ParseUintOption(raw_option, "--generate-test-profile-seed=", &test_profile_seed_);
+      } else if (option == "--copy-and-update-profile-key") {
         copy_and_update_profile_key_ = true;
-      } else if (option.starts_with("--store-aggregation-counters")) {
+      } else if (option == "--store-aggregation-counters") {
         store_aggregation_counters_ = true;
       } else {
-        Usage("Unknown argument '%s'", option.data());
+        Usage("Unknown argument '%s'", raw_option);
       }
     }
 
@@ -1265,11 +1288,11 @@
   }
 
  private:
-  static void ParseFdForCollection(const StringPiece& option,
-                                   const char* arg_name,
+  static void ParseFdForCollection(const char* raw_option,
+                                   std::string_view option_prefix,
                                    std::vector<int>* fds) {
     int fd;
-    ParseUintOption(option, arg_name, &fd, Usage);
+    ParseUintOption(raw_option, option_prefix, &fd);
     fds->push_back(fd);
   }
 
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index c9bdbda..91cea79 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -409,7 +409,7 @@
 
   void AssertDexFileClass(ObjPtr<mirror::ClassLoader> class_loader, const std::string& descriptor)
       REQUIRES_SHARED(Locks::mutator_lock_) {
-    ASSERT_TRUE(descriptor != nullptr);
+    ASSERT_FALSE(descriptor.empty());
     Thread* self = Thread::Current();
     StackHandleScope<1> hs(self);
     Handle<mirror::Class> klass(
diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc
index 36890a6..09171a4 100644
--- a/runtime/verifier/method_verifier_test.cc
+++ b/runtime/verifier/method_verifier_test.cc
@@ -35,7 +35,7 @@
  protected:
   void VerifyClass(const std::string& descriptor)
       REQUIRES_SHARED(Locks::mutator_lock_) {
-    ASSERT_TRUE(descriptor != nullptr);
+    ASSERT_FALSE(descriptor.empty());
     Thread* self = Thread::Current();
     ObjPtr<mirror::Class> klass = class_linker_->FindSystemClass(self, descriptor.c_str());
 
diff --git a/tools/hiddenapi/hiddenapi.cc b/tools/hiddenapi/hiddenapi.cc
index 2692f68..141dd22 100644
--- a/tools/hiddenapi/hiddenapi.cc
+++ b/tools/hiddenapi/hiddenapi.cc
@@ -18,6 +18,8 @@
 #include <iostream>
 #include <map>
 #include <set>
+#include <string>
+#include <string_view>
 
 #include "android-base/stringprintf.h"
 #include "android-base/strings.h"
@@ -27,6 +29,7 @@
 #include "base/mem_map.h"
 #include "base/os.h"
 #include "base/stl_util.h"
+#include "base/string_view_cpp20.h"
 #include "base/unix_file/fd_file.h"
 #include "dex/art_dex_file_loader.h"
 #include "dex/class_accessor-inl.h"
@@ -887,45 +890,48 @@
     argc--;
 
     if (argc > 0) {
-      const StringPiece command(argv[0]);
+      const char* raw_command = argv[0];
+      const std::string_view command(raw_command);
       if (command == "encode") {
         for (int i = 1; i < argc; ++i) {
-          const StringPiece option(argv[i]);
-          if (option.starts_with("--input-dex=")) {
-            boot_dex_paths_.push_back(option.substr(strlen("--input-dex=")).ToString());
-          } else if (option.starts_with("--output-dex=")) {
-            output_dex_paths_.push_back(option.substr(strlen("--output-dex=")).ToString());
-          } else if (option.starts_with("--api-flags=")) {
-            api_flags_path_ = option.substr(strlen("--api-flags=")).ToString();
+          const char* raw_option = argv[i];
+          const std::string_view option(raw_option);
+          if (StartsWith(option, "--input-dex=")) {
+            boot_dex_paths_.push_back(std::string(option.substr(strlen("--input-dex="))));
+          } else if (StartsWith(option, "--output-dex=")) {
+            output_dex_paths_.push_back(std::string(option.substr(strlen("--output-dex="))));
+          } else if (StartsWith(option, "--api-flags=")) {
+            api_flags_path_ = std::string(option.substr(strlen("--api-flags=")));
           } else if (option == "--no-force-assign-all") {
             force_assign_all_ = false;
           } else {
-            Usage("Unknown argument '%s'", option.data());
+            Usage("Unknown argument '%s'", raw_option);
           }
         }
         return Command::kEncode;
       } else if (command == "list") {
         for (int i = 1; i < argc; ++i) {
-          const StringPiece option(argv[i]);
-          if (option.starts_with("--boot-dex=")) {
-            boot_dex_paths_.push_back(option.substr(strlen("--boot-dex=")).ToString());
-          } else if (option.starts_with("--public-stub-classpath=")) {
+          const char* raw_option = argv[i];
+          const std::string_view option(raw_option);
+          if (StartsWith(option, "--boot-dex=")) {
+            boot_dex_paths_.push_back(std::string(option.substr(strlen("--boot-dex="))));
+          } else if (StartsWith(option, "--public-stub-classpath=")) {
             stub_classpaths_.push_back(std::make_pair(
-                option.substr(strlen("--public-stub-classpath=")).ToString(),
+                std::string(option.substr(strlen("--public-stub-classpath="))),
                 ApiList::Whitelist()));
-          } else if (option.starts_with("--core-platform-stub-classpath=")) {
+          } else if (StartsWith(option, "--core-platform-stub-classpath=")) {
             stub_classpaths_.push_back(std::make_pair(
-                option.substr(strlen("--core-platform-stub-classpath=")).ToString(),
+                std::string(option.substr(strlen("--core-platform-stub-classpath="))),
                 ApiList::CorePlatformApi()));
-          } else if (option.starts_with("--out-api-flags=")) {
-            api_flags_path_ = option.substr(strlen("--out-api-flags=")).ToString();
+          } else if (StartsWith(option, "--out-api-flags=")) {
+            api_flags_path_ = std::string(option.substr(strlen("--out-api-flags=")));
           } else {
-            Usage("Unknown argument '%s'", option.data());
+            Usage("Unknown argument '%s'", raw_option);
           }
         }
         return Command::kList;
       } else {
-        Usage("Unknown command '%s'", command.data());
+        Usage("Unknown command '%s'", raw_command);
       }
     } else {
       Usage("No command specified");