* In an nested with' where the inner with is a variable (with ...;
				
					
				
			with someVar; ...'), the contents of the variable would be clobbered. (The attributes in the outer `with' were added to the variable.)
This commit is contained in:
		
							parent
							
								
									04c4bd3624
								
							
						
					
					
						commit
						02c1dac909
					
				
					 3 changed files with 15 additions and 7 deletions
				
			
		|  | @ -649,6 +649,11 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v) | ||||||
|         Env * env3 = &env; |         Env * env3 = &env; | ||||||
|         for (unsigned int l = prevWith; l; --l, env3 = env3->up) ; |         for (unsigned int l = prevWith; l; --l, env3 = env3->up) ; | ||||||
| 
 | 
 | ||||||
|  |         /* Because the first `with' may be a shallow copy of another
 | ||||||
|  |            attribute set (through a tCopy node), we need to clone its | ||||||
|  |            `attrs' before modifying them. */ | ||||||
|  |         env2.values[0].attrs = new Bindings(*env2.values[0].attrs); | ||||||
|  | 
 | ||||||
|         foreach (Bindings::iterator, i, *env3->values[0].attrs) { |         foreach (Bindings::iterator, i, *env3->values[0].attrs) { | ||||||
|             Bindings::iterator j = env2.values[0].attrs->find(i->first); |             Bindings::iterator j = env2.values[0].attrs->find(i->first); | ||||||
|             if (j == env2.values[0].attrs->end()) |             if (j == env2.values[0].attrs->end()) | ||||||
|  | @ -1042,7 +1047,8 @@ void EvalState::printStats() | ||||||
|     printMsg(v, format("  expressions evaluated: %1%") % nrEvaluated); |     printMsg(v, format("  expressions evaluated: %1%") % nrEvaluated); | ||||||
|     printMsg(v, format("  stack space used: %1% bytes") % (&x - deepestStack)); |     printMsg(v, format("  stack space used: %1% bytes") % (&x - deepestStack)); | ||||||
|     printMsg(v, format("  max eval() nesting depth: %1%") % maxRecursionDepth); |     printMsg(v, format("  max eval() nesting depth: %1%") % maxRecursionDepth); | ||||||
|     printMsg(v, format("  stack space per eval() level: %1% bytes") % ((&x - deepestStack) / (float) maxRecursionDepth)); |     printMsg(v, format("  stack space per eval() level: %1% bytes") | ||||||
|  |         % ((&x - deepestStack) / (float) maxRecursionDepth)); | ||||||
|     printMsg(v, format("  environments allocated: %1% (%2% bytes)") |     printMsg(v, format("  environments allocated: %1% (%2% bytes)") | ||||||
|         % nrEnvs % (nrEnvs * sizeof(Env))); |         % nrEnvs % (nrEnvs * sizeof(Env))); | ||||||
|     printMsg(v, format("  values allocated in environments: %1% (%2% bytes)") |     printMsg(v, format("  values allocated in environments: %1% (%2% bytes)") | ||||||
|  |  | ||||||
|  | @ -177,14 +177,15 @@ static void getDerivations(EvalState & state, Value & vIn, | ||||||
|            there are names clashes between derivations, the derivation |            there are names clashes between derivations, the derivation | ||||||
|            bound to the attribute with the "lower" name should take |            bound to the attribute with the "lower" name should take | ||||||
|            precedence). */ |            precedence). */ | ||||||
|         StringSet attrs; |         typedef std::map<string, Symbol> SortedSymbols; | ||||||
|  |         SortedSymbols attrs; | ||||||
|         foreach (Bindings::iterator, i, *v.attrs) |         foreach (Bindings::iterator, i, *v.attrs) | ||||||
|             attrs.insert(i->first); |             attrs.insert(std::pair<string, Symbol>(i->first, i->first)); | ||||||
| 
 | 
 | ||||||
|         foreach (StringSet::iterator, i, attrs) { |         foreach (SortedSymbols::iterator, i, attrs) { | ||||||
|             startNest(nest, lvlDebug, format("evaluating attribute `%1%'") % *i); |             startNest(nest, lvlDebug, format("evaluating attribute `%1%'") % i->first); | ||||||
|             string pathPrefix2 = addToPath(pathPrefix, *i); |             string pathPrefix2 = addToPath(pathPrefix, i->first); | ||||||
|             Value & v2((*v.attrs)[state.symbols.create(*i)]); |             Value & v2((*v.attrs)[i->second]); | ||||||
|             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)) { | ||||||
|  |  | ||||||
|  | @ -1089,6 +1089,7 @@ static void opQuery(Globals & globals, | ||||||
|      |      | ||||||
|     foreach (vector<DrvInfo>::iterator, i, elems2) { |     foreach (vector<DrvInfo>::iterator, i, elems2) { | ||||||
|         try { |         try { | ||||||
|  |             startNest(nest, lvlDebug, format("outputting query result `%1%'") % i->attrPath); | ||||||
| 
 | 
 | ||||||
|             /* For table output. */ |             /* For table output. */ | ||||||
|             Strings columns; |             Strings columns; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue