`absPath`: just take a `std::string_view`

1. Slightly more efficient

2. Easier to call

Co-authored-by: Cole Helbling <cole.e.helbling@outlook.com>
This commit is contained in:
John Ericson 2024-01-13 13:08:38 -05:00
parent 268c49264a
commit beed00c04e
3 changed files with 15 additions and 7 deletions

View File

@ -6,11 +6,11 @@ namespace nix {
CanonPath CanonPath::root = CanonPath("/"); CanonPath CanonPath::root = CanonPath("/");
CanonPath::CanonPath(std::string_view raw) CanonPath::CanonPath(std::string_view raw)
: path(absPath((Path) raw, "/")) : path(absPath(raw, "/"))
{ } { }
CanonPath::CanonPath(std::string_view raw, const CanonPath & root) 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<std::string> & elems) CanonPath::CanonPath(const std::vector<std::string> & elems)
@ -22,7 +22,7 @@ CanonPath::CanonPath(const std::vector<std::string> & elems)
CanonPath CanonPath::fromCwd(std::string_view path) CanonPath CanonPath::fromCwd(std::string_view path)
{ {
return CanonPath(unchecked_t(), absPath((Path) path)); return CanonPath(unchecked_t(), absPath(path));
} }
std::optional<CanonPath> CanonPath::parent() const std::optional<CanonPath> CanonPath::parent() const

View File

@ -21,9 +21,16 @@ namespace fs = std::filesystem;
namespace nix { namespace nix {
Path absPath(Path path, std::optional<PathView> dir, bool resolveSymlinks) Path absPath(PathView path, std::optional<PathView> dir, bool resolveSymlinks)
{ {
std::string scratch;
if (path[0] != '/') { 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) { if (!dir) {
#ifdef __GNU__ #ifdef __GNU__
/* GNU (aka. GNU/Hurd) doesn't have any limitation on path /* GNU (aka. GNU/Hurd) doesn't have any limitation on path
@ -35,12 +42,13 @@ Path absPath(Path path, std::optional<PathView> dir, bool resolveSymlinks)
if (!getcwd(buf, sizeof(buf))) if (!getcwd(buf, sizeof(buf)))
#endif #endif
throw SysError("cannot get cwd"); throw SysError("cannot get cwd");
path = concatStrings(buf, "/", path); scratch = concatStrings(buf, "/", path);
#ifdef __GNU__ #ifdef __GNU__
free(buf); free(buf);
#endif #endif
} else } else
path = concatStrings(*dir, "/", path); scratch = concatStrings(*dir, "/", path);
path = scratch;
} }
return canonPath(path, resolveSymlinks); return canonPath(path, resolveSymlinks);
} }

View File

@ -41,7 +41,7 @@ struct Source;
* specified directory, or the current directory otherwise. The path * specified directory, or the current directory otherwise. The path
* is also canonicalised. * is also canonicalised.
*/ */
Path absPath(Path path, Path absPath(PathView path,
std::optional<PathView> dir = {}, std::optional<PathView> dir = {},
bool resolveSymlinks = false); bool resolveSymlinks = false);