return i;
}
-std::string_view
-dir_name(std::string_view path)
-{
-#ifdef _WIN32
- const char delim[] = "/\\";
-#else
- const char delim[] = "/";
-#endif
- size_t n = path.find_last_of(delim);
- if (n == std::string::npos) {
- // "foo" -> "."
- return ".";
- } else if (n == 0) {
- // "/" -> "/" (Windows: or "\\" -> "\\")
- return path.substr(0, 1);
-#ifdef _WIN32
- } else if (n == 2 && path[1] == ':') {
- // Windows: "C:\\foo" -> "C:\\" or "C:/foo" -> "C:/"
- return path.substr(0, 3);
-#endif
- } else {
- // "/dir/foo" -> "/dir" (Windows: or "C:\\dir\\foo" -> "C:\\dir")
- return path.substr(0, n);
- }
-}
-
std::string
get_relative_path(std::string_view dir, std::string_view path)
{
std::vector<std::string> relpath_candidates;
const auto original_path = path;
- DirEntry dir_entry(path);
- while (!dir_entry.exists()) {
- path = Util::dir_name(path);
- dir_entry = DirEntry(path);
+ fs::path path_path = path;
+ while (!fs::exists(path_path)) {
+ path_path = path_path.parent_path();
}
+ std::string path_str = path_path.string();
+ path = path_str;
const auto path_suffix = std::string(original_path.substr(path.length()));
- const std::string real_path = fs::canonical(path).value_or(path).string();
+ const fs::path real_path = fs::canonical(path).value_or(fs::path(path));
const auto add_relpath_candidates = [&](auto p) {
const std::string normalized_path =
};
add_relpath_candidates(path);
if (real_path != path) {
- add_relpath_candidates(real_path);
+ add_relpath_candidates(real_path.string());
}
// Find best (i.e. shortest existing) match:
return path1.length() < path2.length();
});
for (const auto& relpath : relpath_candidates) {
- if (DirEntry(relpath).same_inode_as(dir_entry)) {
+ if (fs::equivalent(relpath, path_path)) {
return relpath + path_suffix;
}
}
// `dir` (a directory) and `path` (any path).
size_t common_dir_prefix_length(std::string_view dir, std::string_view path);
-// Get directory name of path.
-std::string_view dir_name(std::string_view path);
-
// Compute a relative path from `dir` (an absolute path to a directory) to
// `path` (an absolute path). Assumes that both `dir` and `path` are normalized.
// The algorithm does *not* follow symlinks, so the result may not actually
args_info.generating_dependencies = false;
}
- auto output_dir = Util::dir_name(args_info.output_obj);
- if (!DirEntry(output_dir).is_directory()) {
+ fs::path output_dir = fs::path(args_info.output_obj).parent_path();
+ if (!output_dir.empty() && !fs::is_directory(output_dir)) {
LOG("Directory does not exist: {}", output_dir);
return Statistic::bad_output_file;
}
if (ctx.config.is_compiler_group_msvc() && ctx.config.hash_dir()) {
const std::string output_obj_dir =
fs::path(args_info.output_obj).is_absolute()
- ? std::string(Util::dir_name(args_info.output_obj))
+ ? fs::path(args_info.output_obj).parent_path().string()
: ctx.actual_cwd;
LOG("Hashing object file directory {}", output_obj_dir);
hash.hash_delimiter("source path");
-// 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.
//
#include <Config.hpp>
#include <Context.hpp>
#include <MiniTrace.hpp>
-#include <Util.hpp>
#include <core/AtomicFile.hpp>
#include <core/CacheEntry.hpp>
#include <core/FileRecompressor.hpp>
const std::vector<core::Result::Serializer::RawFile> raw_files)
{
const auto cache_file = look_up_cache_file(key, core::CacheEntryType::result);
- core::ensure_dir_exists(Util::dir_name(cache_file.path));
+ core::ensure_dir_exists(fs::path(cache_file.path).parent_path());
int64_t files_change = 0;
int64_t size_kibibyte_change = 0;
const auto wanted_path = get_path_in_cache(
wanted_level, util::format_digest(key) + suffix_from_type(type));
if (cache_file_path != wanted_path) {
- core::ensure_dir_exists(Util::dir_name(wanted_path));
+ core::ensure_dir_exists(fs::path(wanted_path).parent_path());
// Note: Two ccache processes may move the file at the same time, so failure
// to rename is OK.
for (const auto& raw_file : m_added_raw_files) {
fs::rename(raw_file,
FMT("{}/{}",
- Util::dir_name(wanted_path),
+ fs::path(wanted_path).parent_path(),
fs::path(raw_file).filename()));
}
}
LocalStorage::get_lock_path(const std::string& name) const
{
auto path = FMT("{}/lock/{}", m_config.cache_dir(), name);
- core::ensure_dir_exists(Util::dir_name(path));
+ core::ensure_dir_exists(fs::path(path).parent_path());
return path;
}
{
util::UmaskScope umask_scope(m_umask);
- const auto dir = Util::dir_name(path);
+ const fs::path dir = fs::path(path).parent_path();
if (auto result = fs::create_directories(dir); !result) {
LOG("Failed to create directory {}: {}", dir, result.error().message());
return tl::unexpected(Failure::error);
-// Copyright (C) 2020-2023 Joel Rosdahl and other contributors
+// Copyright (C) 2020-2024 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
#include "../src/Depfile.hpp"
#include "TestUtil.hpp"
-#include <Util.hpp>
+#include <util/filesystem.hpp>
#include <util/fmtmacros.hpp>
#include "third_party/doctest.h"
#include <string>
#include <vector>
+namespace fs = util::filesystem;
+
using TestUtil::TestContext;
TEST_SUITE_BEGIN("Depfile");
{
Context ctx;
- const auto cwd = ctx.actual_cwd;
+ const fs::path cwd = ctx.actual_cwd;
const auto content =
FMT("{0}/foo.o {0}/foo.o: bar.c {0}/bar.h \\\n\n {1}/fie.h {0}/fum.h\n",
cwd,
- Util::dir_name(cwd));
+ cwd.parent_path());
SUBCASE("Base directory not in dep file content")
{
SUBCASE("Base directory in dep file content but not matching")
{
- ctx.config.set_base_dir(FMT("{}/other", Util::dir_name(cwd)));
+ ctx.config.set_base_dir((cwd.parent_path() / "other").string());
CHECK(!Depfile::rewrite_source_paths(ctx, ""));
CHECK(!Depfile::rewrite_source_paths(ctx, content));
}
SUBCASE("Absolute paths under base directory rewritten")
{
- ctx.config.set_base_dir(cwd);
+ ctx.config.set_base_dir(cwd.string());
const auto actual = Depfile::rewrite_source_paths(ctx, content);
const auto expected =
FMT("{0}/foo.o {0}/foo.o: bar.c ./bar.h \\\n\n {1}/fie.h ./fum.h\n",
cwd,
- Util::dir_name(cwd));
+ cwd.parent_path());
REQUIRE(actual);
CHECK(*actual == expected);
}
CHECK(Util::common_dir_prefix_length("/a/b", "/a/bc") == 2);
}
-TEST_CASE("Util::dir_name")
-{
- CHECK(Util::dir_name("") == ".");
- CHECK(Util::dir_name(".") == ".");
- CHECK(Util::dir_name("foo") == ".");
- CHECK(Util::dir_name("/") == "/");
- CHECK(Util::dir_name("/foo") == "/");
- CHECK(Util::dir_name("/foo/bar/f.txt") == "/foo/bar");
-
-#ifdef _WIN32
- CHECK(Util::dir_name("C:/x/y") == "C:/x");
- CHECK(Util::dir_name("X:/x/y") == "X:/x");
- CHECK(Util::dir_name("C:\\x\\y") == "C:\\x");
- CHECK(Util::dir_name("C:/x") == "C:/");
- CHECK(Util::dir_name("C:\\x") == "C:\\");
- CHECK(Util::dir_name("C:/") == "C:/");
- CHECK(Util::dir_name("C:\\") == "C:\\");
-#endif
-}
-
TEST_CASE("Util::get_relative_path")
{
#ifdef _WIN32
CHECK(
make_relative_path(
actual_cwd.substr(0, 3), actual_cwd, apparent_cwd, actual_cwd + "\\\\x")
- == ".\\x");
+ == ".\\\\x");
#else
CHECK(make_relative_path("/", actual_cwd, apparent_cwd, actual_cwd + "/x")
== "./x");