From 07e417041863fc1639b00599acac690635c657f5 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Mon, 13 Oct 2014 17:49:26 -0700 Subject: [PATCH] Suppress wildcard errors in functions Wildcard errors are only supposed to reported when encountered during interactive use. The old parser also suppressed them if `is_block` was true. This was lost in the new parser. However, this also suppresses errors generated from `begin; code_here; end` and other block constructs. Instead, check the parser block stack when we hit an error, and suppress the error if there are any function calls / events / source invocations. These all indicate that the code being executed came from somewhere other than the commandline. --- parse_execution.cpp | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/parse_execution.cpp b/parse_execution.cpp index a77ba5796..b01b6f5eb 100644 --- a/parse_execution.cpp +++ b/parse_execution.cpp @@ -750,10 +750,33 @@ parse_execution_result_t parse_execution_context_t::report_errors(const parse_er parse_execution_result_t parse_execution_context_t::report_unmatched_wildcard_error(const parse_node_t &unmatched_wildcard) { proc_set_last_status(STATUS_UNMATCHED_WILDCARD); - /* For reasons I cannot explain, unmatched wildcards are only reported in interactive use. */ + // unmatched wildcards are only reported in interactive use because scripts have legitimate reasons + // to want to use wildcards without knowing whether they expand to anything. if (get_is_interactive()) { - report_error(unmatched_wildcard, WILDCARD_ERR_MSG, get_source(unmatched_wildcard).c_str()); + // Check if we're running code that was typed at the commandline. + // We can't just use `is_block` or the eval level, because `begin; echo *.unmatched; end` would not report + // the error even though it's run interactively. + // But any non-interactive use must have at least one function / event handler / source on the stack. + bool interactive = true; + for (size_t i = 0, count = parser->block_count(); i < count; ++i) + { + switch (parser->block_at_index(i)->type()) + { + case FUNCTION_CALL: + case FUNCTION_CALL_NO_SHADOW: + case EVENT: + case SOURCE: + interactive = false; + break; + default: + break; + } + } + if (interactive) + { + report_error(unmatched_wildcard, WILDCARD_ERR_MSG, get_source(unmatched_wildcard).c_str()); + } } return parse_execution_errored; }