From beed00c04e136e8d685905e4b2b1116ecdf42f63 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 13 Jan 2024 13:08:38 -0500 Subject: [PATCH] `absPath`: just take a `std::string_view` 1. Slightly more efficient 2. Easier to call Co-authored-by: Cole Helbling --- src/libutil/canon-path.cc | 6 +++--- src/libutil/file-system.cc | 14 +++++++++++--- src/libutil/file-system.hh | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/libutil/canon-path.cc b/src/libutil/canon-path.cc index 1e465f1f6..0a0f96a05 100644 --- a/src/libutil/canon-path.cc +++ b/src/libutil/canon-path.cc @@ -6,11 +6,11 @@ namespace nix { CanonPath CanonPath::root = CanonPath("/"); CanonPath::CanonPath(std::string_view raw) - : path(absPath((Path) raw, "/")) + : path(absPath(raw, "/")) { } CanonPath::CanonPath(std::string_view raw, const CanonPath & root) - : path(absPath((Path) raw, root.abs())) + : path(absPath(raw, root.abs())) { } CanonPath::CanonPath(const std::vector & elems) @@ -22,7 +22,7 @@ CanonPath::CanonPath(const std::vector & elems) CanonPath CanonPath::fromCwd(std::string_view path) { - return CanonPath(unchecked_t(), absPath((Path) path)); + return CanonPath(unchecked_t(), absPath(path)); } std::optional CanonPath::parent() const diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc index 4cac35ace..ab8d32275 100644 --- a/src/libutil/file-system.cc +++ b/src/libutil/file-system.cc @@ -21,9 +21,16 @@ namespace fs = std::filesystem; namespace nix { -Path absPath(Path path, std::optional dir, bool resolveSymlinks) +Path absPath(PathView path, std::optional dir, bool resolveSymlinks) { + std::string scratch; + if (path[0] != '/') { + // In this case we need to call `canonPath` on a newly-created + // string. We set `scratch` to that string first, and then set + // `path` to `scratch`. This ensures the newly-created string + // lives long enough for the call to `canonPath`, and allows us + // to just accept a `std::string_view`. if (!dir) { #ifdef __GNU__ /* GNU (aka. GNU/Hurd) doesn't have any limitation on path @@ -35,12 +42,13 @@ Path absPath(Path path, std::optional dir, bool resolveSymlinks) if (!getcwd(buf, sizeof(buf))) #endif throw SysError("cannot get cwd"); - path = concatStrings(buf, "/", path); + scratch = concatStrings(buf, "/", path); #ifdef __GNU__ free(buf); #endif } else - path = concatStrings(*dir, "/", path); + scratch = concatStrings(*dir, "/", path); + path = scratch; } return canonPath(path, resolveSymlinks); } diff --git a/src/libutil/file-system.hh b/src/libutil/file-system.hh index 4637507b3..464efc242 100644 --- a/src/libutil/file-system.hh +++ b/src/libutil/file-system.hh @@ -41,7 +41,7 @@ struct Source; * specified directory, or the current directory otherwise. The path * is also canonicalised. */ -Path absPath(Path path, +Path absPath(PathView path, std::optional dir = {}, bool resolveSymlinks = false);