From 1eece5b2eece1b04a2e21285ebaf2358b16c63b9 Mon Sep 17 00:00:00 2001 From: Vidar Holen Date: Sat, 10 Oct 2015 20:48:52 -0700 Subject: [PATCH] Add warning about local in sh or not in bash functions. --- ShellCheck/ASTLib.hs | 2 ++ ShellCheck/Analytics.hs | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ShellCheck/ASTLib.hs b/ShellCheck/ASTLib.hs index a043fd4..cd5e8f1 100644 --- a/ShellCheck/ASTLib.hs +++ b/ShellCheck/ASTLib.hs @@ -224,6 +224,8 @@ isAssignment t = T_Annotation _ _ w -> isAssignment w otherwise -> False +isFunction t = case t of T_Function {} -> True; _ -> False + -- Get the list of commands from tokens that contain them, such as -- the body of while loops and if statements. getCommandSequences t = diff --git a/ShellCheck/Analytics.hs b/ShellCheck/Analytics.hs index 6a10e28..f964dcc 100644 --- a/ShellCheck/Analytics.hs +++ b/ShellCheck/Analytics.hs @@ -82,6 +82,7 @@ checksFor Bash = [ ,checkBraceExpansionVars ,checkEchoSed ,checkForDecimals + ,checkLocalScope ] runAnalytics :: AnalysisSpec -> AnalysisResult @@ -683,7 +684,7 @@ checkBashisms _ = bashism bashCommands = [ "let", "caller", "builtin", "complete", "compgen", "declare", "dirs", "disown", "enable", "mapfile", "readarray", "pushd", "popd", "shopt", "suspend", "type", - "typeset" + "typeset", "local" ] allowedFlags = Map.fromList [ ("read", ["r"]), @@ -2965,11 +2966,18 @@ checkLoopKeywordScope params t | subshellType t = case leadType (shellType params) (parentMap params) t of NoneScope -> Nothing SubshellScope str -> return str - isFunction t = case t of T_Function {} -> True; _ -> False relevant t = isLoop t || isFunction t || isJust (subshellType t) checkLoopKeywordScope _ _ = return () +prop_checkLocalScope1 = verify checkLocalScope "local foo=3" +prop_checkLocalScope2 = verifyNot checkLocalScope "f() { local foo=3; }" +checkLocalScope params t | t `isCommand` "local" && not (isInFunction t) = + err (getId t) 2168 "'local' is only valid in functions." + where + isInFunction t = any isFunction $ getPath (parentMap params) t +checkLocalScope _ _ = return () + prop_checkFunctionDeclarations1 = verify checkFunctionDeclarations "#!/bin/ksh\nfunction foo() { command foo --lol \"$@\"; }" prop_checkFunctionDeclarations2 = verify checkFunctionDeclarations "#!/bin/dash\nfunction foo { lol; }" prop_checkFunctionDeclarations3 = verifyNot checkFunctionDeclarations "foo() { echo bar; }"