* Better error messages (especially wrt types).
This commit is contained in:
parent
e10b830251
commit
4f3725b167
7 changed files with 96 additions and 62 deletions
|
@ -41,7 +41,7 @@ static Expr substArgs(Expr body, ATermList formals, Expr arg)
|
||||||
if (!matchNoDefFormal(*i, name) && !matchDefFormal(*i, name, def))
|
if (!matchNoDefFormal(*i, name) && !matchDefFormal(*i, name, def))
|
||||||
abort(); /* can't happen */
|
abort(); /* can't happen */
|
||||||
if (subs[name] == 0) {
|
if (subs[name] == 0) {
|
||||||
if (def == 0) throw Error(format("required function argument `%1%' missing")
|
if (def == 0) throw TypeError(format("the argument named `%1%' required by the function is missing")
|
||||||
% aterm2String(name));
|
% aterm2String(name));
|
||||||
defsUsed.push_back(name);
|
defsUsed.push_back(name);
|
||||||
recAttrs = ATinsert(recAttrs, makeBind(name, def, makeNoPos()));
|
recAttrs = ATinsert(recAttrs, makeBind(name, def, makeNoPos()));
|
||||||
|
@ -68,7 +68,7 @@ static Expr substArgs(Expr body, ATermList formals, Expr arg)
|
||||||
matchNoDefFormal(*i, name) || matchDefFormal(*i, name, def);
|
matchNoDefFormal(*i, name) || matchDefFormal(*i, name, def);
|
||||||
subs.remove(name);
|
subs.remove(name);
|
||||||
}
|
}
|
||||||
throw Error(format("unexpected function argument `%1%'")
|
throw TypeError(format("the function does not expect an argument named `%1%'")
|
||||||
% aterm2String(subs.begin()->key));
|
% aterm2String(subs.begin()->key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,8 @@ string evalString(EvalState & state, Expr e)
|
||||||
{
|
{
|
||||||
e = evalExpr(state, e);
|
e = evalExpr(state, e);
|
||||||
ATerm s;
|
ATerm s;
|
||||||
if (!matchStr(e, s)) throw Error("string expected");
|
if (!matchStr(e, s))
|
||||||
|
throw TypeError(format("value is %1% while a string was expected") % showType(e));
|
||||||
return aterm2String(s);
|
return aterm2String(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +143,8 @@ Path evalPath(EvalState & state, Expr e)
|
||||||
{
|
{
|
||||||
e = evalExpr(state, e);
|
e = evalExpr(state, e);
|
||||||
ATerm s;
|
ATerm s;
|
||||||
if (!matchPath(e, s)) throw Error("path expected");
|
if (!matchPath(e, s))
|
||||||
|
throw TypeError(format("value is %1% while a path was expected") % showType(e));
|
||||||
return aterm2String(s);
|
return aterm2String(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +154,7 @@ bool evalBool(EvalState & state, Expr e)
|
||||||
e = evalExpr(state, e);
|
e = evalExpr(state, e);
|
||||||
if (e == eTrue) return true;
|
if (e == eTrue) return true;
|
||||||
else if (e == eFalse) return false;
|
else if (e == eFalse) return false;
|
||||||
else throw Error("boolean expected");
|
else throw TypeError(format("value is %1% while a boolean was expected") % showType(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,7 +162,8 @@ ATermList evalList(EvalState & state, Expr e)
|
||||||
{
|
{
|
||||||
e = evalExpr(state, e);
|
e = evalExpr(state, e);
|
||||||
ATermList list;
|
ATermList list;
|
||||||
if (!matchList(e, list)) throw Error("list expected");
|
if (!matchList(e, list))
|
||||||
|
throw TypeError(format("value is %1% while a list was expected") % showType(e));
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,13 +229,13 @@ string coerceToStringWithContext(EvalState & state,
|
||||||
Expr a = attrs.get(toATerm("type"));
|
Expr a = attrs.get(toATerm("type"));
|
||||||
if (a && evalString(state, a) == "derivation") {
|
if (a && evalString(state, a) == "derivation") {
|
||||||
a = attrs.get(toATerm("outPath"));
|
a = attrs.get(toATerm("outPath"));
|
||||||
if (!a) throw Error("output path missing from derivation");
|
if (!a) throw TypeError("output path missing from derivation");
|
||||||
context = ATinsert(context, e);
|
context = ATinsert(context, e);
|
||||||
return evalPath(state, a);
|
return evalPath(state, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Error("cannot coerce value to string");
|
throw TypeError(format("cannot coerce %1% to a string") % showType(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -294,7 +297,7 @@ Expr evalExpr2(EvalState & state, Expr e)
|
||||||
if (matchVar(e, name)) {
|
if (matchVar(e, name)) {
|
||||||
ATerm primOp = state.primOps.get(name);
|
ATerm primOp = state.primOps.get(name);
|
||||||
if (!primOp)
|
if (!primOp)
|
||||||
throw Error(format("impossible: undefined variable `%1%'") % aterm2String(name));
|
throw EvalError(format("impossible: undefined variable `%1%'") % aterm2String(name));
|
||||||
int arity;
|
int arity;
|
||||||
ATermBlob fun;
|
ATermBlob fun;
|
||||||
if (!matchPrimOpDef(primOp, arity, fun)) abort();
|
if (!matchPrimOpDef(primOp, arity, fun)) abort();
|
||||||
|
@ -355,7 +358,7 @@ Expr evalExpr2(EvalState & state, Expr e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else throw Error("function or primop expected in function call");
|
else throw TypeError("the left-hand side of the function call is neither a function nor a primop (built-in operation)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attribute selection. */
|
/* Attribute selection. */
|
||||||
|
@ -363,7 +366,7 @@ Expr evalExpr2(EvalState & state, Expr e)
|
||||||
ATerm pos;
|
ATerm pos;
|
||||||
string s1 = aterm2String(name);
|
string s1 = aterm2String(name);
|
||||||
Expr a = queryAttr(evalExpr(state, e1), s1, pos);
|
Expr a = queryAttr(evalExpr(state, e1), s1, pos);
|
||||||
if (!a) throw Error(format("attribute `%1%' missing") % s1);
|
if (!a) throw EvalError(format("attribute `%1%' missing") % s1);
|
||||||
try {
|
try {
|
||||||
return evalExpr(state, a);
|
return evalExpr(state, a);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
|
@ -451,26 +454,33 @@ Expr evalExpr2(EvalState & state, Expr e)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* String or path concatenation. */
|
/* String or path concatenation. */
|
||||||
if (matchOpPlus(e, e1, e2)) {
|
ATermList es;
|
||||||
|
if (matchOpPlus(e, e1, e2) || matchConcatStrings(e, es)) {
|
||||||
ATermVector args;
|
ATermVector args;
|
||||||
|
if (matchOpPlus(e, e1, e2)) {
|
||||||
args.push_back(e1);
|
args.push_back(e1);
|
||||||
args.push_back(e2);
|
args.push_back(e2);
|
||||||
|
} else
|
||||||
|
for (ATermIterator i(es); i; ++i) args.push_back(*i);
|
||||||
|
|
||||||
|
try {
|
||||||
return concatStrings(state, args);
|
return concatStrings(state, args);
|
||||||
|
} catch (Error & e) {
|
||||||
|
e.addPrefix(format("in a string concatenation: "));
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* List concatenation. */
|
/* List concatenation. */
|
||||||
if (matchOpConcat(e, e1, e2)) {
|
if (matchOpConcat(e, e1, e2)) {
|
||||||
|
try {
|
||||||
ATermList l1 = evalList(state, e1);
|
ATermList l1 = evalList(state, e1);
|
||||||
ATermList l2 = evalList(state, e2);
|
ATermList l2 = evalList(state, e2);
|
||||||
return makeList(ATconcat(l1, l2));
|
return makeList(ATconcat(l1, l2));
|
||||||
|
} catch (Error & e) {
|
||||||
|
e.addPrefix(format("in a list concatenation: "));
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* String concatenation. */
|
|
||||||
ATermList es;
|
|
||||||
if (matchConcatStrings(e, es)) {
|
|
||||||
ATermVector args;
|
|
||||||
for (ATermIterator i(es); i; ++i) args.push_back(*i);
|
|
||||||
return concatStrings(state, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Barf. */
|
/* Barf. */
|
||||||
|
@ -492,7 +502,7 @@ Expr evalExpr(EvalState & state, Expr e)
|
||||||
Expr nf = state.normalForms.get(e);
|
Expr nf = state.normalForms.get(e);
|
||||||
if (nf) {
|
if (nf) {
|
||||||
if (nf == makeBlackHole())
|
if (nf == makeBlackHole())
|
||||||
throw Error("infinite recursion encountered");
|
throw EvalError("infinite recursion encountered");
|
||||||
state.nrCached++;
|
state.nrCached++;
|
||||||
return nf;
|
return nf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,10 +41,6 @@ struct EvalState
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
MakeError(EvalError, Error)
|
|
||||||
MakeError(AssertionError, EvalError)
|
|
||||||
|
|
||||||
|
|
||||||
/* Evaluate an expression to normal form. */
|
/* Evaluate an expression to normal form. */
|
||||||
Expr evalExpr(EvalState & state, Expr e);
|
Expr evalExpr(EvalState & state, Expr e);
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,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 Error("output path missing");
|
if (!a) throw TypeError("output path missing");
|
||||||
(string &) outPath = evalPath(state, a);
|
(string &) outPath = evalPath(state, a);
|
||||||
}
|
}
|
||||||
return outPath;
|
return outPath;
|
||||||
|
@ -81,7 +81,7 @@ static bool getDerivation(EvalState & state, Expr e,
|
||||||
|
|
||||||
a = attrs->get(toATerm("name"));
|
a = attrs->get(toATerm("name"));
|
||||||
/* !!! We really would like to have a decent back trace here. */
|
/* !!! We really would like to have a decent back trace here. */
|
||||||
if (!a) throw Error("derivation name missing");
|
if (!a) throw TypeError("derivation name missing");
|
||||||
drv.name = evalString(state, a);
|
drv.name = evalString(state, a);
|
||||||
|
|
||||||
a = attrs->get(toATerm("system"));
|
a = attrs->get(toATerm("system"));
|
||||||
|
@ -123,7 +123,7 @@ static void getDerivations(EvalState & state, Expr e,
|
||||||
for (ATermIterator i(formals); i; ++i) {
|
for (ATermIterator i(formals); i; ++i) {
|
||||||
Expr name, def;
|
Expr name, def;
|
||||||
if (matchNoDefFormal(*i, name))
|
if (matchNoDefFormal(*i, name))
|
||||||
throw Error(format("expression evaluates to a function with no-default arguments (`%1%')")
|
throw TypeError(format("cannot auto-call a function that has an argument without a default value (`%1%')")
|
||||||
% aterm2String(name));
|
% aterm2String(name));
|
||||||
else if (!matchDefFormal(*i, name, def))
|
else if (!matchDefFormal(*i, name, def))
|
||||||
abort(); /* can't happen */
|
abort(); /* can't happen */
|
||||||
|
@ -224,7 +224,7 @@ static void getDerivations(EvalState & state, Expr e,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Error("expression does not evaluate to a derivation (or a set or list of those)");
|
throw TypeError("expression does not evaluate to a derivation (or a set or list of those)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ void queryAllAttrs(Expr e, ATermMap & attrs, bool withPos)
|
||||||
{
|
{
|
||||||
ATermList bnds;
|
ATermList bnds;
|
||||||
if (!matchAttrs(e, bnds))
|
if (!matchAttrs(e, bnds))
|
||||||
throw Error("attribute set expected");
|
throw TypeError("attribute set expected");
|
||||||
|
|
||||||
for (ATermIterator i(bnds); i; ++i) {
|
for (ATermIterator i(bnds); i; ++i) {
|
||||||
ATerm name;
|
ATerm name;
|
||||||
|
@ -73,7 +73,7 @@ Expr queryAttr(Expr e, const string & name, ATerm & pos)
|
||||||
{
|
{
|
||||||
ATermList bnds;
|
ATermList bnds;
|
||||||
if (!matchAttrs(e, bnds))
|
if (!matchAttrs(e, bnds))
|
||||||
throw Error("attribute set expected");
|
throw TypeError("attribute set expected");
|
||||||
|
|
||||||
for (ATermIterator i(bnds); i; ++i) {
|
for (ATermIterator i(bnds); i; ++i) {
|
||||||
ATerm name2, pos2;
|
ATerm name2, pos2;
|
||||||
|
@ -214,7 +214,7 @@ static void checkVarDefs2(set<Expr> & done, const ATermMap & defs, Expr e)
|
||||||
|
|
||||||
if (matchVar(e, name)) {
|
if (matchVar(e, name)) {
|
||||||
if (!defs.get(name))
|
if (!defs.get(name))
|
||||||
throw Error(format("undefined variable `%1%'")
|
throw EvalError(format("undefined variable `%1%'")
|
||||||
% aterm2String(name));
|
% aterm2String(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,3 +289,24 @@ Expr makeBool(bool b)
|
||||||
{
|
{
|
||||||
return b ? eTrue : eFalse;
|
return b ? eTrue : eFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string showType(Expr e)
|
||||||
|
{
|
||||||
|
ATerm t1, t2, t3;
|
||||||
|
ATermList l1;
|
||||||
|
int i1;
|
||||||
|
if (matchStr(e, t1)) return "a string";
|
||||||
|
if (matchPath(e, t1)) return "a path";
|
||||||
|
if (matchUri(e, t1)) return "a path";
|
||||||
|
if (matchNull(e)) return "null";
|
||||||
|
if (matchInt(e, i1)) return "an integer";
|
||||||
|
if (matchBool(e, t1)) return "a boolean";
|
||||||
|
if (matchFunction(e, l1, t1, t2)) return "a function";
|
||||||
|
if (matchFunction1(e, t1, t2, t3)) return "a function";
|
||||||
|
if (matchAttrs(e, l1)) return "an attribute set";
|
||||||
|
if (matchList(e, l1)) return "a list";
|
||||||
|
if (matchContext(e, l1, t1)) return "a context containing " + showType(t1);
|
||||||
|
return "an unknown type";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,11 @@
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
|
||||||
|
|
||||||
|
MakeError(EvalError, Error)
|
||||||
|
MakeError(AssertionError, EvalError)
|
||||||
|
MakeError(TypeError, EvalError)
|
||||||
|
|
||||||
|
|
||||||
/* Nix expressions are represented as ATerms. The maximal sharing
|
/* Nix expressions are represented as ATerms. The maximal sharing
|
||||||
property of the ATerm library allows us to implement caching of
|
property of the ATerm library allows us to implement caching of
|
||||||
normals forms efficiently. */
|
normals forms efficiently. */
|
||||||
|
@ -82,5 +87,7 @@ void checkVarDefs(const ATermMap & def, Expr e);
|
||||||
/* Create an expression representing a boolean. */
|
/* Create an expression representing a boolean. */
|
||||||
Expr makeBool(bool b);
|
Expr makeBool(bool b);
|
||||||
|
|
||||||
|
string showType(Expr e);
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__NIXEXPR_H */
|
#endif /* !__NIXEXPR_H */
|
||||||
|
|
|
@ -103,7 +103,7 @@ static void checkAttrs(ATermMap & names, ATermList bnds)
|
||||||
ATerm pos;
|
ATerm pos;
|
||||||
if (!matchBind(*i, name, e, pos)) abort(); /* can't happen */
|
if (!matchBind(*i, name, e, pos)) abort(); /* can't happen */
|
||||||
if (names.get(name))
|
if (names.get(name))
|
||||||
throw Error(format("duplicate attribute `%1%' at %2%")
|
throw EvalError(format("duplicate attribute `%1%' at %2%")
|
||||||
% aterm2String(name) % showPos(pos));
|
% aterm2String(name) % showPos(pos));
|
||||||
names.set(name, name);
|
names.set(name, name);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ static void checkAttrSets(ATerm e)
|
||||||
!matchDefFormal(*i, name, deflt))
|
!matchDefFormal(*i, name, deflt))
|
||||||
abort();
|
abort();
|
||||||
if (names.get(name))
|
if (names.get(name))
|
||||||
throw Error(format("duplicate formal function argument `%1%' at %2%")
|
throw EvalError(format("duplicate formal function argument `%1%' at %2%")
|
||||||
% aterm2String(name) % showPos(pos));
|
% aterm2String(name) % showPos(pos));
|
||||||
names.set(name, name);
|
names.set(name, name);
|
||||||
}
|
}
|
||||||
|
@ -168,12 +168,12 @@ static Expr parse(EvalState & state,
|
||||||
int res = yyparse(scanner, &data);
|
int res = yyparse(scanner, &data);
|
||||||
yylex_destroy(scanner);
|
yylex_destroy(scanner);
|
||||||
|
|
||||||
if (res) throw Error(data.error);
|
if (res) throw EvalError(data.error);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
checkVarDefs(state.primOps, data.result);
|
checkVarDefs(state.primOps, data.result);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
throw Error(format("%1%, in `%2%'") % e.msg() % path);
|
throw EvalError(format("%1%, in `%2%'") % e.msg() % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAttrSets(data.result);
|
checkAttrSets(data.result);
|
||||||
|
|
|
@ -26,19 +26,19 @@ static Expr primImport(EvalState & state, const ATermVector & args)
|
||||||
Nix expression created at the derivation's output path. */
|
Nix expression created at the derivation's output path. */
|
||||||
if (a && evalString(state, a) == "derivation") {
|
if (a && evalString(state, a) == "derivation") {
|
||||||
a = queryAttr(arg, "drvPath");
|
a = queryAttr(arg, "drvPath");
|
||||||
if (!a) throw Error("bad derivation in import");
|
if (!a) throw EvalError("bad derivation in import");
|
||||||
Path drvPath = evalPath(state, a);
|
Path drvPath = evalPath(state, a);
|
||||||
|
|
||||||
buildDerivations(singleton<PathSet>(drvPath));
|
buildDerivations(singleton<PathSet>(drvPath));
|
||||||
|
|
||||||
a = queryAttr(arg, "outPath");
|
a = queryAttr(arg, "outPath");
|
||||||
if (!a) throw Error("bad derivation in import");
|
if (!a) throw EvalError("bad derivation in import");
|
||||||
path = evalPath(state, a);
|
path = evalPath(state, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path == "")
|
if (path == "")
|
||||||
throw Error("path or derivation expected in import");
|
throw TypeError("`import' requires a path or derivation as its argument");
|
||||||
|
|
||||||
return evalFile(state, path);
|
return evalFile(state, path);
|
||||||
}
|
}
|
||||||
|
@ -133,11 +133,11 @@ static void processBinding(EvalState & state, Expr e, Derivation & drv,
|
||||||
|
|
||||||
if (a && evalString(state, a) == "derivation") {
|
if (a && evalString(state, a) == "derivation") {
|
||||||
a = queryAttr(e, "drvPath");
|
a = queryAttr(e, "drvPath");
|
||||||
if (!a) throw Error("derivation name missing");
|
if (!a) throw EvalError("derivation name missing");
|
||||||
Path drvPath = evalPath(state, a);
|
Path drvPath = evalPath(state, a);
|
||||||
|
|
||||||
a = queryAttr(e, "outPath");
|
a = queryAttr(e, "outPath");
|
||||||
if (!a) throw Error("output path missing");
|
if (!a) throw EvalError("output path missing");
|
||||||
/* !!! supports only single output path */
|
/* !!! supports only single output path */
|
||||||
Path outPath = evalPath(state, a);
|
Path outPath = evalPath(state, a);
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ static void processBinding(EvalState & state, Expr e, Derivation & drv,
|
||||||
else if (a && evalString(state, a) == "storePath") {
|
else if (a && evalString(state, a) == "storePath") {
|
||||||
|
|
||||||
a = queryAttr(e, "outPath");
|
a = queryAttr(e, "outPath");
|
||||||
if (!a) throw Error("output path missing");
|
if (!a) throw EvalError("output path missing");
|
||||||
/* !!! supports only single output path */
|
/* !!! supports only single output path */
|
||||||
Path outPath = evalPath(state, a);
|
Path outPath = evalPath(state, a);
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ static void processBinding(EvalState & state, Expr e, Derivation & drv,
|
||||||
ss.push_back(outPath);
|
ss.push_back(outPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
else throw Error("invalid derivation attribute");
|
else throw TypeError("attribute sets in derivations must either be derivations or store paths");
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (matchPath(e, s)) {
|
else if (matchPath(e, s)) {
|
||||||
|
@ -171,7 +171,7 @@ static void processBinding(EvalState & state, Expr e, Derivation & drv,
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (isDerivation(srcPath))
|
if (isDerivation(srcPath))
|
||||||
throw Error(format("file names are not allowed to end in `%1%'")
|
throw EvalError(format("file names are not allowed to end in `%1%'")
|
||||||
% drvExtension);
|
% drvExtension);
|
||||||
Path dstPath;
|
Path dstPath;
|
||||||
if (state.srcToStore[srcPath] != "")
|
if (state.srcToStore[srcPath] != "")
|
||||||
|
@ -200,14 +200,14 @@ static void processBinding(EvalState & state, Expr e, Derivation & drv,
|
||||||
Strings ss2;
|
Strings ss2;
|
||||||
processBinding(state, evalExpr(state, e1), drv, ss2);
|
processBinding(state, evalExpr(state, e1), drv, ss2);
|
||||||
if (ss2.size() != 1)
|
if (ss2.size() != 1)
|
||||||
throw Error("left-hand side of `~' operator cannot be a list");
|
throw TypeError("left-hand side of `~' operator cannot be a list");
|
||||||
e2 = evalExpr(state, e2);
|
e2 = evalExpr(state, e2);
|
||||||
if (!(matchStr(e2, s) || matchPath(e2, s)))
|
if (!(matchStr(e2, s) || matchPath(e2, s)))
|
||||||
throw Error("right-hand side of `~' operator must be a path or string");
|
throw TypeError("right-hand side of `~' operator must be a path or string");
|
||||||
ss.push_back(canonPath(ss2.front() + "/" + aterm2String(s)));
|
ss.push_back(canonPath(ss2.front() + "/" + aterm2String(s)));
|
||||||
}
|
}
|
||||||
|
|
||||||
else throw Error("invalid derivation attribute");
|
else throw TypeError(format("%1% is not allowed as a derivation argument") % showType(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ static Expr primDerivationStrict(EvalState & state, const ATermVector & args)
|
||||||
/* Figure out the name already (for stack backtraces). */
|
/* Figure out the name already (for stack backtraces). */
|
||||||
Expr eDrvName = attrs.get(toATerm("name"));
|
Expr eDrvName = attrs.get(toATerm("name"));
|
||||||
if (!eDrvName)
|
if (!eDrvName)
|
||||||
throw Error("required attribute `name' missing");
|
throw EvalError("required attribute `name' missing");
|
||||||
ATerm posDrvName;
|
ATerm posDrvName;
|
||||||
if (!matchAttrRHS(eDrvName, eDrvName, posDrvName)) abort();
|
if (!matchAttrRHS(eDrvName, eDrvName, posDrvName)) abort();
|
||||||
string drvName = evalString(state, eDrvName);
|
string drvName = evalString(state, eDrvName);
|
||||||
|
@ -291,16 +291,16 @@ static Expr primDerivationStrict(EvalState & state, const ATermVector & args)
|
||||||
else if (key == "outputHashMode") {
|
else if (key == "outputHashMode") {
|
||||||
if (s == "recursive") outputHashRecursive = true;
|
if (s == "recursive") outputHashRecursive = true;
|
||||||
else if (s == "flat") outputHashRecursive = false;
|
else if (s == "flat") outputHashRecursive = false;
|
||||||
else throw Error(format("invalid value `%1%' for `outputHashMode' attribute") % s);
|
else throw EvalError(format("invalid value `%1%' for `outputHashMode' attribute") % s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do we have all required attributes? */
|
/* Do we have all required attributes? */
|
||||||
if (drv.builder == "")
|
if (drv.builder == "")
|
||||||
throw Error("required attribute `builder' missing");
|
throw EvalError("required attribute `builder' missing");
|
||||||
if (drv.platform == "")
|
if (drv.platform == "")
|
||||||
throw Error("required attribute `system' missing");
|
throw EvalError("required attribute `system' missing");
|
||||||
|
|
||||||
/* If an output hash was given, check it. */
|
/* If an output hash was given, check it. */
|
||||||
if (outputHash == "")
|
if (outputHash == "")
|
||||||
|
@ -308,7 +308,7 @@ static Expr primDerivationStrict(EvalState & state, const ATermVector & args)
|
||||||
else {
|
else {
|
||||||
HashType ht = parseHashType(outputHashAlgo);
|
HashType ht = parseHashType(outputHashAlgo);
|
||||||
if (ht == htUnknown)
|
if (ht == htUnknown)
|
||||||
throw Error(format("unknown hash algorithm `%1%'") % outputHashAlgo);
|
throw EvalError(format("unknown hash algorithm `%1%'") % outputHashAlgo);
|
||||||
Hash h;
|
Hash h;
|
||||||
if (outputHash.size() == Hash(ht).hashSize * 2)
|
if (outputHash.size() == Hash(ht).hashSize * 2)
|
||||||
/* hexadecimal representation */
|
/* hexadecimal representation */
|
||||||
|
@ -326,7 +326,7 @@ static Expr primDerivationStrict(EvalState & state, const ATermVector & args)
|
||||||
alphanumerics and some other characters appear. */
|
alphanumerics and some other characters appear. */
|
||||||
checkStoreName(drvName);
|
checkStoreName(drvName);
|
||||||
if (isDerivation(drvName))
|
if (isDerivation(drvName))
|
||||||
throw Error(format("derivation names are not allowed to end in `%1%'")
|
throw EvalError(format("derivation names are not allowed to end in `%1%'")
|
||||||
% drvExtension);
|
% drvExtension);
|
||||||
|
|
||||||
/* !!! the name should not end in the derivation extension (.drv).
|
/* !!! the name should not end in the derivation extension (.drv).
|
||||||
|
@ -457,7 +457,7 @@ static Expr primIsNull(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
static Path findDependency(Path dir, string dep)
|
static Path findDependency(Path dir, string dep)
|
||||||
{
|
{
|
||||||
if (dep[0] == '/') throw Error(
|
if (dep[0] == '/') throw EvalError(
|
||||||
format("illegal absolute dependency `%1%'") % dep);
|
format("illegal absolute dependency `%1%'") % dep);
|
||||||
|
|
||||||
Path p = canonPath(dir + "/" + dep);
|
Path p = canonPath(dir + "/" + dep);
|
||||||
|
@ -515,7 +515,7 @@ static Expr primDependencyClosure(EvalState & state, const ATermVector & args)
|
||||||
|
|
||||||
/* Get the start set. */
|
/* Get the start set. */
|
||||||
Expr startSet = queryAttr(attrs, "startSet");
|
Expr startSet = queryAttr(attrs, "startSet");
|
||||||
if (!startSet) throw Error("attribute `startSet' required");
|
if (!startSet) throw EvalError("attribute `startSet' required");
|
||||||
ATermList startSet2 = evalList(state, startSet);
|
ATermList startSet2 = evalList(state, startSet);
|
||||||
|
|
||||||
Path pivot;
|
Path pivot;
|
||||||
|
@ -538,7 +538,7 @@ static Expr primDependencyClosure(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr scanner = queryAttr(attrs, "scanner");
|
Expr scanner = queryAttr(attrs, "scanner");
|
||||||
if (!scanner) throw Error("attribute `scanner' required");
|
if (!scanner) throw EvalError("attribute `scanner' required");
|
||||||
|
|
||||||
/* Construct the dependency closure by querying the dependency of
|
/* Construct the dependency closure by querying the dependency of
|
||||||
each path in `workSet', adding the dependencies to
|
each path in `workSet', adding the dependencies to
|
||||||
|
|
Loading…
Reference in a new issue