Skip to content

Commit

Permalink
[translation] Port to context manager: errexit, PushTemp, etc.
Browse files Browse the repository at this point in the history
test/spec-cpp: 842 passing, 46 remaining.
  • Loading branch information
Andy Chu committed Jul 13, 2020
1 parent 8cae0b4 commit 3c9cb2a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 36 deletions.
32 changes: 32 additions & 0 deletions core/state.py
Expand Up @@ -135,6 +135,22 @@ def CachedCommands(self):
return self.cache.values()


class ctx_ErrExit(object):

def __init__(self, mutable_opts, span_id):
# type: (MutableOpts, int) -> None
mutable_opts.errexit.Push(span_id)
self.mutable_opts = mutable_opts

def __enter__(self):
# type: () -> None
pass

def __exit__(self, type, value, traceback):
# type: (Any, Any, Any) -> None
self.mutable_opts.errexit.Pop()


class _ErrExit(object):
"""Manages the errexit setting.
Expand Down Expand Up @@ -700,6 +716,22 @@ def __exit__(self, type, value, traceback):
self.mem.PopCall()


class ctx_Temp(object):

def __init__(self, mem):
# type: (Mem) -> None
mem.PushTemp()
self.mem = mem

def __enter__(self):
# type: () -> None
pass

def __exit__(self, type, value, traceback):
# type: (Any, Any, Any) -> None
self.mem.PopTemp()


class Mem(object):
"""For storing variables.
Expand Down
46 changes: 10 additions & 36 deletions osh/cmd_eval.py
Expand Up @@ -288,14 +288,6 @@ def _RunAssignBuiltin(self, cmd_val):

return status

def _PushErrExit(self, span_id):
# type: (int) -> None
self.mutable_opts.errexit.Push(span_id)

def _PopErrExit(self):
# type: () -> None
self.mutable_opts.errexit.Pop()

# TODO: Also change to BareAssign (set global or mutate local) and
# KeywordAssign. The latter may have flags too.
def _SpanIdForShAssignment(self, node):
Expand Down Expand Up @@ -571,12 +563,9 @@ def _Dispatch(self, node):
self._EvalTempEnv(node.more_env, 0)
status = self._RunSimpleCommand(cmd_val, node.do_fork)
else:
self.mem.PushTemp()
try:
with state.ctx_Temp(self.mem):
self._EvalTempEnv(node.more_env, state.SetExport)
status = self._RunSimpleCommand(cmd_val, node.do_fork)
finally:
self.mem.PopTemp()
else:
status = self._RunSimpleCommand(cmd_val, node.do_fork)

Expand All @@ -589,12 +578,9 @@ def _Dispatch(self, node):
# expansion, since aliases are discouarged.

if len(node.more_env):
self.mem.PushTemp()
try:
with state.ctx_Temp(self.mem):
self._EvalTempEnv(node.more_env, state.SetExport)
status = self._Execute(node.child)
finally:
self.mem.PopTemp()
else:
status = self._Execute(node.child)

Expand All @@ -613,11 +599,8 @@ def _Dispatch(self, node):
e_die("|& isn't supported", span_id=node.spids[0])

if node.negated:
self._PushErrExit(node.spids[0]) # ! spid
try:
with state.ctx_ErrExit(self.mutable_opts, node.spids[0]): # ! spid
status2 = self.shell_ex.RunPipeline(node)
finally:
self._PopErrExit()

# errexit is disabled for !.
check_errexit = False
Expand Down Expand Up @@ -979,11 +962,8 @@ def _Dispatch(self, node):
left = node.children[0]

# Suppress failure for every child except the last one.
self._PushErrExit(node.spids[0])
try:
with state.ctx_ErrExit(self.mutable_opts, node.spids[0]):
status = self._Execute(left)
finally:
self._PopErrExit()

i = 1
n = len(node.children)
Expand All @@ -1006,11 +986,9 @@ def _Dispatch(self, node):
status = self._Execute(child)
check_errexit = True
else:
self._PushErrExit(node.spids[i]) # blame the right && or ||
try:
# blame the right && or ||
with state.ctx_ErrExit(self.mutable_opts, node.spids[i]):
status = self._Execute(child)
finally:
self._PopErrExit()

i += 1

Expand All @@ -1022,11 +1000,9 @@ def _Dispatch(self, node):
try:
while True:
try:
self._PushErrExit(node.spids[0]) # while/until spid
try:
# while/until spid
with state.ctx_ErrExit(self.mutable_opts, node.spids[0]):
cond_status = self._ExecuteList(node.cond)
finally:
self._PopErrExit()

if node.keyword.id == Id.KW_While:
if cond_status != 0:
Expand Down Expand Up @@ -1216,11 +1192,9 @@ def _Dispatch(self, node):
node = cast(command__If, UP_node)
done = False
for if_arm in node.arms:
self._PushErrExit(if_arm.spids[0]) # if/elif spid
try:
# if/elif spid
with state.ctx_ErrExit(self.mutable_opts, if_arm.spids[0]):
status = self._ExecuteList(if_arm.cond)
finally:
self._PopErrExit()

if status == 0:
status = self._ExecuteList(if_arm.action)
Expand Down

0 comments on commit 3c9cb2a

Please sign in to comment.