diff --git a/ShellCheck/Analytics.hs b/ShellCheck/Analytics.hs index bd90b38..f017eb5 100644 --- a/ShellCheck/Analytics.hs +++ b/ShellCheck/Analytics.hs @@ -2625,6 +2625,7 @@ shellSupport t = T_Function _ _ _ "" _ -> ("anonymous functions", [Zsh]) T_ForIn _ _ (_:_:_) _ _ -> ("multi-index for loops", [Zsh]) T_ForIn _ ShortForIn _ _ _ -> ("short form for loops", [Zsh]) + T_ProcSub _ "=" _ -> ("=(..) process substitution", [Zsh]) otherwise -> ("", [Bash, Ksh, Sh, Zsh]) getCommandSequences t = diff --git a/ShellCheck/Parser.hs b/ShellCheck/Parser.hs index 9c03e9b..c8a4d8b 100644 --- a/ShellCheck/Parser.hs +++ b/ShellCheck/Parser.hs @@ -64,6 +64,11 @@ spacing = do optional readComment return $ concat x +spacing1 = do + spacing <- spacing + when (null spacing) $ fail "no spacing" + return spacing + prop_allspacing = isOk allspacing "#foo" prop_allspacing2 = isOk allspacing " #foo\n # bar\n#baz\n" prop_allspacing3 = isOk allspacing "#foo\n#bar\n#baz\n" @@ -745,10 +750,11 @@ readDollarBracedLiteral = do prop_readProcSub1 = isOk readProcSub "<(echo test | wc -l)" prop_readProcSub2 = isOk readProcSub "<( if true; then true; fi )" +prop_readProcSub3 = isOk readProcSub "=(ls)" readProcSub = called "process substitution" $ do id <- getNextId dir <- try $ do - x <- oneOf "<>" + x <- oneOf "<>=" char '(' return [x] allspacing @@ -1317,6 +1323,7 @@ prop_readSimpleCommand3 = isOk readSimpleCommand "export foo=(bar baz)" prop_readSimpleCommand4 = isOk readSimpleCommand "typeset -a foo=(lol)" prop_readSimpleCommand5 = isOk readSimpleCommand "time if true; then echo foo; fi" prop_readSimpleCommand6 = isOk readSimpleCommand "time -p ( ls -l; )" +prop_readSimpleCommand7 = isOk readSimpleCommand "cat =(ls)" readSimpleCommand = called "simple command" $ do id1 <- getNextId id2 <- getNextId @@ -1768,6 +1775,9 @@ readAssignmentWord = try $ do pos <- getPosition optional (char '$' >> parseNote ErrorC 1066 "Don't use $ on the left side of assignments.") variable <- readVariableName + notFollowedBy2 $ do -- Special case for zsh =(..) syntax + spacing1 + string "=(" optional (readNormalDollar >> parseNoteAt pos ErrorC 1067 "For indirection, use (associative) arrays or 'read \"var$n\" <<< \"value\"'") index <- optionMaybe readArrayIndex