diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2020-06-28 18:43:37 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-07-05 15:43:14 +0200 |
commit | 034be8e74c946f2820ab7a31f04d168574456f7c (patch) | |
tree | bc7e068a7387a6289106e1689dab3bec03195d51 /Shell | |
parent | 639c1a17379054138d350c85e6fcab3d886707d8 (diff) | |
download | serenity-034be8e74c946f2820ab7a31f04d168574456f7c.zip |
Shell: Allow a command sequence to be delimited by newlines
Diffstat (limited to 'Shell')
-rw-r--r-- | Shell/Parser.cpp | 21 | ||||
-rw-r--r-- | Shell/Parser.h | 7 | ||||
-rw-r--r-- | Shell/Shell.cpp | 8 |
3 files changed, 26 insertions, 10 deletions
diff --git a/Shell/Parser.cpp b/Shell/Parser.cpp index ebb81bf79e..9d018f0cef 100644 --- a/Shell/Parser.cpp +++ b/Shell/Parser.cpp @@ -102,6 +102,11 @@ static constexpr auto is_not(char c) return [c](char ch) { return ch != c; }; } +static constexpr auto is_any_of(StringView s) +{ + return [s](char ch) { return s.contains(ch); }; +} + static inline char to_byte(char a, char b) { char buf[3] { a, b, 0 }; @@ -139,6 +144,15 @@ RefPtr<AST::Node> Parser::parse_sequence() auto rule_start = push_start(); auto var_decls = parse_variable_decls(); + switch (peek()) { + case ';': + case '\n': + consume_while(is_any_of("\n;")); + break; + default: + break; + } + auto pipe_seq = parse_pipe_sequence(); if (!pipe_seq) return var_decls; @@ -150,7 +164,8 @@ RefPtr<AST::Node> Parser::parse_sequence() switch (peek()) { case ';': - consume(); + case '\n': + consume_while(is_any_of("\n;")); if (auto expr = parse_sequence()) { return create<AST::Sequence>(move(pipe_seq), move(expr)); // Sequence } @@ -429,7 +444,7 @@ RefPtr<AST::Node> Parser::parse_expression() return expr; }; - if (strchr("&|[]){} ;<>", starting_char) != nullptr) + if (strchr("&|[]){} ;<>\n", starting_char) != nullptr) return nullptr; if (isdigit(starting_char)) { @@ -710,7 +725,7 @@ RefPtr<AST::Node> Parser::parse_bareword() auto rule_start = push_start(); StringBuilder builder; auto is_acceptable_bareword_character = [](char c) { - return strchr("\\\"'*$&#|()[]{} ?;<>", c) == nullptr; + return strchr("\\\"'*$&#|()[]{} ?;<>\n", c) == nullptr; }; while (!at_end()) { char ch = peek(); diff --git a/Shell/Parser.h b/Shell/Parser.h index de47af0b46..681d0d29df 100644 --- a/Shell/Parser.h +++ b/Shell/Parser.h @@ -100,11 +100,15 @@ private: constexpr auto the_grammar = R"( toplevel :: sequence? -sequence :: variable_decls? pipe_sequence ';' sequence +sequence :: variable_decls? pipe_sequence terminator sequence | variable_decls? pipe_sequence '&' | variable_decls? pipe_sequence '&' '&' sequence | variable_decls? pipe_sequence '|' '|' sequence | variable_decls? pipe_sequence + | variable_decls? terminator pipe_sequence + +terminator :: ';' + | '\n' variable_decls :: identifier '=' expression (' '+ variable_decls)? ' '* | identifier '=' '(' pipe_sequence ')' (' '+ variable_decls)? ' '* @@ -118,6 +122,7 @@ command :: redirection command redirection :: number? '>'{1,2} ' '* string_composite | number? '<' ' '* string_composite | number? '>' '&' number + | number? '>' '&' '-' list_expression :: ' '* expression (' '+ list_expression)? diff --git a/Shell/Shell.cpp b/Shell/Shell.cpp index 715a8d3f64..3bfbb0c84e 100644 --- a/Shell/Shell.cpp +++ b/Shell/Shell.cpp @@ -497,12 +497,8 @@ bool Shell::run_file(const String& filename) return false; } auto file = file_result.value(); - for (;;) { - auto line = file->read_line(4096); - if (line.is_null()) - break; - run_command(String::copy(line, Chomp)); - } + auto data = file->read_all(); + run_command(data); return true; } void Shell::take_back_stdin() |