1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-26 15:51:15 +02:00

* Make `import' work.

This commit is contained in:
Eelco Dolstra 2010-03-30 09:22:33 +00:00
parent 31428c3a06
commit d78a05ab40
4 changed files with 141 additions and 62 deletions

View file

@ -29,6 +29,9 @@ std::ostream & operator << (std::ostream & str, Value & v)
case tString:
str << "\"" << v.string.s << "\""; // !!! escaping
break;
case tPath:
str << v.path; // !!! escaping?
break;
case tNull:
str << "true";
break;
@ -209,6 +212,20 @@ Env & EvalState::allocEnv()
}
void EvalState::evalFile(const Path & path, Value & v)
{
startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
Expr e = parseExprFromFile(*this, path);
try {
eval(e, v);
} catch (Error & e) {
e.addPrefix(format("while evaluating the file `%1%':\n")
% path);
throw;
}
}
static char * deepestStack = (char *) -1; /* for measuring stack usage */
@ -241,7 +258,12 @@ void EvalState::eval(Env & env, Expr e, Value & v)
ATerm s; ATermList context;
if (matchStr(e, s, context)) {
assert(context == ATempty);
mkString(v, ATgetName(ATgetAFun(s)));
mkString(v, strdup(ATgetName(ATgetAFun(s))));
return;
}
if (matchPath(e, s)) {
mkPath(v, strdup(ATgetName(ATgetAFun(s))));
return;
}
@ -282,8 +304,14 @@ void EvalState::eval(Env & env, Expr e, Value & v)
eval(env, e2, v);
forceAttrs(v); // !!! eval followed by force is slightly inefficient
Bindings::iterator i = v.attrs->find(name);
if (i == v.attrs->end()) throw TypeError("attribute not found");
forceValue(i->second);
if (i == v.attrs->end())
throwEvalError("attribute `%1%' missing", aterm2String(name));
try {
forceValue(i->second);
} catch (Error & e) {
addErrorPrefix(e, "while evaluating the attribute `%1%':\n", aterm2String(name));
throw;
}
v = i->second;
return;
}
@ -569,6 +597,80 @@ void EvalState::forceList(Value & v)
}
string EvalState::coerceToString(Value & v, PathSet & context,
bool coerceMore, bool copyToStore)
{
forceValue(v);
string s;
if (v.type == tString) return v.string.s;
if (v.type == tPath) {
Path path(canonPath(v.path));
if (!copyToStore) return path;
if (isDerivation(path))
throw EvalError(format("file names are not allowed to end in `%1%'")
% drvExtension);
Path dstPath;
if (srcToStore[path] != "")
dstPath = srcToStore[path];
else {
dstPath = readOnlyMode
? computeStorePathForPath(path).first
: store->addToStore(path);
srcToStore[path] = dstPath;
printMsg(lvlChatty, format("copied source `%1%' -> `%2%'")
% path % dstPath);
}
context.insert(dstPath);
return dstPath;
}
if (v.type == tAttrs) {
Bindings::iterator i = v.attrs->find(toATerm("outPath"));
if (i == v.attrs->end())
throwTypeError("cannot coerce an attribute set (except a derivation) to a string");
return coerceToString(i->second, context, coerceMore, copyToStore);
}
if (coerceMore) {
/* Note that `false' is represented as an empty string for
shell scripting convenience, just like `null'. */
if (v.type == tBool && v.boolean) return "1";
if (v.type == tBool && !v.boolean) return "";
if (v.type == tInt) return int2String(v.integer);
if (v.type == tNull) return "";
if (v.type == tList) {
string result;
for (unsigned int n = 0; n < v.list.length; ++n) {
if (n) result += " ";
result += coerceToString(v.list.elems[n],
context, coerceMore, copyToStore);
}
return result;
}
}
throwTypeError("cannot coerce %1% to a string", showType(v));
}
Path EvalState::coerceToPath(Value & v, PathSet & context)
{
string path = coerceToString(v, context, false, false);
if (path == "" || path[0] != '/')
throw EvalError(format("string `%1%' doesn't represent an absolute path") % path);
return path;
}
bool EvalState::eqValues(Value & v1, Value & v2)
{
forceValue(v1);
@ -1046,22 +1148,6 @@ LocalNoInline(Expr evalCall(EvalState & state, Expr fun, Expr arg))
}
LocalNoInline(Expr evalSelect(EvalState & state, Expr e, ATerm name))
{
ATerm pos;
string s = aterm2String(name);
Expr a = queryAttr(evalExpr(state, e), s, pos);
if (!a) throwEvalError("attribute `%1%' missing", s);
try {
return evalExpr(state, a);
} catch (Error & e) {
addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n",
s, showPos(pos));
throw;
}
}
LocalNoInline(Expr evalAssert(EvalState & state, Expr cond, Expr body, ATerm pos))
{
if (!evalBool(state, cond))
@ -1352,20 +1438,6 @@ Expr evalExpr(EvalState & state, Expr e)
}
Expr evalFile(EvalState & state, const Path & path)
{
startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
Expr e = parseExprFromFile(state, path);
try {
return evalExpr(state, e);
} catch (Error & e) {
e.addPrefix(format("while evaluating the file `%1%':\n")
% path);
throw;
}
}
static Expr strictEvalExpr(EvalState & state, Expr e, ATermMap & nfs);