Parse variables and subexpressions in brace expansions
This commit is contained in:
parent
1d26c280d6
commit
6076f0b1da
|
@ -53,7 +53,7 @@ data Token =
|
|||
| T_Backticked Id [Token]
|
||||
| T_Bang Id
|
||||
| T_Banged Id Token
|
||||
| T_BraceExpansion Id String
|
||||
| T_BraceExpansion Id [Token]
|
||||
| T_BraceGroup Id [Token]
|
||||
| T_CLOBBER Id
|
||||
| T_Case Id
|
||||
|
@ -171,6 +171,7 @@ analyze f g i =
|
|||
delve (T_DoubleQuoted id list) = dl list $ T_DoubleQuoted id
|
||||
delve (T_DollarDoubleQuoted id list) = dl list $ T_DollarDoubleQuoted id
|
||||
delve (T_DollarExpansion id list) = dl list $ T_DollarExpansion id
|
||||
delve (T_BraceExpansion id list) = dl list $ T_BraceExpansion id
|
||||
delve (T_Backticked id list) = dl list $ T_Backticked id
|
||||
delve (T_DollarArithmetic id c) = d1 c $ T_DollarArithmetic id
|
||||
delve (T_DollarBracket id c) = d1 c $ T_DollarBracket id
|
||||
|
|
|
@ -1280,8 +1280,18 @@ checkConstantNoary _ _ = return ()
|
|||
|
||||
prop_checkBraceExpansionVars1 = verify checkBraceExpansionVars "echo {1..$n}"
|
||||
prop_checkBraceExpansionVars2 = verifyNot checkBraceExpansionVars "echo {1,3,$n}"
|
||||
checkBraceExpansionVars _ (T_BraceExpansion id s) | "..$" `isInfixOf` s =
|
||||
warn id 2051 "Bash doesn't support variables in brace range expansions."
|
||||
checkBraceExpansionVars _ (T_BraceExpansion id list) = mapM_ check list
|
||||
where
|
||||
check element =
|
||||
when ("..$" `isInfixOf` toString element) $
|
||||
warn id 2051 "Bash doesn't support variables in brace range expansions."
|
||||
literalExt t =
|
||||
case t of
|
||||
T_DollarBraced {} -> return "$"
|
||||
T_DollarExpansion {} -> return "$"
|
||||
T_DollarArithmetic {} -> return "$"
|
||||
otherwise -> return "-"
|
||||
toString t = fromJust $ getLiteralStringExt literalExt t
|
||||
checkBraceExpansionVars _ _ = return ()
|
||||
|
||||
prop_checkForDecimals = verify checkForDecimals "((3.14*c))"
|
||||
|
@ -2413,6 +2423,7 @@ prop_checkSpacefulness22= verifyNotTree checkSpacefulness "echo $\"$1\""
|
|||
prop_checkSpacefulness23= verifyNotTree checkSpacefulness "a=(1); echo ${a[@]}"
|
||||
prop_checkSpacefulness24= verifyTree checkSpacefulness "a='a b'; cat <<< $a"
|
||||
prop_checkSpacefulness25= verifyTree checkSpacefulness "a='s/[0-9]//g'; sed $a"
|
||||
prop_checkSpacefulness26= verifyTree checkSpacefulness "a='foo bar'; echo {1,2,$a}"
|
||||
|
||||
checkSpacefulness params t =
|
||||
doVariableFlowAnalysis readF writeF (Map.fromList defaults) (variableFlow params)
|
||||
|
|
|
@ -237,6 +237,12 @@ attempting rest branch =
|
|||
orFail parser errorAction =
|
||||
try parser <|> (errorAction >>= fail)
|
||||
|
||||
-- Construct a node with a parser, e.g. T_Literal `withParser` (readGenericLiteral ",")
|
||||
withParser node parser = do
|
||||
id <- getNextId
|
||||
contents <- parser
|
||||
return $ node id contents
|
||||
|
||||
wasIncluded p = option False (p >> return True)
|
||||
|
||||
acceptButWarn parser level code note =
|
||||
|
@ -1045,16 +1051,29 @@ readGenericEscaped = do
|
|||
|
||||
prop_readBraced = isOk readBraced "{1..4}"
|
||||
prop_readBraced2 = isOk readBraced "{foo,bar,\"baz lol\"}"
|
||||
readBraced = try $ do
|
||||
let strip (T_Literal _ s) = return ("\"" ++ s ++ "\"")
|
||||
id <- getNextId
|
||||
char '{'
|
||||
str <- many1 ((readDoubleQuotedLiteral >>= strip) <|> readGenericLiteral1 (oneOf "}\"" <|> whitespace))
|
||||
char '}'
|
||||
let result = concat str
|
||||
unless (',' `elem` result || ".." `isInfixOf` result) $
|
||||
fail "Not a brace expression"
|
||||
return $ T_BraceExpansion id result
|
||||
prop_readBraced3 = isOk readBraced "{1,\\},2}"
|
||||
prop_readBraced4 = isOk readBraced "{1,{2,3}}"
|
||||
prop_readBraced5 = isOk readBraced "{JP{,E}G,jp{,e}g}"
|
||||
prop_readBraced6 = isOk readBraced "{foo,bar,$((${var}))}"
|
||||
readBraced = try braceExpansion
|
||||
where
|
||||
braceExpansion =
|
||||
T_BraceExpansion `withParser` do
|
||||
char '{'
|
||||
elements <- bracedElement `sepBy1` char ','
|
||||
char '}'
|
||||
return elements
|
||||
bracedElement =
|
||||
T_NormalWord `withParser` do
|
||||
many $ choice [
|
||||
braceExpansion,
|
||||
readDollarExpression,
|
||||
readSingleQuoted,
|
||||
readDoubleQuoted,
|
||||
braceLiteral
|
||||
]
|
||||
braceLiteral =
|
||||
T_Literal `withParser` readGenericLiteral1 (oneOf "{}\"$'," <|> whitespace)
|
||||
|
||||
readNormalDollar = readDollarExpression <|> readDollarDoubleQuote <|> readDollarSingleQuote <|> readDollarLonely
|
||||
readDoubleQuotedDollar = readDollarExpression <|> readDollarLonely
|
||||
|
@ -1078,7 +1097,6 @@ readDollarDoubleQuote = do
|
|||
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))))"
|
||||
readDollarArithmetic = called "$((..)) expression" $ do
|
||||
|
|
Loading…
Reference in New Issue