summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-04-11 19:59:26 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-04-11 23:41:50 -0700
commit3d7330b827d6e9cc0d9e87edd30388374cb45900 (patch)
tree2731382bb1425855b2adc4d1420a47e4dfa87eb8 /match.c
parenta4c376979d15323ad729e92e41ba43768e8dc163 (diff)
downloadtxr-3d7330b827d6e9cc0d9e87edd30388374cb45900.tar.gz
txr-3d7330b827d6e9cc0d9e87edd30388374cb45900.tar.bz2
txr-3d7330b827d6e9cc0d9e87edd30388374cb45900.zip
txr: avoid by-value match_files_ctx passing.
Passing the match_files_ctx structure by value looks nice in the code, but it is contributing to a long standing false retention issue. This test case runs in constant memory: $ yes | txr -c '@(skip) n' skip scans through the lazy list of "y" lines looking for an "n" that never comes. This version should also run in constant memory, but shows unbounded memory growth. $ yes | txr -c '@(next *stdin*) @(skip) n' This patch doesn't fix it, but it moves things in that direction. * match.c (mf_all, mf_args, mf_data, mf_spec, mf_spec_bindings, mf_file_data, mf_from_ml): Take pointer to structure which to initialize and return that pointer, instead of initializing a local structure and returning it by value. (match_files): Take pointer to context rather than copy. (h_call, do_match_line, v_fuzz, v_block, v_next_impl, v_parallel, v_gather, v_collect, v_bind, hv_trampoline, v_try, v_fun, v_if, v_assesrt, v_load, v_call, match_filter, match_fun, extract): Adjust to by-pointer context handling of mf_all, match_files and other functions.
Diffstat (limited to 'match.c')
-rw-r--r--match.c261
1 files changed, 144 insertions, 117 deletions
diff --git a/match.c b/match.c
index 394843c3..0c0cbc5c 100644
--- a/match.c
+++ b/match.c
@@ -1488,8 +1488,9 @@ typedef struct {
val spec, files, curfile, bindings, data, data_lineno;
} match_files_ctx;
-static match_files_ctx mf_all(val spec, val files, val bindings,
- val data, val curfile);
+static match_files_ctx *mf_all(match_files_ctx *nc,
+ val spec, val files, val bindings,
+ val data, val curfile);
static val v_fun(match_files_ctx *c);
@@ -1513,11 +1514,11 @@ static val h_call(match_line_ctx *c)
if (ret == decline_k) {
val spec = cons(new_specline, nil);
- match_files_ctx vc = mf_all(spec, nil, c->bindings, nil, c->file);
- val vresult = v_fun(&vc);
+ match_files_ctx vcs, *vc = mf_all(&vcs, spec, nil, c->bindings, nil, c->file);
+ val vresult = v_fun(vc);
if (vresult == next_spec_k) {
- c->bindings = vc.bindings;
+ c->bindings = vc->bindings;
return vresult;
} else if (vresult == decline_k) {
sem_error(elem, lit("call: function ~s not found"), funval, nao);
@@ -1582,15 +1583,15 @@ static val do_match_line(match_line_ctx *c)
continue;
} else if (result == decline_k) {
val spec = rlcp(cons(cons(elem, nil), nil), elem);
- match_files_ctx vc = mf_all(spec, nil, c->bindings,
- nil, c->file);
- val vresult = v_fun(&vc);
+ match_files_ctx vcs, *vc = mf_all(&vcs, spec, nil, c->bindings,
+ nil, c->file);
+ val vresult = v_fun(vc);
if (vresult == next_spec_k) {
- c->bindings = vc.bindings;
+ c->bindings = vc->bindings;
break;
} else if (vresult == repeat_spec_k) {
- c->bindings = vc.bindings;
+ c->bindings = vc->bindings;
continue;
} else if (vresult == decline_k) {
if (gethash(v_directive_table, directive))
@@ -2246,78 +2247,80 @@ static void do_output(val bindings, val specs, val filter, val out)
}
}
-static match_files_ctx mf_all(val spec, val files, val bindings,
- val data, val curfile)
+static match_files_ctx *mf_all(match_files_ctx *nc,
+ val spec, val files, val bindings,
+ val data, val curfile)
{
- match_files_ctx c;
- c.spec = spec;
- c.files = files;
- c.curfile = curfile;
- c.bindings = bindings;
- c.data = data;
- c.data_lineno = if3(data, one, zero);
- return c;
+ nc->spec = spec;
+ nc->files = files;
+ nc->curfile = curfile;
+ nc->bindings = bindings;
+ nc->data = data;
+ nc->data_lineno = if3(data, one, zero);
+ return nc;
}
-static match_files_ctx mf_args(match_files_ctx c)
+static match_files_ctx *mf_args(match_files_ctx *nc, match_files_ctx *c)
{
- match_files_ctx nc = c;
- nc.data = c.files;
- nc.curfile = lit("args");
- nc.data_lineno = one;
+ *nc = *c;
+ nc->data = c->files;
+ nc->curfile = lit("args");
+ nc->data_lineno = one;
return nc;
}
-static match_files_ctx mf_data(match_files_ctx c, val data, val data_lineno)
+static match_files_ctx *mf_data(match_files_ctx *nc, match_files_ctx *c,
+ val data, val data_lineno)
{
- match_files_ctx nc = c;
- nc.data = data;
- nc.data_lineno = data_lineno;
+ *nc = *c;
+ nc->data = data;
+ nc->data_lineno = data_lineno;
return nc;
}
-static match_files_ctx mf_spec(match_files_ctx c, val spec)
+static match_files_ctx *mf_spec(match_files_ctx *nc,
+ const match_files_ctx *c, val spec)
{
- match_files_ctx nc = c;
- nc.spec = spec;
+ *nc = *c;
+ nc->spec = spec;
return nc;
}
-static match_files_ctx mf_spec_bindings(match_files_ctx c, val spec,
- val bindings)
+static match_files_ctx *mf_spec_bindings(match_files_ctx *nc,
+ match_files_ctx *c, val spec,
+ val bindings)
{
- match_files_ctx nc = c;
- nc.spec = spec;
- nc.bindings = bindings;
+ *nc = *c;
+ nc->spec = spec;
+ nc->bindings = bindings;
return nc;
}
-static match_files_ctx mf_file_data(match_files_ctx c, val file,
- val data, val data_lineno)
+static match_files_ctx *mf_file_data(match_files_ctx *nc,
+ match_files_ctx *c, val file,
+ val data, val data_lineno)
{
- match_files_ctx nc = c;
- nc.files = cons(file, c.files);
- nc.curfile = file;
- nc.data = data;
- nc.data_lineno = data_lineno;
+ *nc = *c;
+ nc->files = cons(file, c->files);
+ nc->curfile = file;
+ nc->data = data;
+ nc->data_lineno = data_lineno;
return nc;
}
-static match_files_ctx mf_from_ml(match_line_ctx ml)
+static match_files_ctx *mf_from_ml(match_files_ctx *nc, match_line_ctx *ml)
{
- match_files_ctx mf;
-
- mf.spec = cons(ml.specline, nil);
- mf.files = nil;
- mf.curfile = ml.file;
- mf.bindings = ml.bindings;
- mf.data = nil;
- mf.data_lineno = ml.data_lineno;
+ nc->spec = cons(ml->specline, nil);
+ nc->files = nil;
+ nc->curfile = ml->file;
+ nc->bindings = ml->bindings;
+ nc->data = nil;
+ nc->data_lineno = ml->data_lineno;
- return mf;
+ return nc;
}
-static val match_files(match_files_ctx a);
+static val match_files(match_files_ctx *c);
typedef val (*v_match_func)(match_files_ctx *cout);
@@ -2372,7 +2375,7 @@ static val v_skip(match_files_ctx *c)
}
while (greedy || !max || reps_max++ < cmax) {
- result = match_files(*c);
+ result = match_files(c);
if (result) {
if (greedy) {
@@ -2438,7 +2441,7 @@ static val v_fuzz(match_files_ctx *c)
cnum reps, good;
for (reps = 0, good = 0; reps < cn; reps++) {
- match_files_ctx fuzz_ctx = mf_spec(*c, cons(first(c->spec), nil));
+ match_files_ctx fs, *fuzz_ctx = mf_spec(&fs, c, cons(first(c->spec), nil));
val result = match_files(fuzz_ctx);
if (result) {
@@ -2470,7 +2473,7 @@ static val v_fuzz(match_files_ctx *c)
return nil;
}
- return match_files(*c);
+ return match_files(c);
}
}
}
@@ -2490,7 +2493,7 @@ static val v_trailer(match_files_ctx *c)
if (!c->spec) {
result = cons(c->bindings, cons(c->data, c->data_lineno));
} else {
- cons_bind (new_bindings, success, match_files(*c));
+ cons_bind (new_bindings, success, match_files(c));
result = if2(success, cons(new_bindings, cons(c->data, c->data_lineno)));
}
@@ -2627,7 +2630,8 @@ static val v_block(match_files_ctx *c)
{
uw_block_begin(name, result);
- result = match_files(mf_spec(*c, spec));
+ match_files_ctx cs;
+ result = match_files(mf_spec(&cs, c, spec));
uw_block_end;
if (vectorp(result))
@@ -2683,8 +2687,9 @@ static val v_next_impl(match_files_ctx *c)
if (rest(args)) {
sem_error(specline, lit("(next :args) takes no additional arguments"), nao);
} else {
+ match_files_ctx cs;
cons_bind (new_bindings, success,
- match_files(mf_args(*c)));
+ match_files(mf_args(&cs, c)));
if (success)
return cons(new_bindings,
@@ -2695,8 +2700,9 @@ static val v_next_impl(match_files_ctx *c)
if (rest(args)) {
sem_error(specline, lit("(next :env) takes no additional arguments"), nao);
} else {
+ match_files_ctx cs;
cons_bind (new_bindings, success,
- match_files(mf_file_data(*c, lit("env"), env(), one)));
+ match_files(mf_file_data(&cs, c, lit("env"), env(), one)));
if (success)
return cons(new_bindings,
@@ -2708,8 +2714,9 @@ static val v_next_impl(match_files_ctx *c)
if (sym == var_s || sym == expr_s)
meta = t;
} else if (!source) {
+ match_files_ctx cs;
cons_bind (new_bindings, success,
- match_files(mf_all(c->spec, nil, c->bindings, nil, lit("empty"))));
+ match_files(mf_all(&cs, c->spec, nil, c->bindings, nil, lit("empty"))));
if (success)
return cons(new_bindings,
@@ -2764,8 +2771,9 @@ static val v_next_impl(match_files_ctx *c)
val existing = tx_lookup_var_ubc(from_var, c->bindings, first_spec);
{
+ match_files_ctx cs;
cons_bind (new_bindings, success,
- match_files(mf_file_data(*c, lit("var"),
+ match_files(mf_file_data(&cs, c, lit("var"),
lazy_flatten(cdr(existing)), one)));
if (success)
@@ -2782,8 +2790,9 @@ static val v_next_impl(match_files_ctx *c)
goto nothrow_lisp;
{
+ match_files_ctx cs;
cons_bind (new_bindings, success,
- match_files(mf_file_data(*c, lit("var"),
+ match_files(mf_file_data(&cs, c, lit("var"),
lazy_flatten(list_val), one)));
if (success)
@@ -2793,8 +2802,9 @@ static val v_next_impl(match_files_ctx *c)
}
} else if (tlist_expr) {
val list_val = txeval(specline, tlist_expr, c->bindings);
+ match_files_ctx cs;
cons_bind (new_bindings, success,
- match_files(mf_file_data(*c, lit("var"),
+ match_files(mf_file_data(&cs, c, lit("var"),
lazy_flatten(list_val), one)));
if (success)
@@ -2811,8 +2821,9 @@ static val v_next_impl(match_files_ctx *c)
sem_error(specline, lit(":string arg ~s evaluated to non-string ~s"), string_expr, str_val, nao);
{
+ match_files_ctx cs;
cons_bind (new_bindings, success,
- match_files(mf_file_data(*c, lit("var"),
+ match_files(mf_file_data(&cs, c, lit("var"),
split_str(str_val, lit("\n")), one)));
if (success)
@@ -2844,8 +2855,9 @@ static val v_next_impl(match_files_ctx *c)
val stream = complex_open(str, nil, nil, nothrow, nil);
if (stream) {
+ match_files_ctx cs;
cons_bind (new_bindings, success,
- match_files(mf_file_data(*c, str,
+ match_files(mf_file_data(&cs, c, str,
lazy_stream_cons(stream), one)));
if (success)
@@ -2871,7 +2883,8 @@ static val v_next_impl(match_files_ctx *c)
original file we we were called with. Hence, we can't
make a straight tail call here. */
{
- cons_bind (new_bindings, success, match_files(mf_data(*c, t, nil)));
+ match_files_ctx cs;
+ cons_bind (new_bindings, success, match_files(mf_data(&cs, c, t, nil)));
if (success)
return cons(new_bindings,
@@ -2948,8 +2961,9 @@ static val v_parallel(match_files_ctx *c)
for (iter = specs; iter != nil; iter = rest(iter))
{
val nested_spec = first(iter);
+ match_files_ctx cs;
cons_bind (new_bindings, success,
- match_files(mf_spec(*c, nested_spec)));
+ match_files(mf_spec(&cs, c, nested_spec)));
if (success) {
some_match = t;
@@ -3075,8 +3089,9 @@ static val v_gather(match_files_ctx *c)
for (iter = specs, next = cdr(iter); iter != nil; iter = next, next = cdr(iter)) {
val nested_spec = first(iter);
+ match_files_ctx cs;
cons_bind (new_bindings, success,
- match_files(mf_spec(*c, nested_spec)));
+ match_files(mf_spec(&cs, c, nested_spec)));
if (!success) {
rplacd(iter, nil);
@@ -3096,8 +3111,9 @@ static val v_gather(match_files_ctx *c)
if (until_last)
{
+ match_files_ctx cs;
cons_bind (until_last_bindings, success,
- match_files(mf_spec(*c, ul_spec)));
+ match_files(mf_spec(&cs, c, ul_spec)));
if (success) {
debuglf(specline, lit("until/last matched ~a:~d"),
@@ -3378,11 +3394,13 @@ static val v_collect(match_files_ctx *c)
break;
{
+ match_files_ctx cs;
+
if (counter) {
rplacd(counter_binding, plus(num(timescounter), counter_base));
rplacd(bindings_with_counter, c->bindings);
cons_set (new_bindings, success,
- match_files(mf_spec_bindings(*c, coll_spec, bindings_with_counter)));
+ match_files(mf_spec_bindings(&cs, c, coll_spec, bindings_with_counter)));
if (!new_bindings) {
rplacd(counter_binding, nil);
@@ -3390,7 +3408,7 @@ static val v_collect(match_files_ctx *c)
}
} else {
cons_set (new_bindings, success,
- match_files(mf_spec(*c, coll_spec)));
+ match_files(mf_spec(&cs, c, coll_spec)));
}
/* Until/last clause sees un-collated bindings from collect. */
@@ -3398,7 +3416,7 @@ static val v_collect(match_files_ctx *c)
{
uses_or2;
cons_bind (until_last_bindings, success,
- match_files(mf_spec_bindings(*c, ul_spec,
+ match_files(mf_spec_bindings(&cs, c, ul_spec,
or2(new_bindings, c->bindings))));
if (success) {
@@ -3683,7 +3701,7 @@ static val v_bind(match_files_ctx *c)
static val hv_trampoline(match_line_ctx *c)
{
val ret;
- match_files_ctx mf = mf_from_ml(*c);
+ match_files_ctx cs, *mf = mf_from_ml(&cs, c);
val sym = first(first(c->specline));
val entry = gethash(v_directive_table, sym);
@@ -3692,9 +3710,9 @@ static val hv_trampoline(match_line_ctx *c)
{
v_match_func vmf = coerce(v_match_func, cptr_get(entry));
- ret = vmf(&mf);
+ ret = vmf(mf);
if (ret == next_spec_k)
- c->bindings = mf.bindings;
+ c->bindings = mf->bindings;
return ret;
}
}
@@ -3898,10 +3916,11 @@ static val v_try(match_files_ctx *c)
val finally_clause = nil;
{
+ match_files_ctx cs;
uw_block_begin(nil, result);
uw_catch_begin(catch_syms, exsym, exvals);
- result = match_files(mf_spec(*c, try_clause));
+ result = match_files(mf_spec(&cs, c, try_clause));
uw_catch(exsym, exvals) {
{
@@ -3937,8 +3956,9 @@ static val v_try(match_files_ctx *c)
}
if (all_bind) {
+ match_files_ctx cs;
cons_bind (new_bindings, success,
- match_files(mf_spec(*c, body)));
+ match_files(mf_spec(&cs, c, body)));
if (success) {
c->bindings = new_bindings;
result = t; /* catch succeeded, so try succeeds */
@@ -3994,8 +4014,9 @@ static val v_try(match_files_ctx *c)
v_take_accept(c, specline, ex->bl.result);
if (finally_clause) {
+ match_files_ctx cs;
cons_bind (new_bindings, success,
- match_files(mf_spec(*c, finally_clause)));
+ match_files(mf_spec(&cs, c, finally_clause)));
if (success) {
c->bindings = new_bindings;
@@ -4204,12 +4225,14 @@ static val v_fun(match_files_ctx *c)
{
args_decl_list(args, ARGS_MIN, bindings_cp);
+ match_files_ctx cs;
+
uw_block_begin(nil, result);
uw_match_env_begin;
uw_simple_catch_begin;
- result = match_files(mf_spec_bindings(*c, body, bindings_cp));
+ result = match_files(mf_spec_bindings(&cs, c, body, bindings_cp));
uw_unwind {
fun_intercept_accept(c->bindings, ub_p_a_pairs, sym, specline);
@@ -4283,8 +4306,10 @@ static val v_if(match_files_ctx *c)
for (; args; args = cdr(args)) {
cons_bind (expr, spec, car(args));
- if (tleval(c->spec, expr, c->bindings))
- return maybe_next(c, match_files(mf_spec(*c, spec)));
+ if (tleval(c->spec, expr, c->bindings)) {
+ match_files_ctx cs;
+ return maybe_next(c, match_files(mf_spec(&cs, c, spec)));
+ }
}
return next_spec_k;
@@ -4305,7 +4330,7 @@ static val v_assert(match_files_ctx *c)
{
val args = rest(first_spec);
val type = pop(&args);
- val result = match_files(*c);
+ val result = match_files(c);
if (result) {
return result;
@@ -4377,7 +4402,8 @@ static val v_load(match_files_ctx *c)
ret = parser->syntax_tree;
} else {
val spec = parser->syntax_tree;
- val result = match_files(mf_spec(*c, spec));
+ match_files_ctx cs;
+ val result = match_files(mf_spec(&cs, c, spec));
if (!result) {
debuglf(specline, lit("load: ~a failed"), path, nao);
@@ -4518,8 +4544,8 @@ static val v_call(match_files_ctx *c)
val argexprs = cdr(exprs);
val call = cons(funval, argexprs);
val spec = cons(cons(call, nil), nil);
- match_files_ctx ctx = mf_spec_bindings(*c, spec, c->bindings);
- val ret = v_fun(&ctx);
+ match_files_ctx cs, *nc = mf_spec_bindings(&cs, c, spec, c->bindings);
+ val ret = v_fun(nc);
if (ret == nil)
return nil;
@@ -4527,7 +4553,7 @@ static val v_call(match_files_ctx *c)
if (ret == decline_k)
sem_error(nil, lit("call: function ~s not found"), funval, nao);
- return cons(ctx.bindings, if3(ctx.data, cons(ctx.data, ctx.data_lineno), t));
+ return cons(cs.bindings, if3(cs.data, cons(cs.data, cs.data_lineno), t));
}
static val h_do(match_line_ctx *c)
@@ -4619,18 +4645,18 @@ static void open_data_source(match_files_ctx *c)
}
}
-static val match_files(match_files_ctx c)
+static val match_files(match_files_ctx *c)
{
- gc_hint(c.data);
+ gc_hint(c->data);
- for (; c.spec; c.spec = rest(c.spec),
- c.data = rest(c.data),
- c.data_lineno = plus(c.data_lineno, one))
+ for (; c->spec; c->spec = rest(c->spec),
+ c->data = rest(c->data),
+ c->data_lineno = plus(c->data_lineno, one))
repeat_spec_same_data:
{
- spec_bind (specline, first_spec, c.spec);
+ spec_bind (specline, first_spec, c->spec);
- open_data_source(&c);
+ open_data_source(c);
/* Line with nothing but a single directive or call: vertical mode. */
if (consp(first_spec) && !rest(specline)) {
@@ -4642,12 +4668,12 @@ repeat_spec_same_data:
/* It's actually a var or text; go to horizontal processing below */
} else if (entry) {
v_match_func vmf = coerce(v_match_func, cptr_get(entry));
- val result = vmf(&c);
+ val result = vmf(c);
set_last_form_evaled(lfe_save);
if (result == next_spec_k) {
- if ((c.spec = rest(c.spec)) == nil)
+ if ((c->spec = rest(c->spec)) == nil)
break;
goto repeat_spec_same_data;
} else if (result == decline_k) {
@@ -4658,12 +4684,12 @@ repeat_spec_same_data:
} else if (gethash(h_directive_table,sym)) {
/* Lone horizontal-only directive: go to horizontal processing */
} else {
- val result = v_fun(&c);
+ val result = v_fun(c);
set_last_form_evaled(lfe_save);
if (result == next_spec_k) {
- if ((c.spec = rest(c.spec)) == nil)
+ if ((c->spec = rest(c->spec)) == nil)
break;
goto repeat_spec_same_data;
} else if (result == decline_k) {
@@ -4676,22 +4702,22 @@ repeat_spec_same_data:
}
}
- open_data_source(&c);
+ open_data_source(c);
- if (consp(c.data) && car(c.data))
+ if (consp(c->data) && car(c->data))
{
- val dataline = car(c.data);
+ val dataline = car(c->data);
cons_bind (new_bindings, success,
- match_line_completely(ml_all(c.bindings, specline,
+ match_line_completely(ml_all(c->bindings, specline,
dataline, zero,
- c.data, c.data_lineno, c.curfile)));
+ c->data, c->data_lineno, c->curfile)));
if (!success)
return nil;
- c.bindings = new_bindings;
- } else if (consp(c.data) || nilp(c.data)) {
+ c->bindings = new_bindings;
+ } else if (consp(c->data) || nilp(c->data)) {
debuglf(specline, lit("spec ran out of data"), nao);
return nil;
} else {
@@ -4699,7 +4725,7 @@ repeat_spec_same_data:
}
}
- return cons(c.bindings, if3(c.data, cons(c.data, c.data_lineno), t));
+ return cons(c->bindings, if3(c->data, cons(c->data, c->data_lineno), t));
}
val match_filter(val name, val arg, val other_args)
@@ -4712,8 +4738,8 @@ val match_filter(val name, val arg, val other_args)
val spec = cons(list(cons(name,
cons(in_arg_sym, cons(out_arg_sym, other_args))),
nao), nil);
- match_files_ctx c = mf_all(spec, nil, bindings, nil, nil);
- val ret = v_fun(&c);
+ match_files_ctx cs, *c = mf_all(&cs, spec, nil, bindings, nil, nil);
+ val ret = v_fun(c);
(void) first_spec;
rlcp(car(spec), specline);
@@ -4726,7 +4752,7 @@ val match_filter(val name, val arg, val other_args)
sem_error(specline, lit("filter: function ~s not found"), name, nao);
{
- val out = tx_lookup_var(out_arg_sym, c.bindings);
+ val out = tx_lookup_var(out_arg_sym, cs.bindings);
if (!out)
sem_error(specline,
lit("filter: (~s ~s ~s) did not bind ~s"), name,
@@ -4750,10 +4776,10 @@ val match_fun(val name, val args, val input_in, val files_in)
lazy_stream_cons(input),
input);
/* TODO: pass through source location context */
- match_files_ctx c = mf_all(spec, files, in_bindings, data, curfile);
+ match_files_ctx cs, *c = mf_all(&cs, spec, files, in_bindings, data, curfile);
val ret;
- ret = v_fun(&c);
+ ret = v_fun(c);
if (ret == nil)
return nil;
@@ -4761,19 +4787,20 @@ val match_fun(val name, val args, val input_in, val files_in)
if (ret == decline_k)
sem_error(nil, lit("match-fun: function ~s not found"), name, nao);
- return cons(c.bindings, if3(c.data, cons(c.data, c.data_lineno), t));
+ return cons(cs.bindings, if3(cs.data, cons(cs.data, cs.data_lineno), t));
}
val include(val specline)
{
val spec = cons(specline, nil);
- match_files_ctx c = mf_all(spec, nil, nil, nil, nil);
- return v_load(&c);
+ match_files_ctx cs, *c = mf_all(&cs, spec, nil, nil, nil, nil);
+ return v_load(c);
}
val extract(val spec, val files, val predefined_bindings)
{
- val result = match_files(mf_all(spec, files, predefined_bindings,
+ match_files_ctx cs;
+ val result = match_files(mf_all(&cs, spec, files, predefined_bindings,
t, nil));
cons_bind (bindings, success, result);