forked from lix-project/lix
* Added an operator `~' to select paths within a derivation. E.g.,
{stdenv, bash}: derivation { builder = bash ~ /bin/sh; args = ["-e" "-x" ./builder.sh]; ... } Here the attribute `builder' will evaluate to, e.g., `/nix/store/1234abcd...-bash-2.0.1/bin/sh'.
This commit is contained in:
parent
db3e644c1c
commit
f958bcdf1f
|
@ -190,6 +190,7 @@ Expr evalExpr2(EvalState & state, Expr e)
|
||||||
if (atMatch(m, e) >> cons &&
|
if (atMatch(m, e) >> cons &&
|
||||||
(cons == "Str" ||
|
(cons == "Str" ||
|
||||||
cons == "Path" ||
|
cons == "Path" ||
|
||||||
|
cons == "SubPath" ||
|
||||||
cons == "Uri" ||
|
cons == "Uri" ||
|
||||||
cons == "Null" ||
|
cons == "Null" ||
|
||||||
cons == "Int" ||
|
cons == "Int" ||
|
||||||
|
|
|
@ -44,6 +44,7 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, void * data, char * s)
|
||||||
%nonassoc EQ NEQ
|
%nonassoc EQ NEQ
|
||||||
%right UPDATE
|
%right UPDATE
|
||||||
%left NEG
|
%left NEG
|
||||||
|
%nonassoc '~'
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
@ -79,6 +80,7 @@ expr_op
|
||||||
| expr_op OR expr_op { $$ = ATmake("OpOr(<term>, <term>)", $1, $3); }
|
| expr_op OR expr_op { $$ = ATmake("OpOr(<term>, <term>)", $1, $3); }
|
||||||
| expr_op IMPL expr_op { $$ = ATmake("OpImpl(<term>, <term>)", $1, $3); }
|
| expr_op IMPL expr_op { $$ = ATmake("OpImpl(<term>, <term>)", $1, $3); }
|
||||||
| expr_op UPDATE expr_op { $$ = ATmake("OpUpdate(<term>, <term>)", $1, $3); }
|
| expr_op UPDATE expr_op { $$ = ATmake("OpUpdate(<term>, <term>)", $1, $3); }
|
||||||
|
| expr_op '~' expr_op { $$ = ATmake("SubPath(<term>, <term>)", $1, $3); }
|
||||||
| expr_app
|
| expr_app
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ static void processBinding(EvalState & state, Expr e, StoreExpr & ne,
|
||||||
string s;
|
string s;
|
||||||
ATermList es;
|
ATermList es;
|
||||||
int n;
|
int n;
|
||||||
|
Expr e1, e2;
|
||||||
|
|
||||||
if (atMatch(m, e) >> "Str" >> s) ss.push_back(s);
|
if (atMatch(m, e) >> "Str" >> s) ss.push_back(s);
|
||||||
else if (atMatch(m, e) >> "Uri" >> s) ss.push_back(s);
|
else if (atMatch(m, e) >> "Uri" >> s) ss.push_back(s);
|
||||||
|
@ -128,6 +129,18 @@ static void processBinding(EvalState & state, Expr e, StoreExpr & ne,
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (atMatch(m, e) >> "Null") ss.push_back("");
|
else if (atMatch(m, e) >> "Null") ss.push_back("");
|
||||||
|
|
||||||
|
else if (atMatch(m, e) >> "SubPath" >> e1 >> e2) {
|
||||||
|
Strings ss2;
|
||||||
|
processBinding(state, evalExpr(state, e1), ne, ss2);
|
||||||
|
if (ss2.size() != 1)
|
||||||
|
throw Error("left-hand side of `~' operator cannot be a list");
|
||||||
|
e2 = evalExpr(state, e2);
|
||||||
|
if (!(atMatch(m, e2) >> "Str" >> s ||
|
||||||
|
(atMatch(m, e2) >> "Path" >> s)))
|
||||||
|
throw Error("right-hand side of `~' operator must be a path or string");
|
||||||
|
ss.push_back(canonPath(ss2.front() + "/" + s));
|
||||||
|
}
|
||||||
|
|
||||||
else throw badTerm("invalid derivation binding", e);
|
else throw badTerm("invalid derivation binding", e);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue