summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
Diffstat (limited to 'match.c')
-rw-r--r--match.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/match.c b/match.c
index 22bb3fb5..7d738b6d 100644
--- a/match.c
+++ b/match.c
@@ -65,7 +65,7 @@ val include_s, close_s, require_s;
val longest_k, shortest_k, greedy_k;
val vars_k, resolve_k;
val append_k, into_k, var_k, list_k, string_k, env_k, counter_k;
-val named_k, continue_k, finish_k;
+val named_k, continue_k, finish_k, mandatory_k;
val filter_s;
@@ -798,6 +798,9 @@ static val h_coll(match_line_ctx *c)
val op_sym = first(elem);
val coll_specline = second(elem);
val until_last_specline = third(elem);
+ cons_bind (ul_sym, ul_args, until_last_specline);
+ cons_bind (ul_opts, spec, ul_args);
+ val ul_match = nil;
val args = fourth(elem);
val bindings_coll = nil;
val last_bindings = nil;
@@ -848,7 +851,6 @@ static val h_coll(match_line_ctx *c)
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,
or2(new_bindings, c->bindings),
@@ -858,11 +860,12 @@ static val h_coll(match_line_ctx *c)
until_pos = minus(until_pos, c->base);
LOG_MATCH("until/last", until_pos);
- if (sym == last_s) {
+ if (ul_sym == last_s) {
last_bindings = set_diff(until_last_bindings,
new_bindings, eq_f, nil);
c->pos = until_pos;
}
+ ul_match = t;
break;
} else {
LOG_MISMATCH("until/last");
@@ -940,6 +943,12 @@ next_coll:
return nil;
}
+ if (!ul_match && ul_opts && memq(mandatory_k, ul_opts)) {
+ debuglf(elem, lit("~s didn't match mandatory until/last"),
+ op_sym, nao);
+ return nil;
+ }
+
if (!bindings_coll)
debuglf(elem, lit("nothing was collected"), nao);
@@ -2596,6 +2605,9 @@ static val v_gather(match_files_ctx *c)
val specs = copy_list(second(first_spec));
val args = third(first_spec);
val until_last = fourth(first_spec);
+ cons_bind (ul_sym, ul_args, until_last);
+ cons_bind (ul_opts, ul_spec, ul_args);
+ val ul_match = nil;
val have_vars;
val vars = vars_to_bindings(specline,
getplist_f(args, vars_k, mkcloc(have_vars)),
@@ -2631,7 +2643,6 @@ static val v_gather(match_files_ctx *c)
if (until_last)
{
- cons_bind (sym, ul_spec, until_last);
cons_bind (until_last_bindings, success,
match_files(mf_spec(*c, ul_spec)));
@@ -2639,7 +2650,7 @@ static val v_gather(match_files_ctx *c)
debuglf(specline, lit("until/last matched ~a:~d"),
c->curfile, c->data_lineno, nao);
/* Until discards bindings and position, last keeps them. */
- if (sym == last_s) {
+ if (ul_sym == last_s) {
val last_bindings = set_diff(until_last_bindings, c->bindings, eq_f, nil);
c->bindings = nappend2(last_bindings, orig_bindings);
@@ -2651,6 +2662,7 @@ static val v_gather(match_files_ctx *c)
c->data_lineno = new_line;
}
}
+ ul_match = t;
break;
}
}
@@ -2672,6 +2684,11 @@ static val v_gather(match_files_ctx *c)
}
}
+ if (!ul_match && ul_opts && memq(mandatory_k, ul_opts)) {
+ debuglf(specline, lit("gather didn't match mandatory until/last"), nao);
+ return nil;
+ }
+
if (have_vars) {
val iter;
@@ -2706,6 +2723,9 @@ static val v_collect(match_files_ctx *c)
val op_sym = first(first_spec);
val coll_spec = second(first_spec);
val until_last_spec = third(first_spec);
+ cons_bind (ul_sym, ul_args, until_last_spec);
+ cons_bind (ul_opts, ul_spec, ul_args);
+ val ul_match = nil, accept_jump = t;
val args = fourth(first_spec);
volatile val bindings_coll = nil;
volatile val last_bindings = nil;
@@ -2767,7 +2787,6 @@ static val v_collect(match_files_ctx *c)
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,
or2(new_bindings, c->bindings))));
@@ -2776,7 +2795,7 @@ static val v_collect(match_files_ctx *c)
debuglf(specline, lit("until/last matched ~a:~d"),
c->curfile, c->data_lineno, nao);
/* Until discards bindings and position, last keeps them. */
- if (sym == last_s) {
+ if (ul_sym == last_s) {
last_bindings = set_diff(until_last_bindings,
new_bindings, eq_f, nil);
if (success == t) {
@@ -2788,6 +2807,7 @@ static val v_collect(match_files_ctx *c)
c->data_lineno = new_line;
}
}
+ ul_match = t;
break;
}
}
@@ -2869,6 +2889,8 @@ next_collect:
}
}
+ accept_jump = nil;
+
uw_block_end;
if (!result) {
@@ -2882,6 +2904,12 @@ next_collect:
return nil;
}
+ if (!ul_match && ul_opts && memq(mandatory_k, ul_opts) && !accept_jump) {
+ debuglf(specline, lit("~s didn't match mandatory until/last"),
+ op_sym, nao);
+ return nil;
+ }
+
if (!bindings_coll)
debuglf(specline, lit("nothing was collected"), nao);
@@ -4076,6 +4104,7 @@ static void syms_init(void)
named_k = intern(lit("named"), keyword_package);
continue_k = intern(lit("continue"), keyword_package);
finish_k = intern(lit("finish"), keyword_package);
+ mandatory_k = intern(lit("mandatory"), keyword_package);
filter_s = intern(lit("filter"), user_package);
noval_s = intern(lit("noval"), system_package);