Parse let arguments as arithmetic expressions.

This commit is contained in:
Vidar Holen 2014-06-22 13:23:44 -07:00
parent 1a3f6aadaf
commit b9784cbcc0
2 changed files with 40 additions and 15 deletions

View File

@ -1195,12 +1195,20 @@ prop_checkArithmeticDeref4 = verifyNot checkArithmeticDeref "(( ! $? ))"
prop_checkArithmeticDeref5 = verifyNot checkArithmeticDeref "(($1))" prop_checkArithmeticDeref5 = verifyNot checkArithmeticDeref "(($1))"
prop_checkArithmeticDeref6 = verify checkArithmeticDeref "(( a[$i] ))" prop_checkArithmeticDeref6 = verify checkArithmeticDeref "(( a[$i] ))"
prop_checkArithmeticDeref7 = verifyNot checkArithmeticDeref "(( 10#$n ))" prop_checkArithmeticDeref7 = verifyNot checkArithmeticDeref "(( 10#$n ))"
prop_checkArithmeticDeref8 = verifyNot checkArithmeticDeref "let i=$i+1"
checkArithmeticDeref params t@(TA_Expansion _ [T_DollarBraced id l]) = checkArithmeticDeref params t@(TA_Expansion _ [T_DollarBraced id l]) =
unless (excepting $ bracedString l) $ unless ((isException $ bracedString l) || (not isNormal)) $
style id 2004 "$ on variables in (( )) is unnecessary." style id 2004 "$ on variables in (( )) is unnecessary."
where where
excepting [] = True isException [] = True
excepting s = any (`elem` "/.:#%?*@") s || isDigit (head s) isException s = any (`elem` "/.:#%?*@") s || isDigit (head s)
isNormal = fromMaybe True $ msum $ map isNormalContext $ (parents params t)
isNormalContext t =
case t of
T_Arithmetic {} -> return True
T_DollarArithmetic {} -> return True
T_SimpleCommand {} -> return False
_ -> fail "Irrelevant"
checkArithmeticDeref _ _ = return () checkArithmeticDeref _ _ = return ()
prop_checkArithmeticBadOctal1 = verify checkArithmeticBadOctal "(( 0192 ))" prop_checkArithmeticBadOctal1 = verify checkArithmeticBadOctal "(( 0192 ))"
@ -2265,6 +2273,7 @@ prop_checkUnused15= verifyNotTree checkUnusedAssignments "x=(1); n=0; (( x[n] ))
prop_checkUnused16= verifyNotTree checkUnusedAssignments "foo=5; declare -x foo" prop_checkUnused16= verifyNotTree checkUnusedAssignments "foo=5; declare -x foo"
prop_checkUnused17= verifyNotTree checkUnusedAssignments "read -i 'foo' -e -p 'Input: ' bar; $bar;" prop_checkUnused17= verifyNotTree checkUnusedAssignments "read -i 'foo' -e -p 'Input: ' bar; $bar;"
prop_checkUnused18= verifyNotTree checkUnusedAssignments "a=1; arr=( [$a]=42 ); echo \"${arr[@]}\"" prop_checkUnused18= verifyNotTree checkUnusedAssignments "a=1; arr=( [$a]=42 ); echo \"${arr[@]}\""
prop_checkUnused19= verifyNotTree checkUnusedAssignments "a=1; let b=a+1; echo $b"
checkUnusedAssignments params t = snd $ runWriter (mapM_ checkAssignment flow) checkUnusedAssignments params t = snd $ runWriter (mapM_ checkAssignment flow)
where where
flow = variableFlow params flow = variableFlow params

View File

@ -1345,20 +1345,20 @@ readSimpleCommand = called "simple command" $ do
case cmd of case cmd of
Nothing -> return $ makeSimpleCommand id1 id2 prefix [] [] Nothing -> return $ makeSimpleCommand id1 id2 prefix [] []
Just cmd -> do Just cmd -> do
suffix <- option [] $ suffix <- option [] $ getParser readCmdSuffix cmd [
if isModifierCommand cmd (["declare", "export", "local", "readonly", "typeset"], readModifierSuffix),
then readModifierSuffix (["time"], readTimeSuffix),
else if isTimeCommand cmd (["let"], readLetSuffix)
then readTimeSuffix ]
else readCmdSuffix
return $ makeSimpleCommand id1 id2 prefix [cmd] suffix return $ makeSimpleCommand id1 id2 prefix [cmd] suffix
where where
isModifierCommand (T_NormalWord _ [T_Literal _ s]) = isCommand strings (T_NormalWord _ [T_Literal _ s]) = s `elem` strings
s `elem` ["declare", "export", "local", "readonly", "typeset"] isCommand _ _ = False
isModifierCommand _ = False getParser def cmd [] = def
-- Might not belong in T_SimpleCommand. Fixme? getParser def cmd ((list, action):rest) =
isTimeCommand (T_NormalWord _ [T_Literal _ "time"]) = True if isCommand list cmd
isTimeCommand _ = False then action
else getParser def cmd rest
prop_readPipeline = isOk readPipeline "! cat /etc/issue | grep -i ubuntu" prop_readPipeline = isOk readPipeline "! cat /etc/issue | grep -i ubuntu"
prop_readPipeline2 = isWarning readPipeline "!cat /etc/issue | grep -i ubuntu" prop_readPipeline2 = isWarning readPipeline "!cat /etc/issue | grep -i ubuntu"
@ -1782,6 +1782,22 @@ readTimeSuffix = do
lookAhead $ char '-' lookAhead $ char '-'
readCmdWord readCmdWord
-- Fixme: this is a hack that doesn't handle let '++c' or let a\>b
readLetSuffix = many1 (readIoRedirect <|> try readLetExpression <|> readCmdWord)
where
readLetExpression = do
startPos <- getPosition
expression <- readStringForParser readCmdWord
subParse startPos readArithmeticContents expression
-- Get whatever a parser would parse as a string
readStringForParser parser = do
pos <- lookAhead (parser >> getPosition)
s <- readUntil pos
return s
where
readUntil endPos = anyChar `reluctantlyTill` (getPosition >>= guard . (== endPos))
prop_readAssignmentWord = isOk readAssignmentWord "a=42" prop_readAssignmentWord = isOk readAssignmentWord "a=42"
prop_readAssignmentWord2 = isOk readAssignmentWord "b=(1 2 3)" prop_readAssignmentWord2 = isOk readAssignmentWord "b=(1 2 3)"
prop_readAssignmentWord3 = isWarning readAssignmentWord "$b = 13" prop_readAssignmentWord3 = isWarning readAssignmentWord "$b = 13"