Support for &> and &| as convenience redirections

This adds support for &> and &| syntax, which both redirect stdout, and
also apply a redirection of stderr to stdout.
This commit is contained in:
ridiculousfish
2019-10-14 15:45:40 -07:00
parent 756e9826bc
commit 2a92e66902
8 changed files with 107 additions and 11 deletions

View File

@@ -590,15 +590,16 @@ static void test_tokenizer() {
const wchar_t *str =
L"string <redirection 2>&1 'nested \"quoted\" '(string containing subshells "
L"){and,brackets}$as[$well (as variable arrays)] not_a_redirect^ ^ ^^is_a_redirect "
L"&| &> "
L"&&& ||| "
L"&& || & |"
L"Compress_Newlines\n \n\t\n \nInto_Just_One";
using tt = token_type_t;
const token_type_t types[] = {
tt::string, tt::redirect, tt::string, tt::redirect, tt::string, tt::string,
tt::string, tt::redirect, tt::redirect, tt::string, tt::andand, tt::background,
tt::oror, tt::pipe, tt::andand, tt::oror, tt::background, tt::pipe,
tt::string, tt::end, tt::string};
tt::string, tt::redirect, tt::string, tt::redirect, tt::string, tt::string,
tt::string, tt::redirect, tt::redirect, tt::string, tt::pipe, tt::redirect,
tt::andand, tt::background, tt::oror, tt::pipe, tt::andand, tt::oror,
tt::background, tt::pipe, tt::string, tt::end, tt::string};
say(L"Test correct tokenization");
@@ -686,6 +687,13 @@ static void test_tokenizer() {
do_test(pipe_or_redir(L"9999999999999>&2")->is_valid() == false);
do_test(pipe_or_redir(L"9999999999999>&2")->is_valid() == false);
do_test(pipe_or_redir(L"&|")->is_pipe);
do_test(pipe_or_redir(L"&|")->stderr_merge);
do_test(!pipe_or_redir(L"&>")->is_pipe);
do_test(pipe_or_redir(L"&>")->stderr_merge);
do_test(pipe_or_redir(L"&>>")->stderr_merge);
do_test(pipe_or_redir(L"&>?")->stderr_merge);
auto get_redir_mode = [](const wchar_t *s) -> maybe_t<redirection_mode_t> {
if (auto redir = pipe_or_redir_t::from_string(s)) {
return redir->mode;
@@ -4609,6 +4617,12 @@ static void test_highlighting() {
{L"self%not", highlight_role_t::param},
});
highlight_tests.push_back({
{L"false", highlight_role_t::command},
{L"&|", highlight_role_t::statement_terminator},
{L"true", highlight_role_t::command},
});
auto &vars = parser_t::principal_parser().vars();
// Verify variables and wildcards in commands using /bin/cat.
vars.set(L"VARIABLE_IN_COMMAND", ENV_LOCAL, {L"a"});