From 825c1b5d2298e6d4513c888465692f86455f6921 Mon Sep 17 00:00:00 2001 From: Vidar Holen Date: Sat, 6 Feb 2016 22:19:29 -0800 Subject: [PATCH] Support parsing $((( as $( ((, with warning. --- ShellCheck/Parser.hs | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/ShellCheck/Parser.hs b/ShellCheck/Parser.hs index 31417c5..a4878aa 100644 --- a/ShellCheck/Parser.hs +++ b/ShellCheck/Parser.hs @@ -1226,7 +1226,10 @@ readBraced = try braceExpansion readNormalDollar = readDollarExpression <|> readDollarDoubleQuote <|> readDollarSingleQuote <|> readDollarLonely readDoubleQuotedDollar = readDollarExpression <|> readDollarLonely -readDollarExpression = readDollarArithmetic <|> readDollarBracket <|> readDollarBraceCommandExpansion <|> readDollarBraced <|> readDollarExpansion <|> readDollarVariable + +prop_readDollarExpression1 = isOk readDollarExpression "$(((1) && 3))" +prop_readDollarExpression2 = isWarning readDollarExpression "$(((1)) && 3)" +readDollarExpression = readTripleParenthesis "$" readDollarArithmetic readDollarExpansion <|> readDollarArithmetic <|> readDollarBracket <|> readDollarBraceCommandExpansion <|> readDollarBraced <|> readDollarExpansion <|> readDollarVariable prop_readDollarSingleQuote = isOk readDollarSingleQuote "$'foo\\\'lol'" readDollarSingleQuote = called "$'..' expression" $ do @@ -1270,6 +1273,25 @@ readArithmeticExpression = called "((..)) command" $ do string "))" return (T_Arithmetic id c) +-- Check if maybe ((( was intended as ( (( rather than (( ( +readTripleParenthesis prefix expected alternative = do + pos <- try . lookAhead $ do + string prefix + p <- getPosition + string "(((" -- should optimally be "((" but it's noisy and rarely helpful + return p + + -- If the expected parser fails, try the alt. + -- If the alt fails, run the expected one again for the errors. + try expected <|> tryAlt pos <|> expected + where + tryAlt pos = do + t <- try alternative + parseNoteAt pos WarningC 1102 $ + "Shells differ in parsing ambiguous " ++ prefix ++ "(((. Use spaces: " ++ prefix ++ "( (( ." + return t + + prop_readDollarBraceCommandExpansion1 = isOk readDollarBraceCommandExpansion "${ ls; }" prop_readDollarBraceCommandExpansion2 = isOk readDollarBraceCommandExpansion "${\nls\n}" readDollarBraceCommandExpansion = called "ksh ${ ..; } command expansion" $ do @@ -2063,7 +2085,20 @@ readPattern = (readNormalWord `thenSkip` spacing) `sepBy1` (char '|' `thenSkip` prop_readCompoundCommand = isOk readCompoundCommand "{ echo foo; }>/dev/null" readCompoundCommand = do id <- getNextId - cmd <- choice [ readBraceGroup, readArithmeticExpression, readSubshell, readCondition, readWhileClause, readUntilClause, readIfClause, readForClause, readSelectClause, readCaseClause, readFunctionDefinition] + cmd <- choice [ + readBraceGroup, + readTripleParenthesis "" readArithmeticExpression readSubshell, + readArithmeticExpression, + readSubshell, + readCondition, + readWhileClause, + readUntilClause, + readIfClause, + readForClause, + readSelectClause, + readCaseClause, + readFunctionDefinition + ] spacing redirs <- many readIoRedirect unless (null redirs) $ optional $ do -- GitLab