mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 07:08:10 +00:00
Shell: Expand for loop's iterated expr before iterating over it
This only applies to the POSIX mode. Fixes #21715.
This commit is contained in:
parent
b74f5b1ca1
commit
2eb0a8f3d2
2 changed files with 38 additions and 51 deletions
|
@ -123,6 +123,20 @@ static inline bool is_valid_name(StringView word)
|
|||
}
|
||||
|
||||
namespace Shell::Posix {
|
||||
|
||||
template<typename... Args>
|
||||
static NonnullRefPtr<AST::Node> reexpand(AST::Position position, Args&&... args)
|
||||
{
|
||||
return make_ref_counted<AST::ImmediateExpression>(
|
||||
position,
|
||||
AST::NameWithPosition {
|
||||
"reexpand"_string,
|
||||
position,
|
||||
},
|
||||
Vector<NonnullRefPtr<AST::Node>> { forward<Args>(args)... },
|
||||
Optional<AST::Position> {});
|
||||
}
|
||||
|
||||
ErrorOr<void> Parser::fill_token_buffer(Optional<Reduction> starting_reduction)
|
||||
{
|
||||
for (;;) {
|
||||
|
@ -1444,8 +1458,10 @@ ErrorOr<RefPtr<AST::Node>> Parser::parse_for_clause()
|
|||
iterated_expression = TRY(Parser { "\"$@\""_string }.parse_word());
|
||||
}
|
||||
|
||||
if (saw_in && !saw_newline)
|
||||
iterated_expression = parse_word_list();
|
||||
if (saw_in && !saw_newline) {
|
||||
if (auto list = parse_word_list())
|
||||
iterated_expression = reexpand(peek().position.value_or(empty_position()), list.release_nonnull());
|
||||
}
|
||||
|
||||
if (saw_in) {
|
||||
if (peek().type == Token::Type::Semicolon || peek().type == Token::Type::Newline)
|
||||
|
@ -1583,19 +1599,13 @@ ErrorOr<RefPtr<AST::Node>> Parser::parse_word()
|
|||
token.position.value_or(empty_position()),
|
||||
},
|
||||
Vector<NonnullRefPtr<AST::Node>> {
|
||||
make_ref_counted<AST::ImmediateExpression>(
|
||||
reexpand(
|
||||
token.position.value_or(empty_position()),
|
||||
AST::NameWithPosition {
|
||||
"reexpand"_string,
|
||||
make_ref_counted<AST::StringLiteral>(
|
||||
token.position.value_or(empty_position()),
|
||||
},
|
||||
Vector<NonnullRefPtr<AST::Node>> {
|
||||
make_ref_counted<AST::StringLiteral>(
|
||||
token.position.value_or(empty_position()),
|
||||
TRY(String::from_utf8(x.source_expression)),
|
||||
AST::StringLiteral::EnclosureType::DoubleQuotes),
|
||||
},
|
||||
Optional<AST::Position> {}) },
|
||||
TRY(String::from_utf8(x.source_expression)),
|
||||
AST::StringLiteral::EnclosureType::DoubleQuotes)),
|
||||
},
|
||||
Optional<AST::Position> {});
|
||||
|
||||
if (word) {
|
||||
|
@ -1714,16 +1724,8 @@ ErrorOr<RefPtr<AST::Node>> Parser::parse_word()
|
|||
Optional<AST::Position> {});
|
||||
}
|
||||
|
||||
if (x.expand == ResolvedParameterExpansion::Expand::Word) {
|
||||
node = make_ref_counted<AST::ImmediateExpression>(
|
||||
token.position.value_or(empty_position()),
|
||||
AST::NameWithPosition {
|
||||
"reexpand"_string,
|
||||
token.position.value_or(empty_position()),
|
||||
},
|
||||
Vector { node.release_nonnull() },
|
||||
Optional<AST::Position> {});
|
||||
}
|
||||
if (x.expand == ResolvedParameterExpansion::Expand::Word)
|
||||
node = reexpand(token.position.value_or(empty_position()), node.release_nonnull());
|
||||
|
||||
if (word) {
|
||||
word = make_ref_counted<AST::Juxtaposition>(
|
||||
|
@ -1990,19 +1992,7 @@ ErrorOr<RefPtr<AST::Node>> Parser::parse_simple_command()
|
|||
}
|
||||
|
||||
auto position = peek().position.value_or(empty_position());
|
||||
nodes.append(make_ref_counted<AST::ImmediateExpression>(
|
||||
position,
|
||||
AST::NameWithPosition {
|
||||
"reexpand"_string,
|
||||
position,
|
||||
},
|
||||
Vector<NonnullRefPtr<AST::Node>> {
|
||||
make_ref_counted<AST::StringLiteral>(
|
||||
position,
|
||||
TRY(String::formatted("-e{}", consume().value)),
|
||||
AST::StringLiteral::EnclosureType::DoubleQuotes),
|
||||
},
|
||||
Optional<AST::Position> {}));
|
||||
nodes.append(reexpand(position, make_ref_counted<AST::StringLiteral>(position, TRY(String::formatted("-e{}", consume().value)), AST::StringLiteral::EnclosureType::DoubleQuotes)));
|
||||
}
|
||||
|
||||
if (!definitions.is_empty()) {
|
||||
|
@ -2026,19 +2016,7 @@ ErrorOr<RefPtr<AST::Node>> Parser::parse_simple_command()
|
|||
TRY(definition.substring_from_byte_offset_with_shared_superstring(0, split_offset)));
|
||||
|
||||
auto position = peek().position.value_or(empty_position());
|
||||
auto expanded_value = make_ref_counted<AST::ImmediateExpression>(
|
||||
position,
|
||||
AST::NameWithPosition {
|
||||
"reexpand"_string,
|
||||
position,
|
||||
},
|
||||
Vector<NonnullRefPtr<AST::Node>> {
|
||||
make_ref_counted<AST::StringLiteral>(
|
||||
position,
|
||||
TRY(definition.substring_from_byte_offset_with_shared_superstring(split_offset + 1)),
|
||||
AST::StringLiteral::EnclosureType::DoubleQuotes),
|
||||
},
|
||||
Optional<AST::Position> {});
|
||||
auto expanded_value = reexpand(position, make_ref_counted<AST::StringLiteral>(position, TRY(definition.substring_from_byte_offset_with_shared_superstring(split_offset + 1)), AST::StringLiteral::EnclosureType::DoubleQuotes));
|
||||
|
||||
variables.append({ move(name), move(expanded_value) });
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue