From b6b1ea80260db58067c6a71f6ef9f1833b4102b2 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 27 Dec 2015 17:57:04 -0800 Subject: Shocking four-year-old bug in collect/coll. This originates to a commit on 2011-10-21. In that commit, I attempted to make until/last clauses have visibility to the bindings in the collect body (even though those are discarded). The problem is that the until/last clause is tried whether or not the body succeeds. When the body fails, no bindings emanate from it. In that case, the until/last clause is wrongly evaluated in an environment with no bindings whatsoever, meaning that even bindings that existed before the collect are not available to it. * match.c (h_coll, v_collect): Evaluate the last/until clause using the collect body bindings only if those bindings are not nil, otherwise use the original bindings from before entry into the collect. --- match.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/match.c b/match.c index 2995aca6..d2c2ef6e 100644 --- a/match.c +++ b/match.c @@ -862,9 +862,12 @@ static val h_coll(match_line_ctx *c) match_line(ml_specline(*c, coll_specline))); if (until_last_specline) { + uses_or2; cons_bind (sym, spec, until_last_specline); cons_bind (until_last_bindings, until_pos, - match_line(ml_bindings_specline(*c, new_bindings, spec))); + match_line(ml_bindings_specline(*c, + or2(new_bindings, c->bindings), + spec))); if (until_pos) { until_pos = minus(until_pos, c->base); @@ -2820,9 +2823,11 @@ static val v_collect(match_files_ctx *c) /* Until/last clause sees un-collated bindings from collect. */ if (until_last_spec) { + uses_or2; cons_bind (sym, ul_spec, until_last_spec); cons_bind (until_last_bindings, success, - match_files(mf_spec_bindings(*c, ul_spec, new_bindings))); + match_files(mf_spec_bindings(*c, ul_spec, + or2(new_bindings, c->bindings)))); if (success) { debuglf(specline, lit("until/last matched ~a:~d"), -- cgit v1.2.3