* Keep track of the source positions of attributes.
This commit is contained in:
		
							parent
							
								
									84ce7ac76f
								
							
						
					
					
						commit
						e2d5e40f4f
					
				
					 8 changed files with 117 additions and 86 deletions
				
			
		|  | @ -48,7 +48,7 @@ void findAlongAttrPath(EvalState & state, const string & attrPath, | ||||||
|             Bindings::iterator a = v.attrs->find(state.symbols.create(attr)); |             Bindings::iterator a = v.attrs->find(state.symbols.create(attr)); | ||||||
|             if (a == v.attrs->end()) |             if (a == v.attrs->end()) | ||||||
|                 throw Error(format("attribute `%1%' in selection path `%2%' not found") % attr % curPath); |                 throw Error(format("attribute `%1%' in selection path `%2%' not found") % attr % curPath); | ||||||
|             v = a->second; |             v = a->second.value; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         else if (apType == apIndex) { |         else if (apType == apIndex) { | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ bool parseOptionArg(const string & arg, Strings::iterator & i, | ||||||
|     if (i == argsEnd) throw error; |     if (i == argsEnd) throw error; | ||||||
|     string value = *i++; |     string value = *i++; | ||||||
| 
 | 
 | ||||||
|     Value & v(autoArgs[state.symbols.create(name)]); |     Value & v(autoArgs[state.symbols.create(name)].value); | ||||||
| 
 | 
 | ||||||
|     if (arg == "--arg") |     if (arg == "--arg") | ||||||
|         state.mkThunk_( v, parseExprFromString(state, value, absPath("."))); |         state.mkThunk_( v, parseExprFromString(state, value, absPath("."))); | ||||||
|  |  | ||||||
|  | @ -44,7 +44,7 @@ std::ostream & operator << (std::ostream & str, Value & v) | ||||||
|     case tAttrs: |     case tAttrs: | ||||||
|         str << "{ "; |         str << "{ "; | ||||||
|         foreach (Bindings::iterator, i, *v.attrs) |         foreach (Bindings::iterator, i, *v.attrs) | ||||||
|             str << (string) i->first << " = " << i->second << "; "; |             str << (string) i->first << " = " << i->second.value << "; "; | ||||||
|         str << "}"; |         str << "}"; | ||||||
|         break; |         break; | ||||||
|     case tList: |     case tList: | ||||||
|  | @ -128,7 +128,7 @@ void EvalState::addConstant(const string & name, Value & v) | ||||||
|     staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl; |     staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl; | ||||||
|     baseEnv.values[baseEnvDispl++] = v; |     baseEnv.values[baseEnvDispl++] = v; | ||||||
|     string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name; |     string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name; | ||||||
|     (*baseEnv.values[0].attrs)[symbols.create(name2)] = v; |     (*baseEnv.values[0].attrs)[symbols.create(name2)].value = v; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -143,7 +143,7 @@ void EvalState::addPrimOp(const string & name, | ||||||
|     v.primOp.name = strdup(name2.c_str()); |     v.primOp.name = strdup(name2.c_str()); | ||||||
|     staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl; |     staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl; | ||||||
|     baseEnv.values[baseEnvDispl++] = v; |     baseEnv.values[baseEnvDispl++] = v; | ||||||
|     (*baseEnv.values[0].attrs)[symbols.create(name2)] = v; |     (*baseEnv.values[0].attrs)[symbols.create(name2)].value = v; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -202,6 +202,11 @@ LocalNoInline(void addErrorPrefix(Error & e, const char * s, const Pos & pos)) | ||||||
|     e.addPrefix(format(s) % pos); |     e.addPrefix(format(s) % pos); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | LocalNoInline(void addErrorPrefix(Error & e, const char * s, const string & s2, const Pos & pos)) | ||||||
|  | { | ||||||
|  |     e.addPrefix(format(s) % s2 % pos); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| void mkString(Value & v, const char * s) | void mkString(Value & v, const char * s) | ||||||
| { | { | ||||||
|  | @ -239,7 +244,7 @@ Value * EvalState::lookupVar(Env * env, const VarRef & var) | ||||||
|         while (1) { |         while (1) { | ||||||
|             Bindings::iterator j = env->values[0].attrs->find(var.name); |             Bindings::iterator j = env->values[0].attrs->find(var.name); | ||||||
|             if (j != env->values[0].attrs->end()) |             if (j != env->values[0].attrs->end()) | ||||||
|                 return &j->second; |                 return &j->second.value; | ||||||
|             if (env->prevWith == 0) |             if (env->prevWith == 0) | ||||||
|                 throwEvalError("undefined variable `%1%'", var.name); |                 throwEvalError("undefined variable `%1%'", var.name); | ||||||
|             for (unsigned int l = env->prevWith; l; --l, env = env->up) ; |             for (unsigned int l = env->prevWith; l; --l, env = env->up) ; | ||||||
|  | @ -290,8 +295,11 @@ void EvalState::mkThunk_(Value & v, Expr * expr) | ||||||
| void EvalState::cloneAttrs(Value & src, Value & dst) | void EvalState::cloneAttrs(Value & src, Value & dst) | ||||||
| { | { | ||||||
|     mkAttrs(dst); |     mkAttrs(dst); | ||||||
|     foreach (Bindings::iterator, i, *src.attrs) |     foreach (Bindings::iterator, i, *src.attrs) { | ||||||
|         mkCopy((*dst.attrs)[i->first], i->second); |         Attr & a = (*dst.attrs)[i->first]; | ||||||
|  |         mkCopy(a.value, i->second.value); | ||||||
|  |         a.pos = i->second.pos; | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -414,15 +422,16 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) | ||||||
|         /* The recursive attributes are evaluated in the new
 |         /* The recursive attributes are evaluated in the new
 | ||||||
|            environment. */ |            environment. */ | ||||||
|         foreach (Attrs::iterator, i, attrs) { |         foreach (Attrs::iterator, i, attrs) { | ||||||
|             Value & v2 = (*v.attrs)[i->first]; |             nix::Attr & a = (*v.attrs)[i->first]; | ||||||
|             mkCopy(v2, env2.values[displ]); |             mkCopy(a.value, env2.values[displ]); | ||||||
|             mkThunk(env2.values[displ++], env2, i->second.first); |             mkThunk(env2.values[displ++], env2, i->second.first); | ||||||
|  |             a.pos = &i->second.second; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /* The inherited attributes, on the other hand, are
 |         /* The inherited attributes, on the other hand, are
 | ||||||
|            evaluated in the original environment. */ |            evaluated in the original environment. */ | ||||||
|         foreach (list<VarRef>::iterator, i, inherited) { |         foreach (list<VarRef>::iterator, i, inherited) { | ||||||
|             Value & v2 = (*v.attrs)[i->name]; |             Value & v2 = (*v.attrs)[i->name].value; | ||||||
|             Value * v3 = state.lookupVar(&env, *i); |             Value * v3 = state.lookupVar(&env, *i); | ||||||
|             mkCopy(v2, *v3); |             mkCopy(v2, *v3); | ||||||
|             mkCopy(env2.values[displ++], *v3); |             mkCopy(env2.values[displ++], *v3); | ||||||
|  | @ -432,12 +441,13 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) | ||||||
| 
 | 
 | ||||||
|     else { |     else { | ||||||
|         foreach (Attrs::iterator, i, attrs) { |         foreach (Attrs::iterator, i, attrs) { | ||||||
|             Value & v2 = (*v.attrs)[i->first]; |             nix::Attr & a = (*v.attrs)[i->first]; | ||||||
|             mkThunk(v2, env, i->second.first); |             mkThunk(a.value, env, i->second.first); | ||||||
|  |             a.pos = &i->second.second; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         foreach (list<VarRef>::iterator, i, inherited) { |         foreach (list<VarRef>::iterator, i, inherited) { | ||||||
|             Value & v2 = (*v.attrs)[i->name]; |             Value & v2 = (*v.attrs)[i->name].value; | ||||||
|             mkCopy(v2, *state.lookupVar(&env, *i)); |             mkCopy(v2, *state.lookupVar(&env, *i)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -494,12 +504,13 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) | ||||||
|     if (i == v2.attrs->end()) |     if (i == v2.attrs->end()) | ||||||
|         throwEvalError("attribute `%1%' missing", name); |         throwEvalError("attribute `%1%' missing", name); | ||||||
|     try {             |     try {             | ||||||
|         state.forceValue(i->second); |         state.forceValue(i->second.value); | ||||||
|     } catch (Error & e) { |     } catch (Error & e) { | ||||||
|         addErrorPrefix(e, "while evaluating the attribute `%1%':\n", name); |         addErrorPrefix(e, "while evaluating the attribute `%1%' at %2%:\n", | ||||||
|  |             name, *i->second.pos); | ||||||
|         throw; |         throw; | ||||||
|     } |     } | ||||||
|     v = i->second; |     v = i->second.value; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -601,7 +612,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v) | ||||||
|                 mkThunk(env2.values[displ++], env2, i->def); |                 mkThunk(env2.values[displ++], env2, i->def); | ||||||
|             } else { |             } else { | ||||||
|                 attrsUsed++; |                 attrsUsed++; | ||||||
|                 mkCopy(env2.values[displ++], j->second); |                 mkCopy(env2.values[displ++], j->second.value); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -721,8 +732,11 @@ void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v) | ||||||
|          |          | ||||||
|     state.evalAttrs(env, e2, v2); |     state.evalAttrs(env, e2, v2); | ||||||
|      |      | ||||||
|     foreach (Bindings::iterator, i, *v2.attrs) |     foreach (Bindings::iterator, i, *v2.attrs) { | ||||||
|         mkCopy((*v.attrs)[i->first], i->second); |         Attr & a = (*v.attrs)[i->first]; | ||||||
|  |         mkCopy(a.value, i->second.value); | ||||||
|  |         a.pos = i->second.pos; | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -802,7 +816,7 @@ void EvalState::strictForceValue(Value & v) | ||||||
|      |      | ||||||
|     if (v.type == tAttrs) { |     if (v.type == tAttrs) { | ||||||
|         foreach (Bindings::iterator, i, *v.attrs) |         foreach (Bindings::iterator, i, *v.attrs) | ||||||
|             strictForceValue(i->second); |             strictForceValue(i->second.value); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     else if (v.type == tList) { |     else if (v.type == tList) { | ||||||
|  | @ -887,7 +901,7 @@ bool EvalState::isDerivation(Value & v) | ||||||
| { | { | ||||||
|     if (v.type != tAttrs) return false; |     if (v.type != tAttrs) return false; | ||||||
|     Bindings::iterator i = v.attrs->find(sType); |     Bindings::iterator i = v.attrs->find(sType); | ||||||
|     return i != v.attrs->end() && forceStringNoCtx(i->second) == "derivation"; |     return i != v.attrs->end() && forceStringNoCtx(i->second.value) == "derivation"; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -933,7 +947,7 @@ string EvalState::coerceToString(Value & v, PathSet & context, | ||||||
|         Bindings::iterator i = v.attrs->find(sOutPath); |         Bindings::iterator i = v.attrs->find(sOutPath); | ||||||
|         if (i == v.attrs->end()) |         if (i == v.attrs->end()) | ||||||
|             throwTypeError("cannot coerce an attribute set (except a derivation) to a string"); |             throwTypeError("cannot coerce an attribute set (except a derivation) to a string"); | ||||||
|         return coerceToString(i->second, context, coerceMore, copyToStore); |         return coerceToString(i->second.value, context, coerceMore, copyToStore); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (coerceMore) { |     if (coerceMore) { | ||||||
|  | @ -1021,7 +1035,8 @@ bool EvalState::eqValues(Value & v1, Value & v2) | ||||||
|             if (v1.attrs->size() != v2.attrs->size()) return false; |             if (v1.attrs->size() != v2.attrs->size()) return false; | ||||||
|             Bindings::iterator i, j; |             Bindings::iterator i, j; | ||||||
|             for (i = v1.attrs->begin(), j = v2.attrs->begin(); i != v1.attrs->end(); ++i, ++j) |             for (i = v1.attrs->begin(), j = v2.attrs->begin(); i != v1.attrs->end(); ++i, ++j) | ||||||
|                 if (i->first != j->first || !eqValues(i->second, j->second)) return false; |                 if (i->first != j->first || !eqValues(i->second.value, j->second.value)) | ||||||
|  |                     return false; | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -14,8 +14,9 @@ class Hash; | ||||||
| class EvalState; | class EvalState; | ||||||
| struct Env; | struct Env; | ||||||
| struct Value; | struct Value; | ||||||
|  | struct Attr; | ||||||
| 
 | 
 | ||||||
| typedef std::map<Symbol, Value> Bindings; | typedef std::map<Symbol, Attr> Bindings; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
|  | @ -111,6 +112,14 @@ struct Env | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | struct Attr | ||||||
|  | { | ||||||
|  |     Value value; | ||||||
|  |     Pos * pos; | ||||||
|  |     Attr() : pos(&noPos) { }; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| static inline void mkInt(Value & v, int n) | static inline void mkInt(Value & v, int n) | ||||||
| { | { | ||||||
|     v.type = tInt; |     v.type = tInt; | ||||||
|  |  | ||||||
|  | @ -10,7 +10,7 @@ string DrvInfo::queryDrvPath(EvalState & state) const | ||||||
|     if (drvPath == "" && attrs) { |     if (drvPath == "" && attrs) { | ||||||
|         Bindings::iterator i = attrs->find(state.sDrvPath); |         Bindings::iterator i = attrs->find(state.sDrvPath); | ||||||
|         PathSet context; |         PathSet context; | ||||||
|         (string &) drvPath = i != attrs->end() ? state.coerceToPath(i->second, context) : ""; |         (string &) drvPath = i != attrs->end() ? state.coerceToPath(i->second.value, context) : ""; | ||||||
|     } |     } | ||||||
|     return drvPath; |     return drvPath; | ||||||
| } | } | ||||||
|  | @ -21,7 +21,7 @@ string DrvInfo::queryOutPath(EvalState & state) const | ||||||
|     if (outPath == "" && attrs) { |     if (outPath == "" && attrs) { | ||||||
|         Bindings::iterator i = attrs->find(state.sOutPath); |         Bindings::iterator i = attrs->find(state.sOutPath); | ||||||
|         PathSet context; |         PathSet context; | ||||||
|         (string &) outPath = i != attrs->end() ? state.coerceToPath(i->second, context) : ""; |         (string &) outPath = i != attrs->end() ? state.coerceToPath(i->second.value, context) : ""; | ||||||
|     } |     } | ||||||
|     return outPath; |     return outPath; | ||||||
| } | } | ||||||
|  | @ -36,21 +36,21 @@ MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const | ||||||
|     Bindings::iterator a = attrs->find(state.sMeta); |     Bindings::iterator a = attrs->find(state.sMeta); | ||||||
|     if (a == attrs->end()) return meta; /* fine, empty meta information */ |     if (a == attrs->end()) return meta; /* fine, empty meta information */ | ||||||
| 
 | 
 | ||||||
|     state.forceAttrs(a->second); |     state.forceAttrs(a->second.value); | ||||||
| 
 | 
 | ||||||
|     foreach (Bindings::iterator, i, *a->second.attrs) { |     foreach (Bindings::iterator, i, *a->second.value.attrs) { | ||||||
|         MetaValue value; |         MetaValue value; | ||||||
|         state.forceValue(i->second); |         state.forceValue(i->second.value); | ||||||
|         if (i->second.type == tString) { |         if (i->second.value.type == tString) { | ||||||
|             value.type = MetaValue::tpString; |             value.type = MetaValue::tpString; | ||||||
|             value.stringValue = i->second.string.s; |             value.stringValue = i->second.value.string.s; | ||||||
|         } else if (i->second.type == tInt) { |         } else if (i->second.value.type == tInt) { | ||||||
|             value.type = MetaValue::tpInt; |             value.type = MetaValue::tpInt; | ||||||
|             value.intValue = i->second.integer; |             value.intValue = i->second.value.integer; | ||||||
|         } else if (i->second.type == tList) { |         } else if (i->second.value.type == tList) { | ||||||
|             value.type = MetaValue::tpStrings; |             value.type = MetaValue::tpStrings; | ||||||
|             for (unsigned int j = 0; j < i->second.list.length; ++j) |             for (unsigned int j = 0; j < i->second.value.list.length; ++j) | ||||||
|                 value.stringValues.push_back(state.forceStringNoCtx(*i->second.list.elems[j])); |                 value.stringValues.push_back(state.forceStringNoCtx(*i->second.value.list.elems[j])); | ||||||
|         } else continue; |         } else continue; | ||||||
|         ((MetaInfo &) meta)[i->first] = value; |         ((MetaInfo &) meta)[i->first] = value; | ||||||
|     } |     } | ||||||
|  | @ -99,13 +99,13 @@ static bool getDerivation(EvalState & state, Value & v, | ||||||
|         Bindings::iterator i = v.attrs->find(state.sName); |         Bindings::iterator i = v.attrs->find(state.sName); | ||||||
|         /* !!! We really would like to have a decent back trace here. */ |         /* !!! We really would like to have a decent back trace here. */ | ||||||
|         if (i == v.attrs->end()) throw TypeError("derivation name missing"); |         if (i == v.attrs->end()) throw TypeError("derivation name missing"); | ||||||
|         drv.name = state.forceStringNoCtx(i->second); |         drv.name = state.forceStringNoCtx(i->second.value); | ||||||
| 
 | 
 | ||||||
|         i = v.attrs->find(state.sSystem); |         i = v.attrs->find(state.sSystem); | ||||||
|         if (i == v.attrs->end()) |         if (i == v.attrs->end()) | ||||||
|             drv.system = "unknown"; |             drv.system = "unknown"; | ||||||
|         else |         else | ||||||
|             drv.system = state.forceStringNoCtx(i->second); |             drv.system = state.forceStringNoCtx(i->second.value); | ||||||
| 
 | 
 | ||||||
|         drv.attrs = v.attrs; |         drv.attrs = v.attrs; | ||||||
| 
 | 
 | ||||||
|  | @ -168,7 +168,7 @@ static void getDerivations(EvalState & state, Value & vIn, | ||||||
|         foreach (SortedSymbols::iterator, i, attrs) { |         foreach (SortedSymbols::iterator, i, attrs) { | ||||||
|             startNest(nest, lvlDebug, format("evaluating attribute `%1%'") % i->first); |             startNest(nest, lvlDebug, format("evaluating attribute `%1%'") % i->first); | ||||||
|             string pathPrefix2 = addToPath(pathPrefix, i->first); |             string pathPrefix2 = addToPath(pathPrefix, i->first); | ||||||
|             Value & v2((*v.attrs)[i->second]); |             Value & v2((*v.attrs)[i->second].value); | ||||||
|             if (combineChannels) |             if (combineChannels) | ||||||
|                 getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done); |                 getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done); | ||||||
|             else if (getDerivation(state, v2, pathPrefix2, drvs, done)) { |             else if (getDerivation(state, v2, pathPrefix2, drvs, done)) { | ||||||
|  | @ -178,7 +178,7 @@ static void getDerivations(EvalState & state, Value & vIn, | ||||||
|                    attribute. */ |                    attribute. */ | ||||||
|                 if (v2.type == tAttrs) { |                 if (v2.type == tAttrs) { | ||||||
|                     Bindings::iterator j = v2.attrs->find(state.symbols.create("recurseForDerivations")); |                     Bindings::iterator j = v2.attrs->find(state.symbols.create("recurseForDerivations")); | ||||||
|                     if (j != v2.attrs->end() && state.forceBool(j->second)) |                     if (j != v2.attrs->end() && state.forceBool(j->second.value)) | ||||||
|                         getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done); |                         getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  | @ -115,18 +115,18 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v) | ||||||
|         args[0]->attrs->find(state.symbols.create("startSet")); |         args[0]->attrs->find(state.symbols.create("startSet")); | ||||||
|     if (startSet == args[0]->attrs->end()) |     if (startSet == args[0]->attrs->end()) | ||||||
|         throw EvalError("attribute `startSet' required"); |         throw EvalError("attribute `startSet' required"); | ||||||
|     state.forceList(startSet->second); |     state.forceList(startSet->second.value); | ||||||
| 
 | 
 | ||||||
|     list<Value *> workSet; |     list<Value *> workSet; | ||||||
|     for (unsigned int n = 0; n < startSet->second.list.length; ++n) |     for (unsigned int n = 0; n < startSet->second.value.list.length; ++n) | ||||||
|         workSet.push_back(startSet->second.list.elems[n]); |         workSet.push_back(startSet->second.value.list.elems[n]); | ||||||
| 
 | 
 | ||||||
|     /* Get the operator. */ |     /* Get the operator. */ | ||||||
|     Bindings::iterator op = |     Bindings::iterator op = | ||||||
|         args[0]->attrs->find(state.symbols.create("operator")); |         args[0]->attrs->find(state.symbols.create("operator")); | ||||||
|     if (op == args[0]->attrs->end()) |     if (op == args[0]->attrs->end()) | ||||||
|         throw EvalError("attribute `operator' required"); |         throw EvalError("attribute `operator' required"); | ||||||
|     state.forceValue(op->second); |     state.forceValue(op->second.value); | ||||||
| 
 | 
 | ||||||
|     /* Construct the closure by applying the operator to element of
 |     /* Construct the closure by applying the operator to element of
 | ||||||
|        `workSet', adding the result to `workSet', continuing until |        `workSet', adding the result to `workSet', continuing until | ||||||
|  | @ -143,15 +143,15 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v) | ||||||
|             e->attrs->find(state.symbols.create("key")); |             e->attrs->find(state.symbols.create("key")); | ||||||
|         if (key == e->attrs->end()) |         if (key == e->attrs->end()) | ||||||
|             throw EvalError("attribute `key' required"); |             throw EvalError("attribute `key' required"); | ||||||
|         state.forceValue(key->second); |         state.forceValue(key->second.value); | ||||||
| 
 | 
 | ||||||
|         if (doneKeys.find(key->second) != doneKeys.end()) continue; |         if (doneKeys.find(key->second.value) != doneKeys.end()) continue; | ||||||
|         doneKeys.insert(key->second); |         doneKeys.insert(key->second.value); | ||||||
|         res.push_back(*e); |         res.push_back(*e); | ||||||
|          |          | ||||||
|         /* Call the `operator' function with `e' as argument. */ |         /* Call the `operator' function with `e' as argument. */ | ||||||
|         Value call; |         Value call; | ||||||
|         mkApp(call, op->second, *e); |         mkApp(call, op->second.value, *e); | ||||||
|         state.forceList(call); |         state.forceList(call); | ||||||
| 
 | 
 | ||||||
|         /* Add the values returned by the operator to the work set. */ |         /* Add the values returned by the operator to the work set. */ | ||||||
|  | @ -323,11 +323,11 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) | ||||||
|     if (attr == args[0]->attrs->end()) |     if (attr == args[0]->attrs->end()) | ||||||
|         throw EvalError("required attribute `name' missing"); |         throw EvalError("required attribute `name' missing"); | ||||||
|     string drvName; |     string drvName; | ||||||
|  |     Pos & posDrvName(*attr->second.pos); | ||||||
|     try {         |     try {         | ||||||
|         drvName = state.forceStringNoCtx(attr->second); |         drvName = state.forceStringNoCtx(attr->second.value); | ||||||
|     } catch (Error & e) { |     } catch (Error & e) { | ||||||
|         e.addPrefix(format("while evaluating the derivation attribute `name' at <SOMEWHERE>:\n")); |         e.addPrefix(format("while evaluating the derivation attribute `name' at %1%:\n") % posDrvName); | ||||||
|         // !!! % showPos(posDrvName));
 |  | ||||||
|         throw; |         throw; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  | @ -348,9 +348,9 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) | ||||||
|             /* The `args' attribute is special: it supplies the
 |             /* The `args' attribute is special: it supplies the
 | ||||||
|                command-line arguments to the builder. */ |                command-line arguments to the builder. */ | ||||||
|             if (key == "args") { |             if (key == "args") { | ||||||
|                 state.forceList(i->second); |                 state.forceList(i->second.value); | ||||||
|                 for (unsigned int n = 0; n < i->second.list.length; ++n) { |                 for (unsigned int n = 0; n < i->second.value.list.length; ++n) { | ||||||
|                     string s = state.coerceToString(*i->second.list.elems[n], context, true); |                     string s = state.coerceToString(*i->second.value.list.elems[n], context, true); | ||||||
|                     drv.args.push_back(s); |                     drv.args.push_back(s); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | @ -358,7 +358,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) | ||||||
|             /* All other attributes are passed to the builder through
 |             /* All other attributes are passed to the builder through
 | ||||||
|                the environment. */ |                the environment. */ | ||||||
|             else { |             else { | ||||||
|                 string s = state.coerceToString(i->second, context, true); |                 string s = state.coerceToString(i->second.value, context, true); | ||||||
|                 drv.env[key] = s; |                 drv.env[key] = s; | ||||||
|                 if (key == "builder") drv.builder = s; |                 if (key == "builder") drv.builder = s; | ||||||
|                 else if (i->first == state.sSystem) drv.platform = s; |                 else if (i->first == state.sSystem) drv.platform = s; | ||||||
|  | @ -373,10 +373,10 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|         } catch (Error & e) { |         } catch (Error & e) { | ||||||
|             e.addPrefix(format("while evaluating the derivation attribute `%1%' at <SOMEWHERE>:\n") |             e.addPrefix(format("while evaluating the derivation attribute `%1%' at %2%:\n") | ||||||
|                 % key /* !!! % showPos(pos) */); |                 % key % *i->second.pos); | ||||||
|             e.addPrefix(format("while instantiating the derivation named `%1%' at <SOMEWHERE>:\n") |             e.addPrefix(format("while instantiating the derivation named `%1%' at %2%:\n") | ||||||
|                 % drvName /* !!! % showPos(posDrvName) */); |                 % drvName % posDrvName); | ||||||
|             throw; |             throw; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -487,8 +487,8 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) | ||||||
| 
 | 
 | ||||||
|     /* !!! assumes a single output */ |     /* !!! assumes a single output */ | ||||||
|     state.mkAttrs(v); |     state.mkAttrs(v); | ||||||
|     mkString((*v.attrs)[state.sOutPath], outPath, singleton<PathSet>(drvPath)); |     mkString((*v.attrs)[state.sOutPath].value, outPath, singleton<PathSet>(drvPath)); | ||||||
|     mkString((*v.attrs)[state.sDrvPath], drvPath, singleton<PathSet>("=" + drvPath)); |     mkString((*v.attrs)[state.sDrvPath].value, drvPath, singleton<PathSet>("=" + drvPath)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -711,8 +711,9 @@ static void prim_getAttr(EvalState & state, Value * * args, Value & v) | ||||||
|     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()) | ||||||
|         throw EvalError(format("attribute `%1%' missing") % attr); |         throw EvalError(format("attribute `%1%' missing") % attr); | ||||||
|     state.forceValue(i->second); |     // !!! add to stack trace?
 | ||||||
|     v = i->second; |     state.forceValue(i->second.value); | ||||||
|  |     v = i->second.value; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -764,13 +765,15 @@ static void prim_listToAttrs(EvalState & state, Value * * args, Value & v) | ||||||
|         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("`name' attribute missing in a call to `listToAttrs'"); |             throw TypeError("`name' attribute missing in a call to `listToAttrs'"); | ||||||
|         string name = state.forceStringNoCtx(j->second); |         string name = state.forceStringNoCtx(j->second.value); | ||||||
|          |          | ||||||
|         j = v2.attrs->find(state.symbols.create("value")); |         j = v2.attrs->find(state.symbols.create("value")); | ||||||
|         if (j == v2.attrs->end()) |         if (j == v2.attrs->end()) | ||||||
|             throw TypeError("`value' attribute missing in a call to `listToAttrs'"); |             throw TypeError("`value' attribute missing in a call to `listToAttrs'"); | ||||||
| 
 | 
 | ||||||
|         mkCopy((*v.attrs)[state.symbols.create(name)], j->second); |         Attr & a = (*v.attrs)[state.symbols.create(name)]; | ||||||
|  |         mkCopy(a.value, j->second.value); | ||||||
|  |         a.pos = j->second.pos; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -787,8 +790,11 @@ static void prim_intersectAttrs(EvalState & state, Value * * args, Value & v) | ||||||
|      |      | ||||||
|     foreach (Bindings::iterator, i, *args[1]->attrs) { |     foreach (Bindings::iterator, i, *args[1]->attrs) { | ||||||
|         Bindings::iterator j = args[0]->attrs->find(i->first); |         Bindings::iterator j = args[0]->attrs->find(i->first); | ||||||
|         if (j != args[0]->attrs->end()) |         if (j != args[0]->attrs->end()) { | ||||||
|             mkCopy((*v.attrs)[i->first], i->second); |             Attr & a = (*v.attrs)[i->first]; | ||||||
|  |             mkCopy(a.value, i->second.value); | ||||||
|  |             a.pos = i->second.pos; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -817,7 +823,7 @@ static void prim_functionArgs(EvalState & state, Value * * args, Value & v) | ||||||
|     if (!args[0]->lambda.fun->matchAttrs) return; |     if (!args[0]->lambda.fun->matchAttrs) return; | ||||||
| 
 | 
 | ||||||
|     foreach (Formals::Formals_::iterator, i, args[0]->lambda.fun->formals->formals) |     foreach (Formals::Formals_::iterator, i, args[0]->lambda.fun->formals->formals) | ||||||
|         mkBool((*v.attrs)[i->name], i->def); |         mkBool((*v.attrs)[i->name].value, i->def); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -1000,8 +1006,8 @@ static void prim_parseDrvName(EvalState & state, Value * * args, Value & v) | ||||||
|     string name = state.forceStringNoCtx(*args[0]); |     string name = state.forceStringNoCtx(*args[0]); | ||||||
|     DrvName parsed(name); |     DrvName parsed(name); | ||||||
|     state.mkAttrs(v); |     state.mkAttrs(v); | ||||||
|     mkString((*v.attrs)[state.sName], parsed.name); |     mkString((*v.attrs)[state.sName].value, parsed.name); | ||||||
|     mkString((*v.attrs)[state.symbols.create("version")], parsed.version); |     mkString((*v.attrs)[state.symbols.create("version")].value, parsed.version); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -28,7 +28,8 @@ static void showAttrs(EvalState & state, bool strict, Bindings & attrs, | ||||||
|         names.insert(i->first); |         names.insert(i->first); | ||||||
|     foreach (StringSet::iterator, i, names) { |     foreach (StringSet::iterator, i, names) { | ||||||
|         XMLOpenElement _(doc, "attr", singletonAttrs("name", *i)); |         XMLOpenElement _(doc, "attr", singletonAttrs("name", *i)); | ||||||
|         printValueAsXML(state, strict, attrs[state.symbols.create(*i)], doc, context, drvsSeen); |         printValueAsXML(state, strict, attrs[state.symbols.create(*i)].value, | ||||||
|  |             doc, context, drvsSeen); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -71,12 +72,12 @@ static void printValueAsXML(EvalState & state, bool strict, Value & v, | ||||||
| 
 | 
 | ||||||
|                 Path drvPath; |                 Path drvPath; | ||||||
|                 a = v.attrs->find(state.sDrvPath); |                 a = v.attrs->find(state.sDrvPath); | ||||||
|                 if (a != v.attrs->end() && a->second.type == tString) |                 if (a != v.attrs->end() && a->second.value.type == tString) | ||||||
|                     xmlAttrs["drvPath"] = drvPath = a->second.string.s; |                     xmlAttrs["drvPath"] = drvPath = a->second.value.string.s; | ||||||
|          |          | ||||||
|                 a = v.attrs->find(state.sOutPath); |                 a = v.attrs->find(state.sOutPath); | ||||||
|                 if (a != v.attrs->end() && a->second.type == tString) |                 if (a != v.attrs->end() && a->second.value.type == tString) | ||||||
|                     xmlAttrs["outPath"] = a->second.string.s; |                     xmlAttrs["outPath"] = a->second.value.string.s; | ||||||
| 
 | 
 | ||||||
|                 XMLOpenElement _(doc, "derivation", xmlAttrs); |                 XMLOpenElement _(doc, "derivation", xmlAttrs); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -62,19 +62,19 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, | ||||||
|         manifest.list.elems[n++] = &v; |         manifest.list.elems[n++] = &v; | ||||||
|         state.mkAttrs(v); |         state.mkAttrs(v); | ||||||
| 
 | 
 | ||||||
|         mkString((*v.attrs)[state.sType], "derivation"); |         mkString((*v.attrs)[state.sType].value, "derivation"); | ||||||
|         mkString((*v.attrs)[state.sName], i->name); |         mkString((*v.attrs)[state.sName].value, i->name); | ||||||
|         mkString((*v.attrs)[state.sSystem], i->system); |         mkString((*v.attrs)[state.sSystem].value, i->system); | ||||||
|         mkString((*v.attrs)[state.sOutPath], i->queryOutPath(state)); |         mkString((*v.attrs)[state.sOutPath].value, i->queryOutPath(state)); | ||||||
|         if (drvPath != "") |         if (drvPath != "") | ||||||
|             mkString((*v.attrs)[state.sDrvPath], i->queryDrvPath(state)); |             mkString((*v.attrs)[state.sDrvPath].value, i->queryDrvPath(state)); | ||||||
|          |          | ||||||
|         state.mkAttrs((*v.attrs)[state.sMeta]); |         state.mkAttrs((*v.attrs)[state.sMeta].value); | ||||||
|          |          | ||||||
|         MetaInfo meta = i->queryMetaInfo(state); |         MetaInfo meta = i->queryMetaInfo(state); | ||||||
| 
 | 
 | ||||||
|         foreach (MetaInfo::const_iterator, j, meta) { |         foreach (MetaInfo::const_iterator, j, meta) { | ||||||
|             Value & v2((*(*v.attrs)[state.sMeta].attrs)[state.symbols.create(j->first)]); |             Value & v2((*(*v.attrs)[state.sMeta].value.attrs)[state.symbols.create(j->first)].value); | ||||||
|             switch (j->second.type) { |             switch (j->second.type) { | ||||||
|                 case MetaValue::tpInt: mkInt(v2, j->second.intValue); break; |                 case MetaValue::tpInt: mkInt(v2, j->second.intValue); break; | ||||||
|                 case MetaValue::tpString: mkString(v2, j->second.stringValue); break; |                 case MetaValue::tpString: mkString(v2, j->second.stringValue); break; | ||||||
|  | @ -116,10 +116,10 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, | ||||||
|        builder with the manifest as argument. */ |        builder with the manifest as argument. */ | ||||||
|     Value args, topLevel; |     Value args, topLevel; | ||||||
|     state.mkAttrs(args); |     state.mkAttrs(args); | ||||||
|     mkString((*args.attrs)[state.sSystem], thisSystem); |     mkString((*args.attrs)[state.sSystem].value, thisSystem); | ||||||
|     mkString((*args.attrs)[state.symbols.create("manifest")], |     mkString((*args.attrs)[state.symbols.create("manifest")].value, | ||||||
|         manifestFile, singleton<PathSet>(manifestFile)); |         manifestFile, singleton<PathSet>(manifestFile)); | ||||||
|     (*args.attrs)[state.symbols.create("derivations")] = manifest; |     (*args.attrs)[state.symbols.create("derivations")].value = manifest; | ||||||
|     mkApp(topLevel, envBuilder, args); |     mkApp(topLevel, envBuilder, args); | ||||||
|          |          | ||||||
|     /* Evaluate it. */ |     /* Evaluate it. */ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue