mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 06:32:44 +00:00 
			
		
		
		
	Shell: Make for/match/functions put their variables only in the new scope
Otherwise, a function would, for example, overwrite its parent scope:
```sh
foo(x) { }
x=1
foo 2 # would make x=2 otherwise
```
			
			
This commit is contained in:
		
							parent
							
								
									97c5a78d27
								
							
						
					
					
						commit
						9bd81f34a5
					
				
					 3 changed files with 9 additions and 4 deletions
				
			
		|  | @ -1034,7 +1034,7 @@ RefPtr<Value> ForLoop::run(RefPtr<Shell> shell) | ||||||
| 
 | 
 | ||||||
|         { |         { | ||||||
|             auto frame = shell->push_frame(String::formatted("for ({})", this)); |             auto frame = shell->push_frame(String::formatted("for ({})", this)); | ||||||
|             shell->set_local_variable(m_variable_name, value); |             shell->set_local_variable(m_variable_name, value, true); | ||||||
| 
 | 
 | ||||||
|             block_value = m_block->run(shell); |             block_value = m_block->run(shell); | ||||||
|         } |         } | ||||||
|  | @ -1587,7 +1587,7 @@ RefPtr<Value> MatchExpr::run(RefPtr<Shell> shell) | ||||||
| 
 | 
 | ||||||
|     auto frame = shell->push_frame(String::formatted("match ({})", this)); |     auto frame = shell->push_frame(String::formatted("match ({})", this)); | ||||||
|     if (!m_expr_name.is_empty()) |     if (!m_expr_name.is_empty()) | ||||||
|         shell->set_local_variable(m_expr_name, value); |         shell->set_local_variable(m_expr_name, value, true); | ||||||
| 
 | 
 | ||||||
|     for (auto& entry : m_entries) { |     for (auto& entry : m_entries) { | ||||||
|         for (auto& option : entry.options) { |         for (auto& option : entry.options) { | ||||||
|  | @ -1598,7 +1598,7 @@ RefPtr<Value> MatchExpr::run(RefPtr<Shell> shell) | ||||||
|                         size_t i = 0; |                         size_t i = 0; | ||||||
|                         for (auto& name : entry.match_names.value()) { |                         for (auto& name : entry.match_names.value()) { | ||||||
|                             if (spans.size() > i) |                             if (spans.size() > i) | ||||||
|                                 shell->set_local_variable(name, create<AST::StringValue>(spans[i])); |                                 shell->set_local_variable(name, create<AST::StringValue>(spans[i]), true); | ||||||
|                             ++i; |                             ++i; | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|  | @ -479,7 +479,7 @@ bool Shell::invoke_function(const AST::Command& command, int& retval) | ||||||
|     size_t index = 0; |     size_t index = 0; | ||||||
|     for (auto& arg : function.arguments) { |     for (auto& arg : function.arguments) { | ||||||
|         ++index; |         ++index; | ||||||
|         set_local_variable(arg, adopt(*new AST::StringValue(command.argv[index]))); |         set_local_variable(arg, adopt(*new AST::StringValue(command.argv[index])), true); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto argv = command.argv; |     auto argv = command.argv; | ||||||
|  |  | ||||||
|  | @ -34,3 +34,8 @@ fn() { | ||||||
| fn2() { } | fn2() { } | ||||||
| 
 | 
 | ||||||
| test "$(fn foobar)" = "foobar" || echo 'Frames are somehow messed up in nested functions' && exit 1 | test "$(fn foobar)" = "foobar" || echo 'Frames are somehow messed up in nested functions' && exit 1 | ||||||
|  | 
 | ||||||
|  | fn(xfoo) { } | ||||||
|  | xfoo=1 | ||||||
|  | fn 2 | ||||||
|  | test $xfoo -eq 1 || echo 'Functions overwrite parent scopes' && exit 1 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 AnotherTest
						AnotherTest