summaryrefslogtreecommitdiffstats
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
authorGriffin Smith <root@gws.fyi>2020-08-27 12:28:12 -0400
committerGriffin Smith <root@gws.fyi>2020-08-27 12:38:25 -0400
commit626200713bb3cc844a9feb6af583c9b6b42c6dbc (patch)
tree14f1b5193add9e0502cd2bbad06f122eef34b2d5 /src/libexpr/eval.cc
parenteb75282b8dc855983368c79cc4c2943c298518f7 (diff)
Pass all args when auto-calling a function with an ellipsis
The command line options --arg and --argstr that are used by a bunch of CLI commands to pass arguments to top-level functions in files go through the same code-path as auto-calling top-level functions with their default arguments - this, however, was only passing the arguments that were *explicitly* mentioned in the formals of the function - in the case of an as-pattern with an ellipsis (eg args @ { ... }) extra passed arguments would get omitted. This fixes that to instead pass *all* specified auto args in the case that our function has an ellipsis. Fixes #598
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 0123070d1..00191bce0 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -1299,12 +1299,23 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
Value * actualArgs = allocValue();
mkAttrs(*actualArgs, fun.lambda.fun->formals->formals.size());
- for (auto & i : fun.lambda.fun->formals->formals) {
- Bindings::iterator j = args.find(i.name);
- if (j != args.end())
- actualArgs->attrs->push_back(*j);
- else if (!i.def)
- throwTypeError("cannot auto-call a function that has an argument without a default value ('%1%')", i.name);
+ if (fun.lambda.fun->formals->ellipsis) {
+ // If the formals have an ellipsis (eg the function accepts extra args) pass
+ // all available automatic arguments (which includes arguments specified on
+ // the command line via --arg/--argstr)
+ for (auto& v : args) {
+ actualArgs->attrs->push_back(v);
+ }
+ } else {
+ // Otherwise, only pass the arguments that the function accepts
+ for (auto & i : fun.lambda.fun->formals->formals) {
+ Bindings::iterator j = args.find(i.name);
+ if (j != args.end()) {
+ actualArgs->attrs->push_back(*j);
+ } else if (!i.def) {
+ throwTypeError("cannot auto-call a function that has an argument without a default value ('%1%')", i.name);
+ }
+ }
}
actualArgs->attrs->sort();