about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/attr-path.cc2
-rw-r--r--src/libexpr/eval.cc15
-rw-r--r--src/libexpr/eval.hh6
-rw-r--r--src/libexpr/get-drvs.cc13
-rw-r--r--src/libexpr/get-drvs.hh2
-rw-r--r--src/nix-env/main.cc8
-rw-r--r--src/nix-instantiate/main.cc32
7 files changed, 48 insertions, 30 deletions
diff --git a/src/libexpr/attr-path.cc b/src/libexpr/attr-path.cc
index 274f49ceab09..63bb1e554041 100644
--- a/src/libexpr/attr-path.cc
+++ b/src/libexpr/attr-path.cc
@@ -33,7 +33,7 @@ Expr findAlongAttrPath(EvalState & state, const string & attrPath, Expr e)
         if (string2Int(attr, attrIndex)) apType = apIndex;
 
         /* Evaluate the expression. */
-        e = evalExpr(state, autoCallFunction(evalExpr(state, e)));
+        e = evalExpr(state, autoCallFunction(evalExpr(state, e), ATermMap(1)));
 
         /* It should evaluate to either an attribute set or an
            expression, according to what is specified in the
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 6c78356db8ef..834b15cbdf76 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -287,20 +287,27 @@ static ATerm concatStrings(EvalState & state, const ATermVector & args)
 }
 
 
-Expr autoCallFunction(Expr e)
+Expr autoCallFunction(Expr e, const ATermMap & args)
 {
     ATermList formals;
     ATerm body, pos;
+    
     if (matchFunction(e, formals, body, pos)) {
+        ATermMap actualArgs(128);
+        
         for (ATermIterator i(formals); i; ++i) {
-            Expr name, def; ATerm values, def2;
+            Expr name, def, value; ATerm values, def2;
             if (!matchFormal(*i, name, values, def2)) abort();
-            if (!matchDefaultValue(def2, def))
+            if ((value = args.get(name)))
+                actualArgs.set(name, makeAttrRHS(value, makeNoPos()));
+            else if (!matchDefaultValue(def2, def))
                 throw TypeError(format("cannot auto-call a function that has an argument without a default value (`%1%')")
                     % aterm2String(name));
         }
-        e = makeCall(e, makeAttrs(ATermMap(0)));
+        
+        e = makeCall(e, makeAttrs(actualArgs));
     }
+    
     return e;
 }
 
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 018c6b726bd4..ff050b398680 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -60,9 +60,9 @@ string coerceToStringWithContext(EvalState & state,
 Expr wrapInContext(ATermList context, Expr e);
 
 /* Automatically call a function for which each argument has a default
-   value.  Note: result is a call, not a normal form; it should be
-   evaluated by calling evalExpr(). */
-Expr autoCallFunction(Expr e);
+   value or has a binding in the `args' map.  Note: result is a call,
+   not a normal form; it should be evaluated by calling evalExpr(). */
+Expr autoCallFunction(Expr e, const ATermMap & args);
 
 /* Print statistics. */
 void printEvalStats(EvalState & state);
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index 0afc7bd6d186..07dd88e4c7b8 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -121,9 +121,10 @@ static string addToPath(const string & s1, const string & s2)
 
 
 static void getDerivations(EvalState & state, Expr e,
-    const string & pathPrefix, DrvInfos & drvs, Exprs & doneExprs)
+    const string & pathPrefix, const ATermMap & autoArgs,
+    DrvInfos & drvs, Exprs & doneExprs)
 {
-    e = evalExpr(state, autoCallFunction(evalExpr(state, e)));
+    e = evalExpr(state, autoCallFunction(evalExpr(state, e), autoArgs));
 
     /* Process the expression. */
     ATermList es;
@@ -152,7 +153,7 @@ static void getDerivations(EvalState & state, Expr e,
                     queryAllAttrs(e, attrs, false);
                     Expr e2 = attrs.get(toATerm("recurseForDerivations"));
                     if (e2 && evalBool(state, e2))
-                        getDerivations(state, e, pathPrefix2, drvs, doneExprs);
+                        getDerivations(state, e, pathPrefix2, autoArgs, drvs, doneExprs);
                 }
             }
         }
@@ -167,7 +168,7 @@ static void getDerivations(EvalState & state, Expr e,
                 format("evaluating list element"));
             string pathPrefix2 = addToPath(pathPrefix, (format("%1%") % n).str());
             if (getDerivation(state, *i, pathPrefix2, drvs, doneExprs))
-                getDerivations(state, *i, pathPrefix2, drvs, doneExprs);
+                getDerivations(state, *i, pathPrefix2, autoArgs, drvs, doneExprs);
         }
         return;
     }
@@ -177,8 +178,8 @@ static void getDerivations(EvalState & state, Expr e,
 
 
 void getDerivations(EvalState & state, Expr e, const string & pathPrefix,
-    DrvInfos & drvs)
+    const ATermMap & autoArgs, DrvInfos & drvs)
 {
     Exprs doneExprs;
-    getDerivations(state, e, pathPrefix, drvs, doneExprs);
+    getDerivations(state, e, pathPrefix, autoArgs, drvs, doneExprs);
 }
diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh
index 84ffe25cabfe..75f6bcf9d796 100644
--- a/src/libexpr/get-drvs.hh
+++ b/src/libexpr/get-drvs.hh
@@ -50,7 +50,7 @@ typedef list<DrvInfo> DrvInfos;
 bool getDerivation(EvalState & state, Expr e, DrvInfo & drv);
 
 void getDerivations(EvalState & state, Expr e, const string & pathPrefix,
-    DrvInfos & drvs);
+    const ATermMap & autoArgs, DrvInfos & drvs);
 
 
 #endif /* !__GET_DRVS_H */
diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc
index 3fcaaff42441..0eb3fe4d3791 100644
--- a/src/nix-env/main.cc
+++ b/src/nix-env/main.cc
@@ -65,7 +65,7 @@ static void loadDerivations(EvalState & state, Path nixExprPath,
     string systemFilter, DrvInfos & elems)
 {
     getDerivations(state,
-        parseExprFromFile(state, absPath(nixExprPath)), "", elems);
+        parseExprFromFile(state, absPath(nixExprPath)), "", ATermMap(1), elems);
 
     /* Filter out all derivations not applicable to the current
        system. */
@@ -119,7 +119,7 @@ static DrvInfos queryInstalled(EvalState & state, const Path & userEnv)
     e = bottomupRewrite(addPos, e);
 
     DrvInfos elems;
-    getDerivations(state, e, "", elems);
+    getDerivations(state, e, "", ATermMap(1), elems);
     return elems;
 }
 
@@ -334,7 +334,7 @@ static void queryInstSources(EvalState & state,
             {
                 Expr e2 = parseExprFromString(state, *i, absPath("."));
                 Expr call = makeCall(e2, e1);
-                getDerivations(state, call, "", elems);
+                getDerivations(state, call, "", ATermMap(1), elems);
             }
             
             break;
@@ -390,7 +390,7 @@ static void queryInstSources(EvalState & state,
                 getDerivations(state,
                     findAlongAttrPath(state, *i, 
                         parseExprFromFile(state, instSource.nixExprPath)),
-                    "", elems);
+                    "", ATermMap(1), elems);
             break;
         }
     }
diff --git a/src/nix-instantiate/main.cc b/src/nix-instantiate/main.cc
index 857aeaa24798..f49615648f92 100644
--- a/src/nix-instantiate/main.cc
+++ b/src/nix-instantiate/main.cc
@@ -34,7 +34,7 @@ static bool indirectRoot = false;
 
 
 static void printResult(EvalState & state, Expr e,
-    bool evalOnly, bool printArgs)
+    bool evalOnly, bool printArgs, const ATermMap & autoArgs)
 {
     if (evalOnly)
         cout << format("%1%\n") % e;
@@ -62,7 +62,7 @@ static void printResult(EvalState & state, Expr e,
     
     else {
         DrvInfos drvs;
-        getDerivations(state, e, "", drvs);
+        getDerivations(state, e, "", autoArgs, drvs);
         for (DrvInfos::iterator i = drvs.begin(); i != drvs.end(); ++i) {
             Path drvPath = i->queryDrvPath(state);
             if (gcRoot == "")
@@ -86,6 +86,7 @@ void run(Strings args)
     bool parseOnly = false;
     bool printArgs = false;
     string attrPath;
+    ATermMap autoArgs(128);
 
     for (Strings::iterator i = args.begin();
          i != args.end(); )
@@ -106,20 +107,29 @@ void run(Strings args)
             readOnlyMode = true;
             printArgs = true;
         }
-        else if (arg == "--add-root") {
-            if (i == args.end())
-                throw UsageError("`--add-root requires an argument");
-            gcRoot = absPath(*i++);
-        }
         else if (arg == "--attr" || arg == "-A") {
             if (i == args.end())
-                throw UsageError("`--attr requires an argument");
+                throw UsageError("`--attr' requires an argument");
             attrPath = *i++;
         }
+        else if (arg == "--arg") {
+            if (i == args.end())
+                throw UsageError("`--arg' requires two arguments");
+            string name = *i++;
+            if (i == args.end())
+                throw UsageError("`--arg' requires two arguments");
+            Expr value = parseExprFromString(state, *i++, absPath("."));
+            autoArgs.set(toATerm(name), value);
+        }
+        else if (arg == "--add-root") {
+            if (i == args.end())
+                throw UsageError("`--add-root' requires an argument");
+            gcRoot = absPath(*i++);
+        }
         else if (arg == "--indirect")
             indirectRoot = true;
         else if (arg[0] == '-')
-            throw UsageError(format("unknown flag `%1%`") % arg);
+            throw UsageError(format("unknown flag `%1%'") % arg);
         else
             files.push_back(arg);
     }
@@ -129,7 +139,7 @@ void run(Strings args)
     if (readStdin) {
         Expr e = findAlongAttrPath(state, attrPath, parseStdin(state));
         if (!parseOnly) e = evalExpr(state, e);
-        printResult(state, e, evalOnly, printArgs);
+        printResult(state, e, evalOnly, printArgs, autoArgs);
     }
 
     for (Strings::iterator i = files.begin();
@@ -139,7 +149,7 @@ void run(Strings args)
         Expr e = findAlongAttrPath(state, attrPath,
             parseExprFromFile(state, path));
         if (!parseOnly) e = evalExpr(state, e);
-        printResult(state, e, evalOnly, printArgs);
+        printResult(state, e, evalOnly, printArgs, autoArgs);
     }
 
     printEvalStats(state);