From 4661282fde9f37780877fbeeb34b06b0c221e6bf Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 28 Jul 2006 16:03:28 +0000 Subject: [PATCH] * `nix-instantiate ... --arg NAME VALUE': allow arguments to be passed to functions from the command line. * nix-build: started removing backticks. --- scripts/nix-build.in | 12 ++++++++++-- src/libexpr/attr-path.cc | 2 +- src/libexpr/eval.cc | 15 +++++++++++---- src/libexpr/eval.hh | 6 +++--- src/libexpr/get-drvs.cc | 13 +++++++------ src/libexpr/get-drvs.hh | 2 +- src/nix-env/main.cc | 8 ++++---- src/nix-instantiate/main.cc | 32 +++++++++++++++++++++----------- 8 files changed, 58 insertions(+), 32 deletions(-) diff --git a/scripts/nix-build.in b/scripts/nix-build.in index 645fdb1e64..fab8fae84e 100644 --- a/scripts/nix-build.in +++ b/scripts/nix-build.in @@ -77,6 +77,12 @@ EOF push @instArgs, ("--attr", $ARGV[$n]); } + elsif ($arg eq "--arg") { + die "$0: `--arg' requires two arguments\n" unless $n + 2 < scalar @ARGV; + push @instArgs, ("--arg", $ARGV[$n + 1], $ARGV[$n + 2]); + $n += 2; + } + elsif (substr($arg, 0, 1) eq "-") { push @buildArgs, $arg; } @@ -103,8 +109,10 @@ if (!defined $outLink) { foreach my $expr (@exprs) { # Instantiate. - my $drvPaths = `@bindir@/nix-instantiate --add-root "$drvLink" --indirect @instArgs "$expr"`; - my @drvPaths = split ' ', $drvPaths; + my @drvPaths; + open DRVPATHS, "-|", "@bindir@/nix-instantiate", "--add-root", $drvLink, "--indirect", @instArgs, $expr; + while () {chomp; push @drvPaths, $_;} + close DRVPATHS; foreach my $drvPath (@drvPaths) { my $target = readlink $drvPath; diff --git a/src/libexpr/attr-path.cc b/src/libexpr/attr-path.cc index 274f49ceab..63bb1e5540 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 6c78356db8..834b15cbdf 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 018c6b726b..ff050b3986 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 0afc7bd6d1..07dd88e4c7 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 84ffe25cab..75f6bcf9d7 100644 --- a/src/libexpr/get-drvs.hh +++ b/src/libexpr/get-drvs.hh @@ -50,7 +50,7 @@ typedef list 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 3fcaaff424..0eb3fe4d37 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 857aeaa247..f49615648f 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);