mirror of
https://github.com/NixOS/nix.git
synced 2025-11-17 07:52:43 +01:00
* In string contexts containing derivations
(e.g. "${somePkg}/bin/foo"), store the original derivation
expression in the context.
This commit is contained in:
parent
25fc95d56d
commit
6d1abdc6d9
12 changed files with 123 additions and 101 deletions
|
|
@ -242,7 +242,7 @@ LocalNoInline(Expr updateAttrs(Expr e1, Expr e2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string evalString(EvalState & state, Expr e, PathSet & context)
|
string evalString(EvalState & state, Expr e, ATermList & context)
|
||||||
{
|
{
|
||||||
e = evalExpr(state, e);
|
e = evalExpr(state, e);
|
||||||
string s;
|
string s;
|
||||||
|
|
@ -254,11 +254,10 @@ string evalString(EvalState & state, Expr e, PathSet & context)
|
||||||
|
|
||||||
string evalStringNoCtx(EvalState & state, Expr e)
|
string evalStringNoCtx(EvalState & state, Expr e)
|
||||||
{
|
{
|
||||||
PathSet context;
|
ATermList context;
|
||||||
string s = evalString(state, e, context);
|
string s = evalString(state, e, context);
|
||||||
if (!context.empty())
|
if (context != ATempty)
|
||||||
throw EvalError(format("the string `%1%' is not allowed to refer to a store path (such as `%2%')")
|
throw EvalError(format("the string `%1%' is not allowed to refer to a store path") % s);
|
||||||
% s % *(context.begin()));
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -312,7 +311,7 @@ ATermList flattenList(EvalState & state, Expr e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string coerceToString(EvalState & state, Expr e, PathSet & context,
|
string coerceToString(EvalState & state, Expr e, Context & context,
|
||||||
bool coerceMore, bool copyToStore)
|
bool coerceMore, bool copyToStore)
|
||||||
{
|
{
|
||||||
e = evalExpr(state, e);
|
e = evalExpr(state, e);
|
||||||
|
|
@ -343,7 +342,7 @@ string coerceToString(EvalState & state, Expr e, PathSet & context,
|
||||||
% path % dstPath);
|
% path % dstPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.insert(dstPath);
|
context.set(toATerm(dstPath), makeNull());
|
||||||
return dstPath;
|
return dstPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -351,6 +350,7 @@ string coerceToString(EvalState & state, Expr e, PathSet & context,
|
||||||
if (matchAttrs(e, es)) {
|
if (matchAttrs(e, es)) {
|
||||||
Expr e2 = queryAttr(e, "outPath");
|
Expr e2 = queryAttr(e, "outPath");
|
||||||
if (!e2) throwTypeError("cannot coerce an attribute set (except a derivation) to a string");
|
if (!e2) throwTypeError("cannot coerce an attribute set (except a derivation) to a string");
|
||||||
|
/* XXX handle derivation */
|
||||||
return coerceToString(state, e2, context, coerceMore, copyToStore);
|
return coerceToString(state, e2, context, coerceMore, copyToStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -385,9 +385,9 @@ string coerceToString(EvalState & state, Expr e, PathSet & context,
|
||||||
static ATerm concatStrings(EvalState & state, ATermVector & args,
|
static ATerm concatStrings(EvalState & state, ATermVector & args,
|
||||||
string separator = "")
|
string separator = "")
|
||||||
{
|
{
|
||||||
if (args.empty()) return makeStr("", PathSet());
|
if (args.empty()) return makeStr("", ATempty);
|
||||||
|
|
||||||
PathSet context;
|
Context context;
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
|
|
||||||
/* If the first element is a path, then the result will also be a
|
/* If the first element is a path, then the result will also be a
|
||||||
|
|
@ -403,7 +403,7 @@ static ATerm concatStrings(EvalState & state, ATermVector & args,
|
||||||
s << coerceToString(state, *i, context, false, !isPath);
|
s << coerceToString(state, *i, context, false, !isPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPath && !context.empty())
|
if (isPath && context.size() != 0)
|
||||||
throw EvalError(format("a string that refers to a store path cannot be appended to a path, in `%1%'")
|
throw EvalError(format("a string that refers to a store path cannot be appended to a path, in `%1%'")
|
||||||
% s.str());
|
% s.str());
|
||||||
|
|
||||||
|
|
@ -413,7 +413,7 @@ static ATerm concatStrings(EvalState & state, ATermVector & args,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path coerceToPath(EvalState & state, Expr e, PathSet & context)
|
Path coerceToPath(EvalState & state, Expr e, Context & context)
|
||||||
{
|
{
|
||||||
string path = coerceToString(state, e, context, false, false);
|
string path = coerceToString(state, e, context, false, false);
|
||||||
if (path == "" || path[0] != '/')
|
if (path == "" || path[0] != '/')
|
||||||
|
|
@ -600,7 +600,7 @@ LocalNoInline(Expr evalPlusConcat(EvalState & state, Expr e))
|
||||||
"concatenation of a derivation and a path is deprecated; "
|
"concatenation of a derivation and a path is deprecated; "
|
||||||
"you should write `drv + \"%1%\"' instead of `drv + %1%'")
|
"you should write `drv + \"%1%\"' instead of `drv + %1%'")
|
||||||
% aterm2String(p));
|
% aterm2String(p));
|
||||||
PathSet context;
|
Context context;
|
||||||
return makeStr(
|
return makeStr(
|
||||||
coerceToString(state, makeSelect(e1, toATerm("outPath")), context)
|
coerceToString(state, makeSelect(e1, toATerm("outPath")), context)
|
||||||
+ aterm2String(p), context);
|
+ aterm2String(p), context);
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ Expr evalFile(EvalState & state, const Path & path);
|
||||||
Expr strictEvalExpr(EvalState & state, Expr e);
|
Expr strictEvalExpr(EvalState & state, Expr e);
|
||||||
|
|
||||||
/* Specific results. */
|
/* Specific results. */
|
||||||
string evalString(EvalState & state, Expr e, PathSet & context);
|
string evalString(EvalState & state, Expr e, ATermList & context);
|
||||||
string evalStringNoCtx(EvalState & state, Expr e);
|
string evalStringNoCtx(EvalState & state, Expr e);
|
||||||
int evalInt(EvalState & state, Expr e);
|
int evalInt(EvalState & state, Expr e);
|
||||||
bool evalBool(EvalState & state, Expr e);
|
bool evalBool(EvalState & state, Expr e);
|
||||||
|
|
@ -74,13 +74,13 @@ ATermList flattenList(EvalState & state, Expr e);
|
||||||
/* String coercion. Converts strings, paths and derivations to a
|
/* String coercion. Converts strings, paths and derivations to a
|
||||||
string. If `coerceMore' is set, also converts nulls, integers,
|
string. If `coerceMore' is set, also converts nulls, integers,
|
||||||
booleans and lists to a string. */
|
booleans and lists to a string. */
|
||||||
string coerceToString(EvalState & state, Expr e, PathSet & context,
|
string coerceToString(EvalState & state, Expr e, Context & context,
|
||||||
bool coerceMore = false, bool copyToStore = true);
|
bool coerceMore = false, bool copyToStore = true);
|
||||||
|
|
||||||
/* Path coercion. Converts strings, paths and derivations to a path.
|
/* Path coercion. Converts strings, paths and derivations to a path.
|
||||||
The result is guaranteed to be an canonicalised, absolute path.
|
The result is guaranteed to be an canonicalised, absolute path.
|
||||||
Nothing is copied to the store. */
|
Nothing is copied to the store. */
|
||||||
Path coerceToPath(EvalState & state, Expr e, PathSet & context);
|
Path coerceToPath(EvalState & state, Expr e, Context & context);
|
||||||
|
|
||||||
/* Automatically call a function for which each argument has a default
|
/* Automatically call a function for which each argument has a default
|
||||||
value or has a binding in the `args' map. Note: result is a call,
|
value or has a binding in the `args' map. Note: result is a call,
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,12 @@ static XMLAttrs singletonAttrs(const string & name, const string & value)
|
||||||
typedef set<Expr> ExprSet;
|
typedef set<Expr> ExprSet;
|
||||||
|
|
||||||
|
|
||||||
static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context,
|
static void printTermAsXML(Expr e, XMLWriter & doc, Context & context,
|
||||||
ExprSet & drvsSeen);
|
ExprSet & drvsSeen);
|
||||||
|
|
||||||
|
|
||||||
static void showAttrs(const ATermMap & attrs, XMLWriter & doc,
|
static void showAttrs(const ATermMap & attrs, XMLWriter & doc,
|
||||||
PathSet & context, ExprSet & drvsSeen)
|
Context & context, ExprSet & drvsSeen)
|
||||||
{
|
{
|
||||||
StringSet names;
|
StringSet names;
|
||||||
for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i)
|
for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i)
|
||||||
|
|
@ -65,7 +65,7 @@ static void printPatternAsXML(Pattern pat, XMLWriter & doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context,
|
static void printTermAsXML(Expr e, XMLWriter & doc, Context & context,
|
||||||
ExprSet & drvsSeen)
|
ExprSet & drvsSeen)
|
||||||
{
|
{
|
||||||
XMLAttrs attrs;
|
XMLAttrs attrs;
|
||||||
|
|
@ -144,7 +144,7 @@ static void printTermAsXML(Expr e, XMLWriter & doc, PathSet & context,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void printTermAsXML(Expr e, std::ostream & out, PathSet & context)
|
void printTermAsXML(Expr e, std::ostream & out, Context & context)
|
||||||
{
|
{
|
||||||
XMLWriter doc(true, out);
|
XMLWriter doc(true, out);
|
||||||
XMLOpenElement root(doc, "expr");
|
XMLOpenElement root(doc, "expr");
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
void printTermAsXML(Expr e, std::ostream & out, PathSet & context);
|
void printTermAsXML(Expr e, std::ostream & out, Context & context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ string DrvInfo::queryDrvPath(EvalState & state) const
|
||||||
if (a && matchPath(evalExpr(state, a), t))
|
if (a && matchPath(evalExpr(state, a), t))
|
||||||
return aterm2String(t);
|
return aterm2String(t);
|
||||||
|
|
||||||
PathSet context;
|
Context context;
|
||||||
(string &) drvPath = a ? coerceToPath(state, a, context) : "";
|
(string &) drvPath = a ? coerceToPath(state, a, context) : "";
|
||||||
}
|
}
|
||||||
return drvPath;
|
return drvPath;
|
||||||
|
|
@ -29,7 +29,7 @@ string DrvInfo::queryOutPath(EvalState & state) const
|
||||||
if (outPath == "") {
|
if (outPath == "") {
|
||||||
Expr a = attrs->get(toATerm("outPath"));
|
Expr a = attrs->get(toATerm("outPath"));
|
||||||
if (!a) throw TypeError("output path missing");
|
if (!a) throw TypeError("output path missing");
|
||||||
PathSet context;
|
Context context;
|
||||||
(string &) outPath = coerceToPath(state, a, context);
|
(string &) outPath = coerceToPath(state, a, context);
|
||||||
}
|
}
|
||||||
return outPath;
|
return outPath;
|
||||||
|
|
@ -49,7 +49,7 @@ MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const
|
||||||
for (ATermMap::const_iterator i = attrs2.begin(); i != attrs2.end(); ++i) {
|
for (ATermMap::const_iterator i = attrs2.begin(); i != attrs2.end(); ++i) {
|
||||||
Expr e = evalExpr(state, i->value);
|
Expr e = evalExpr(state, i->value);
|
||||||
string s;
|
string s;
|
||||||
PathSet context;
|
ATermList context;
|
||||||
MetaValue value;
|
MetaValue value;
|
||||||
int n;
|
int n;
|
||||||
ATermList es;
|
ATermList es;
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,8 @@ Int | int | Expr |
|
||||||
Str | string ATermList | Expr |
|
Str | string ATermList | Expr |
|
||||||
Str | string | Expr | ObsoleteStr
|
Str | string | Expr | ObsoleteStr
|
||||||
|
|
||||||
|
ContextElem | string Expr | ContextElem |
|
||||||
|
|
||||||
# Internal to the parser, doesn't occur in ASTs.
|
# Internal to the parser, doesn't occur in ASTs.
|
||||||
IndStr | string | Expr |
|
IndStr | string | Expr |
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -336,25 +336,47 @@ Expr makeBool(bool b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool matchStr(Expr e, string & s, PathSet & context)
|
bool matchStr(Expr e, string & s, ATermList & context)
|
||||||
{
|
{
|
||||||
ATermList l;
|
|
||||||
ATerm s_;
|
ATerm s_;
|
||||||
|
if (!matchStr(e, s_, context)) return false;
|
||||||
if (!matchStr(e, s_, l)) return false;
|
|
||||||
|
|
||||||
s = aterm2String(s_);
|
s = aterm2String(s_);
|
||||||
|
|
||||||
for (ATermIterator i(l); i; ++i)
|
|
||||||
context.insert(aterm2String(*i));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Expr makeStr(const string & s, const PathSet & context)
|
bool matchStr(Expr e, string & s, Context & context)
|
||||||
{
|
{
|
||||||
return makeStr(toATerm(s), toATermList(context));
|
ATermList c;
|
||||||
|
if (!matchStr(e, s, c)) return false;
|
||||||
|
matchContext(c, context);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Expr makeStr(const string & s, ATermList context)
|
||||||
|
{
|
||||||
|
return makeStr(toATerm(s), context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Expr makeStr(const string & s, const Context & context)
|
||||||
|
{
|
||||||
|
ATermList l = ATempty;
|
||||||
|
/* !!! should define a canonical ordering of context elements. */
|
||||||
|
foreach (Context::const_iterator, i, context)
|
||||||
|
l = ATinsert(l, makeContextElem(i->key, i->value));
|
||||||
|
return makeStr(s, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void matchContext(ATermList context, Context & result)
|
||||||
|
{
|
||||||
|
for (ATermIterator i(context); i; ++i) {
|
||||||
|
ATerm s, e;
|
||||||
|
if (!matchContextElem(*i, s, e)) abort();
|
||||||
|
result.set(s, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -380,7 +402,7 @@ string showType(Expr e)
|
||||||
|
|
||||||
string showValue(Expr e)
|
string showValue(Expr e)
|
||||||
{
|
{
|
||||||
PathSet context;
|
ATermList context;
|
||||||
string s;
|
string s;
|
||||||
ATerm s2;
|
ATerm s2;
|
||||||
int i;
|
int i;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ typedef ATerm DefaultValue;
|
||||||
typedef ATerm Pos;
|
typedef ATerm Pos;
|
||||||
typedef ATerm Pattern;
|
typedef ATerm Pattern;
|
||||||
typedef ATerm ATermBool;
|
typedef ATerm ATermBool;
|
||||||
|
typedef ATerm ContextElem;
|
||||||
|
|
||||||
|
|
||||||
/* A STL vector of ATerms. Should be used with great care since it's
|
/* A STL vector of ATerms. Should be used with great care since it's
|
||||||
|
|
@ -104,11 +105,18 @@ Expr canonicaliseExpr(Expr e);
|
||||||
Expr makeBool(bool b);
|
Expr makeBool(bool b);
|
||||||
|
|
||||||
|
|
||||||
/* Manipulation of Str() nodes. Note: matchStr() does not clear
|
/* Manipulation of Str() nodes. */
|
||||||
context! */
|
typedef ATermMap Context;
|
||||||
bool matchStr(Expr e, string & s, PathSet & context);
|
|
||||||
|
|
||||||
Expr makeStr(const string & s, const PathSet & context = PathSet());
|
bool matchStr(Expr e, string & s, ATermList & context);
|
||||||
|
|
||||||
|
bool matchStr(Expr e, string & s, Context & context);
|
||||||
|
|
||||||
|
Expr makeStr(const string & s, ATermList context = ATempty);
|
||||||
|
|
||||||
|
Expr makeStr(const string & s, const Context & context);
|
||||||
|
|
||||||
|
void matchContext(ATermList context, Context & result);
|
||||||
|
|
||||||
|
|
||||||
/* Showing types, values. */
|
/* Showing types, values. */
|
||||||
|
|
|
||||||
|
|
@ -93,16 +93,17 @@ static Expr prim_currentTime(EvalState & state, const ATermVector & args)
|
||||||
argument. */
|
argument. */
|
||||||
static Expr prim_import(EvalState & state, const ATermVector & args)
|
static Expr prim_import(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
Context context;
|
||||||
Path path = coerceToPath(state, args[0], context);
|
Path path = coerceToPath(state, args[0], context);
|
||||||
|
|
||||||
for (PathSet::iterator i = context.begin(); i != context.end(); ++i) {
|
foreach (Context::const_iterator, i, context) {
|
||||||
assert(isStorePath(*i));
|
Path p = aterm2String(i->key);
|
||||||
if (!store->isValidPath(*i))
|
assert(isStorePath(p));
|
||||||
|
if (!store->isValidPath(p))
|
||||||
throw EvalError(format("cannot import `%1%', since path `%2%' is not valid")
|
throw EvalError(format("cannot import `%1%', since path `%2%' is not valid")
|
||||||
% path % *i);
|
% path % p);
|
||||||
if (isDerivation(*i))
|
if (isDerivation(p))
|
||||||
store->buildDerivations(singleton<PathSet>(*i));
|
store->buildDerivations(singleton<PathSet>(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
return evalFile(state, path);
|
return evalFile(state, path);
|
||||||
|
|
@ -136,8 +137,8 @@ static Expr prim_isInt(EvalState & state, const ATermVector & args)
|
||||||
static Expr prim_isString(EvalState & state, const ATermVector & args)
|
static Expr prim_isString(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
string s;
|
string s;
|
||||||
PathSet l;
|
ATermList context;
|
||||||
return makeBool(matchStr(evalExpr(state, args[0]), s, l));
|
return makeBool(matchStr(evalExpr(state, args[0]), s, context));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine whether the argument is an Bool. */
|
/* Determine whether the argument is an Bool. */
|
||||||
|
|
@ -197,7 +198,7 @@ static Expr prim_genericClosure(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
static Expr prim_abort(EvalState & state, const ATermVector & args)
|
static Expr prim_abort(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
ATermList context;
|
||||||
throw Abort(format("evaluation aborted with the following error message: `%1%'") %
|
throw Abort(format("evaluation aborted with the following error message: `%1%'") %
|
||||||
evalString(state, args[0], context));
|
evalString(state, args[0], context));
|
||||||
}
|
}
|
||||||
|
|
@ -205,7 +206,7 @@ static Expr prim_abort(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
static Expr prim_throw(EvalState & state, const ATermVector & args)
|
static Expr prim_throw(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
ATermList context;
|
||||||
throw ThrownError(format("user-thrown exception: %1%") %
|
throw ThrownError(format("user-thrown exception: %1%") %
|
||||||
evalString(state, args[0], context));
|
evalString(state, args[0], context));
|
||||||
}
|
}
|
||||||
|
|
@ -213,7 +214,7 @@ static Expr prim_throw(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
static Expr prim_addErrorContext(EvalState & state, const ATermVector & args)
|
static Expr prim_addErrorContext(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
ATermList context;
|
||||||
try {
|
try {
|
||||||
return evalExpr(state, args[1]);
|
return evalExpr(state, args[1]);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
|
|
@ -257,7 +258,7 @@ static Expr prim_trace(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
Expr e = evalExpr(state, args[0]);
|
Expr e = evalExpr(state, args[0]);
|
||||||
string s;
|
string s;
|
||||||
PathSet context;
|
ATermList context;
|
||||||
if (matchStr(e, s, context))
|
if (matchStr(e, s, context))
|
||||||
printMsg(lvlError, format("trace: %1%") % s);
|
printMsg(lvlError, format("trace: %1%") % s);
|
||||||
else
|
else
|
||||||
|
|
@ -360,7 +361,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
|
||||||
/* Build the derivation expression by processing the attributes. */
|
/* Build the derivation expression by processing the attributes. */
|
||||||
Derivation drv;
|
Derivation drv;
|
||||||
|
|
||||||
PathSet context;
|
Context context;
|
||||||
|
|
||||||
string outputHash, outputHashAlgo;
|
string outputHash, outputHashAlgo;
|
||||||
bool outputHashRecursive = false;
|
bool outputHashRecursive = false;
|
||||||
|
|
@ -421,8 +422,8 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
|
||||||
/* Everything in the context of the strings in the derivation
|
/* Everything in the context of the strings in the derivation
|
||||||
attributes should be added as dependencies of the resulting
|
attributes should be added as dependencies of the resulting
|
||||||
derivation. */
|
derivation. */
|
||||||
foreach (PathSet::iterator, i, context) {
|
foreach (Context::const_iterator, i, context) {
|
||||||
Path path = *i;
|
Path path = aterm2String(i->key);
|
||||||
|
|
||||||
/* Paths marked with `=' denote that the path of a derivation
|
/* Paths marked with `=' denote that the path of a derivation
|
||||||
is explicitly passed to the builder. Since that allows the
|
is explicitly passed to the builder. Since that allows the
|
||||||
|
|
@ -523,11 +524,12 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
|
||||||
state.drvHashes[drvPath] = hashDerivationModulo(state, drv);
|
state.drvHashes[drvPath] = hashDerivationModulo(state, drv);
|
||||||
|
|
||||||
/* !!! assumes a single output */
|
/* !!! assumes a single output */
|
||||||
|
/* XXX makeNull? */
|
||||||
ATermMap outAttrs(2);
|
ATermMap outAttrs(2);
|
||||||
outAttrs.set(toATerm("outPath"),
|
outAttrs.set(toATerm("outPath"),
|
||||||
makeAttrRHS(makeStr(outPath, singleton<PathSet>(drvPath)), makeNoPos()));
|
makeAttrRHS(makeStr(outPath, ATmakeList1(makeContextElem(toATerm(drvPath), makeNull()))), makeNoPos()));
|
||||||
outAttrs.set(toATerm("drvPath"),
|
outAttrs.set(toATerm("drvPath"),
|
||||||
makeAttrRHS(makeStr(drvPath, singleton<PathSet>("=" + drvPath)), makeNoPos()));
|
makeAttrRHS(makeStr(drvPath, ATmakeList1(makeContextElem(toATerm("=" + drvPath), makeNull()))), makeNoPos()));
|
||||||
|
|
||||||
return makeAttrs(outAttrs);
|
return makeAttrs(outAttrs);
|
||||||
}
|
}
|
||||||
|
|
@ -561,7 +563,7 @@ static Expr prim_derivationLazy(EvalState & state, const ATermVector & args)
|
||||||
/* Convert the argument to a path. !!! obsolete? */
|
/* Convert the argument to a path. !!! obsolete? */
|
||||||
static Expr prim_toPath(EvalState & state, const ATermVector & args)
|
static Expr prim_toPath(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
Context context;
|
||||||
string path = coerceToPath(state, args[0], context);
|
string path = coerceToPath(state, args[0], context);
|
||||||
return makeStr(canonPath(path), context);
|
return makeStr(canonPath(path), context);
|
||||||
}
|
}
|
||||||
|
|
@ -577,23 +579,23 @@ static Expr prim_toPath(EvalState & state, const ATermVector & args)
|
||||||
corner cases. */
|
corner cases. */
|
||||||
static Expr prim_storePath(EvalState & state, const ATermVector & args)
|
static Expr prim_storePath(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
Context context;
|
||||||
Path path = canonPath(coerceToPath(state, args[0], context));
|
Path path = canonPath(coerceToPath(state, args[0], context));
|
||||||
if (!isInStore(path))
|
if (!isInStore(path))
|
||||||
throw EvalError(format("path `%1%' is not in the Nix store") % path);
|
throw EvalError(format("path `%1%' is not in the Nix store") % path);
|
||||||
Path path2 = toStorePath(path);
|
Path path2 = toStorePath(path);
|
||||||
if (!store->isValidPath(path2))
|
if (!store->isValidPath(path2))
|
||||||
throw EvalError(format("store path `%1%' is not valid") % path2);
|
throw EvalError(format("store path `%1%' is not valid") % path2);
|
||||||
context.insert(path2);
|
context.set(toATerm(path2), makeNull());
|
||||||
return makeStr(path, context);
|
return makeStr(path, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_pathExists(EvalState & state, const ATermVector & args)
|
static Expr prim_pathExists(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
Context context;
|
||||||
Path path = coerceToPath(state, args[0], context);
|
Path path = coerceToPath(state, args[0], context);
|
||||||
if (!context.empty())
|
if (context.size() != 0)
|
||||||
throw EvalError(format("string `%1%' cannot refer to other paths") % path);
|
throw EvalError(format("string `%1%' cannot refer to other paths") % path);
|
||||||
return makeBool(pathExists(path));
|
return makeBool(pathExists(path));
|
||||||
}
|
}
|
||||||
|
|
@ -603,7 +605,7 @@ static Expr prim_pathExists(EvalState & state, const ATermVector & args)
|
||||||
following the last slash. */
|
following the last slash. */
|
||||||
static Expr prim_baseNameOf(EvalState & state, const ATermVector & args)
|
static Expr prim_baseNameOf(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
Context context;
|
||||||
return makeStr(baseNameOf(coerceToString(state, args[0], context)), context);
|
return makeStr(baseNameOf(coerceToString(state, args[0], context)), context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -613,7 +615,7 @@ static Expr prim_baseNameOf(EvalState & state, const ATermVector & args)
|
||||||
of the argument. */
|
of the argument. */
|
||||||
static Expr prim_dirOf(EvalState & state, const ATermVector & args)
|
static Expr prim_dirOf(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
Context context;
|
||||||
Expr e = evalExpr(state, args[0]); ATerm dummy;
|
Expr e = evalExpr(state, args[0]); ATerm dummy;
|
||||||
bool isPath = matchPath(e, dummy);
|
bool isPath = matchPath(e, dummy);
|
||||||
Path dir = dirOf(coerceToPath(state, e, context));
|
Path dir = dirOf(coerceToPath(state, e, context));
|
||||||
|
|
@ -624,9 +626,9 @@ static Expr prim_dirOf(EvalState & state, const ATermVector & args)
|
||||||
/* Return the contents of a file as a string. */
|
/* Return the contents of a file as a string. */
|
||||||
static Expr prim_readFile(EvalState & state, const ATermVector & args)
|
static Expr prim_readFile(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
Context context;
|
||||||
Path path = coerceToPath(state, args[0], context);
|
Path path = coerceToPath(state, args[0], context);
|
||||||
if (!context.empty())
|
if (context.size() != 0)
|
||||||
throw EvalError(format("string `%1%' cannot refer to other paths") % path);
|
throw EvalError(format("string `%1%' cannot refer to other paths") % path);
|
||||||
return makeStr(readFile(path));
|
return makeStr(readFile(path));
|
||||||
}
|
}
|
||||||
|
|
@ -643,7 +645,7 @@ static Expr prim_readFile(EvalState & state, const ATermVector & args)
|
||||||
static Expr prim_toXML(EvalState & state, const ATermVector & args)
|
static Expr prim_toXML(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
PathSet context;
|
Context context;
|
||||||
printTermAsXML(strictEvalExpr(state, args[0]), out, context);
|
printTermAsXML(strictEvalExpr(state, args[0]), out, context);
|
||||||
return makeStr(out.str(), context);
|
return makeStr(out.str(), context);
|
||||||
}
|
}
|
||||||
|
|
@ -653,14 +655,15 @@ static Expr prim_toXML(EvalState & state, const ATermVector & args)
|
||||||
as an input by derivations. */
|
as an input by derivations. */
|
||||||
static Expr prim_toFile(EvalState & state, const ATermVector & args)
|
static Expr prim_toFile(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
ATermList context;
|
||||||
string name = evalStringNoCtx(state, args[0]);
|
string name = evalStringNoCtx(state, args[0]);
|
||||||
string contents = evalString(state, args[1], context);
|
string contents = evalString(state, args[1], context);
|
||||||
|
|
||||||
PathSet refs;
|
PathSet refs;
|
||||||
|
|
||||||
for (PathSet::iterator i = context.begin(); i != context.end(); ++i) {
|
Context context2; matchContext(context, context2);
|
||||||
Path path = *i;
|
foreach (Context::const_iterator, i, context2) {
|
||||||
|
Path path = aterm2String(i->key);
|
||||||
if (path.at(0) == '=') path = string(path, 1);
|
if (path.at(0) == '=') path = string(path, 1);
|
||||||
if (isDerivation(path))
|
if (isDerivation(path))
|
||||||
throw EvalError(format("in `toFile': the file `%1%' cannot refer to derivation outputs") % name);
|
throw EvalError(format("in `toFile': the file `%1%' cannot refer to derivation outputs") % name);
|
||||||
|
|
@ -675,7 +678,7 @@ static Expr prim_toFile(EvalState & state, const ATermVector & args)
|
||||||
result, since `storePath' itself has references to the paths
|
result, since `storePath' itself has references to the paths
|
||||||
used in args[1]. */
|
used in args[1]. */
|
||||||
|
|
||||||
return makeStr(storePath, singleton<PathSet>(storePath));
|
return makeStr(storePath, ATmakeList1(makeContextElem(toATerm(storePath), makeNull())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -712,9 +715,9 @@ struct FilterFromExpr : PathFilter
|
||||||
|
|
||||||
static Expr prim_filterSource(EvalState & state, const ATermVector & args)
|
static Expr prim_filterSource(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
Context context;
|
||||||
Path path = coerceToPath(state, args[1], context);
|
Path path = coerceToPath(state, args[1], context);
|
||||||
if (!context.empty())
|
if (context.size() != 0)
|
||||||
throw EvalError(format("string `%1%' cannot refer to other paths") % path);
|
throw EvalError(format("string `%1%' cannot refer to other paths") % path);
|
||||||
|
|
||||||
FilterFromExpr filter(state, args[0]);
|
FilterFromExpr filter(state, args[0]);
|
||||||
|
|
@ -723,7 +726,7 @@ static Expr prim_filterSource(EvalState & state, const ATermVector & args)
|
||||||
? computeStorePathForPath(path, true, htSHA256, filter).first
|
? computeStorePathForPath(path, true, htSHA256, filter).first
|
||||||
: store->addToStore(path, true, htSHA256, filter);
|
: store->addToStore(path, true, htSHA256, filter);
|
||||||
|
|
||||||
return makeStr(dstPath, singleton<PathSet>(dstPath));
|
return makeStr(dstPath, ATmakeList1(makeContextElem(toATerm(dstPath), makeNull())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -746,7 +749,7 @@ static Expr prim_attrNames(EvalState & state, const ATermVector & args)
|
||||||
ATermList list = ATempty;
|
ATermList list = ATempty;
|
||||||
for (StringSet::const_reverse_iterator i = names.rbegin();
|
for (StringSet::const_reverse_iterator i = names.rbegin();
|
||||||
i != names.rend(); ++i)
|
i != names.rend(); ++i)
|
||||||
list = ATinsert(list, makeStr(*i, PathSet()));
|
list = ATinsert(list, makeStr(*i));
|
||||||
|
|
||||||
return makeList(list);
|
return makeList(list);
|
||||||
}
|
}
|
||||||
|
|
@ -1001,7 +1004,7 @@ static Expr prim_lessThan(EvalState & state, const ATermVector & args)
|
||||||
`"/nix/store/whatever..."'. */
|
`"/nix/store/whatever..."'. */
|
||||||
static Expr prim_toString(EvalState & state, const ATermVector & args)
|
static Expr prim_toString(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
Context context;
|
||||||
string s = coerceToString(state, args[0], context, true, false);
|
string s = coerceToString(state, args[0], context, true, false);
|
||||||
return makeStr(s, context);
|
return makeStr(s, context);
|
||||||
}
|
}
|
||||||
|
|
@ -1015,7 +1018,7 @@ static Expr prim_substring(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
int start = evalInt(state, args[0]);
|
int start = evalInt(state, args[0]);
|
||||||
int len = evalInt(state, args[1]);
|
int len = evalInt(state, args[1]);
|
||||||
PathSet context;
|
Context context;
|
||||||
string s = coerceToString(state, args[2], context);
|
string s = coerceToString(state, args[2], context);
|
||||||
|
|
||||||
if (start < 0) throw EvalError("negative start position in `substring'");
|
if (start < 0) throw EvalError("negative start position in `substring'");
|
||||||
|
|
@ -1026,7 +1029,7 @@ static Expr prim_substring(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
static Expr prim_stringLength(EvalState & state, const ATermVector & args)
|
static Expr prim_stringLength(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
Context context;
|
||||||
string s = coerceToString(state, args[0], context);
|
string s = coerceToString(state, args[0], context);
|
||||||
return makeInt(s.size());
|
return makeInt(s.size());
|
||||||
}
|
}
|
||||||
|
|
@ -1034,9 +1037,9 @@ static Expr prim_stringLength(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
static Expr prim_unsafeDiscardStringContext(EvalState & state, const ATermVector & args)
|
static Expr prim_unsafeDiscardStringContext(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
Context context;
|
||||||
string s = coerceToString(state, args[0], context);
|
string s = coerceToString(state, args[0], context);
|
||||||
return makeStr(s, PathSet());
|
return makeStr(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1048,14 +1051,14 @@ static Expr prim_unsafeDiscardStringContext(EvalState & state, const ATermVector
|
||||||
drv.inputDrvs. */
|
drv.inputDrvs. */
|
||||||
static Expr prim_unsafeDiscardOutputDependency(EvalState & state, const ATermVector & args)
|
static Expr prim_unsafeDiscardOutputDependency(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
PathSet context;
|
Context context;
|
||||||
string s = coerceToString(state, args[0], context);
|
string s = coerceToString(state, args[0], context);
|
||||||
|
|
||||||
PathSet context2;
|
Context context2;
|
||||||
foreach (PathSet::iterator, i, context) {
|
foreach (Context::const_iterator, i, context) {
|
||||||
Path p = *i;
|
Path p = aterm2String(i->key);
|
||||||
if (p.at(0) == '=') p = "~" + string(p, 1);
|
if (p.at(0) == '=') p = "~" + string(p, 1);
|
||||||
context2.insert(p);
|
context2.set(toATerm(p), i->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return makeStr(s, context2);
|
return makeStr(s, context2);
|
||||||
|
|
@ -1072,18 +1075,6 @@ static Expr prim_exprToString(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr prim_stringToExpr(EvalState & state, const ATermVector & args)
|
|
||||||
{
|
|
||||||
/* !!! this can introduce arbitrary garbage terms in the
|
|
||||||
evaluator! */;
|
|
||||||
string s;
|
|
||||||
PathSet l;
|
|
||||||
if (!matchStr(evalExpr(state, args[0]), s, l))
|
|
||||||
throw EvalError("stringToExpr needs string argument!");
|
|
||||||
return ATreadFromString(s.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Versions
|
* Versions
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
|
@ -1140,10 +1131,8 @@ void EvalState::addPrimOps()
|
||||||
addPrimOp("__getEnv", 1, prim_getEnv);
|
addPrimOp("__getEnv", 1, prim_getEnv);
|
||||||
addPrimOp("__trace", 2, prim_trace);
|
addPrimOp("__trace", 2, prim_trace);
|
||||||
|
|
||||||
|
|
||||||
// Expr <-> String
|
// Expr <-> String
|
||||||
addPrimOp("__exprToString", 1, prim_exprToString);
|
addPrimOp("__exprToString", 1, prim_exprToString);
|
||||||
addPrimOp("__stringToExpr", 1, prim_stringToExpr);
|
|
||||||
|
|
||||||
// Derivations
|
// Derivations
|
||||||
addPrimOp("derivation!", 1, prim_derivationStrict);
|
addPrimOp("derivation!", 1, prim_derivationStrict);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#define __ATERM_MAP_H
|
#define __ATERM_MAP_H
|
||||||
|
|
||||||
#include <aterm1.h>
|
#include <aterm1.h>
|
||||||
|
#include <aterm2.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -327,7 +327,7 @@ static bool createUserEnv(EvalState & state, DrvInfos & elems,
|
||||||
makeBind(toATerm("derivations"),
|
makeBind(toATerm("derivations"),
|
||||||
makeList(ATreverse(manifest)), makeNoPos()),
|
makeList(ATreverse(manifest)), makeNoPos()),
|
||||||
makeBind(toATerm("manifest"),
|
makeBind(toATerm("manifest"),
|
||||||
makeStr(manifestFile, singleton<PathSet>(manifestFile)), makeNoPos())
|
makeStr(manifestFile, ATmakeList1(makeContextElem(toATerm(manifestFile), makeNull()))), makeNoPos())
|
||||||
)));
|
)));
|
||||||
|
|
||||||
/* Instantiate it. */
|
/* Instantiate it. */
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ static bool indirectRoot = false;
|
||||||
static void printResult(EvalState & state, Expr e,
|
static void printResult(EvalState & state, Expr e,
|
||||||
bool evalOnly, bool xmlOutput, const ATermMap & autoArgs)
|
bool evalOnly, bool xmlOutput, const ATermMap & autoArgs)
|
||||||
{
|
{
|
||||||
PathSet context;
|
Context context;
|
||||||
|
|
||||||
if (evalOnly)
|
if (evalOnly)
|
||||||
if (xmlOutput)
|
if (xmlOutput)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue