Permalink
Browse files

Turn more from cmd_parse.py into exceptions.

Addresses #27 and #103.
  • Loading branch information...
Andy Chu
Andy Chu committed Aug 22, 2018
1 parent 62017dc commit 51f5cdf25d0f9ae64f135a69e5b4a4a10b50b1f8
Showing with 21 additions and 23 deletions.
  1. +1 −1 core/cmd_exec.py
  2. +6 −21 osh/cmd_parse.py
  3. +4 −1 osh/cmd_parse_test.py
  4. +10 −0 test/parse-errors.sh
View
@@ -203,7 +203,7 @@ def _EvalHelper(self, c_parser, source_name):
self.arena.PopSource()
def _Eval(self, argv):
# TODO: set -o sane-eval should change eval to
# TODO: set -o sane-eval should change eval to take a single string.
code_str = ' '.join(argv)
line_reader = reader.StringLineReader(code_str, self.arena)
_, c_parser = parse_lib.MakeParser(line_reader, self.arena)
View
@@ -77,15 +77,6 @@ def ResetInputObjects(self):
def Error(self):
return self.error_stack
def _BadWord(self, msg, w):
"""Helper function for errors involving a word.
Args:
msg: format string with a single %s token
w: Word
"""
self.AddErrorContext(msg, w, word=w)
def AddErrorContext(self, msg, *args, **kwargs):
err = util.ParseError(msg, *args, **kwargs)
self.error_stack.append(err)
@@ -108,8 +99,8 @@ def _MaybeReadHereDocs(self):
# fatal because we want to be strict, and because it causes problems
# reporting other errors.
# Attribute it to the << in <<EOF for now.
self.AddErrorContext('Unterminated here doc', span_id=h.spids[0])
return False
p_die("Couldn't find terminator for here doc that starts here",
span_id=h.spids[0])
# NOTE: Could do this runtime to preserve LST.
if h.op_id == Id.Redir_DLessDash:
@@ -252,8 +243,7 @@ def ParseRedirect(self):
# NOTE: \EOF counts, or even E\OF
ok, node.here_end, quoted = word.StaticEval(self.cur_word)
if not ok:
self._BadWord('Error evaluating here doc delimiter: %s', self.cur_word)
return None
p_die('Invalid here doc delimiter', word=self.cur_word)
node.do_expansion = not quoted
self._Next()
@@ -352,9 +342,7 @@ def _MakeSimpleCommand(self, prefix_bindings, suffix_words, redirects):
# FOO=(1 2 3) ls is not allowed
for k, _, v, _ in prefix_bindings:
if word.HasArrayPart(v):
self.AddErrorContext(
'Unexpected array literal in binding: %s', v, word=v)
return None
p_die("Environment bindings can't contain array literals", word=v)
# echo FOO=(1 2 3) is not allowed
# NOTE: Other checks can be inserted here. Can resolve builtins,
@@ -364,8 +352,7 @@ def _MakeSimpleCommand(self, prefix_bindings, suffix_words, redirects):
if kov:
_, _, v = kov
if word.HasArrayPart(v):
self.AddErrorContext('Unexpected array literal: %s', v, word=w)
return None
p_die("Commands can't contain array literals", word=w)
# NOTE: # In bash, {~bob,~jane}/src works, even though ~ isn't the leading
# character of the initial word.
@@ -382,9 +369,7 @@ def _MakeSimpleCommand(self, prefix_bindings, suffix_words, redirects):
for name, op, val, left_spid in prefix_bindings:
if op != assign_op_e.Equal:
# NOTE: Using spid of RHS for now, since we don't have one for op.
self.AddErrorContext('Expected = in environment binding, got +=',
word=val)
return None
p_die('Expected = in environment binding, got +=', word=val)
pair = ast.env_pair(name, val)
pair.spids.append(left_spid)
node.more_env.append(pair)
View
@@ -31,7 +31,10 @@ def InitCommandParser(code_str):
def _assertParseMethod(test, code_str, method, expect_success=True):
arena, c_parser = InitCommandParser(code_str)
m = getattr(c_parser, method)
node = m()
try:
node = m()
except util.ParseError as e:
node = None
if node:
ast_lib.PrettyPrint(node)
View
@@ -196,10 +196,20 @@ cmd-parse() {
_error-case 'echo $( echo > >> )'
}
simple-command() {
set +o errexit
_error-case 'PYTHONPATH=. FOO=(1 2) python'
_error-case 'echo foo FOO=(1 2)'
_error-case 'PYTHONPATH+=1 python'
}
cases-in-strings() {
set +o errexit
cmd-parse
simple-command
# Word
word-parse

0 comments on commit 51f5cdf

Please sign in to comment.