forceString: Show position info
This commit is contained in:
		
							parent
							
								
									27b44b8cf7
								
							
						
					
					
						commit
						a5fe730940
					
				
					 6 changed files with 46 additions and 30 deletions
				
			
		|  | @ -140,7 +140,8 @@ static void * oomHandler(size_t requested) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static Symbol getName(const AttrName & name, EvalState & state, Env & env) { | static Symbol getName(const AttrName & name, EvalState & state, Env & env) | ||||||
|  | { | ||||||
|     if (name.symbol.set()) { |     if (name.symbol.set()) { | ||||||
|         return name.symbol; |         return name.symbol; | ||||||
|     } else { |     } else { | ||||||
|  | @ -279,6 +280,11 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, con | ||||||
|     throw EvalError(format(s) % s2 % s3); |     throw EvalError(format(s) % s2 % s3); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, const Pos & pos)) | ||||||
|  | { | ||||||
|  |     throw EvalError(format(s) % s2 % s3 % pos); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| LocalNoInlineNoReturn(void throwEvalError(const char * s, const Symbol & sym, const Pos & p1, const Pos & p2)) | LocalNoInlineNoReturn(void throwEvalError(const char * s, const Symbol & sym, const Pos & p1, const Pos & p2)) | ||||||
| { | { | ||||||
|     throw EvalError(format(s) % sym % p1 % p2); |     throw EvalError(format(s) % sym % p1 % p2); | ||||||
|  | @ -1172,11 +1178,15 @@ void EvalState::forceFunction(Value & v, const Pos & pos) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| string EvalState::forceString(Value & v) | string EvalState::forceString(Value & v, const Pos & pos) | ||||||
| { | { | ||||||
|     forceValue(v); |     forceValue(v); | ||||||
|     if (v.type != tString) |     if (v.type != tString) { | ||||||
|         throwTypeError("value is %1% while a string was expected", v); |         if (pos) | ||||||
|  |             throwTypeError("value is %1% while a string was expected, at %2%", v, pos); | ||||||
|  |         else | ||||||
|  |             throwTypeError("value is %1% while a string was expected", v); | ||||||
|  |     } | ||||||
|     return string(v.string.s); |     return string(v.string.s); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1197,12 +1207,17 @@ string EvalState::forceString(Value & v, PathSet & context) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| string EvalState::forceStringNoCtx(Value & v) | string EvalState::forceStringNoCtx(Value & v, const Pos & pos) | ||||||
| { | { | ||||||
|     string s = forceString(v); |     string s = forceString(v, pos); | ||||||
|     if (v.string.context) |     if (v.string.context) { | ||||||
|         throwEvalError("the string `%1%' is not allowed to refer to a store path (such as `%2%')", |         if (pos) | ||||||
|             v.string.s, v.string.context[0]); |             throwEvalError("the string `%1%' is not allowed to refer to a store path (such as `%2%'), at %3%", | ||||||
|  |                 v.string.s, v.string.context[0], pos); | ||||||
|  |         else | ||||||
|  |             throwEvalError("the string `%1%' is not allowed to refer to a store path (such as `%2%')", | ||||||
|  |                 v.string.s, v.string.context[0]); | ||||||
|  |     } | ||||||
|     return s; |     return s; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -165,9 +165,9 @@ public: | ||||||
|     inline void forceList(Value & v); |     inline void forceList(Value & v); | ||||||
|     inline void forceList(Value & v, const Pos & pos); |     inline void forceList(Value & v, const Pos & pos); | ||||||
|     void forceFunction(Value & v, const Pos & pos); // either lambda or primop
 |     void forceFunction(Value & v, const Pos & pos); // either lambda or primop
 | ||||||
|     string forceString(Value & v); |     string forceString(Value & v, const Pos & pos = noPos); | ||||||
|     string forceString(Value & v, PathSet & context); |     string forceString(Value & v, PathSet & context); | ||||||
|     string forceStringNoCtx(Value & v); |     string forceStringNoCtx(Value & v, const Pos & pos = noPos); | ||||||
| 
 | 
 | ||||||
|     /* Return true iff the value `v' denotes a derivation (i.e. a
 |     /* Return true iff the value `v' denotes a derivation (i.e. a
 | ||||||
|        set with attribute `type = "derivation"'). */ |        set with attribute `type = "derivation"'). */ | ||||||
|  |  | ||||||
|  | @ -41,7 +41,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs() | ||||||
|             /* For each output... */ |             /* For each output... */ | ||||||
|             for (unsigned int j = 0; j < i->value->list.length; ++j) { |             for (unsigned int j = 0; j < i->value->list.length; ++j) { | ||||||
|                 /* Evaluate the corresponding set. */ |                 /* Evaluate the corresponding set. */ | ||||||
|                 string name = state->forceStringNoCtx(*i->value->list.elems[j]); |                 string name = state->forceStringNoCtx(*i->value->list.elems[j], *i->pos); | ||||||
|                 Bindings::iterator out = attrs->find(state->symbols.create(name)); |                 Bindings::iterator out = attrs->find(state->symbols.create(name)); | ||||||
|                 if (out == attrs->end()) continue; // FIXME: throw error?
 |                 if (out == attrs->end()) continue; // FIXME: throw error?
 | ||||||
|                 state->forceAttrs(*out->value); |                 state->forceAttrs(*out->value); | ||||||
|  | @ -199,11 +199,8 @@ static bool getDerivation(EvalState & state, Value & v, | ||||||
| 
 | 
 | ||||||
|         Bindings::iterator i2 = v.attrs->find(state.sSystem); |         Bindings::iterator i2 = v.attrs->find(state.sSystem); | ||||||
| 
 | 
 | ||||||
|         DrvInfo drv( |         DrvInfo drv(state, state.forceStringNoCtx(*i->value), attrPath, | ||||||
|             state, |             i2 == v.attrs->end() ? "unknown" : state.forceStringNoCtx(*i2->value, *i2->pos), | ||||||
|             state.forceStringNoCtx(*i->value), |  | ||||||
|             attrPath, |  | ||||||
|             i2 == v.attrs->end() ? "unknown" : state.forceStringNoCtx(*i2->value), |  | ||||||
|             v.attrs); |             v.attrs); | ||||||
| 
 | 
 | ||||||
|         drvs.push_back(drv); |         drvs.push_back(drv); | ||||||
|  |  | ||||||
|  | @ -145,7 +145,7 @@ void ExprPos::show(std::ostream & str) | ||||||
| 
 | 
 | ||||||
| std::ostream & operator << (std::ostream & str, const Pos & pos) | std::ostream & operator << (std::ostream & str, const Pos & pos) | ||||||
| { | { | ||||||
|     if (!pos.line) |     if (!pos) | ||||||
|         str << "undefined position"; |         str << "undefined position"; | ||||||
|     else |     else | ||||||
|         str << (format("%1%:%2%:%3%") % pos.file % pos.line % pos.column).str(); |         str << (format("%1%:%2%:%3%") % pos.file % pos.line % pos.column).str(); | ||||||
|  |  | ||||||
|  | @ -28,6 +28,10 @@ struct Pos | ||||||
|     Pos() : line(0), column(0) { }; |     Pos() : line(0), column(0) { }; | ||||||
|     Pos(const Symbol & file, unsigned int line, unsigned int column) |     Pos(const Symbol & file, unsigned int line, unsigned int column) | ||||||
|         : file(file), line(line), column(column) { }; |         : file(file), line(line), column(column) { }; | ||||||
|  |     operator bool() const | ||||||
|  |     { | ||||||
|  |         return line != 0; | ||||||
|  |     } | ||||||
|     bool operator < (const Pos & p2) const |     bool operator < (const Pos & p2) const | ||||||
|     { |     { | ||||||
|         if (!line) return p2.line; |         if (!line) return p2.line; | ||||||
|  |  | ||||||
|  | @ -299,7 +299,7 @@ static void prim_tryEval(EvalState & state, const Pos & pos, Value * * args, Val | ||||||
| /* Return an environment variable.  Use with care. */ | /* Return an environment variable.  Use with care. */ | ||||||
| static void prim_getEnv(EvalState & state, const Pos & pos, Value * * args, Value & v) | static void prim_getEnv(EvalState & state, const Pos & pos, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     string name = state.forceStringNoCtx(*args[0]); |     string name = state.forceStringNoCtx(*args[0], pos); | ||||||
|     mkString(v, getEnv(name)); |     mkString(v, getEnv(name)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -343,7 +343,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * | ||||||
|     string drvName; |     string drvName; | ||||||
|     Pos & posDrvName(*attr->pos); |     Pos & posDrvName(*attr->pos); | ||||||
|     try { |     try { | ||||||
|         drvName = state.forceStringNoCtx(*attr->value); |         drvName = state.forceStringNoCtx(*attr->value, pos); | ||||||
|     } catch (Error & e) { |     } catch (Error & e) { | ||||||
|         e.addPrefix(format("while evaluating the derivation attribute `name' at %1%:\n") % posDrvName); |         e.addPrefix(format("while evaluating the derivation attribute `name' at %1%:\n") % posDrvName); | ||||||
|         throw; |         throw; | ||||||
|  | @ -664,7 +664,7 @@ static void prim_toJSON(EvalState & state, const Pos & pos, Value * * args, Valu | ||||||
| static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Value & v) | static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     string name = state.forceStringNoCtx(*args[0]); |     string name = state.forceStringNoCtx(*args[0], pos); | ||||||
|     string contents = state.forceString(*args[1], context); |     string contents = state.forceString(*args[1], context); | ||||||
| 
 | 
 | ||||||
|     PathSet refs; |     PathSet refs; | ||||||
|  | @ -775,7 +775,7 @@ static void prim_attrNames(EvalState & state, const Pos & pos, Value * * args, V | ||||||
| /* Dynamic version of the `.' operator. */ | /* Dynamic version of the `.' operator. */ | ||||||
| void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v) | void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     string attr = state.forceStringNoCtx(*args[0]); |     string attr = state.forceStringNoCtx(*args[0], pos); | ||||||
|     state.forceAttrs(*args[1], pos); |     state.forceAttrs(*args[1], pos); | ||||||
|     // !!! Should we create a symbol here or just do a lookup?
 |     // !!! Should we create a symbol here or just do a lookup?
 | ||||||
|     Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr)); |     Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr)); | ||||||
|  | @ -791,7 +791,7 @@ void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v) | ||||||
| /* Return position information of the specified attribute. */ | /* Return position information of the specified attribute. */ | ||||||
| void prim_unsafeGetAttrPos(EvalState & state, const Pos & pos, Value * * args, Value & v) | void prim_unsafeGetAttrPos(EvalState & state, const Pos & pos, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     string attr = state.forceStringNoCtx(*args[0]); |     string attr = state.forceStringNoCtx(*args[0], pos); | ||||||
|     state.forceAttrs(*args[1], pos); |     state.forceAttrs(*args[1], pos); | ||||||
|     Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr)); |     Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr)); | ||||||
|     if (i == args[1]->attrs->end()) |     if (i == args[1]->attrs->end()) | ||||||
|  | @ -804,7 +804,7 @@ void prim_unsafeGetAttrPos(EvalState & state, const Pos & pos, Value * * args, V | ||||||
| /* Dynamic version of the `?' operator. */ | /* Dynamic version of the `?' operator. */ | ||||||
| static void prim_hasAttr(EvalState & state, const Pos & pos, Value * * args, Value & v) | static void prim_hasAttr(EvalState & state, const Pos & pos, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     string attr = state.forceStringNoCtx(*args[0]); |     string attr = state.forceStringNoCtx(*args[0], pos); | ||||||
|     state.forceAttrs(*args[1], pos); |     state.forceAttrs(*args[1], pos); | ||||||
|     mkBool(v, args[1]->attrs->find(state.symbols.create(attr)) != args[1]->attrs->end()); |     mkBool(v, args[1]->attrs->find(state.symbols.create(attr)) != args[1]->attrs->end()); | ||||||
| } | } | ||||||
|  | @ -826,7 +826,7 @@ static void prim_removeAttrs(EvalState & state, const Pos & pos, Value * * args, | ||||||
|     /* Get the attribute names to be removed. */ |     /* Get the attribute names to be removed. */ | ||||||
|     std::set<Symbol> names; |     std::set<Symbol> names; | ||||||
|     for (unsigned int i = 0; i < args[1]->list.length; ++i) { |     for (unsigned int i = 0; i < args[1]->list.length; ++i) { | ||||||
|         state.forceStringNoCtx(*args[1]->list.elems[i]); |         state.forceStringNoCtx(*args[1]->list.elems[i], pos); | ||||||
|         names.insert(state.symbols.create(args[1]->list.elems[i]->string.s)); |         names.insert(state.symbols.create(args[1]->list.elems[i]->string.s)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -861,7 +861,7 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args, | ||||||
|         Bindings::iterator j = v2.attrs->find(state.sName); |         Bindings::iterator j = v2.attrs->find(state.sName); | ||||||
|         if (j == v2.attrs->end()) |         if (j == v2.attrs->end()) | ||||||
|             throw TypeError(format("`name' attribute missing in a call to `listToAttrs', at %1%") % pos); |             throw TypeError(format("`name' attribute missing in a call to `listToAttrs', at %1%") % pos); | ||||||
|         string name = state.forceStringNoCtx(*j->value); |         string name = state.forceStringNoCtx(*j->value, pos); | ||||||
| 
 | 
 | ||||||
|         Symbol sym = state.symbols.create(name); |         Symbol sym = state.symbols.create(name); | ||||||
|         if (seen.find(sym) == seen.end()) { |         if (seen.find(sym) == seen.end()) { | ||||||
|  | @ -1168,7 +1168,7 @@ static void prim_unsafeDiscardOutputDependency(EvalState & state, const Pos & po | ||||||
| /* Return the cryptographic hash of a string in base-16. */ | /* Return the cryptographic hash of a string in base-16. */ | ||||||
| static void prim_hashString(EvalState & state, const Pos & pos, Value * * args, Value & v) | static void prim_hashString(EvalState & state, const Pos & pos, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     string type = state.forceStringNoCtx(*args[0]); |     string type = state.forceStringNoCtx(*args[0], pos); | ||||||
|     HashType ht = parseHashType(type); |     HashType ht = parseHashType(type); | ||||||
|     if (ht == htUnknown) |     if (ht == htUnknown) | ||||||
|       throw Error(format("unknown hash type `%1%', at %2%") % type % pos); |       throw Error(format("unknown hash type `%1%', at %2%") % type % pos); | ||||||
|  | @ -1187,7 +1187,7 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args, | ||||||
| 
 | 
 | ||||||
| static void prim_parseDrvName(EvalState & state, const Pos & pos, Value * * args, Value & v) | static void prim_parseDrvName(EvalState & state, const Pos & pos, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     string name = state.forceStringNoCtx(*args[0]); |     string name = state.forceStringNoCtx(*args[0], pos); | ||||||
|     DrvName parsed(name); |     DrvName parsed(name); | ||||||
|     state.mkAttrs(v, 2); |     state.mkAttrs(v, 2); | ||||||
|     mkString(*state.allocAttr(v, state.sName), parsed.name); |     mkString(*state.allocAttr(v, state.sName), parsed.name); | ||||||
|  | @ -1198,8 +1198,8 @@ static void prim_parseDrvName(EvalState & state, const Pos & pos, Value * * args | ||||||
| 
 | 
 | ||||||
| static void prim_compareVersions(EvalState & state, const Pos & pos, Value * * args, Value & v) | static void prim_compareVersions(EvalState & state, const Pos & pos, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     string version1 = state.forceStringNoCtx(*args[0]); |     string version1 = state.forceStringNoCtx(*args[0], pos); | ||||||
|     string version2 = state.forceStringNoCtx(*args[1]); |     string version2 = state.forceStringNoCtx(*args[1], pos); | ||||||
|     mkInt(v, compareVersions(version1, version2)); |     mkInt(v, compareVersions(version1, version2)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue