summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-02-01 06:50:14 -0800
committerKaz Kylheku <kaz@kylheku.com>2019-02-01 06:50:14 -0800
commitc9cab7138636c6c1d6e47f8d1a4053bec2dd0ad4 (patch)
treeb38a8252d3cbd61a96501e775ed1b4d708c98086 /match.c
parent91458f386b639b58024044874eedc45c2175d363 (diff)
downloadtxr-c9cab7138636c6c1d6e47f8d1a4053bec2dd0ad4.tar.gz
txr-c9cab7138636c6c1d6e47f8d1a4053bec2dd0ad4.tar.bz2
txr-c9cab7138636c6c1d6e47f8d1a4053bec2dd0ad4.zip
pattern lang: diagnose undefined function facing EOF.
This addresses the following issue. Suppose the query is something like this: @abc @(nonexistent) and there is one line of data. In this case, there is no error about a nonexistent function. The function lookup fails in vertical mode, so horizontal mode fallback takes place. But that just concludes that there is no data, and reports a failed match. But the programmer might have intended to invoke some function or directive that doesn't need to match anything, but rather has an important effect. In this patch we fix that. As part of the change, we disallow functions from shadowing horizontal directives. * match.c (match_files): Do not look up sys:var and sys:text through the directive table, but check for these. If the directive is not found in the vertical table, check the horizontal table; if found there, don't try it as a function but go to horizontal processing. Then if the function lookup fails, we diagnose a failed lookup; don't fall through to horizontal processing.
Diffstat (limited to 'match.c')
-rw-r--r--match.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/match.c b/match.c
index 74c19468..d36525b1 100644
--- a/match.c
+++ b/match.c
@@ -4602,12 +4602,15 @@ repeat_spec_same_data:
debug_check(specline, c.bindings, c.data, c.data_lineno, nil, nil);
+ /* Line with nothing but a single directive or call: vertical mode. */
if (consp(first_spec) && !rest(specline)) {
val lfe_save = set_last_form_evaled(first_spec);
val sym = first(first_spec);
val entry = gethash(v_directive_table, sym);
- if (entry) {
+ if (sym == var_s || sym == text_s) {
+ /* 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);
@@ -4618,10 +4621,12 @@ repeat_spec_same_data:
break;
goto repeat_spec_same_data;
} else if (result == decline_k) {
- /* go on to other processing below */
+ /* Vertical directive declined; go to horizontal processing */
} else {
debug_return (result);
}
+ } else if (gethash(h_directive_table,sym)) {
+ /* Lone horizontal-only directive: go to horizontal processing */
} else {
val result = v_fun(&c);
@@ -4632,7 +4637,9 @@ repeat_spec_same_data:
break;
goto repeat_spec_same_data;
} else if (result == decline_k) {
- /* go on to other processing below */
+ /* Function declined; we know the lookup failed because
+ since rest(specline) is nil, this is not horizontal fallback. */
+ sem_error(specline, lit("function ~s not found"), sym, nao);
} else {
debug_return (result);
}