Skip to content

Commit

Permalink
feat: implement |& for function declarations (#244)
Browse files Browse the repository at this point in the history
  • Loading branch information
39555 authored Oct 28, 2024
1 parent a7d77ff commit 7dcbe7c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 13 deletions.
60 changes: 47 additions & 13 deletions brush-parser/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -847,27 +847,30 @@ fn add_pipe_extension_redirection(c: &mut ast::Command) -> Result<(), &'static s
ast::IoFileRedirectKind::DuplicateOutput,
ast::IoFileRedirectTarget::Fd(1),
);

fn add_to_redirect_list(l: &mut Option<ast::RedirectList>, r: ast::IoRedirect) {
if let Some(l) = l {
l.0.push(r);
} else {
let v = vec![r];
*l = Some(ast::RedirectList(v));
}
}

match c {
ast::Command::Simple(c) => {
let r = ast::CommandPrefixOrSuffixItem::IoRedirect(r);
if let Some(suffix) = &mut c.suffix {
suffix.0.push(r);
} else {
let v = vec![r];
c.suffix = Some(ast::CommandSuffix(v));
}
}
ast::Command::Compound(_, l) => {
if let Some(r_list) = l {
r_list.0.push(r);
if let Some(l) = &mut c.suffix {
l.0.push(r);
} else {
let v = vec![r];
*l = Some(ast::RedirectList(v));
c.suffix = Some(ast::CommandSuffix(vec![r]));
}
}
ast::Command::Compound(_, l) => add_to_redirect_list(l, r),
ast::Command::Function(f) => add_to_redirect_list(&mut f.body.1, r),
ast::Command::ExtendedTest(_) => return Err("|& unimplemented for extended tests"),
ast::Command::Function(_) => return Err("|& unimplemented for functions"),
};

Ok(())
}

Expand Down Expand Up @@ -987,4 +990,35 @@ esac\
}
Ok(())
}

#[test]
fn parse_function_with_pipe_redirection() -> Result<()> {
let inputs = [r"foo() { echo 1; } 2>&1 | cat", r"foo() { echo 1; } |& cat"];

for input in inputs {
let tokens = tokenize_str(input)?;
let seq = super::token_parser::pipe_sequence(
&Tokens {
tokens: tokens.as_slice(),
},
&ParserOptions::default(),
&SourceInfo::default(),
)?;
assert_eq!(seq.len(), 2);
assert_matches!(seq[0], ast::Command::Function(..));
if let ast::Command::Function(f) = &seq[0] {
let l = &f.body.1;
assert!(l.is_some());
assert_matches!(
l.as_ref().unwrap().0[0],
ast::IoRedirect::File(
Some(2),
ast::IoFileRedirectKind::DuplicateOutput,
ast::IoFileRedirectTarget::Fd(1)
)
)
}
}
Ok(())
}
}
1 change: 1 addition & 0 deletions brush-shell/tests/cases/pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ cases:
stdin: |
echo -e "hello" |& wc -l
cat dfdfgdfgdf |& wc -l
foo() { cat dfgdfg; } |& wc -l

0 comments on commit 7dcbe7c

Please sign in to comment.