parse_util: Only reject time in a pipeline without decorator

This allows e.g. `foo | command time`, while still rejecting `foo | time`.

(this should really be done in the ast itself, but tbh most of
parse_util kinda should)

Fixes #9985
This commit is contained in:
Fabian Boehm 2023-08-25 19:34:24 +02:00
parent b48fa1f1a0
commit 482616f101
3 changed files with 37 additions and 8 deletions

View file

@ -1459,12 +1459,19 @@ fn detect_errors_in_decorated_statement(
// Similarly for time (#8841). // Similarly for time (#8841).
if command == L!("time") { if command == L!("time") {
errored = append_syntax_error!( // We only reject it if we have no decoration.
parse_errors, // `echo foo | command time something`
source_start, // is entirely fair and valid.
source_length, // Other current decorations like "exec"
TIME_IN_PIPELINE_ERR_MSG // are already forbidden.
); if dst.decoration() == StatementDecoration::none {
errored = append_syntax_error!(
parse_errors,
source_start,
source_length,
TIME_IN_PIPELINE_ERR_MSG
);
}
} }
} }

View file

@ -961,8 +961,16 @@ static bool detect_errors_in_decorated_statement(const wcstring &buff_src,
// Similarly for time (#8841). // Similarly for time (#8841).
if (command == L"time") { if (command == L"time") {
errored = append_syntax_error(parse_errors, source_start, source_length, // We only reject it if we have no decoration.
TIME_IN_PIPELINE_ERR_MSG); // `echo foo | command time something`
// is entirely fair and valid.
// Other current decorations like "exec"
// are already forbidden.
const auto &deco = dst.decoration();
if (deco == statement_decoration_t::none) {
errored = append_syntax_error(parse_errors, source_start, source_length,
TIME_IN_PIPELINE_ERR_MSG);
}
} }
} }

View file

@ -48,3 +48,17 @@ $fish -c 'not time true&'
#CHECKERR: not time true& #CHECKERR: not time true&
#FIXME: This error marks the entire statement. Would be cool to mark just `time true&`. #FIXME: This error marks the entire statement. Would be cool to mark just `time true&`.
#CHECKERR: ^~~~~~~~~~~~~^ #CHECKERR: ^~~~~~~~~~~~~^
$fish -c 'echo Is it time yet | time cat'
#CHECKERR: fish: The 'time' command may only be at the beginning of a pipeline
#CHECKERR: echo Is it time yet | time cat
#CHECKERR: ^~~~~~~^
begin
printf '%s\n' "#!/bin/sh" 'echo No this is Patrick' > time
chmod +x time
set -l PATH .
echo Hello is this time | command time
# CHECK: No this is Patrick
end
rm time