aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/parser.y
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2023-04-06 13:15:50 +0200
committerEelco Dolstra <edolstra@gmail.com>2023-04-06 13:15:50 +0200
commit94812cca98fbb157e5f64a15a85a2b852d289feb (patch)
tree2f02c31fc42c7286f3c35dfd3ff1a88f235ab65b /src/libexpr/parser.y
parent5256ba6d87403f2b58ec4586c26d8fb14027252f (diff)
Backport SourcePath from the lazy-trees branch
This introduces the SourcePath type from lazy-trees as an abstraction for accessing files from inputs that may not be materialized in the real filesystem (e.g. Git repositories). Currently, however, it's just a wrapper around CanonPath, so it shouldn't change any behaviour. (On lazy-trees, SourcePath is a <InputAccessor, CanonPath> tuple.)
Diffstat (limited to 'src/libexpr/parser.y')
-rw-r--r--src/libexpr/parser.y52
1 files changed, 20 insertions, 32 deletions
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index 97e615c37..8b67665db 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -31,7 +31,7 @@ namespace nix {
EvalState & state;
SymbolTable & symbols;
Expr * result;
- Path basePath;
+ SourcePath basePath;
PosTable::Origin origin;
std::optional<ErrorInfo> error;
};
@@ -509,7 +509,7 @@ string_parts_interpolated
path_start
: PATH {
- Path path(absPath({$1.p, $1.l}, data->basePath));
+ Path path(absPath({$1.p, $1.l}, data->basePath.path.abs()));
/* add back in the trailing '/' to the first segment */
if ($1.p[$1.l-1] == '/' && $1.l > 1)
path += "/";
@@ -651,7 +651,7 @@ Expr * EvalState::parse(
char * text,
size_t length,
Pos::Origin origin,
- Path basePath,
+ const SourcePath & basePath,
std::shared_ptr<StaticEnv> & staticEnv)
{
yyscan_t scanner;
@@ -675,48 +675,36 @@ Expr * EvalState::parse(
}
-Path resolveExprPath(Path path)
+SourcePath resolveExprPath(const SourcePath & path)
{
- assert(path[0] == '/');
-
- unsigned int followCount = 0, maxFollow = 1024;
-
/* If `path' is a symlink, follow it. This is so that relative
path references work. */
- struct stat st;
- while (true) {
- // Basic cycle/depth limit to avoid infinite loops.
- if (++followCount >= maxFollow)
- throw Error("too many symbolic links encountered while traversing the path '%s'", path);
- st = lstat(path);
- if (!S_ISLNK(st.st_mode)) break;
- path = absPath(readLink(path), dirOf(path));
- }
+ auto path2 = path.resolveSymlinks();
/* If `path' refers to a directory, append `/default.nix'. */
- if (S_ISDIR(st.st_mode))
- path = canonPath(path + "/default.nix");
+ if (path2.lstat().type == InputAccessor::tDirectory)
+ return path2 + "default.nix";
- return path;
+ return path2;
}
-Expr * EvalState::parseExprFromFile(const Path & path)
+Expr * EvalState::parseExprFromFile(const SourcePath & path)
{
return parseExprFromFile(path, staticBaseEnv);
}
-Expr * EvalState::parseExprFromFile(const Path & path, std::shared_ptr<StaticEnv> & staticEnv)
+Expr * EvalState::parseExprFromFile(const SourcePath & path, std::shared_ptr<StaticEnv> & staticEnv)
{
- auto buffer = readFile(path);
- // readFile should have left some extra space for terminators
+ auto buffer = path.readFile();
+ // readFile hopefully have left some extra space for terminators
buffer.append("\0\0", 2);
- return parse(buffer.data(), buffer.size(), path, dirOf(path), staticEnv);
+ return parse(buffer.data(), buffer.size(), path.path.abs(), path.parent(), staticEnv);
}
-Expr * EvalState::parseExprFromString(std::string s_, const Path & basePath, std::shared_ptr<StaticEnv> & staticEnv)
+Expr * EvalState::parseExprFromString(std::string s_, const SourcePath & basePath, std::shared_ptr<StaticEnv> & staticEnv)
{
auto s = make_ref<std::string>(std::move(s_));
s->append("\0\0", 2);
@@ -724,7 +712,7 @@ Expr * EvalState::parseExprFromString(std::string s_, const Path & basePath, std
}
-Expr * EvalState::parseExprFromString(std::string s, const Path & basePath)
+Expr * EvalState::parseExprFromString(std::string s, const SourcePath & basePath)
{
return parseExprFromString(std::move(s), basePath, staticBaseEnv);
}
@@ -737,7 +725,7 @@ Expr * EvalState::parseStdin()
// drainFD should have left some extra space for terminators
buffer.append("\0\0", 2);
auto s = make_ref<std::string>(std::move(buffer));
- return parse(s->data(), s->size(), Pos::Stdin{.source = s}, absPath("."), staticBaseEnv);
+ return parse(s->data(), s->size(), Pos::Stdin{.source = s}, rootPath(CanonPath::fromCwd()), staticBaseEnv);
}
@@ -757,13 +745,13 @@ void EvalState::addToSearchPath(const std::string & s)
}
-Path EvalState::findFile(const std::string_view path)
+SourcePath EvalState::findFile(const std::string_view path)
{
return findFile(searchPath, path);
}
-Path EvalState::findFile(SearchPath & searchPath, const std::string_view path, const PosIdx pos)
+SourcePath EvalState::findFile(SearchPath & searchPath, const std::string_view path, const PosIdx pos)
{
for (auto & i : searchPath) {
std::string suffix;
@@ -779,11 +767,11 @@ Path EvalState::findFile(SearchPath & searchPath, const std::string_view path, c
auto r = resolveSearchPathElem(i);
if (!r.first) continue;
Path res = r.second + suffix;
- if (pathExists(res)) return canonPath(res);
+ if (pathExists(res)) return CanonPath(canonPath(res));
}
if (hasPrefix(path, "nix/"))
- return concatStrings(corepkgsPrefix, path.substr(4));
+ return CanonPath(concatStrings(corepkgsPrefix, path.substr(4)));
debugThrow(ThrownError({
.msg = hintfmt(evalSettings.pureEval