diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index c7fc52db15..736c3e522f 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -124,15 +124,15 @@ static void getDerivations(EvalState & state, Expr e, DrvInfos & drvs, Exprs & doneExprs, const string & attrPath, const string & pathTaken) { - /* Automatically call functions that have defaults for all - arguments. */ + /* Automatically call functions for which each argument has a + default value. */ ATermList formals; ATerm body, pos; if (matchFunction(e, formals, body, pos)) { for (ATermIterator i(formals); i; ++i) { Expr name, def; ATerm values, def2; if (!matchFormal(*i, name, values, def2)) abort(); - if (!matchDefaultValue(def2, def)) + if (!matchDefaultValue(def2, def)) throw TypeError(format("cannot auto-call a function that has an argument without a default value (`%1%')") % aterm2String(name)); } diff --git a/src/nix-instantiate/help.txt b/src/nix-instantiate/help.txt index 45607b71af..18b1d8bd0d 100644 --- a/src/nix-instantiate/help.txt +++ b/src/nix-instantiate/help.txt @@ -15,4 +15,6 @@ Options: --eval-only: evaluate and print resulting term; do not instantiate --parse-only: parse and print abstract syntax tree + --attr / -A PATH: select an attribute from the top-level expression + --add-root: add garbage collector roots for the result diff --git a/src/nix-instantiate/main.cc b/src/nix-instantiate/main.cc index d73d0e613f..31d61f3afe 100644 --- a/src/nix-instantiate/main.cc +++ b/src/nix-instantiate/main.cc @@ -33,11 +33,25 @@ static int rootNr = 0; static bool indirectRoot = false; -static void printResult(EvalState & state, Expr e, bool evalOnly, - const string & attrPath) +static void printResult(EvalState & state, Expr e, + bool evalOnly, bool printArgs, const string & attrPath) { if (evalOnly) cout << format("%1%\n") % e; + + else if (printArgs) { + ATermList formals; + ATerm body, pos; + if (matchFunction(e, formals, body, pos)) { + for (ATermIterator i(formals); i; ++i) { + Expr name; ATerm d1, d2; + if (!matchFormal(*i, name, d1, d2)) abort(); + cout << format("%1%\n") % aterm2String(name); + } + } else + printMsg(lvlError, "warning: expression does not evaluate to a function"); + } + else { DrvInfos drvs; getDerivations(state, e, drvs, attrPath); @@ -62,6 +76,7 @@ void run(Strings args) bool readStdin = false; bool evalOnly = false; bool parseOnly = false; + bool printArgs = false; string attrPath; for (Strings::iterator i = args.begin(); @@ -79,6 +94,10 @@ void run(Strings args) readOnlyMode = true; parseOnly = evalOnly = true; } + else if (arg == "--print-args") { + readOnlyMode = true; + printArgs = true; + } else if (arg == "--add-root") { if (i == args.end()) throw UsageError("`--add-root requires an argument"); @@ -101,7 +120,7 @@ void run(Strings args) if (readStdin) { Expr e = evalStdin(state, parseOnly); - printResult(state, e, evalOnly, attrPath); + printResult(state, e, evalOnly, printArgs, attrPath); } for (Strings::iterator i = files.begin(); @@ -111,7 +130,7 @@ void run(Strings args) Expr e = parseOnly ? parseExprFromFile(state, path) : evalFile(state, path); - printResult(state, e, evalOnly, attrPath); + printResult(state, e, evalOnly, printArgs, attrPath); } printEvalStats(state);