* 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue