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 | ||||
| 
 | ||||
| 
 | ||||
| static Symbol getName(const AttrName & name, EvalState & state, Env & env) { | ||||
| static Symbol getName(const AttrName & name, EvalState & state, Env & env) | ||||
| { | ||||
|     if (name.symbol.set()) { | ||||
|         return name.symbol; | ||||
|     } else { | ||||
|  | @ -279,6 +280,11 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, con | |||
|     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)) | ||||
| { | ||||
|     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); | ||||
|     if (v.type != tString) | ||||
|         throwTypeError("value is %1% while a string was expected", v); | ||||
|     if (v.type != tString) { | ||||
|         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); | ||||
| } | ||||
| 
 | ||||
|  | @ -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); | ||||
|     if (v.string.context) | ||||
|         throwEvalError("the string `%1%' is not allowed to refer to a store path (such as `%2%')", | ||||
|             v.string.s, v.string.context[0]); | ||||
|     string s = forceString(v, pos); | ||||
|     if (v.string.context) { | ||||
|         if (pos) | ||||
|             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; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -165,9 +165,9 @@ public: | |||
|     inline void forceList(Value & v); | ||||
|     inline void forceList(Value & v, const Pos & pos); | ||||
|     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 forceStringNoCtx(Value & v); | ||||
|     string forceStringNoCtx(Value & v, const Pos & pos = noPos); | ||||
| 
 | ||||
|     /* Return true iff the value `v' denotes a derivation (i.e. a
 | ||||
|        set with attribute `type = "derivation"'). */ | ||||
|  |  | |||
|  | @ -41,7 +41,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs() | |||
|             /* For each output... */ | ||||
|             for (unsigned int j = 0; j < i->value->list.length; ++j) { | ||||
|                 /* 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)); | ||||
|                 if (out == attrs->end()) continue; // FIXME: throw error?
 | ||||
|                 state->forceAttrs(*out->value); | ||||
|  | @ -199,11 +199,8 @@ static bool getDerivation(EvalState & state, Value & v, | |||
| 
 | ||||
|         Bindings::iterator i2 = v.attrs->find(state.sSystem); | ||||
| 
 | ||||
|         DrvInfo drv( | ||||
|             state, | ||||
|             state.forceStringNoCtx(*i->value), | ||||
|             attrPath, | ||||
|             i2 == v.attrs->end() ? "unknown" : state.forceStringNoCtx(*i2->value), | ||||
|         DrvInfo drv(state, state.forceStringNoCtx(*i->value), attrPath, | ||||
|             i2 == v.attrs->end() ? "unknown" : state.forceStringNoCtx(*i2->value, *i2->pos), | ||||
|             v.attrs); | ||||
| 
 | ||||
|         drvs.push_back(drv); | ||||
|  |  | |||
|  | @ -145,7 +145,7 @@ void ExprPos::show(std::ostream & str) | |||
| 
 | ||||
| std::ostream & operator << (std::ostream & str, const Pos & pos) | ||||
| { | ||||
|     if (!pos.line) | ||||
|     if (!pos) | ||||
|         str << "undefined position"; | ||||
|     else | ||||
|         str << (format("%1%:%2%:%3%") % pos.file % pos.line % pos.column).str(); | ||||
|  |  | |||
|  | @ -28,6 +28,10 @@ struct Pos | |||
|     Pos() : line(0), column(0) { }; | ||||
|     Pos(const Symbol & file, unsigned int line, unsigned int column) | ||||
|         : file(file), line(line), column(column) { }; | ||||
|     operator bool() const | ||||
|     { | ||||
|         return line != 0; | ||||
|     } | ||||
|     bool operator < (const Pos & p2) const | ||||
|     { | ||||
|         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. */ | ||||
| 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)); | ||||
| } | ||||
| 
 | ||||
|  | @ -343,7 +343,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * | |||
|     string drvName; | ||||
|     Pos & posDrvName(*attr->pos); | ||||
|     try { | ||||
|         drvName = state.forceStringNoCtx(*attr->value); | ||||
|         drvName = state.forceStringNoCtx(*attr->value, pos); | ||||
|     } catch (Error & e) { | ||||
|         e.addPrefix(format("while evaluating the derivation attribute `name' at %1%:\n") % posDrvName); | ||||
|         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) | ||||
| { | ||||
|     PathSet context; | ||||
|     string name = state.forceStringNoCtx(*args[0]); | ||||
|     string name = state.forceStringNoCtx(*args[0], pos); | ||||
|     string contents = state.forceString(*args[1], context); | ||||
| 
 | ||||
|     PathSet refs; | ||||
|  | @ -775,7 +775,7 @@ static void prim_attrNames(EvalState & state, const Pos & pos, Value * * args, V | |||
| /* Dynamic version of the `.' operator. */ | ||||
| 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); | ||||
|     // !!! Should we create a symbol here or just do a lookup?
 | ||||
|     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. */ | ||||
| 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); | ||||
|     Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr)); | ||||
|     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. */ | ||||
| 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); | ||||
|     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. */ | ||||
|     std::set<Symbol> names; | ||||
|     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)); | ||||
|     } | ||||
| 
 | ||||
|  | @ -861,7 +861,7 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args, | |||
|         Bindings::iterator j = v2.attrs->find(state.sName); | ||||
|         if (j == v2.attrs->end()) | ||||
|             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); | ||||
|         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. */ | ||||
| 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); | ||||
|     if (ht == htUnknown) | ||||
|       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) | ||||
| { | ||||
|     string name = state.forceStringNoCtx(*args[0]); | ||||
|     string name = state.forceStringNoCtx(*args[0], pos); | ||||
|     DrvName parsed(name); | ||||
|     state.mkAttrs(v, 2); | ||||
|     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) | ||||
| { | ||||
|     string version1 = state.forceStringNoCtx(*args[0]); | ||||
|     string version2 = state.forceStringNoCtx(*args[1]); | ||||
|     string version1 = state.forceStringNoCtx(*args[0], pos); | ||||
|     string version2 = state.forceStringNoCtx(*args[1], pos); | ||||
|     mkInt(v, compareVersions(version1, version2)); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue