Permalink
Browse files

Fix parsing of for (( )) loops.

We weren't properly accounting for spaces in the conditions.

This was caught by a 'bashdb' source file with an empty initial
condition.

Added tests.
  • Loading branch information...
Andy Chu
Andy Chu committed Aug 25, 2018
1 parent 2bba597 commit 25ef33cc267a58b9e8d8041dc03cc898bbd4f5dd
Showing with 49 additions and 20 deletions.
  1. +12 −7 osh/word_parse.py
  2. +36 −12 spec/for-expr.test.sh
  3. +1 −1 test/spec.sh
View
@@ -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:
View
@@ -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
View
@@ -591,7 +591,7 @@ let() {
for-expr() {
sh-spec spec/for-expr.test.sh \
$MKSH $BASH $OSH "$@"
$BASH $ZSH $OSH "$@"
}
empty-bodies() {

0 comments on commit 25ef33c

Please sign in to comment.