@@ -220,6 +220,9 @@ prop_checkBashisms125 = verifyNot checkBashisms "#!/bin/busybox sh\ntype -p test
220220prop_checkBashisms126 = verifyNot checkBashisms " #!/bin/busybox sh\n read -p foo -r bar"
221221prop_checkBashisms127 = verifyNot checkBashisms " #!/bin/busybox sh\n echo -ne foo"
222222prop_checkBashisms128 = verify checkBashisms " #!/bin/dash\n type -p test"
223+ prop_checkBashisms129 = verify checkBashisms " #!/bin/sh\n [ -k /tmp ]"
224+ prop_checkBashisms130 = verifyNot checkBashisms " #!/bin/dash\n test -k /tmp"
225+ prop_checkBashisms131 = verify checkBashisms " #!/bin/sh\n [ -o errexit ]"
223226checkBashisms = ForShell [Sh , Dash , BusyboxSh ] $ \ t -> do
224227 params <- ask
225228 kludge params t
@@ -248,36 +251,16 @@ checkBashisms = ForShell [Sh, Dash, BusyboxSh] $ \t -> do
248251 bashism (T_Condition id DoubleBracket _) =
249252 unless isBusyboxSh $ warnMsg id 3010 " [[ ]] is"
250253 bashism (T_HereString id _) = warnMsg id 3011 " here-strings are"
251- bashism (TC_Binary id SingleBracket op _ _)
252- | op `elem` [ " <" , " >" , " \\ <" , " \\ >" , " <=" , " >=" , " \\ <=" , " \\ >=" ] =
253- unless isDash $ warnMsg id 3012 $ " lexicographical " ++ op ++ " is"
254- bashism (T_SimpleCommand id _ [asStr -> Just " test" , lhs, asStr -> Just op, rhs])
255- | op `elem` [ " <" , " >" , " \\ <" , " \\ >" , " <=" , " >=" , " \\ <=" , " \\ >=" ] =
256- unless isDash $ warnMsg id 3012 $ " lexicographical " ++ op ++ " is"
257- bashism (TC_Binary id SingleBracket op _ _)
258- | op `elem` [ " -ot" , " -nt" , " -ef" ] =
259- unless isDash $ warnMsg id 3013 $ op ++ " is"
260- bashism (T_SimpleCommand id _ [asStr -> Just " test" , lhs, asStr -> Just op, rhs])
261- | op `elem` [ " -ot" , " -nt" , " -ef" ] =
262- unless isDash $ warnMsg id 3013 $ op ++ " is"
263- bashism (TC_Binary id SingleBracket " ==" _ _) =
264- unless isBusyboxSh $ warnMsg id 3014 " == in place of = is"
265- bashism (T_SimpleCommand id _ [asStr -> Just " test" , lhs, asStr -> Just " ==" , rhs]) =
266- unless isBusyboxSh $ warnMsg id 3014 " == in place of = is"
267- bashism (TC_Binary id SingleBracket " =~" _ _) =
268- warnMsg id 3015 " =~ regex matching is"
269- bashism (T_SimpleCommand id _ [asStr -> Just " test" , lhs, asStr -> Just " =~" , rhs]) =
270- warnMsg id 3015 " =~ regex matching is"
271- bashism (TC_Unary id SingleBracket " -v" _) =
272- warnMsg id 3016 " unary -v (in place of [ -n \" ${var+x}\" ]) is"
273- bashism (T_SimpleCommand id _ [asStr -> Just " test" , asStr -> Just " -v" , _]) =
274- warnMsg id 3016 " unary -v (in place of [ -n \" ${var+x}\" ]) is"
275- bashism (TC_Unary id _ " -a" _) =
276- warnMsg id 3017 " unary -a in place of -e is"
277- bashism (TC_Unary id _ " -o" _) =
278- warnMsg id 3062 " unary -o to check options is"
279- bashism (T_SimpleCommand id _ [asStr -> Just " test" , asStr -> Just " -a" , _]) =
280- warnMsg id 3017 " unary -a in place of -e is"
254+
255+ bashism (TC_Binary id _ op _ _) =
256+ checkTestOp bashismBinaryTestFlags op id
257+ bashism (T_SimpleCommand id _ [asStr -> Just " test" , lhs, asStr -> Just op, rhs]) =
258+ checkTestOp bashismBinaryTestFlags op id
259+ bashism (TC_Unary id _ op _) =
260+ checkTestOp bashismUnaryTestFlags op id
261+ bashism (T_SimpleCommand id _ [asStr -> Just " test" , asStr -> Just op, _]) =
262+ checkTestOp bashismUnaryTestFlags op id
263+
281264 bashism (TA_Unary id op _)
282265 | op `elem` [ " |++" , " |--" , " ++|" , " --|" ] =
283266 warnMsg id 3018 $ filter (/= ' |' ) op ++ " is"
@@ -514,6 +497,52 @@ checkBashisms = ForShell [Sh, Dash, BusyboxSh] $ \t -> do
514497 Assignment (_, _, name, _) -> name == var
515498 _ -> False
516499
500+ checkTestOp table op id = sequence_ $ do
501+ (code, shells, msg) <- Map. lookup op table
502+ guard . not $ shellType params `elem` shells
503+ return $ warnMsg id code (msg op)
504+
505+
506+ buildTestFlagMap list = Map. fromList $ concatMap (\ (x,y) -> map (\ c -> (c,y)) x) list
507+ bashismBinaryTestFlags = buildTestFlagMap [
508+ -- ([list of applicable flags],
509+ -- (error code, exempt shells, message builder :: String -> String)),
510+ --
511+ -- Distinct error codes allow the wiki to give more helpful, targeted
512+ -- information.
513+ ([" <" , " >" , " \\ <" , " \\ >" , " <=" , " >=" , " \\ <=" , " \\ >=" ],
514+ (3012 , [Dash , BusyboxSh ], \ op -> " lexicographical " ++ op ++ " is" )),
515+ ([" -nt" , " -ot" , " -ef" ],
516+ (3013 , [Dash , BusyboxSh ], \ op -> op ++ " is" )),
517+ ([" ==" ],
518+ (3014 , [BusyboxSh ], \ op -> op ++ " in place of = is" )),
519+ ([" =~" ],
520+ (3015 , [] , \ op -> op ++ " regex matching is" )),
521+
522+ ([] , (0 ,[] ,const " " ))
523+ ]
524+ bashismUnaryTestFlags = buildTestFlagMap [
525+ ([" -v" ],
526+ (3016 , [] , \ op -> " test " ++ op ++ " (in place of [ -n \" ${var+x}\" ]) is" )),
527+ ([" -a" ],
528+ (3017 , [] , \ op -> " unary " ++ op ++ " in place of -e is" )),
529+ ([" -o" ],
530+ (3062 , [] , \ op -> " test " ++ op ++ " to check options is" )),
531+ ([" -R" ],
532+ (3063 , [] , \ op -> " test " ++ op ++ " and namerefs in general are" )),
533+ ([" -N" ],
534+ (3064 , [] , \ op -> " test " ++ op ++ " is" )),
535+ ([" -k" ],
536+ (3065 , [Dash , BusyboxSh ], \ op -> " test " ++ op ++ " is" )),
537+ ([" -G" ],
538+ (3066 , [Dash , BusyboxSh ], \ op -> " test " ++ op ++ " is" )),
539+ ([" -O" ],
540+ (3067 , [Dash , BusyboxSh ], \ op -> " test " ++ op ++ " is" )),
541+
542+ ([] , (0 ,[] ,const " " ))
543+ ]
544+
545+
517546prop_checkEchoSed1 = verify checkEchoSed " FOO=$(echo \" $cow\" | sed 's/foo/bar/g')"
518547prop_checkEchoSed1b = verify checkEchoSed " FOO=$(sed 's/foo/bar/g' <<< \" $cow\" )"
519548prop_checkEchoSed2 = verify checkEchoSed " rm $(echo $cow | sed -e 's,foo,bar,')"
0 commit comments