From 9dbc8475d1a28ec7e80708f517ece4e39bb5e705 Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Wed, 23 Apr 2025 19:16:24 +0200 Subject: [PATCH] chore: Split util::split_once into util::split_once{,_to_views} The util::split_once(std::string&&, char) version is a bit overly smart in that it returns std::string instead of std::string_view for a temporary std::string input. To reduce the risk for surprises, introduce a util::split_once_into_views so that input lifetime is indicated in the method name instead. --- src/ccache/storage/remote/httpstorage.cpp | 5 +++-- src/ccache/storage/remote/redisstorage.cpp | 4 ++-- src/ccache/storage/storage.cpp | 5 +++-- src/ccache/util/string.cpp | 18 ++++-------------- src/ccache/util/string.hpp | 8 ++++---- 5 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/ccache/storage/remote/httpstorage.cpp b/src/ccache/storage/remote/httpstorage.cpp index fe0aa4b8..a1ae2cc5 100644 --- a/src/ccache/storage/remote/httpstorage.cpp +++ b/src/ccache/storage/remote/httpstorage.cpp @@ -111,7 +111,8 @@ HttpStorageBackend::HttpStorageBackend( m_http_client(get_url(url)) { if (!url.user_info().empty()) { - const auto [user, password] = util::split_once(url.user_info(), ':'); + const auto [user, password] = + util::split_once_into_views(url.user_info(), ':'); if (!password) { throw core::Fatal(FMT("Expected username:password in URL but got \"{}\"", url.user_info())); @@ -147,7 +148,7 @@ HttpStorageBackend::HttpStorageBackend( } else if (attr.key == "operation-timeout") { operation_timeout = parse_timeout_attribute(attr.value); } else if (attr.key == "header") { - const auto [key, value] = util::split_once(attr.value, '='); + const auto [key, value] = util::split_once_into_views(attr.value, '='); if (value) { default_headers.emplace(std::string(key), std::string(*value)); } else { diff --git a/src/ccache/storage/remote/redisstorage.cpp b/src/ccache/storage/remote/redisstorage.cpp index f7be7e24..a87395af 100644 --- a/src/ccache/storage/remote/redisstorage.cpp +++ b/src/ccache/storage/remote/redisstorage.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2024 Joel Rosdahl and other contributors +// Copyright (C) 2021-2025 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -101,7 +101,7 @@ to_timeval(const uint32_t ms) std::pair, std::optional> split_user_info(const std::string& user_info) { - const auto [left, right] = util::split_once(user_info, ':'); + const auto [left, right] = util::split_once_into_views(user_info, ':'); if (left.empty()) { // redis://HOST return {std::nullopt, std::nullopt}; diff --git a/src/ccache/storage/storage.cpp b/src/ccache/storage/storage.cpp index 63e03380..702d7126 100644 --- a/src/ccache/storage/storage.cpp +++ b/src/ccache/storage/storage.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2024 Joel Rosdahl and other contributors +// Copyright (C) 2021-2025 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -162,7 +162,8 @@ parse_storage_config(const std::string_view entry) if (parts[i].empty()) { continue; } - const auto [key, right_hand_side] = util::split_once(parts[i], '='); + const auto [key, right_hand_side] = + util::split_once_into_views(parts[i], '='); const auto& raw_value = right_hand_side.value_or("true"); const auto value = util::value_or_throw(util::percent_decode(raw_value)); diff --git a/src/ccache/util/string.cpp b/src/ccache/util/string.cpp index 35453a69..1cefb126 100644 --- a/src/ccache/util/string.cpp +++ b/src/ccache/util/string.cpp @@ -468,25 +468,15 @@ split_into_views(std::string_view string, string, separators, mode, include_delimiter); } -std::pair> -split_once(const char* string, const char split_char) -{ - return split_once(std::string_view(string), split_char); -} - std::pair> -split_once(std::string&& string, const char split_char) +split_once(std::string_view string, char split_char) { - const auto [left, right] = split_once(std::string_view(string), split_char); - if (right) { - return std::make_pair(std::string(left), std::string(*right)); - } else { - return std::make_pair(std::string(left), std::nullopt); - } + auto [left, right] = split_once_into_views(string, split_char); + return std::pair>{left, right}; } std::pair> -split_once(const std::string_view string, const char split_char) +split_once_into_views(std::string_view string, char split_char) { const size_t sep_pos = string.find(split_char); if (sep_pos == std::string_view::npos) { diff --git a/src/ccache/util/string.hpp b/src/ccache/util/string.hpp index 219b1c34..e59e5287 100644 --- a/src/ccache/util/string.hpp +++ b/src/ccache/util/string.hpp @@ -178,13 +178,13 @@ split_into_views(std::string_view string, // Split `string` into two parts using `split_char` as the delimiter. The second // part will be `nullopt` if there is no `split_char` in `string.` -std::pair> -split_once(const char* string, char split_char); std::pair> -split_once(std::string&& string, char split_char); -std::pair> split_once(std::string_view string, char split_char); +// Like `split_once` but splits into `std::string_view`. +std::pair> +split_once_into_views(std::string_view string, char split_char); + // Split `string` into two parts where the split point is before a potential // absolute path. The second part will be `nullopt` if no absolute path // candidate was found. -- 2.47.2