diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index c59203aa5..67bdd4de4 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -309,8 +309,8 @@ private: friend struct ExprAttrs; friend struct ExprLet; - Expr * parse(char * text, size_t length, FileOrigin origin, const Path & path, - const Path & basePath, StaticEnv & staticEnv); + Expr * parse(char * text, size_t length, FileOrigin origin, const PathView path, + const PathView basePath, StaticEnv & staticEnv); public: diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 7a8e93c12..dd76fd66f 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -598,7 +598,7 @@ namespace nix { Expr * EvalState::parse(char * text, size_t length, FileOrigin origin, - const Path & path, const Path & basePath, StaticEnv & staticEnv) + const PathView path, const PathView basePath, StaticEnv & staticEnv) { yyscan_t scanner; ParseData data(*this); diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc index 1833c954e..13cb142f8 100644 --- a/src/libstore/optimise-store.cc +++ b/src/libstore/optimise-store.cc @@ -26,7 +26,7 @@ static void makeWritable(const Path & path) struct MakeReadOnly { Path path; - MakeReadOnly(const Path & path) : path(path) { } + MakeReadOnly(const PathView path) : path(path) { } ~MakeReadOnly() { try { @@ -205,12 +205,13 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, /* Make the containing directory writable, but only if it's not the store itself (we don't want or need to mess with its permissions). */ - bool mustToggle = dirOf(path) != realStoreDir.get(); - if (mustToggle) makeWritable(dirOf(path)); + const Path dirOfPath(dirOf(path)); + bool mustToggle = dirOfPath != realStoreDir.get(); + if (mustToggle) makeWritable(dirOfPath); /* When we're done, make the directory read-only again and reset its timestamp back to 0. */ - MakeReadOnly makeReadOnly(mustToggle ? dirOf(path) : ""); + MakeReadOnly makeReadOnly(mustToggle ? dirOfPath : ""); Path tempLink = (format("%1%/.tmp-link-%2%-%3%") % realStoreDir % getpid() % random()).str(); diff --git a/src/libstore/parsed-derivations.cc b/src/libstore/parsed-derivations.cc index caddba9b1..8c65053e4 100644 --- a/src/libstore/parsed-derivations.cc +++ b/src/libstore/parsed-derivations.cc @@ -170,7 +170,7 @@ std::string writeStructuredAttrsShell(const nlohmann::json & json) auto handleSimpleType = [](const nlohmann::json & value) -> std::optional { if (value.is_string()) - return shellEscape(value); + return shellEscape(value.get()); if (value.is_number()) { auto f = value.get(); diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 1f1f2c861..692bcb180 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -81,7 +81,7 @@ void replaceEnv(std::map newEnv) } -Path absPath(Path path, std::optional dir, bool resolveSymlinks) +Path absPath(Path path, std::optional dir, bool resolveSymlinks) { if (path[0] != '/') { if (!dir) { @@ -95,12 +95,12 @@ Path absPath(Path path, std::optional dir, bool resolveSymlinks) if (!getcwd(buf, sizeof(buf))) #endif throw SysError("cannot get cwd"); - dir = buf; + path = concatStrings(buf, "/", path); #ifdef __GNU__ free(buf); #endif - } - path = *dir + "/" + path; + } else + path = concatStrings(*dir, "/", path); } return canonPath(path, resolveSymlinks); } @@ -172,7 +172,7 @@ Path canonPath(PathView path, bool resolveSymlinks) } -Path dirOf(const Path & path) +Path dirOf(const PathView path) { Path::size_type pos = path.rfind('/'); if (pos == string::npos) @@ -1344,9 +1344,11 @@ std::string toLower(const std::string & s) } -std::string shellEscape(const std::string & s) +std::string shellEscape(const std::string_view s) { - std::string r = "'"; + std::string r; + r.reserve(s.size() + 2); + r += "'"; for (auto & i : s) if (i == '\'') r += "'\\''"; else r += i; r += '\''; @@ -1751,7 +1753,7 @@ void bind(int fd, const std::string & path) if (path.size() + 1 >= sizeof(addr.sun_path)) { Pid pid = startProcess([&]() { - auto dir = dirOf(path); + Path dir = dirOf(path); if (chdir(dir.c_str()) == -1) throw SysError("chdir to '%s' failed", dir); std::string base(baseNameOf(path)); @@ -1780,7 +1782,7 @@ void connect(int fd, const std::string & path) if (path.size() + 1 >= sizeof(addr.sun_path)) { Pid pid = startProcess([&]() { - auto dir = dirOf(path); + Path dir = dirOf(path); if (chdir(dir.c_str()) == -1) throw SysError("chdir to '%s' failed", dir); std::string base(baseNameOf(path)); diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 369c44f78..579a42785 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -49,7 +49,7 @@ void clearEnv(); specified directory, or the current directory otherwise. The path is also canonicalised. */ Path absPath(Path path, - std::optional dir = {}, + std::optional dir = {}, bool resolveSymlinks = false); /* Canonicalise a path by removing all `.' or `..' components and @@ -62,7 +62,7 @@ Path canonPath(PathView path, bool resolveSymlinks = false); everything before the final `/'. If the path is the root or an immediate child thereof (e.g., `/foo'), this means `/' is returned.*/ -Path dirOf(const Path & path); +Path dirOf(const PathView path); /* Return the base name of the given canonical path, i.e., everything following the final `/' (trailing slashes are removed). */ @@ -148,6 +148,9 @@ Path getDataDir(); /* Create a directory and all its parents, if necessary. Returns the list of created directories, in order of creation. */ Paths createDirs(const Path & path); +inline Paths createDirs(PathView path) { + return createDirs(Path(path)); +} /* Create a symlink. */ void createSymlink(const Path & target, const Path & link, @@ -187,6 +190,7 @@ public: void cancel(); void reset(const Path & p, bool recursive = true); operator Path() const { return path; } + operator PathView() const { return path; } }; @@ -491,7 +495,7 @@ std::string toLower(const std::string & s); /* Escape a string as a shell word. */ -std::string shellEscape(const std::string & s); +std::string shellEscape(const std::string_view s); /* Exception handling in destructors: print an error message, then diff --git a/src/nix/develop.cc b/src/nix/develop.cc index a8ca1cac2..42e13436a 100644 --- a/src/nix/develop.cc +++ b/src/nix/develop.cc @@ -472,9 +472,11 @@ struct CmdDevelop : Common, MixEnvironment else { script = "[ -n \"$PS1\" ] && [ -e ~/.bashrc ] && source ~/.bashrc;\n" + script; if (developSettings.bashPrompt != "") - script += fmt("[ -n \"$PS1\" ] && PS1=%s;\n", shellEscape(developSettings.bashPrompt)); + script += fmt("[ -n \"$PS1\" ] && PS1=%s;\n", + shellEscape(developSettings.bashPrompt.get())); if (developSettings.bashPromptSuffix != "") - script += fmt("[ -n \"$PS1\" ] && PS1+=%s;\n", shellEscape(developSettings.bashPromptSuffix)); + script += fmt("[ -n \"$PS1\" ] && PS1+=%s;\n", + shellEscape(developSettings.bashPromptSuffix.get())); } writeFull(rcFileFd.get(), script); diff --git a/src/resolve-system-dependencies/resolve-system-dependencies.cc b/src/resolve-system-dependencies/resolve-system-dependencies.cc index 27cf53a45..98c969437 100644 --- a/src/resolve-system-dependencies/resolve-system-dependencies.cc +++ b/src/resolve-system-dependencies/resolve-system-dependencies.cc @@ -107,7 +107,7 @@ Path resolveSymlink(const Path & path) auto target = readLink(path); return hasPrefix(target, "/") ? target - : dirOf(path) + "/" + target; + : concatStrings(dirOf(path), "/", target); } std::set resolveTree(const Path & path, PathSet & deps)