瀏覽代碼

AK+Everywhere: Turn bool keep_empty to an enum in split* functions

demostanis 2 年之前
父節點
當前提交
3e8b5ac920
共有 44 個文件被更改,包括 96 次插入81 次删除
  1. 1 1
      AK/IPv6Address.h
  2. 8 6
      AK/String.cpp
  3. 4 4
      AK/String.h
  4. 10 0
      AK/StringUtils.h
  5. 7 6
      AK/StringView.cpp
  6. 8 6
      AK/StringView.h
  7. 1 1
      Kernel/CommandLine.cpp
  8. 1 1
      Kernel/GlobalProcessExposed.cpp
  9. 1 1
      Kernel/Storage/StorageManagement.cpp
  10. 1 1
      Kernel/Syscalls/pledge.cpp
  11. 1 1
      Meta/Lagom/Tools/CodeGenerators/LibEDID/GeneratePnpIDs.cpp
  12. 3 3
      Meta/Lagom/Tools/CodeGenerators/LibLocale/GeneratePluralRulesData.cpp
  13. 1 1
      Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp
  14. 1 1
      Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp
  15. 9 9
      Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeData.cpp
  16. 1 1
      Meta/Lagom/Tools/ConfigureComponents/main.cpp
  17. 3 3
      Tests/AK/TestString.cpp
  18. 7 7
      Tests/AK/TestStringView.cpp
  19. 1 1
      Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp
  20. 1 1
      Userland/DevTools/UserspaceEmulator/Emulator.cpp
  21. 1 1
      Userland/Libraries/LibC/getopt.cpp
  22. 1 1
      Userland/Libraries/LibC/grp.cpp
  23. 1 1
      Userland/Libraries/LibC/pwd.cpp
  24. 1 1
      Userland/Libraries/LibC/shadow.cpp
  25. 1 1
      Userland/Libraries/LibCodeComprehension/Shell/ShellComprehensionEngine.cpp
  26. 1 1
      Userland/Libraries/LibCore/ArgsParser.cpp
  27. 1 1
      Userland/Libraries/LibDiff/Format.cpp
  28. 1 1
      Userland/Libraries/LibGUI/EmojiInputDialog.cpp
  29. 1 1
      Userland/Libraries/LibHTTP/HttpRequest.cpp
  30. 1 1
      Userland/Libraries/LibHTTP/Job.cpp
  31. 1 1
      Userland/Libraries/LibJS/Parser.h
  32. 1 1
      Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp
  33. 3 3
      Userland/Libraries/LibMarkdown/Table.cpp
  34. 1 1
      Userland/Libraries/LibTest/JavaScriptTestRunner.h
  35. 1 1
      Userland/Services/LookupServer/LookupServer.cpp
  36. 1 1
      Userland/Services/WebDriver/Client.cpp
  37. 1 1
      Userland/Shell/AST.cpp
  38. 1 1
      Userland/Shell/Builtin.cpp
  39. 1 1
      Userland/Shell/ImmediateFunctions.cpp
  40. 1 1
      Userland/Utilities/chown.cpp
  41. 1 1
      Userland/Utilities/cp.cpp
  42. 1 1
      Userland/Utilities/dd.cpp
  43. 1 1
      Userland/Utilities/readelf.cpp
  44. 1 1
      Userland/Utilities/xargs.cpp

+ 1 - 1
AK/IPv6Address.h

@@ -125,7 +125,7 @@ public:
         if (string.is_null())
             return {};
 
-        auto const parts = string.split_view(':', true);
+        auto const parts = string.split_view(':', SplitBehavior::KeepEmpty);
         if (parts.is_empty())
             return {};
         if (parts.size() > 9) {

+ 8 - 6
AK/String.cpp

@@ -97,18 +97,19 @@ StringView String::substring_view(size_t start) const
     return { characters() + start, length() - start };
 }
 
-Vector<String> String::split(char separator, bool keep_empty) const
+Vector<String> String::split(char separator, SplitBehavior split_behavior) const
 {
-    return split_limit(separator, 0, keep_empty);
+    return split_limit(separator, 0, split_behavior);
 }
 
-Vector<String> String::split_limit(char separator, size_t limit, bool keep_empty) const
+Vector<String> String::split_limit(char separator, size_t limit, SplitBehavior split_behavior) const
 {
     if (is_empty())
         return {};
 
     Vector<String> v;
     size_t substart = 0;
+    bool keep_empty = has_flag(split_behavior, SplitBehavior::KeepEmpty);
     for (size_t i = 0; i < length() && (v.size() + 1) != limit; ++i) {
         char ch = characters()[i];
         if (ch == separator) {
@@ -124,13 +125,14 @@ Vector<String> String::split_limit(char separator, size_t limit, bool keep_empty
     return v;
 }
 
-Vector<StringView> String::split_view(Function<bool(char)> separator, bool keep_empty) const
+Vector<StringView> String::split_view(Function<bool(char)> separator, SplitBehavior split_behavior) const
 {
     if (is_empty())
         return {};
 
     Vector<StringView> v;
     size_t substart = 0;
+    bool keep_empty = has_flag(split_behavior, SplitBehavior::KeepEmpty);
     for (size_t i = 0; i < length(); ++i) {
         char ch = characters()[i];
         if (separator(ch)) {
@@ -146,9 +148,9 @@ Vector<StringView> String::split_view(Function<bool(char)> separator, bool keep_
     return v;
 }
 
-Vector<StringView> String::split_view(char const separator, bool keep_empty) const
+Vector<StringView> String::split_view(char const separator, SplitBehavior split_behavior) const
 {
-    return split_view([separator](char ch) { return ch == separator; }, keep_empty);
+    return split_view([separator](char ch) { return ch == separator; }, split_behavior);
 }
 
 ByteBuffer String::to_byte_buffer() const

+ 4 - 4
AK/String.h

@@ -150,10 +150,10 @@ public:
     [[nodiscard]] bool contains(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const;
     [[nodiscard]] bool contains(char, CaseSensitivity = CaseSensitivity::CaseSensitive) const;
 
-    [[nodiscard]] Vector<String> split_limit(char separator, size_t limit, bool keep_empty = false) const;
-    [[nodiscard]] Vector<String> split(char separator, bool keep_empty = false) const;
-    [[nodiscard]] Vector<StringView> split_view(char separator, bool keep_empty = false) const;
-    [[nodiscard]] Vector<StringView> split_view(Function<bool(char)> separator, bool keep_empty = false) const;
+    [[nodiscard]] Vector<String> split_limit(char separator, size_t limit, SplitBehavior = SplitBehavior::Nothing) const;
+    [[nodiscard]] Vector<String> split(char separator, SplitBehavior = SplitBehavior::Nothing) const;
+    [[nodiscard]] Vector<StringView> split_view(char separator, SplitBehavior = SplitBehavior::Nothing) const;
+    [[nodiscard]] Vector<StringView> split_view(Function<bool(char)> separator, SplitBehavior = SplitBehavior::Nothing) const;
 
     [[nodiscard]] Optional<size_t> find(char needle, size_t start = 0) const { return StringUtils::find(*this, needle, start); }
     [[nodiscard]] Optional<size_t> find(StringView needle, size_t start = 0) const { return StringUtils::find(*this, needle, start); }

+ 10 - 0
AK/StringUtils.h

@@ -8,6 +8,7 @@
 #pragma once
 
 #include <AK/Concepts.h>
+#include <AK/EnumBits.h>
 #include <AK/Forward.h>
 
 namespace AK {
@@ -38,6 +39,14 @@ enum class TrimWhitespace {
     No,
 };
 
+enum class SplitBehavior : unsigned {
+    Nothing = 0,
+    // If two separators follow each other without any characters
+    // in between, keep a "" in the resulting vector.
+    KeepEmpty = 1,
+};
+AK_ENUM_BITWISE_OPERATORS(SplitBehavior);
+
 struct MaskSpan {
     size_t start;
     size_t length;
@@ -99,5 +108,6 @@ size_t count(StringView, StringView needle);
 
 using AK::CaseSensitivity;
 using AK::ReplaceMode;
+using AK::SplitBehavior;
 using AK::TrimMode;
 using AK::TrimWhitespace;

+ 7 - 6
AK/StringView.cpp

@@ -40,16 +40,16 @@ StringView::StringView(ByteBuffer const& buffer)
 {
 }
 
-Vector<StringView> StringView::split_view(char const separator, bool keep_empty) const
+Vector<StringView> StringView::split_view(char const separator, SplitBehavior split_behavior) const
 {
     StringView seperator_view { &separator, 1 };
-    return split_view(seperator_view, keep_empty);
+    return split_view(seperator_view, split_behavior);
 }
 
-Vector<StringView> StringView::split_view(StringView separator, bool keep_empty) const
+Vector<StringView> StringView::split_view(StringView separator, SplitBehavior split_behavior) const
 {
     Vector<StringView> parts;
-    for_each_split_view(separator, keep_empty, [&](StringView view) {
+    for_each_split_view(separator, split_behavior, [&](StringView view) {
         parts.append(view);
     });
     return parts;
@@ -61,7 +61,7 @@ Vector<StringView> StringView::lines(bool consider_cr) const
         return {};
 
     if (!consider_cr)
-        return split_view('\n', true);
+        return split_view('\n', SplitBehavior::KeepEmpty);
 
     Vector<StringView> v;
     size_t substart = 0;
@@ -264,13 +264,14 @@ Vector<size_t> StringView::find_all(StringView needle) const
     return StringUtils::find_all(*this, needle);
 }
 
-Vector<StringView> StringView::split_view_if(Function<bool(char)> const& predicate, bool keep_empty) const
+Vector<StringView> StringView::split_view_if(Function<bool(char)> const& predicate, SplitBehavior split_behavior) const
 {
     if (is_empty())
         return {};
 
     Vector<StringView> v;
     size_t substart = 0;
+    bool keep_empty = has_flag(split_behavior, SplitBehavior::KeepEmpty);
     for (size_t i = 0; i < length(); ++i) {
         char ch = characters_without_null_termination()[i];
         if (predicate(ch)) {

+ 8 - 6
AK/StringView.h

@@ -8,6 +8,7 @@
 
 #include <AK/Assertions.h>
 #include <AK/Checked.h>
+#include <AK/EnumBits.h>
 #include <AK/Forward.h>
 #include <AK/Optional.h>
 #include <AK/Span.h>
@@ -129,10 +130,10 @@ public:
         return substring_view(start, length() - start);
     }
 
-    [[nodiscard]] Vector<StringView> split_view(char, bool keep_empty = false) const;
-    [[nodiscard]] Vector<StringView> split_view(StringView, bool keep_empty = false) const;
+    [[nodiscard]] Vector<StringView> split_view(char, SplitBehavior = SplitBehavior::Nothing) const;
+    [[nodiscard]] Vector<StringView> split_view(StringView, SplitBehavior = SplitBehavior::Nothing) const;
 
-    [[nodiscard]] Vector<StringView> split_view_if(Function<bool(char)> const& predicate, bool keep_empty = false) const;
+    [[nodiscard]] Vector<StringView> split_view_if(Function<bool(char)> const& predicate, SplitBehavior = SplitBehavior::Nothing) const;
 
     [[nodiscard]] StringView find_last_split_view(char separator) const
     {
@@ -151,14 +152,14 @@ public:
     }
 
     template<VoidFunction<StringView> Callback>
-    void for_each_split_view(char separator, bool keep_empty, Callback callback) const
+    void for_each_split_view(char separator, SplitBehavior split_behavior, Callback callback) const
     {
         StringView seperator_view { &separator, 1 };
-        for_each_split_view(seperator_view, keep_empty, callback);
+        for_each_split_view(seperator_view, split_behavior, callback);
     }
 
     template<VoidFunction<StringView> Callback>
-    void for_each_split_view(StringView separator, bool keep_empty, Callback callback) const
+    void for_each_split_view(StringView separator, SplitBehavior split_behavior, Callback callback) const
     {
         VERIFY(!separator.is_empty());
 
@@ -168,6 +169,7 @@ public:
         StringView view { *this };
 
         auto maybe_separator_index = find(separator);
+        bool keep_empty = has_flag(split_behavior, SplitBehavior::KeepEmpty);
         while (maybe_separator_index.has_value()) {
             auto separator_index = maybe_separator_index.value();
             auto part_with_separator = view.substring_view(0, separator_index + separator.length());

+ 1 - 1
Kernel/CommandLine.cpp

@@ -65,7 +65,7 @@ UNMAP_AFTER_INIT void CommandLine::add_arguments(Vector<StringView> const& args)
             continue;
         }
 
-        auto pair = str.split_view('=', false);
+        auto pair = str.split_view('=');
         VERIFY(pair.size() == 2 || pair.size() == 1);
 
         if (pair.size() == 1) {

+ 1 - 1
Kernel/GlobalProcessExposed.cpp

@@ -642,7 +642,7 @@ private:
                     TRY(obj.add("hypervisor_vendor_id"sv, info.hypervisor_vendor_id_string()));
 
                 auto features_array = TRY(obj.add_array("features"sv));
-                auto keep_empty = false;
+                auto keep_empty = SplitBehavior::KeepEmpty;
 
                 ErrorOr<void> result; // FIXME: Make this nicer
                 info.features_string().for_each_split_view(' ', keep_empty, [&](StringView feature) {

+ 1 - 1
Kernel/Storage/StorageManagement.cpp

@@ -213,7 +213,7 @@ UNMAP_AFTER_INIT Array<unsigned, 3> StorageManagement::extract_boot_device_addre
     auto parameters_view = m_boot_argument.substring_view(device_prefix.length()).find_first_split_view(';');
     size_t parts_count = 0;
     bool parse_failure = false;
-    parameters_view.for_each_split_view(':', false, [&](StringView parameter_view) {
+    parameters_view.for_each_split_view(':', SplitBehavior::Nothing, [&](StringView parameter_view) {
         if (parse_failure)
             return;
         if (parts_count > 2)

+ 1 - 1
Kernel/Syscalls/pledge.cpp

@@ -29,7 +29,7 @@ ErrorOr<FlatPtr> Process::sys$pledge(Userspace<Syscall::SC_pledge_params const*>
 
     auto parse_pledge = [&](auto pledge_spec, u32& mask) {
         auto found_invalid_pledge = true;
-        pledge_spec.for_each_split_view(' ', false, [&mask, &found_invalid_pledge](auto const& part) {
+        pledge_spec.for_each_split_view(' ', SplitBehavior::Nothing, [&mask, &found_invalid_pledge](auto const& part) {
 #define __ENUMERATE_PLEDGE_PROMISE(x)   \
     if (part == #x##sv) {               \
         mask |= (1u << (u32)Pledge::x); \

+ 1 - 1
Meta/Lagom/Tools/CodeGenerators/LibEDID/GeneratePnpIDs.cpp

@@ -91,7 +91,7 @@ static ErrorOr<String> decode_html_entities(StringView const& str)
 
 static ErrorOr<ApprovalDate> parse_approval_date(StringView const& str)
 {
-    auto parts = str.trim_whitespace().split_view('/', true);
+    auto parts = str.trim_whitespace().split_view('/', SplitBehavior::KeepEmpty);
     if (parts.size() != 3)
         return Error::from_string_literal("Failed to parse approval date parts (mm/dd/yyyy)");
 

+ 3 - 3
Meta/Lagom/Tools/CodeGenerators/LibLocale/GeneratePluralRulesData.cpp

@@ -258,7 +258,7 @@ static Relation parse_relation(StringView relation)
         parsed.symbol = lhs[0];
     }
 
-    rhs.for_each_split_view(set_operator, false, [&](auto set) {
+    rhs.for_each_split_view(set_operator, SplitBehavior::Nothing, [&](auto set) {
         if (auto index = set.find(range_operator); index.has_value()) {
             auto range_begin = set.substring_view(0, *index).to_uint();
             VERIFY(range_begin.has_value());
@@ -313,10 +313,10 @@ static void parse_condition(StringView category, StringView rule, Conditions& ru
     //     and_condition = relation ('and' relation)*
     //
     // This affords some simplicity in that disjunctions are never embedded within a conjunction.
-    condition.for_each_split_view(disjunction_keyword, false, [&](auto disjunction) {
+    condition.for_each_split_view(disjunction_keyword, SplitBehavior::Nothing, [&](auto disjunction) {
         Vector<Relation> conjunctions;
 
-        disjunction.for_each_split_view(conjunction_keyword, false, [&](auto relation) {
+        disjunction.for_each_split_view(conjunction_keyword, SplitBehavior::Nothing, [&](auto relation) {
             conjunctions.append(parse_relation(relation));
         });
 

+ 1 - 1
Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp

@@ -400,7 +400,7 @@ static ErrorOr<void> parse_time_zone_coordinates(Core::Stream::BufferedFile& fil
 
         time_zone_data.time_zone_coordinates.set(zone, { latitude, longitude });
 
-        regions.for_each_split_view(',', false, [&](auto region) {
+        regions.for_each_split_view(',', SplitBehavior::Nothing, [&](auto region) {
             auto index = time_zone_data.unique_strings.ensure(zone);
             time_zone_data.time_zone_regions.ensure(region).append(index);
 

+ 1 - 1
Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp

@@ -112,7 +112,7 @@ static ErrorOr<void> parse_emoji_serenity_data(Core::Stream::BufferedFile& file,
         emoji.group = Unicode::EmojiGroup::SerenityOS;
         emoji.display_order = display_order++;
 
-        line.for_each_split_view(' ', false, [&](auto segment) {
+        line.for_each_split_view(' ', SplitBehavior::Nothing, [&](auto segment) {
             if (segment.starts_with(code_point_header)) {
                 segment = segment.substring_view(code_point_header.length());
 

+ 9 - 9
Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeData.cpp

@@ -223,7 +223,7 @@ static ErrorOr<void> parse_special_casing(Core::Stream::BufferedFile& file, Unic
         if (auto index = line.find('#'); index.has_value())
             line = line.substring_view(0, *index);
 
-        auto segments = line.split_view(';', true);
+        auto segments = line.split_view(';', SplitBehavior::KeepEmpty);
         VERIFY(segments.size() == 5 || segments.size() == 6);
 
         SpecialCasing casing {};
@@ -233,7 +233,7 @@ static ErrorOr<void> parse_special_casing(Core::Stream::BufferedFile& file, Unic
         casing.uppercase_mapping = parse_code_point_list(segments[3]);
 
         if (auto condition = segments[4].trim_whitespace(); !condition.is_empty()) {
-            auto conditions = condition.split_view(' ', true);
+            auto conditions = condition.split_view(' ', SplitBehavior::KeepEmpty);
             VERIFY(conditions.size() == 1 || conditions.size() == 2);
 
             if (conditions.size() == 2) {
@@ -294,7 +294,7 @@ static ErrorOr<void> parse_prop_list(Core::Stream::BufferedFile& file, PropList&
         if (auto index = line.find('#'); index.has_value())
             line = line.substring_view(0, *index);
 
-        auto segments = line.split_view(';', true);
+        auto segments = line.split_view(';', SplitBehavior::KeepEmpty);
         VERIFY(segments.size() == 2);
 
         auto code_point_range = parse_code_point_range(segments[0].trim_whitespace());
@@ -344,7 +344,7 @@ static ErrorOr<void> parse_alias_list(Core::Stream::BufferedFile& file, PropList
         if (current_property != "Binary Properties"sv)
             continue;
 
-        auto segments = line.split_view(';', true);
+        auto segments = line.split_view(';', SplitBehavior::KeepEmpty);
         VERIFY((segments.size() == 2) || (segments.size() == 3));
 
         auto alias = segments[0].trim_whitespace();
@@ -370,7 +370,7 @@ static ErrorOr<void> parse_name_aliases(Core::Stream::BufferedFile& file, Unicod
         if (line.is_empty() || line.starts_with('#'))
             continue;
 
-        auto segments = line.split_view(';', true);
+        auto segments = line.split_view(';', SplitBehavior::KeepEmpty);
         VERIFY(segments.size() == 3);
 
         auto code_point = AK::StringUtils::convert_to_uint_from_hex<u32>(segments[0].trim_whitespace());
@@ -417,7 +417,7 @@ static ErrorOr<void> parse_value_alias_list(Core::Stream::BufferedFile& file, St
         if (auto index = line.find('#'); index.has_value())
             line = line.substring_view(0, *index);
 
-        auto segments = line.split_view(';', true);
+        auto segments = line.split_view(';', SplitBehavior::KeepEmpty);
         auto category = segments[0].trim_whitespace();
 
         if (category != desired_category)
@@ -450,7 +450,7 @@ static ErrorOr<void> parse_normalization_props(Core::Stream::BufferedFile& file,
         if (auto index = line.find('#'); index.has_value())
             line = line.substring_view(0, *index);
 
-        auto segments = line.split_view(';', true);
+        auto segments = line.split_view(';', SplitBehavior::KeepEmpty);
         VERIFY((segments.size() == 2) || (segments.size() == 3));
 
         auto code_point_range = parse_code_point_range(segments[0].trim_whitespace());
@@ -579,7 +579,7 @@ static ErrorOr<void> parse_block_display_names(Core::Stream::BufferedFile& file,
         if (line.is_empty() || line.starts_with('#'))
             continue;
 
-        auto segments = line.split_view(';', true);
+        auto segments = line.split_view(';', SplitBehavior::KeepEmpty);
         VERIFY(segments.size() == 2);
 
         auto code_point_range = parse_code_point_range(segments[0].trim_whitespace());
@@ -610,7 +610,7 @@ static ErrorOr<void> parse_unicode_data(Core::Stream::BufferedFile& file, Unicod
         if (line.is_empty())
             continue;
 
-        auto segments = line.split_view(';', true);
+        auto segments = line.split_view(';', SplitBehavior::KeepEmpty);
         VERIFY(segments.size() == 15);
 
         CodePointData data {};

+ 1 - 1
Meta/Lagom/Tools/ConfigureComponents/main.cpp

@@ -195,7 +195,7 @@ static Result<Vector<String>, int> run_whiptail(WhiptailMode mode, Vector<Whipta
     auto file = Core::File::construct();
     file->open(read_fd, Core::OpenMode::ReadOnly, Core::File::ShouldCloseFileDescriptor::Yes);
     auto data = String::copy(file->read_all());
-    return data.split('\n', false);
+    return data.split('\n');
 }
 
 static bool run_system_command(String const& command, StringView command_name)

+ 3 - 3
Tests/AK/TestString.cpp

@@ -233,7 +233,7 @@ TEST_CASE(split)
     EXPECT_EQ(parts[0], "a");
     EXPECT_EQ(parts[1], "b");
 
-    parts = test.split(' ', true);
+    parts = test.split(' ', SplitBehavior::KeepEmpty);
     EXPECT_EQ(parts.size(), 5u);
     EXPECT_EQ(parts[0], "a");
     EXPECT_EQ(parts[1], "");
@@ -243,9 +243,9 @@ TEST_CASE(split)
 
     test = "axxbx";
     EXPECT_EQ(test.split('x').size(), 2u);
-    EXPECT_EQ(test.split('x', true).size(), 4u);
+    EXPECT_EQ(test.split('x', SplitBehavior::KeepEmpty).size(), 4u);
     EXPECT_EQ(test.split_view('x').size(), 2u);
-    EXPECT_EQ(test.split_view('x', true).size(), 4u);
+    EXPECT_EQ(test.split_view('x', SplitBehavior::KeepEmpty).size(), 4u);
 }
 
 TEST_CASE(builder_zero_initial_capacity)

+ 7 - 7
Tests/AK/TestStringView.cpp

@@ -143,26 +143,26 @@ TEST_CASE(split_view)
 {
     StringView test_string_view = "axxbxcxd"sv;
     EXPECT_EQ(test_string_view.split_view('x'), Vector({ "a"sv, "b"sv, "c"sv, "d"sv }));
-    EXPECT_EQ(test_string_view.split_view('x', true), Vector({ "a"sv, ""sv, "b"sv, "c"sv, "d"sv }));
+    EXPECT_EQ(test_string_view.split_view('x', SplitBehavior::KeepEmpty), Vector({ "a"sv, ""sv, "b"sv, "c"sv, "d"sv }));
     EXPECT_EQ(test_string_view.split_view("x"sv), Vector({ "a"sv, "b"sv, "c"sv, "d"sv }));
-    EXPECT_EQ(test_string_view.split_view("x"sv, true), Vector({ "a"sv, ""sv, "b"sv, "c"sv, "d"sv }));
+    EXPECT_EQ(test_string_view.split_view("x"sv, SplitBehavior::KeepEmpty), Vector({ "a"sv, ""sv, "b"sv, "c"sv, "d"sv }));
 
     test_string_view = "axxbx"sv;
     EXPECT_EQ(test_string_view.split_view('x'), Vector({ "a"sv, "b"sv }));
-    EXPECT_EQ(test_string_view.split_view('x', true), Vector({ "a"sv, ""sv, "b"sv, ""sv }));
+    EXPECT_EQ(test_string_view.split_view('x', SplitBehavior::KeepEmpty), Vector({ "a"sv, ""sv, "b"sv, ""sv }));
     EXPECT_EQ(test_string_view.split_view("x"sv), Vector({ "a"sv, "b"sv }));
-    EXPECT_EQ(test_string_view.split_view("x"sv, true), Vector({ "a"sv, ""sv, "b"sv, ""sv }));
+    EXPECT_EQ(test_string_view.split_view("x"sv, SplitBehavior::KeepEmpty), Vector({ "a"sv, ""sv, "b"sv, ""sv }));
 
     test_string_view = "axxbcxxdxx"sv;
     EXPECT_EQ(test_string_view.split_view("xx"sv), Vector({ "a"sv, "bc"sv, "d"sv }));
-    EXPECT_EQ(test_string_view.split_view("xx"sv, true), Vector({ "a"sv, "bc"sv, "d"sv, ""sv }));
+    EXPECT_EQ(test_string_view.split_view("xx"sv, SplitBehavior::KeepEmpty), Vector({ "a"sv, "bc"sv, "d"sv, ""sv }));
 
     test_string_view = "ax_b_cxd"sv;
     Function<bool(char)> predicate = [](char ch) { return ch == 'x' || ch == '_'; };
     EXPECT_EQ(test_string_view.split_view_if(predicate), Vector({ "a"sv, "b"sv, "c"sv, "d"sv }));
-    EXPECT_EQ(test_string_view.split_view_if(predicate, true), Vector({ "a"sv, ""sv, "b"sv, "c"sv, "d"sv }));
+    EXPECT_EQ(test_string_view.split_view_if(predicate, SplitBehavior::KeepEmpty), Vector({ "a"sv, ""sv, "b"sv, "c"sv, "d"sv }));
     EXPECT_EQ(test_string_view.split_view_if(predicate), Vector({ "a"sv, "b"sv, "c"sv, "d"sv }));
-    EXPECT_EQ(test_string_view.split_view_if(predicate, true), Vector({ "a"sv, ""sv, "b"sv, "c"sv, "d"sv }));
+    EXPECT_EQ(test_string_view.split_view_if(predicate, SplitBehavior::KeepEmpty), Vector({ "a"sv, ""sv, "b"sv, "c"sv, "d"sv }));
 }
 
 TEST_CASE(constexpr_stuff)

+ 1 - 1
Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp

@@ -87,7 +87,7 @@ RefPtr<Mesh> WavefrontOBJLoader::load(Core::File& file)
             auto normal_indices = FixedArray<GLuint>::must_create_but_fixme_should_propagate_errors(number_of_vertices);
 
             for (size_t i = 0; i < number_of_vertices; ++i) {
-                auto vertex_parts = face_line.at(i).split_view('/', true);
+                auto vertex_parts = face_line.at(i).split_view('/', SplitBehavior::KeepEmpty);
                 vertex_indices[i] = get_index_value(vertex_parts[0]);
                 tex_coord_indices[i] = (vertex_parts.size() >= 2) ? get_index_value(vertex_parts[1]) : 0;
                 normal_indices[i] = (vertex_parts.size() >= 3) ? get_index_value(vertex_parts[2]) : 0;

+ 1 - 1
Userland/DevTools/UserspaceEmulator/Emulator.cpp

@@ -343,7 +343,7 @@ void Emulator::handle_repl()
         line = m_editor->history().last().entry;
     }
 
-    auto parts = line.split_view(' ', false);
+    auto parts = line.split_view(' ');
     m_editor->add_to_history(line);
 
     if (parts[0].is_one_of("s"sv, "step"sv)) {

+ 1 - 1
Userland/Libraries/LibC/getopt.cpp

@@ -138,7 +138,7 @@ int OptionParser::getopt()
 
 bool OptionParser::lookup_short_option(char option, int& needs_value) const
 {
-    Vector<StringView> parts = m_short_options.split_view(option, true);
+    Vector<StringView> parts = m_short_options.split_view(option, SplitBehavior::KeepEmpty);
 
     VERIFY(parts.size() <= 2);
     if (parts.size() < 2) {

+ 1 - 1
Userland/Libraries/LibC/grp.cpp

@@ -73,7 +73,7 @@ struct group* getgrnam(char const* name)
 
 static bool parse_grpdb_entry(String const& line)
 {
-    auto parts = line.split_view(':', true);
+    auto parts = line.split_view(':', SplitBehavior::KeepEmpty);
     if (parts.size() != 4) {
         warnln("getgrent(): Malformed entry on line {}: '{}' has {} parts", s_line_number, line, parts.size());
         return false;

+ 1 - 1
Userland/Libraries/LibC/pwd.cpp

@@ -73,7 +73,7 @@ struct passwd* getpwnam(char const* name)
 
 static bool parse_pwddb_entry(String const& line)
 {
-    auto parts = line.split_view(':', true);
+    auto parts = line.split_view(':', SplitBehavior::KeepEmpty);
     if (parts.size() != 7) {
         dbgln("getpwent(): Malformed entry on line {}", s_line_number);
         return false;

+ 1 - 1
Userland/Libraries/LibC/shadow.cpp

@@ -64,7 +64,7 @@ struct spwd* getspnam(char const* name)
 
 static bool parse_shadow_entry(String const& line)
 {
-    auto parts = line.split_view(':', true);
+    auto parts = line.split_view(':', SplitBehavior::KeepEmpty);
     if (parts.size() != 9) {
         dbgln("getspent(): Malformed entry on line {}", s_line_number);
         return false;

+ 1 - 1
Userland/Libraries/LibCodeComprehension/Shell/ShellComprehensionEngine.cpp

@@ -117,7 +117,7 @@ size_t ShellComprehensionEngine::resolve(ShellComprehensionEngine::DocumentData
     if (position.line() > 0) {
         auto first = true;
         size_t line = 0;
-        for (auto& line_view : document.text.split_limit('\n', position.line() + 1, true)) {
+        for (auto& line_view : document.text.split_limit('\n', position.line() + 1, SplitBehavior::KeepEmpty)) {
             if (line == position.line())
                 break;
             if (first)

+ 1 - 1
Userland/Libraries/LibCore/ArgsParser.cpp

@@ -554,7 +554,7 @@ void ArgsParser::add_option(Vector<size_t>& values, char const* help_string, cha
         [&values, separator](char const* s) {
             bool parsed_all_values = true;
 
-            StringView { s, strlen(s) }.for_each_split_view(separator, false, [&](auto value) {
+            StringView { s, strlen(s) }.for_each_split_view(separator, SplitBehavior::Nothing, [&](auto value) {
                 if (auto maybe_value = AK::StringUtils::convert_to_uint<size_t>(value); maybe_value.has_value())
                     values.append(*maybe_value);
                 else

+ 1 - 1
Userland/Libraries/LibDiff/Format.cpp

@@ -12,7 +12,7 @@
 namespace Diff {
 String generate_only_additions(String const& text)
 {
-    auto lines = text.split('\n', true); // Keep empty
+    auto lines = text.split('\n', SplitBehavior::KeepEmpty);
     StringBuilder builder;
     builder.appendff("@@ -0,0 +1,{} @@\n", lines.size());
     for (auto const& line : lines) {

+ 1 - 1
Userland/Libraries/LibGUI/EmojiInputDialog.cpp

@@ -179,7 +179,7 @@ auto EmojiInputDialog::supported_emoji() -> Vector<Emoji>
         StringBuilder builder;
         Vector<u32> code_points;
 
-        basename.for_each_split_view('_', false, [&](auto segment) {
+        basename.for_each_split_view('_', SplitBehavior::Nothing, [&](auto segment) {
             auto code_point = AK::StringUtils::convert_to_uint_from_hex<u32>(segment.substring_view(2));
             VERIFY(code_point.has_value());
 

+ 1 - 1
Userland/Libraries/LibHTTP/HttpRequest.cpp

@@ -211,7 +211,7 @@ Optional<HttpRequest> HttpRequest::from_raw_request(ReadonlyBytes raw_request)
         return {};
 
     request.m_headers = move(headers);
-    auto url_parts = resource.split_limit('?', 2, true);
+    auto url_parts = resource.split_limit('?', 2, SplitBehavior::KeepEmpty);
 
     request.m_url.set_cannot_be_a_base_url(true);
     if (url_parts.size() == 2) {

+ 1 - 1
Userland/Libraries/LibHTTP/Job.cpp

@@ -453,7 +453,7 @@ void Job::on_socket_connected()
                         finish_up();
                         break;
                     } else {
-                        auto chunk = size_lines[0].split_view(';', true);
+                        auto chunk = size_lines[0].split_view(';', SplitBehavior::KeepEmpty);
                         String size_string = chunk[0];
                         char* endptr;
                         auto size = strtoul(size_string.characters(), &endptr, 16);

+ 1 - 1
Userland/Libraries/LibJS/Parser.h

@@ -192,7 +192,7 @@ public:
             // line terminators to \n is easier than splitting using all different LT characters.
             String source_string = source.replace("\r\n"sv, "\n"sv, ReplaceMode::All).replace("\r"sv, "\n"sv, ReplaceMode::All).replace(LINE_SEPARATOR_STRING, "\n"sv, ReplaceMode::All).replace(PARAGRAPH_SEPARATOR_STRING, "\n"sv, ReplaceMode::All);
             StringBuilder builder;
-            builder.append(source_string.split_view('\n', true)[position.value().line - 1]);
+            builder.append(source_string.split_view('\n', SplitBehavior::KeepEmpty)[position.value().line - 1]);
             builder.append('\n');
             for (size_t i = 0; i < position.value().column - 1; ++i)
                 builder.append(spacer);

+ 1 - 1
Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp

@@ -965,7 +965,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
 
     // 19. Repeat, while q < size,
     while (next_search_from < string.length_in_code_units()) {
-        // a. Perform ? Set(splitter, "lastIndex", 𝔽(q), true).
+        // a. Perform ? Set(splitter, "lastIndex", 𝔽(q), SplitBehavior::KeepEmpty).
         TRY(splitter->set(vm.names.lastIndex, Value(next_search_from), Object::ShouldThrowExceptions::Yes));
 
         // b. Let z be ? RegExpExec(splitter, S).

+ 3 - 3
Userland/Libraries/LibMarkdown/Table.cpp

@@ -138,8 +138,8 @@ OwnPtr<Table> Table::parse(LineIterator& lines)
     if (peek_it.is_end())
         return {};
 
-    auto header_segments = first_line.split_view('|', true);
-    auto header_delimiters = peek_it->split_view('|', true);
+    auto header_segments = first_line.split_view('|', SplitBehavior::KeepEmpty);
+    auto header_delimiters = peek_it->split_view('|', SplitBehavior::KeepEmpty);
 
     if (!header_segments.is_empty())
         header_segments.take_first();
@@ -214,7 +214,7 @@ OwnPtr<Table> Table::parse(LineIterator& lines)
 
         ++lines;
 
-        auto segments = line.split_view('|', true);
+        auto segments = line.split_view('|', SplitBehavior::KeepEmpty);
         segments.take_first();
         if (!segments.is_empty() && segments.last().is_empty())
             segments.take_last();

+ 1 - 1
Userland/Libraries/LibTest/JavaScriptTestRunner.h

@@ -522,7 +522,7 @@ inline void TestRunner::print_file_result(JSFileResult const& file_result) const
 #endif
         outln();
         print_modifiers({ FG_GRAY });
-        for (auto& message : test_error.hint.split('\n', true)) {
+        for (auto& message : test_error.hint.split('\n', SplitBehavior::KeepEmpty)) {
             outln("         {}", message);
         }
         print_modifiers({ FG_RED });

+ 1 - 1
Userland/Services/LookupServer/LookupServer.cpp

@@ -96,7 +96,7 @@ void LookupServer::load_etc_hosts()
             break;
         auto trimmed_line = original_line.view().trim_whitespace();
         auto replaced_line = trimmed_line.replace(" "sv, "\t"sv, ReplaceMode::All);
-        auto fields = replaced_line.split_view('\t', false);
+        auto fields = replaced_line.split_view('\t');
 
         if (fields.size() < 2) {
             dbgln("Failed to parse line {} from '/etc/hosts': '{}'", line_number, original_line);

+ 1 - 1
Userland/Services/WebDriver/Client.cpp

@@ -252,7 +252,7 @@ ErrorOr<Client::RoutingResult, WebDriverError> Client::match_route(HTTP::HttpReq
     if (!resource.starts_with(m_prefix))
         return WebDriverError::from_code(ErrorCode::UnknownCommand, "The resource doesn't start with the prefix.");
 
-    Vector<StringView> resource_split = resource.substring_view(m_prefix.length()).split_view('/', true);
+    Vector<StringView> resource_split = resource.substring_view(m_prefix.length()).split_view('/', SplitBehavior::KeepEmpty);
     Vector<StringView> parameters;
 
     bool matched_path = false;

+ 1 - 1
Userland/Shell/AST.cpp

@@ -3577,7 +3577,7 @@ String StringValue::resolve_as_string(RefPtr<Shell> shell)
 Vector<String> StringValue::resolve_as_list(RefPtr<Shell> shell)
 {
     if (is_list()) {
-        auto parts = StringView(m_string).split_view(m_split, m_keep_empty);
+        auto parts = StringView(m_string).split_view(m_split, m_keep_empty ? SplitBehavior::KeepEmpty : SplitBehavior::Nothing);
         Vector<String> result;
         result.ensure_capacity(parts.size());
         for (auto& part : parts)

+ 1 - 1
Userland/Shell/Builtin.cpp

@@ -57,7 +57,7 @@ int Shell::builtin_alias(int argc, char const** argv)
 
     bool fail = false;
     for (auto& argument : arguments) {
-        auto parts = argument.split_limit('=', 2, true);
+        auto parts = argument.split_limit('=', 2, SplitBehavior::KeepEmpty);
         if (parts.size() == 1) {
             auto alias = m_aliases.get(parts[0]);
             if (alias.has_value()) {

+ 1 - 1
Userland/Shell/ImmediateFunctions.cpp

@@ -349,7 +349,7 @@ RefPtr<AST::Node> Shell::immediate_split(AST::ImmediateExpression& invoking_node
                 builder.clear();
             }
         } else {
-            auto split = StringView { value }.split_view(delimiter_str, options.inline_exec_keep_empty_segments);
+            auto split = StringView { value }.split_view(delimiter_str, options.inline_exec_keep_empty_segments ? SplitBehavior::KeepEmpty : SplitBehavior::Nothing);
             split_strings.ensure_capacity(split.size());
             for (auto& entry : split)
                 split_strings.append(entry);

+ 1 - 1
Userland/Utilities/chown.cpp

@@ -39,7 +39,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
     uid_t new_uid = -1;
     gid_t new_gid = -1;
 
-    auto parts = spec.split_view(':', true);
+    auto parts = spec.split_view(':', SplitBehavior::KeepEmpty);
     if (parts[0].is_empty() || (parts.size() == 2 && parts[1].is_empty()) || parts.size() > 2) {
         warnln("Invalid uid/gid spec");
         return 1;

+ 1 - 1
Userland/Utilities/cp.cpp

@@ -39,7 +39,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
 
             bool values_ok = true;
 
-            StringView { s, strlen(s) }.for_each_split_view(',', false, [&](StringView value) {
+            StringView { s, strlen(s) }.for_each_split_view(',', SplitBehavior::Nothing, [&](StringView value) {
                 if (value == "mode"sv) {
                     preserve |= Core::File::PreserveMode::Permissions;
                 } else if (value == "ownership"sv) {

+ 1 - 1
Userland/Utilities/dd.cpp

@@ -38,7 +38,7 @@ enum Status {
 
 static StringView split_at_equals(StringView argument)
 {
-    auto values = argument.split_view('=', true);
+    auto values = argument.split_view('=', SplitBehavior::KeepEmpty);
     if (values.size() < 2) {
         warnln("Unable to parse: {}", argument);
         return {};

+ 1 - 1
Userland/Utilities/readelf.cpp

@@ -730,7 +730,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
         if (maybe_section.has_value()) {
             outln("String dump of section \'{}\':", string_dump_section);
             StringView data(maybe_section->raw_data(), maybe_section->size());
-            data.for_each_split_view('\0', false, [&data](auto string) {
+            data.for_each_split_view('\0', SplitBehavior::Nothing, [&data](auto string) {
                 auto offset = string.characters_without_null_termination() - data.characters_without_null_termination();
                 outln("[{:6x}] {}", offset, string);
             });

+ 1 - 1
Userland/Utilities/xargs.cpp

@@ -245,7 +245,7 @@ ParsedInitialArguments::ParsedInitialArguments(Vector<String>& arguments, String
         if (placeholder.is_empty()) {
             m_all_parts.append({ arg });
         } else {
-            auto parts = arg.view().split_view(placeholder, true);
+            auto parts = arg.view().split_view(placeholder, SplitBehavior::KeepEmpty);
             some_argument_has_placeholder = some_argument_has_placeholder || parts.size() > 1;
             m_all_parts.append(move(parts));
         }