diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-02-01 06:50:14 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-02-01 06:50:14 -0800 |
commit | c9cab7138636c6c1d6e47f8d1a4053bec2dd0ad4 (patch) | |
tree | b38a8252d3cbd61a96501e775ed1b4d708c98086 /match.c | |
parent | 91458f386b639b58024044874eedc45c2175d363 (diff) | |
download | txr-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.c | 13 |
1 files changed, 10 insertions, 3 deletions
@@ -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); } |