From 4d92a2e15c36c9a3c029b66144e41db42a83cfc3 Mon Sep 17 00:00:00 2001 From: "Joseph C. Sible" Date: Sun, 9 Feb 2020 21:36:38 -0500 Subject: [PATCH] Add getLiteralStringDef and simplify with it --- src/ShellCheck/ASTLib.hs | 6 +++++- src/ShellCheck/Analytics.hs | 4 ++-- src/ShellCheck/AnalyzerLib.hs | 2 +- src/ShellCheck/Checks/Commands.hs | 8 ++++---- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/ShellCheck/ASTLib.hs b/src/ShellCheck/ASTLib.hs index 658ed64..17a475d 100644 --- a/src/ShellCheck/ASTLib.hs +++ b/src/ShellCheck/ASTLib.hs @@ -176,9 +176,13 @@ willConcatInAssignment token = getLiteralString :: Token -> Maybe String getLiteralString = getLiteralStringExt (const Nothing) +-- Definitely get a literal string, with a given default for all non-literals +getLiteralStringDef :: String -> Token -> String +getLiteralStringDef x = runIdentity . getLiteralStringExt (const $ return x) + -- Definitely get a literal string, skipping over all non-literals onlyLiteralString :: Token -> String -onlyLiteralString = runIdentity . getLiteralStringExt (const $ return "") +onlyLiteralString = getLiteralStringDef "" -- Maybe get a literal string, but only if it's an unquoted argument. getUnquotedLiteral (T_NormalWord _ list) = diff --git a/src/ShellCheck/Analytics.hs b/src/ShellCheck/Analytics.hs index 71743b4..f390b53 100644 --- a/src/ShellCheck/Analytics.hs +++ b/src/ShellCheck/Analytics.hs @@ -1066,7 +1066,7 @@ checkNumberComparisons params (TC_Binary id typ op lhs rhs) = do checkStrings = mapM_ stringError . take 1 . filter isNonNum - isNonNum t = not . all numChar . runIdentity $ getLiteralStringExt (const $ return "") t + isNonNum t = not . all numChar $ onlyLiteralString t numChar x = isDigit x || x `elem` "+-. " stringError t = err (getId t) 2170 $ @@ -2593,7 +2593,7 @@ checkTildeInPath _ (T_SimpleCommand _ vars _) = warn id 2147 "Literal tilde in PATH works poorly across programs." checkVar _ = return () - hasTilde t = '~' `elem` runIdentity (getLiteralStringExt (const $ return "") t) + hasTilde t = '~' `elem` onlyLiteralString t isQuoted T_DoubleQuoted {} = True isQuoted T_SingleQuoted {} = True isQuoted _ = False diff --git a/src/ShellCheck/AnalyzerLib.hs b/src/ShellCheck/AnalyzerLib.hs index 0da80e3..7c046f3 100644 --- a/src/ShellCheck/AnalyzerLib.hs +++ b/src/ShellCheck/AnalyzerLib.hs @@ -806,7 +806,7 @@ isVariableName (x:r) = isVariableStartChar x && all isVariableChar r isVariableName _ = False getVariablesFromLiteralToken token = - getVariablesFromLiteral (runIdentity $ getLiteralStringExt (const $ return " ") token) + getVariablesFromLiteral (getLiteralStringDef " " token) -- Try to get referenced variables from a literal string like "$foo" -- Ignores tons of cases like arithmetic evaluation and array indices. diff --git a/src/ShellCheck/Checks/Commands.hs b/src/ShellCheck/Checks/Commands.hs index a6b8d9e..88b5967 100644 --- a/src/ShellCheck/Checks/Commands.hs +++ b/src/ShellCheck/Checks/Commands.hs @@ -252,7 +252,7 @@ checkGrepRe = CommandCheck (Basename "grep") check where skippable s = not ("--regex=" `isPrefixOf` s) && "-" `isPrefixOf` s f _ [] = return () f cmd (x:r) = - let str = runIdentity $ getLiteralStringExt (const $ return "_") x + let str = getLiteralStringDef "_" x in if str `elem` ["--", "-e", "--regex"] then checkRE cmd r -- Regex is *after* this @@ -365,7 +365,7 @@ checkFindExecWithSingleArgument = CommandCheck (Basename "find") (f . arguments) check (exec:arg:term:_) = do execS <- getLiteralString exec termS <- getLiteralString term - let cmdS = runIdentity $ getLiteralStringExt (const $ return " ") arg + let cmdS = getLiteralStringDef " " arg guard $ execS `elem` ["-exec", "-execdir"] && termS `elem` [";", "+"] guard $ cmdS `matches` commandRegex @@ -735,7 +735,7 @@ checkAliasesUsesArgs = CommandCheck (Exactly "alias") (f . arguments) re = mkRegex "\\$\\{?[0-9*@]" f = mapM_ checkArg checkArg arg = - let string = runIdentity $ getLiteralStringExt (const $ return "_") arg in + let string = getLiteralStringDef "_" arg in when ('=' `elem` string && string `matches` re) $ err (getId arg) 2142 "Aliases can't use positional parameters. Use a function." @@ -781,7 +781,7 @@ checkFindWithoutPath = CommandCheck (Basename "find") f -- path. We assume that all the pre-path flags are single characters from a -- list of GNU and macOS flags. hasPath (first:rest) = - let flag = runIdentity $ getLiteralStringExt (const $ return "___") first in + let flag = getLiteralStringDef "___" first in not ("-" `isPrefixOf` flag) || isLeadingFlag flag && hasPath rest hasPath [] = False isLeadingFlag flag = length flag <= 2 || all (`elem` leadingFlagChars) flag