aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-04-16 13:44:02 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-04-16 13:44:02 +0000
commit02c1dac90934e1b833c4d6bd9280bda27c146d80 (patch)
treee84f70d93fd75d162099275d3facd6ec9037844c /src
parent04c4bd3624b094043ff0f2410c1e376a51f457f7 (diff)
* 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.)
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval.cc8
-rw-r--r--src/libexpr/get-drvs.cc13
-rw-r--r--src/nix-env/nix-env.cc1
3 files changed, 15 insertions, 7 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 69e7bd8b3..ac475c893 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -649,6 +649,11 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v)
Env * env3 = &env;
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) {
Bindings::iterator j = env2.values[0].attrs->find(i->first);
if (j == env2.values[0].attrs->end())
@@ -1042,7 +1047,8 @@ void EvalState::printStats()
printMsg(v, format(" expressions evaluated: %1%") % nrEvaluated);
printMsg(v, format(" stack space used: %1% bytes") % (&x - deepestStack));
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)")
% nrEnvs % (nrEnvs * sizeof(Env)));
printMsg(v, format(" values allocated in environments: %1% (%2% bytes)")
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index 6964e3e3b..8af011d54 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -177,14 +177,15 @@ static void getDerivations(EvalState & state, Value & vIn,
there are names clashes between derivations, the derivation
bound to the attribute with the "lower" name should take
precedence). */
- StringSet attrs;
+ typedef std::map<string, Symbol> SortedSymbols;
+ SortedSymbols 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) {
- startNest(nest, lvlDebug, format("evaluating attribute `%1%'") % *i);
- string pathPrefix2 = addToPath(pathPrefix, *i);
- Value & v2((*v.attrs)[state.symbols.create(*i)]);
+ foreach (SortedSymbols::iterator, i, attrs) {
+ startNest(nest, lvlDebug, format("evaluating attribute `%1%'") % i->first);
+ string pathPrefix2 = addToPath(pathPrefix, i->first);
+ Value & v2((*v.attrs)[i->second]);
if (combineChannels)
getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done);
else if (getDerivation(state, v2, pathPrefix2, drvs, done)) {
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index d44517ba6..f9f828fe9 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -1089,6 +1089,7 @@ static void opQuery(Globals & globals,
foreach (vector<DrvInfo>::iterator, i, elems2) {
try {
+ startNest(nest, lvlDebug, format("outputting query result `%1%'") % i->attrPath);
/* For table output. */
Strings columns;