Skip to content

Commit

Permalink
[core] Fix check for parsing options at top level
Browse files Browse the repository at this point in the history
This is #1628.

There are non-proc calls like 'source foo.sh a b c' and 'FOO=bar' that
push the stacks in state.Mem().  So we have more subtle logic.

It would be nice if mem.debug_stack had more structured data.  It could
tell us about 'source' vs function calls.  What they have in common is
the argv_stack.
  • Loading branch information
Andy C committed May 24, 2023
1 parent 6eeff1b commit 5b6b75b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
10 changes: 7 additions & 3 deletions core/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ def set_xtrace(self, b):
def _SetArrayByNum(self, opt_num, b):
# type: (int, bool) -> None
if (opt_num in consts.PARSE_OPTION_NUMS and
not self.mem.InGlobalNamespace()):
not self.mem.ParsingChangesAllowed()):
e_die('Syntax options must be set at the top level '
'(outside any function)')

Expand Down Expand Up @@ -1331,10 +1331,14 @@ def SetPwd(self, pwd):
"""Used by builtins."""
self.pwd = pwd

def InGlobalNamespace(self):
def ParsingChangesAllowed(self):
# type: () -> bool
"""For checking that syntax options are only used at the top level."""
return len(self.argv_stack) == 1

# DISALLOW proc calls : they push argv_stack, var_stack, debug_stack
# ALLOW source foo.sh arg1: pushes argv_stack, debug_stack
# ALLOW FOO=bar : pushes var_stack
return len(self.var_stack) == 1 or len(self.argv_stack) == 1

def Dump(self):
# type: () -> Tuple[Any, Any, Any]
Expand Down
30 changes: 30 additions & 0 deletions spec/oil-options.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -779,3 +779,33 @@ common
status=0
2 stderr.txt
## END


#### parse options in sourced file (bug #1628)

set -e # catch errors

alias e=echo
shopt -u expand_aliases

source $REPO_ROOT/spec/testdata/parse_opts.sh a b c

echo OK

# alias persists
e alias on

# parse_paren doesn't persist
#if (x > 1) {
# echo 'OK'
#}

FOO=bar source $REPO_ROOT/spec/testdata/parse_opts.sh
echo OK


## STDOUT:
OK
alias on
OK
## END
5 changes: 5 additions & 0 deletions spec/testdata/parse_opts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Used by spec/oil-options.test.sh

shopt -s parse_paren
shopt -s expand_aliases

0 comments on commit 5b6b75b

Please sign in to comment.