diff --git a/osh/word_parse.py b/osh/word_parse.py index ca417e4c5f..280c7aee64 100644 --- a/osh/word_parse.py +++ b/osh/word_parse.py @@ -846,33 +846,38 @@ def ReadDParen(self): return anode + def _NextNonSpace(self): + """Same logic as _ReadWord, but for ReadForExpresion.""" + while True: + self._Next(lex_mode_e.ARITH) + self._Peek() + if self.token_kind not in (Kind.Ignored, Kind.WS): + break + def ReadForExpression(self): """Read ((i=0; i<5; ++i)) -- part of command context.""" - # No PushHint because we're in arith state. - #self.lexer.PushHint(Id.Op_RParen, Id.Op_DRightParen) - - self._Next(lex_mode_e.ARITH) # skip over (( + self._NextNonSpace() # skip over (( self._Peek() if self.token_type == Id.Arith_Semi: # for (( ; i < 10; i++ )) init_node = None else: init_node = self._ReadArithExpr(do_next=False) - self._Next(lex_mode_e.ARITH) + self._NextNonSpace() self._Peek() if self.token_type == Id.Arith_Semi: # for (( ; ; i++ )) cond_node = None else: cond_node = self._ReadArithExpr(do_next=False) - self._Next(lex_mode_e.ARITH) + self._NextNonSpace() self._Peek() if self.token_type == Id.Arith_RParen: # for (( ; ; )) update_node = None else: update_node = self._ReadArithExpr(do_next=False) - self._Next(lex_mode_e.ARITH) + self._NextNonSpace() self._Peek() if self.token_type != Id.Arith_RParen: diff --git a/spec/for-expr.test.sh b/spec/for-expr.test.sh index 626dacf420..2f445bc08d 100644 --- a/spec/for-expr.test.sh +++ b/spec/for-expr.test.sh @@ -14,23 +14,22 @@ do break fi echo $a -done # A construct borrowed from ksh93. +done ## status: 0 ## STDOUT: 1 2 4 5 -## N-I mksh status: 1 -## N-I mksh stdout-json: "" +## END #### For loop with and without semicolon for ((a=1; a <= 3; a++)); do echo $a -done # A construct borrowed from ksh93. +done for ((a=1; a <= 3; a++)) do echo $a -done # A construct borrowed from ksh93. +done ## status: 0 ## STDOUT: 1 @@ -39,21 +38,46 @@ done # A construct borrowed from ksh93. 1 2 3 -## N-I mksh status: 1 -## N-I mksh stdout-json: "" +## END -#### For loop with empty head +#### Empty init +i=1 +for (( ;i < 4; i++ )); do + echo $i +done +## status: 0 +## STDOUT: +1 +2 +3 +## END + +#### Empty init and cond +i=1 +for (( ; ; i++ )); do + if test $i = 4; then + break + fi + echo $i +done +## status: 0 +## STDOUT: +1 +2 +3 +## END + +#### Infinite loop with ((;;)) a=1 -for ((;;)); do +for (( ; ; )); do if test $a = 4; then break fi echo $((a++)) -done # A construct borrowed from ksh93. +done ## status: 0 ## STDOUT: 1 2 3 -## N-I mksh status: 1 -## N-I mksh stdout-json: "" +## END diff --git a/test/spec.sh b/test/spec.sh index 6a6808a0a2..24a8b2e50b 100755 --- a/test/spec.sh +++ b/test/spec.sh @@ -591,7 +591,7 @@ let() { for-expr() { sh-spec spec/for-expr.test.sh \ - $MKSH $BASH $OSH "$@" + $BASH $ZSH $OSH "$@" } empty-bodies() {