1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 02:27:43 +00:00

Shell: Add support for the '!' POSIX pipeline prefix

This prefix simply inverts the exit code of the pipeline, which we
implement using the 'not' builtin.
This commit is contained in:
Ali Mohammad Pur 2023-07-31 16:19:39 +03:30 committed by Ali Mohammad Pur
parent b6d7c5fb0e
commit da7bf5f785
2 changed files with 26 additions and 3 deletions

View file

@ -769,15 +769,38 @@ ErrorOr<RefPtr<AST::Node>> Parser::parse_and_or()
ErrorOr<RefPtr<AST::Node>> Parser::parse_pipeline() ErrorOr<RefPtr<AST::Node>> Parser::parse_pipeline()
{ {
return parse_pipe_sequence(); while (peek().type == Token::Type::Newline)
skip();
auto is_negated = false;
if (peek().type == Token::Type::Bang) {
is_negated = true;
skip();
}
return parse_pipe_sequence(is_negated);
} }
ErrorOr<RefPtr<AST::Node>> Parser::parse_pipe_sequence() ErrorOr<RefPtr<AST::Node>> Parser::parse_pipe_sequence(bool is_negated)
{ {
auto node = TRY(parse_command()); auto node = TRY(parse_command());
if (!node) if (!node)
return RefPtr<AST::Node> {}; return RefPtr<AST::Node> {};
if (is_negated) {
if (is<AST::CastToCommand>(node.ptr())) {
node = make_ref_counted<AST::CastToCommand>(
node->position(),
make_ref_counted<AST::ListConcatenate>(
node->position(),
Vector<NonnullRefPtr<AST::Node>> {
make_ref_counted<AST::BarewordLiteral>(
node->position(),
"not"_short_string),
*static_cast<AST::CastToCommand&>(*node).inner() }));
}
}
for (;;) { for (;;) {
if (peek().type != Token::Type::Pipe) if (peek().type != Token::Type::Pipe)
break; break;

View file

@ -71,7 +71,7 @@ private:
ErrorOr<RefPtr<AST::Node>> parse_list(); ErrorOr<RefPtr<AST::Node>> parse_list();
ErrorOr<RefPtr<AST::Node>> parse_and_or(); ErrorOr<RefPtr<AST::Node>> parse_and_or();
ErrorOr<RefPtr<AST::Node>> parse_pipeline(); ErrorOr<RefPtr<AST::Node>> parse_pipeline();
ErrorOr<RefPtr<AST::Node>> parse_pipe_sequence(); ErrorOr<RefPtr<AST::Node>> parse_pipe_sequence(bool is_negated);
ErrorOr<RefPtr<AST::Node>> parse_command(); ErrorOr<RefPtr<AST::Node>> parse_command();
ErrorOr<RefPtr<AST::Node>> parse_compound_command(); ErrorOr<RefPtr<AST::Node>> parse_compound_command();
ErrorOr<RefPtr<AST::Node>> parse_subshell(); ErrorOr<RefPtr<AST::Node>> parse_subshell();