From: Joel Rosdahl Date: Sun, 7 Jan 2024 13:53:01 +0000 (+0100) Subject: refactor: Move Util::is_absolute_path_with_prefix to util X-Git-Tag: v4.10~132 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac05df21de6a72d50614ee64c6e4752846625593;p=thirdparty%2Fccache.git refactor: Move Util::is_absolute_path_with_prefix to util --- diff --git a/src/Util.cpp b/src/Util.cpp index ecd347a5f..1e171c76c 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -119,31 +119,6 @@ get_relative_path(std::string_view dir, std::string_view path) return result.empty() ? "." : result; } -std::optional -is_absolute_path_with_prefix(std::string_view path) -{ -#ifdef _WIN32 - const char delim[] = "/\\"; -#else - const char delim[] = "/"; -#endif - auto split_pos = path.find_first_of(delim); - if (split_pos != std::string::npos) { -#ifdef _WIN32 - // -I/C:/foo and -I/c/foo will already be handled by delim_pos correctly - // resulting in -I and /C:/foo or /c/foo respectively. -IC:/foo will not as - // we would get -IC: and /foo. - if (split_pos > 0 && path[split_pos - 1] == ':') { - split_pos = split_pos - 2; - } -#endif - // This is not redundant on some platforms, so nothing to simplify. - // NOLINTNEXTLINE(readability-simplify-boolean-expr) - return split_pos; - } - return std::nullopt; -} - std::string make_relative_path(const std::string& base_dir, const std::string& actual_cwd, diff --git a/src/Util.hpp b/src/Util.hpp index b0a7d5590..8fe54f83a 100644 --- a/src/Util.hpp +++ b/src/Util.hpp @@ -45,10 +45,6 @@ size_t common_dir_prefix_length(std::string_view dir, std::string_view path); // resolve to the same file as `path`. std::string get_relative_path(std::string_view dir, std::string_view path); -// Determine if `path` is an absolute path with prefix, returning the split -// point. -std::optional is_absolute_path_with_prefix(std::string_view path); - // Construct a normalized native path. // // Example: diff --git a/src/argprocessing.cpp b/src/argprocessing.cpp index b08fac754..eebe7e926 100644 --- a/src/argprocessing.cpp +++ b/src/argprocessing.cpp @@ -1071,17 +1071,15 @@ process_option_arg(const Context& ctx, // Potentially rewrite concatenated absolute path argument to relative. if (arg[0] == '-') { - const auto path_pos = Util::is_absolute_path_with_prefix(arg); - if (path_pos) { - const std::string option = args[i].substr(0, *path_pos); + const auto [option, path] = util::split_option_with_concat_path(arg); + if (path) { if (compopt_takes_concat_arg(option) && compopt_takes_path(option)) { - const auto relpath = Util::make_relative_path( - ctx, std::string_view(arg).substr(*path_pos)); - std::string new_option = option + relpath; + const auto relpath = Util::make_relative_path(ctx, *path); + std::string new_option = FMT("{}{}", option, relpath); if (compopt_affects_cpp_output(option)) { - state.cpp_args.push_back(new_option); + state.cpp_args.push_back(std::move(new_option)); } else { - state.common_args.push_back(new_option); + state.common_args.push_back(std::move(new_option)); } return Statistic::none; } diff --git a/src/util/string.cpp b/src/util/string.cpp index 8f4c805d4..24c14b6b2 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2023 Joel Rosdahl and other contributors +// Copyright (C) 2021-2024 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -480,6 +480,31 @@ split_once(const std::string_view string, const char split_char) } } +std::pair> +split_option_with_concat_path(std::string_view string) +{ +#ifdef _WIN32 + const char delim[] = "/\\"; +#else + const char delim[] = "/"; +#endif + size_t split_pos = string.find_first_of(delim); + if (split_pos == std::string_view::npos) { + return std::make_pair(string, std::nullopt); + } + +#ifdef _WIN32 + // -I/C:/foo and -I/c/foo will already be handled by delim_pos correctly + // resulting in -I and /C:/foo or /c/foo respectively. -IC:/foo will not as + // we would get -IC: and /foo. + if (split_pos >= 2 && string[split_pos - 1] == ':') { + split_pos -= 2; + } +#endif + + return std::make_pair(string.substr(0, split_pos), string.substr(split_pos)); +} + std::vector split_path_list(std::string_view path_list) { diff --git a/src/util/string.hpp b/src/util/string.hpp index 4c981eb34..07f111f00 100644 --- a/src/util/string.hpp +++ b/src/util/string.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2023 Joel Rosdahl and other contributors +// Copyright (C) 2021-2024 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -181,6 +181,12 @@ split_once(std::string&& string, char split_char); std::pair> split_once(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. +std::pair> +split_option_with_concat_path(std::string_view string); + // Split a list of paths (such as the content of $PATH on Unix platforms or // %PATH% on Windows platforms) into paths. std::vector split_path_list(std::string_view path_list); diff --git a/unittest/test_Util.cpp b/unittest/test_Util.cpp index 432b18251..d729c8afb 100644 --- a/unittest/test_Util.cpp +++ b/unittest/test_Util.cpp @@ -95,20 +95,6 @@ TEST_CASE("Util::get_relative_path") #endif } -TEST_CASE("Util::is_absolute_path_with_prefix") -{ - CHECK(*Util::is_absolute_path_with_prefix("-I/c/foo") == 2); - CHECK(*Util::is_absolute_path_with_prefix("-W,path/c/foo") == 7); - CHECK(!Util::is_absolute_path_with_prefix("-DMACRO")); -#ifdef _WIN32 - CHECK(*Util::is_absolute_path_with_prefix("-I/C:/foo") == 2); - CHECK(*Util::is_absolute_path_with_prefix("-IC:/foo") == 2); - CHECK(*Util::is_absolute_path_with_prefix("-W,path/c:/foo") == 7); - CHECK(*Util::is_absolute_path_with_prefix("-W,pathc:/foo") == 7); - CHECK(!Util::is_absolute_path_with_prefix("-opt:value")); -#endif -} - TEST_CASE("Util::make_relative_path") { using Util::make_relative_path; diff --git a/unittest/test_util_string.cpp b/unittest/test_util_string.cpp index 876295ba6..41ac55076 100644 --- a/unittest/test_util_string.cpp +++ b/unittest/test_util_string.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2023 Joel Rosdahl and other contributors +// Copyright (C) 2021-2024 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -567,6 +567,24 @@ TEST_CASE("util::split_once") } } +TEST_CASE("util::split_option_with_concat_path") +{ + using std::make_pair; + using std::nullopt; + const auto split = util::split_option_with_concat_path; + + CHECK(split("-I/c/foo") == make_pair("-I", "/c/foo")); + CHECK(split("-W,path/c/foo") == make_pair("-W,path", "/c/foo")); + CHECK(split("-DMACRO") == make_pair("-DMACRO", nullopt)); +#ifdef _WIN32 + CHECK(split("-I/C:/foo") == make_pair("-I", "/C:/foo")); + CHECK(split("-IC:/foo") == make_pair("-I", "C:/foo")); + CHECK(split("-W,path/c:/foo") == make_pair("-W,path", "/c:/foo")); + CHECK(split("-W,pathc:/foo") == make_pair("-W,path", "c:/foo")); + CHECK(split("-opt:value") == make_pair("-opt:value", nullopt)); +#endif +} + TEST_CASE("util::split_path_list") { CHECK(util::split_path_list("").empty());