about summary refs log tree commit diff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2011-07-13T12·19+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2011-07-13T12·19+0000
commit0a623a10c7e89a80b6dc74445a0ae6240f65723e (patch)
tree1c7a415095c4851c69d9b4c5dd1fea46a961a37c /src/libexpr/eval.cc
parent2b9e29b1c8b6b8e4884a46a3ba71ee795f1f97cd (diff)
* Allow a default value in attribute selection by writing
    x.y.z or default

  (as originally proposed in
  https://mail.cs.uu.nl/pipermail/nix-dev/2009-September/002989.html).

  For instance, an expression like

    stdenv.lib.attrByPath ["features" "ckSched"] false args

  can now be written as

    args.features.ckSched or false


Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc19
1 files changed, 13 insertions, 6 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 4d3a369aa1..acf5d7a8ae 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -632,7 +632,6 @@ void ExprVar::eval(EvalState & state, Env & env, Value & v)
 
 
 unsigned long nrLookups = 0;
-unsigned long nrLookupSize = 0;
 
 void ExprSelect::eval(EvalState & state, Env & env, Value & v)
 {
@@ -646,11 +645,20 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
         
         foreach (AttrPath::const_iterator, i, attrPath) {
             nrLookups++;
-            state.forceAttrs(*vAttrs);
-            nrLookupSize += vAttrs->attrs->size();
             Bindings::iterator j;
-            if ((j = vAttrs->attrs->find(*i)) == vAttrs->attrs->end())
-                throwEvalError("attribute `%1%' missing", showAttrPath(attrPath));
+            if (def) {
+                state.forceValue(*vAttrs);
+                if (vAttrs->type != tAttrs ||
+                    (j = vAttrs->attrs->find(*i)) == vAttrs->attrs->end())
+                {
+                    state.eval(env, def, v);
+                    return;
+                }
+            } else {
+                state.forceAttrs(*vAttrs);
+                if ((j = vAttrs->attrs->find(*i)) == vAttrs->attrs->end())
+                    throwEvalError("attribute `%1%' missing", showAttrPath(attrPath));
+            }
             vAttrs = j->value;
             pos = j->pos;
         }
@@ -1270,7 +1278,6 @@ void EvalState::printStats()
     printMsg(v, format("  number of thunks: %1%") % nrThunks);
     printMsg(v, format("  number of thunks avoided: %1%") % nrAvoided);
     printMsg(v, format("  number of attr lookups: %1%") % nrLookups);
-    printMsg(v, format("  attr lookup size: %1%") % nrLookupSize);
 }