From d3a4c9852f64a8510fac82959a747bae63ad6ee3 Mon Sep 17 00:00:00 2001 From: Vidar Holen Date: Sun, 2 Dec 2012 14:50:31 -0800 Subject: [PATCH] Read any -* as binary/unary op, and warn on unknown. --- ShellCheck/Analytics.hs | 15 ++++++++++++++- ShellCheck/Parser.hs | 34 ++++++++++++++++++++-------------- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/ShellCheck/Analytics.hs b/ShellCheck/Analytics.hs index 4efed69..5b462fd 100644 --- a/ShellCheck/Analytics.hs +++ b/ShellCheck/Analytics.hs @@ -75,6 +75,7 @@ basicChecks = [ ,checkQuotedCondRegex ,checkForInCat ,checkFindExec + ,checkValidCondOps ] modifyMap = modify @@ -227,7 +228,7 @@ isMagicInQuotes _ = False prop_checkShebang1 = verifyFull checkShebang "#!/usr/bin/env bash -x\necho cow" prop_checkShebang2 = verifyNotFull checkShebang "#! /bin/sh -l " checkShebang (T_Script id sb _) m = - if (length $ words sb) > 2 then + if (length $ words sb) > 2 then let note = Note ErrorC $ "On most OS, shebangs can only specify a single parameter." in Map.adjust (\(Metadata pos notes) -> Metadata pos (note:notes)) id m else m @@ -514,6 +515,18 @@ checkDollarArithmeticCommand _ = return () allModifiedVariables t = snd $ runState (doAnalysis (\x -> modify $ (++) (getModifiedVariables x)) t) [] +prop_checkValidCondOps1 = verify checkValidCondOps "[[ a -xz b ]]" +prop_checkValidCondOps2 = verify checkValidCondOps "[ -M a ]" +prop_checkValidCondOps3 = verifyNot checkValidCondOps "[ 1 = 2 -a 3 -ge 4 ]" +prop_checkValidCondOps4 = verifyNot checkValidCondOps "[[ ! -v foo ]]" +checkValidCondOps (TC_Binary id _ s _ _) + | not (s `elem` ["-nt", "-ot", "-ef", "==", "!=", "<=", ">=", "-eq", "-ne", "-lt", "-le", "-gt", "-ge", "=~", ">", "<", "="]) = + warn id "Unknown binary operator." +checkValidCondOps (TC_Unary id _ s _) + | not (s `elem` [ "!", "-a", "-b", "-c", "-d", "-e", "-f", "-g", "-h", "-L", "-k", "-p", "-r", "-s", "-S", "-t", "-u", "-w", "-x", "-O", "-G", "-N", "-z", "-n", "-o", "-v", "-R"]) = + warn id "Unknown unary operator." +checkValidCondOps _ = return () + --- Context seeking getParentTree t = diff --git a/ShellCheck/Parser.hs b/ShellCheck/Parser.hs index e953fa8..3f84df6 100644 --- a/ShellCheck/Parser.hs +++ b/ShellCheck/Parser.hs @@ -212,13 +212,19 @@ readConditionContents single = do where typ = if single then SingleBracket else DoubleBracket readCondBinaryOp = try $ do - op <- choice $ (map tryOp ["-nt", "-ot", "-ef", "==", "!=", "<=", ">=", "-eq", "-ne", "-lt", "-le", "-gt", "-ge", "=~", ">", "<", "="]) + id <- getNextId + op <- (choice $ (map tryOp ["==", "!=", "<=", ">=", "=~", ">", "<", "="])) <|> otherOp hardCondSpacing return op - where tryOp s = try $ do - id <- getNextId - string s - return $ TC_Binary id typ s + where + tryOp s = try $ do + id <- getNextId + string s + return $ TC_Binary id typ s + otherOp = try $ do + id <- getNextId + s <- readOp + return $ TC_Binary id typ s readCondUnaryExp = do op <- readCondUnaryOp @@ -231,15 +237,15 @@ readConditionContents single = do fail "oops") readCondUnaryOp = try $ do - op <- choice $ (map tryOp [ "-a", "-b", "-c", "-d", "-e", "-f", "-g", "-h", "-L", "-k", "-p", "-r", "-s", "-S", "-t", "-u", "-w", "-x", "-O", "-G", "-N", - "-z", "-n", "-o", "-v", "-R" - ]) + id <- getNextId + s <- readOp hardCondSpacing - return op - where tryOp s = try $ do - id <- getNextId - string s - return $ TC_Unary id typ s + return $ TC_Unary id typ s + + readOp = try $ do + char '-' + s <- many1 letter + return ('-':s) readCondWord = do notFollowedBy2 (try (spacing >> (string "]"))) @@ -733,7 +739,7 @@ readDollarDoubleQuote = do x <- many doubleQuotedPart doubleQuote "end of translated double quoted string" return $ T_DollarDoubleQuoted id x - + prop_readDollarArithmetic = isOk readDollarArithmetic "$(( 3 * 4 +5))" prop_readDollarArithmetic2 = isOk readDollarArithmetic "$(((3*4)+(1*2+(3-1))))" -- GitLab