From 3e8b5ac92012e19847e536a20a3f0ec7e5c787d3 Mon Sep 17 00:00:00 2001 From: demostanis Date: Sat, 22 Oct 2022 15:38:21 +0200 Subject: [PATCH] AK+Everywhere: Turn bool keep_empty to an enum in split* functions --- AK/IPv6Address.h | 2 +- AK/String.cpp | 14 ++++++++------ AK/String.h | 8 ++++---- AK/StringUtils.h | 10 ++++++++++ AK/StringView.cpp | 13 +++++++------ AK/StringView.h | 14 ++++++++------ Kernel/CommandLine.cpp | 2 +- Kernel/GlobalProcessExposed.cpp | 2 +- Kernel/Storage/StorageManagement.cpp | 2 +- Kernel/Syscalls/pledge.cpp | 2 +- .../CodeGenerators/LibEDID/GeneratePnpIDs.cpp | 2 +- .../LibLocale/GeneratePluralRulesData.cpp | 6 +++--- .../LibTimeZone/GenerateTimeZoneData.cpp | 2 +- .../LibUnicode/GenerateEmojiData.cpp | 2 +- .../LibUnicode/GenerateUnicodeData.cpp | 18 +++++++++--------- Meta/Lagom/Tools/ConfigureComponents/main.cpp | 2 +- Tests/AK/TestString.cpp | 6 +++--- Tests/AK/TestStringView.cpp | 14 +++++++------- .../3DFileViewer/WavefrontOBJLoader.cpp | 2 +- .../DevTools/UserspaceEmulator/Emulator.cpp | 2 +- Userland/Libraries/LibC/getopt.cpp | 2 +- Userland/Libraries/LibC/grp.cpp | 2 +- Userland/Libraries/LibC/pwd.cpp | 2 +- Userland/Libraries/LibC/shadow.cpp | 2 +- .../Shell/ShellComprehensionEngine.cpp | 2 +- Userland/Libraries/LibCore/ArgsParser.cpp | 2 +- Userland/Libraries/LibDiff/Format.cpp | 2 +- Userland/Libraries/LibGUI/EmojiInputDialog.cpp | 2 +- Userland/Libraries/LibHTTP/HttpRequest.cpp | 2 +- Userland/Libraries/LibHTTP/Job.cpp | 2 +- Userland/Libraries/LibJS/Parser.h | 2 +- .../LibJS/Runtime/RegExpPrototype.cpp | 2 +- Userland/Libraries/LibMarkdown/Table.cpp | 6 +++--- .../Libraries/LibTest/JavaScriptTestRunner.h | 2 +- .../Services/LookupServer/LookupServer.cpp | 2 +- Userland/Services/WebDriver/Client.cpp | 2 +- Userland/Shell/AST.cpp | 2 +- Userland/Shell/Builtin.cpp | 2 +- Userland/Shell/ImmediateFunctions.cpp | 2 +- Userland/Utilities/chown.cpp | 2 +- Userland/Utilities/cp.cpp | 2 +- Userland/Utilities/dd.cpp | 2 +- Userland/Utilities/readelf.cpp | 2 +- Userland/Utilities/xargs.cpp | 2 +- 44 files changed, 96 insertions(+), 81 deletions(-) diff --git a/AK/IPv6Address.h b/AK/IPv6Address.h index b5e02559569..808c71a131d 100644 --- a/AK/IPv6Address.h +++ b/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) { diff --git a/AK/String.cpp b/AK/String.cpp index cd318efbd5f..2497e8c8b42 100644 --- a/AK/String.cpp +++ b/AK/String.cpp @@ -97,18 +97,19 @@ StringView String::substring_view(size_t start) const return { characters() + start, length() - start }; } -Vector String::split(char separator, bool keep_empty) const +Vector String::split(char separator, SplitBehavior split_behavior) const { - return split_limit(separator, 0, keep_empty); + return split_limit(separator, 0, split_behavior); } -Vector String::split_limit(char separator, size_t limit, bool keep_empty) const +Vector String::split_limit(char separator, size_t limit, SplitBehavior split_behavior) const { if (is_empty()) return {}; Vector 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::split_limit(char separator, size_t limit, bool keep_empty return v; } -Vector String::split_view(Function separator, bool keep_empty) const +Vector String::split_view(Function separator, SplitBehavior split_behavior) const { if (is_empty()) return {}; Vector 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 String::split_view(Function separator, bool keep_ return v; } -Vector String::split_view(char const separator, bool keep_empty) const +Vector 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 diff --git a/AK/String.h b/AK/String.h index 89dcff15d6a..1fb63362243 100644 --- a/AK/String.h +++ b/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 split_limit(char separator, size_t limit, bool keep_empty = false) const; - [[nodiscard]] Vector split(char separator, bool keep_empty = false) const; - [[nodiscard]] Vector split_view(char separator, bool keep_empty = false) const; - [[nodiscard]] Vector split_view(Function separator, bool keep_empty = false) const; + [[nodiscard]] Vector split_limit(char separator, size_t limit, SplitBehavior = SplitBehavior::Nothing) const; + [[nodiscard]] Vector split(char separator, SplitBehavior = SplitBehavior::Nothing) const; + [[nodiscard]] Vector split_view(char separator, SplitBehavior = SplitBehavior::Nothing) const; + [[nodiscard]] Vector split_view(Function separator, SplitBehavior = SplitBehavior::Nothing) const; [[nodiscard]] Optional find(char needle, size_t start = 0) const { return StringUtils::find(*this, needle, start); } [[nodiscard]] Optional find(StringView needle, size_t start = 0) const { return StringUtils::find(*this, needle, start); } diff --git a/AK/StringUtils.h b/AK/StringUtils.h index 10b9952516a..60dde9c359b 100644 --- a/AK/StringUtils.h +++ b/AK/StringUtils.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include 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; diff --git a/AK/StringView.cpp b/AK/StringView.cpp index 278b833bfd5..1b906d7970f 100644 --- a/AK/StringView.cpp +++ b/AK/StringView.cpp @@ -40,16 +40,16 @@ StringView::StringView(ByteBuffer const& buffer) { } -Vector StringView::split_view(char const separator, bool keep_empty) const +Vector 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::split_view(StringView separator, bool keep_empty) const +Vector StringView::split_view(StringView separator, SplitBehavior split_behavior) const { Vector 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::lines(bool consider_cr) const return {}; if (!consider_cr) - return split_view('\n', true); + return split_view('\n', SplitBehavior::KeepEmpty); Vector v; size_t substart = 0; @@ -264,13 +264,14 @@ Vector StringView::find_all(StringView needle) const return StringUtils::find_all(*this, needle); } -Vector StringView::split_view_if(Function const& predicate, bool keep_empty) const +Vector StringView::split_view_if(Function const& predicate, SplitBehavior split_behavior) const { if (is_empty()) return {}; Vector 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)) { diff --git a/AK/StringView.h b/AK/StringView.h index bb1b6641849..e9d58c31985 100644 --- a/AK/StringView.h +++ b/AK/StringView.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -129,10 +130,10 @@ public: return substring_view(start, length() - start); } - [[nodiscard]] Vector split_view(char, bool keep_empty = false) const; - [[nodiscard]] Vector split_view(StringView, bool keep_empty = false) const; + [[nodiscard]] Vector split_view(char, SplitBehavior = SplitBehavior::Nothing) const; + [[nodiscard]] Vector split_view(StringView, SplitBehavior = SplitBehavior::Nothing) const; - [[nodiscard]] Vector split_view_if(Function const& predicate, bool keep_empty = false) const; + [[nodiscard]] Vector split_view_if(Function const& predicate, SplitBehavior = SplitBehavior::Nothing) const; [[nodiscard]] StringView find_last_split_view(char separator) const { @@ -151,14 +152,14 @@ public: } template 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 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()); diff --git a/Kernel/CommandLine.cpp b/Kernel/CommandLine.cpp index ad9349f68dc..cbc0d72ea72 100644 --- a/Kernel/CommandLine.cpp +++ b/Kernel/CommandLine.cpp @@ -65,7 +65,7 @@ UNMAP_AFTER_INIT void CommandLine::add_arguments(Vector 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) { diff --git a/Kernel/GlobalProcessExposed.cpp b/Kernel/GlobalProcessExposed.cpp index 189c297c5d2..1b5d72acf82 100644 --- a/Kernel/GlobalProcessExposed.cpp +++ b/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 result; // FIXME: Make this nicer info.features_string().for_each_split_view(' ', keep_empty, [&](StringView feature) { diff --git a/Kernel/Storage/StorageManagement.cpp b/Kernel/Storage/StorageManagement.cpp index 4ae642cb695..1c3fc8d4fd0 100644 --- a/Kernel/Storage/StorageManagement.cpp +++ b/Kernel/Storage/StorageManagement.cpp @@ -213,7 +213,7 @@ UNMAP_AFTER_INIT Array 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) diff --git a/Kernel/Syscalls/pledge.cpp b/Kernel/Syscalls/pledge.cpp index 8b2412196ee..39c3b86aee5 100644 --- a/Kernel/Syscalls/pledge.cpp +++ b/Kernel/Syscalls/pledge.cpp @@ -29,7 +29,7 @@ ErrorOr Process::sys$pledge(Userspace 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); \ diff --git a/Meta/Lagom/Tools/CodeGenerators/LibEDID/GeneratePnpIDs.cpp b/Meta/Lagom/Tools/CodeGenerators/LibEDID/GeneratePnpIDs.cpp index 40bf24360e9..aab3df4ecd3 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibEDID/GeneratePnpIDs.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibEDID/GeneratePnpIDs.cpp @@ -91,7 +91,7 @@ static ErrorOr decode_html_entities(StringView const& str) static ErrorOr 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)"); diff --git a/Meta/Lagom/Tools/CodeGenerators/LibLocale/GeneratePluralRulesData.cpp b/Meta/Lagom/Tools/CodeGenerators/LibLocale/GeneratePluralRulesData.cpp index 46af3a493dd..3ad8d769a38 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibLocale/GeneratePluralRulesData.cpp +++ b/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 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)); }); diff --git a/Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp b/Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp index adac6c33876..0493c5e01ee 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp @@ -400,7 +400,7 @@ static ErrorOr 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); diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp index 6a9d53974cd..444fd5f4756 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp @@ -112,7 +112,7 @@ static ErrorOr 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()); diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeData.cpp b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeData.cpp index 46aadc960ea..d58bbd974d0 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeData.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeData.cpp @@ -223,7 +223,7 @@ static ErrorOr 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 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 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 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 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(segments[0].trim_whitespace()); @@ -417,7 +417,7 @@ static ErrorOr 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 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 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 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 {}; diff --git a/Meta/Lagom/Tools/ConfigureComponents/main.cpp b/Meta/Lagom/Tools/ConfigureComponents/main.cpp index be1464a10f5..052d2d1ec17 100644 --- a/Meta/Lagom/Tools/ConfigureComponents/main.cpp +++ b/Meta/Lagom/Tools/ConfigureComponents/main.cpp @@ -195,7 +195,7 @@ static Result, int> run_whiptail(WhiptailMode mode, Vectoropen(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) diff --git a/Tests/AK/TestString.cpp b/Tests/AK/TestString.cpp index 520ed872e80..bf608e62a33 100644 --- a/Tests/AK/TestString.cpp +++ b/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) diff --git a/Tests/AK/TestStringView.cpp b/Tests/AK/TestStringView.cpp index 08277100e80..6aafffe82ba 100644 --- a/Tests/AK/TestStringView.cpp +++ b/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 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) diff --git a/Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp b/Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp index c9d05d33189..e4709c227c4 100644 --- a/Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp +++ b/Userland/Applications/3DFileViewer/WavefrontOBJLoader.cpp @@ -87,7 +87,7 @@ RefPtr WavefrontOBJLoader::load(Core::File& file) auto normal_indices = FixedArray::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; diff --git a/Userland/DevTools/UserspaceEmulator/Emulator.cpp b/Userland/DevTools/UserspaceEmulator/Emulator.cpp index 1f84a0210b2..133e32097fa 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator.cpp +++ b/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)) { diff --git a/Userland/Libraries/LibC/getopt.cpp b/Userland/Libraries/LibC/getopt.cpp index 3c6b346e6ce..9819f356d37 100644 --- a/Userland/Libraries/LibC/getopt.cpp +++ b/Userland/Libraries/LibC/getopt.cpp @@ -138,7 +138,7 @@ int OptionParser::getopt() bool OptionParser::lookup_short_option(char option, int& needs_value) const { - Vector parts = m_short_options.split_view(option, true); + Vector parts = m_short_options.split_view(option, SplitBehavior::KeepEmpty); VERIFY(parts.size() <= 2); if (parts.size() < 2) { diff --git a/Userland/Libraries/LibC/grp.cpp b/Userland/Libraries/LibC/grp.cpp index 5bfa1b72770..7d90833e9dd 100644 --- a/Userland/Libraries/LibC/grp.cpp +++ b/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; diff --git a/Userland/Libraries/LibC/pwd.cpp b/Userland/Libraries/LibC/pwd.cpp index 3d9ffcb1567..f3ef1aa5052 100644 --- a/Userland/Libraries/LibC/pwd.cpp +++ b/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; diff --git a/Userland/Libraries/LibC/shadow.cpp b/Userland/Libraries/LibC/shadow.cpp index 099fca4cae2..53739944f8e 100644 --- a/Userland/Libraries/LibC/shadow.cpp +++ b/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; diff --git a/Userland/Libraries/LibCodeComprehension/Shell/ShellComprehensionEngine.cpp b/Userland/Libraries/LibCodeComprehension/Shell/ShellComprehensionEngine.cpp index 94a34201eb7..aeac3addcd9 100644 --- a/Userland/Libraries/LibCodeComprehension/Shell/ShellComprehensionEngine.cpp +++ b/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) diff --git a/Userland/Libraries/LibCore/ArgsParser.cpp b/Userland/Libraries/LibCore/ArgsParser.cpp index 15866d95737..6a450b41619 100644 --- a/Userland/Libraries/LibCore/ArgsParser.cpp +++ b/Userland/Libraries/LibCore/ArgsParser.cpp @@ -554,7 +554,7 @@ void ArgsParser::add_option(Vector& 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(value); maybe_value.has_value()) values.append(*maybe_value); else diff --git a/Userland/Libraries/LibDiff/Format.cpp b/Userland/Libraries/LibDiff/Format.cpp index 1e1718ada02..9f109b4c245 100644 --- a/Userland/Libraries/LibDiff/Format.cpp +++ b/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) { diff --git a/Userland/Libraries/LibGUI/EmojiInputDialog.cpp b/Userland/Libraries/LibGUI/EmojiInputDialog.cpp index 682de4192d1..9e89a151fea 100644 --- a/Userland/Libraries/LibGUI/EmojiInputDialog.cpp +++ b/Userland/Libraries/LibGUI/EmojiInputDialog.cpp @@ -179,7 +179,7 @@ auto EmojiInputDialog::supported_emoji() -> Vector StringBuilder builder; Vector 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(segment.substring_view(2)); VERIFY(code_point.has_value()); diff --git a/Userland/Libraries/LibHTTP/HttpRequest.cpp b/Userland/Libraries/LibHTTP/HttpRequest.cpp index fa43b6585ef..baa26d22d9d 100644 --- a/Userland/Libraries/LibHTTP/HttpRequest.cpp +++ b/Userland/Libraries/LibHTTP/HttpRequest.cpp @@ -211,7 +211,7 @@ Optional 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) { diff --git a/Userland/Libraries/LibHTTP/Job.cpp b/Userland/Libraries/LibHTTP/Job.cpp index c4dcb092852..787eff13c60 100644 --- a/Userland/Libraries/LibHTTP/Job.cpp +++ b/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); diff --git a/Userland/Libraries/LibJS/Parser.h b/Userland/Libraries/LibJS/Parser.h index 867361fbaca..4e9b904aaa3 100644 --- a/Userland/Libraries/LibJS/Parser.h +++ b/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); diff --git a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp index 3014fe94e30..3738d38ecb2 100644 --- a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/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). diff --git a/Userland/Libraries/LibMarkdown/Table.cpp b/Userland/Libraries/LibMarkdown/Table.cpp index 417e604565d..d0144e2a014 100644 --- a/Userland/Libraries/LibMarkdown/Table.cpp +++ b/Userland/Libraries/LibMarkdown/Table.cpp @@ -138,8 +138,8 @@ OwnPtr 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::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(); diff --git a/Userland/Libraries/LibTest/JavaScriptTestRunner.h b/Userland/Libraries/LibTest/JavaScriptTestRunner.h index b2d4e01fe85..3971b1a4500 100644 --- a/Userland/Libraries/LibTest/JavaScriptTestRunner.h +++ b/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 }); diff --git a/Userland/Services/LookupServer/LookupServer.cpp b/Userland/Services/LookupServer/LookupServer.cpp index d62970fe0cb..a59d28b3671 100644 --- a/Userland/Services/LookupServer/LookupServer.cpp +++ b/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); diff --git a/Userland/Services/WebDriver/Client.cpp b/Userland/Services/WebDriver/Client.cpp index 24ab6e4c667..716ca8a6ee7 100644 --- a/Userland/Services/WebDriver/Client.cpp +++ b/Userland/Services/WebDriver/Client.cpp @@ -252,7 +252,7 @@ ErrorOr 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 resource_split = resource.substring_view(m_prefix.length()).split_view('/', true); + Vector resource_split = resource.substring_view(m_prefix.length()).split_view('/', SplitBehavior::KeepEmpty); Vector parameters; bool matched_path = false; diff --git a/Userland/Shell/AST.cpp b/Userland/Shell/AST.cpp index ba79b546f95..2de54974968 100644 --- a/Userland/Shell/AST.cpp +++ b/Userland/Shell/AST.cpp @@ -3577,7 +3577,7 @@ String StringValue::resolve_as_string(RefPtr shell) Vector StringValue::resolve_as_list(RefPtr 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 result; result.ensure_capacity(parts.size()); for (auto& part : parts) diff --git a/Userland/Shell/Builtin.cpp b/Userland/Shell/Builtin.cpp index 1186efcd089..df14ea521ba 100644 --- a/Userland/Shell/Builtin.cpp +++ b/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()) { diff --git a/Userland/Shell/ImmediateFunctions.cpp b/Userland/Shell/ImmediateFunctions.cpp index eb65f014dd9..081a35c3018 100644 --- a/Userland/Shell/ImmediateFunctions.cpp +++ b/Userland/Shell/ImmediateFunctions.cpp @@ -349,7 +349,7 @@ RefPtr 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); diff --git a/Userland/Utilities/chown.cpp b/Userland/Utilities/chown.cpp index a487a09e4c7..880610984d9 100644 --- a/Userland/Utilities/chown.cpp +++ b/Userland/Utilities/chown.cpp @@ -39,7 +39,7 @@ ErrorOr 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; diff --git a/Userland/Utilities/cp.cpp b/Userland/Utilities/cp.cpp index 781b33b18d2..ccec431fb2d 100644 --- a/Userland/Utilities/cp.cpp +++ b/Userland/Utilities/cp.cpp @@ -39,7 +39,7 @@ ErrorOr 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) { diff --git a/Userland/Utilities/dd.cpp b/Userland/Utilities/dd.cpp index 74ca5c386a4..50fb9420c1a 100644 --- a/Userland/Utilities/dd.cpp +++ b/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 {}; diff --git a/Userland/Utilities/readelf.cpp b/Userland/Utilities/readelf.cpp index 9521a3a9ddd..2dc1bcb5e4b 100644 --- a/Userland/Utilities/readelf.cpp +++ b/Userland/Utilities/readelf.cpp @@ -730,7 +730,7 @@ ErrorOr 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); }); diff --git a/Userland/Utilities/xargs.cpp b/Userland/Utilities/xargs.cpp index 6973fbd877b..a089ef14df8 100644 --- a/Userland/Utilities/xargs.cpp +++ b/Userland/Utilities/xargs.cpp @@ -245,7 +245,7 @@ ParsedInitialArguments::ParsedInitialArguments(Vector& 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)); }