1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-30 14:10:59 +01:00

Fix relative path handling in the parser

This commit is contained in:
Eelco Dolstra 2022-05-12 18:25:36 +02:00
parent cd893a22f5
commit 1ee5dd6d96
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
18 changed files with 72 additions and 46 deletions

View file

@ -190,8 +190,8 @@ public:
Expr * parseExprFromFile(const SourcePath & path, StaticEnv & staticEnv);
/* Parse a Nix expression from the specified string. */
Expr * parseExprFromString(std::string s, const Path & basePath, StaticEnv & staticEnv);
Expr * parseExprFromString(std::string s, const Path & basePath);
Expr * parseExprFromString(std::string s, const SourcePath & basePath, StaticEnv & staticEnv);
Expr * parseExprFromString(std::string s, const SourcePath & basePath);
Expr * parseStdin();
@ -356,8 +356,13 @@ private:
friend struct ExprAttrs;
friend struct ExprLet;
Expr * parse(char * text, size_t length, FileOrigin origin, const PathView path,
const PathView basePath, StaticEnv & staticEnv);
Expr * parse(
char * text,
size_t length,
FileOrigin origin,
const PathView path,
const SourcePath & basePath,
StaticEnv & staticEnv);
public:

View file

@ -723,7 +723,7 @@ void callFlake(EvalState & state,
state.vCallFlake = allocRootValue(state.allocValue());
state.eval(state.parseExprFromString(
#include "call-flake.nix.gen.hh"
, "/"), **state.vCallFlake);
, state.rootPath("/")), **state.vCallFlake);
}
state.callFunction(**state.vCallFlake, *vLocks, *vTmp1, noPos);

View file

@ -185,10 +185,10 @@ struct ExprPath : Expr
{
std::string s; // FIXME: remove
Value v;
ExprPath(InputAccessor & accessor, std::string s)
: s(std::move(s))
ExprPath(SourcePath && path)
: s(path.path)
{
v.mkPath({accessor, this->s});
v.mkPath(std::move(path));
}
COMMON_METHODS
Value * maybeThunk(EvalState & state, Env & env);

View file

@ -31,14 +31,9 @@ namespace nix {
EvalState & state;
SymbolTable & symbols;
Expr * result;
Path basePath;
SourcePath basePath;
PosTable::Origin origin;
std::optional<ErrorInfo> error;
ParseData(EvalState & state, PosTable::Origin origin)
: state(state)
, symbols(state.symbols)
, origin(std::move(origin))
{ };
};
struct ParserFormals {
@ -513,15 +508,15 @@ string_parts_interpolated
path_start
: PATH {
Path path(absPath({$1.p, $1.l}, data->basePath));
SourcePath path { data->basePath.accessor, absPath({$1.p, $1.l}, data->basePath.path) };
/* add back in the trailing '/' to the first segment */
if ($1.p[$1.l-1] == '/' && $1.l > 1)
path += "/";
$$ = new ExprPath(*data->state.rootFS, path);
path.path += "/";
$$ = new ExprPath(std::move(path));
}
| HPATH {
Path path(getHome() + std::string($1.p + 1, $1.l - 1));
$$ = new ExprPath(*data->state.rootFS, path);
$$ = new ExprPath(data->state.rootPath(path));
}
;
@ -643,12 +638,13 @@ namespace nix {
Expr * EvalState::parse(char * text, size_t length, FileOrigin origin,
const PathView path, const PathView basePath, StaticEnv & staticEnv)
const PathView path, const SourcePath & basePath, StaticEnv & staticEnv)
{
yyscan_t scanner;
std::string file;
switch (origin) {
case foFile:
// FIXME: change this to a SourcePath.
file = path;
break;
case foStdin:
@ -658,8 +654,12 @@ Expr * EvalState::parse(char * text, size_t length, FileOrigin origin,
default:
assert(false);
}
ParseData data(*this, {file, origin});
data.basePath = basePath;
ParseData data {
.state = *this,
.symbols = symbols,
.basePath = basePath,
.origin = {file, origin},
};
yylex_init(&scanner);
yy_scan_buffer(text, length, scanner);
@ -716,18 +716,18 @@ Expr * EvalState::parseExprFromFile(const SourcePath & path, StaticEnv & staticE
// readFile hopefully have left some extra space for terminators
buffer.append("\0\0", 2);
// FIXME: pass SourcePaths
return parse(buffer.data(), buffer.size(), foFile, path.path, dirOf(path.path), staticEnv);
return parse(buffer.data(), buffer.size(), foFile, path.path, path.parent(), staticEnv);
}
Expr * EvalState::parseExprFromString(std::string s, const Path & basePath, StaticEnv & staticEnv)
Expr * EvalState::parseExprFromString(std::string s, const SourcePath & basePath, StaticEnv & staticEnv)
{
s.append("\0\0", 2);
return parse(s.data(), s.size(), foString, "", basePath, staticEnv);
}
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);
}
@ -739,7 +739,7 @@ Expr * EvalState::parseStdin()
auto buffer = drainFD(0);
// drainFD should have left some extra space for terminators
buffer.append("\0\0", 2);
return parse(buffer.data(), buffer.size(), foStdin, "", absPath("."), staticBaseEnv);
return parse(buffer.data(), buffer.size(), foStdin, "", rootPath(absPath(".")), staticBaseEnv);
}

View file

@ -375,7 +375,7 @@ void prim_exec(EvalState & state, const PosIdx pos, Value * * args, Value & v)
Expr * parsed;
try {
auto base = state.positions[pos];
parsed = state.parseExprFromString(std::move(output), base.file);
parsed = state.parseExprFromString(std::move(output), state.rootPath(base.file));
} catch (Error & e) {
e.addTrace(state.positions[pos], "While parsing the output from '%1%'", program);
throw;
@ -1464,7 +1464,7 @@ static void prim_dirOf(EvalState & state, const PosIdx pos, Value * * args, Valu
state.forceValue(*args[0], pos);
if (args[0]->type() == nPath) {
auto path = args[0]->path();
v.mkPath({path.accessor, dirOf(path.path)});
v.mkPath(path.parent());
} else {
auto path = state.coerceToString(pos, *args[0], context, false, false);
auto dir = dirOf(*path);
@ -3967,7 +3967,7 @@ void EvalState::createBaseEnv()
// the parser needs two NUL bytes as terminators; one of them
// is implied by being a C string.
"\0";
eval(parse(code, sizeof(code), foFile, derivationNixPath, "/", staticBaseEnv), *vDerivation);
eval(parse(code, sizeof(code), foFile, derivationNixPath, rootPath("/"), staticBaseEnv), *vDerivation);
}