Merged DollarVariable and DollarBraced, and made the $* test more general

This commit is contained in:
Vidar Holen 2012-11-05 18:45:23 -08:00
parent 90c1b63790
commit ce46defec8
2 changed files with 12 additions and 15 deletions

View File

@ -24,7 +24,7 @@ basicChecks = [
,checkUnquotedExpansions ,checkUnquotedExpansions
,checkRedirectToSame ,checkRedirectToSame
,checkShorthandIf ,checkShorthandIf
,checkForInDollarStar ,checkDollarStar
,checkUnquotedDollarAt ,checkUnquotedDollarAt
,checkStderrRedirect ,checkStderrRedirect
] ]
@ -34,7 +34,6 @@ addNoteFor id note = modifyMap $ Map.adjust (\(Metadata pos notes) -> Metadata p
willSplit x = willSplit x =
case x of case x of
T_DollarVariable _ _ -> True
T_DollarBraced _ _ -> True T_DollarBraced _ _ -> True
T_DollarExpansion _ _ -> True T_DollarExpansion _ _ -> True
T_BraceExpansion _ s -> True T_BraceExpansion _ s -> True
@ -53,7 +52,6 @@ simplify = doTransform makeSimple
deadSimple (T_NormalWord _ l) = [concat (concatMap (deadSimple) l)] deadSimple (T_NormalWord _ l) = [concat (concatMap (deadSimple) l)]
deadSimple (T_DoubleQuoted _ l) = ["\"" ++(concat (concatMap (deadSimple) l)) ++ "\""] deadSimple (T_DoubleQuoted _ l) = ["\"" ++(concat (concatMap (deadSimple) l)) ++ "\""]
deadSimple (T_SingleQuoted _ s) = [s] deadSimple (T_SingleQuoted _ s) = [s]
deadSimple (T_DollarVariable _ _) = ["${VAR}"]
deadSimple (T_DollarBraced _ _) = ["${VAR}"] deadSimple (T_DollarBraced _ _) = ["${VAR}"]
deadSimple (T_DollarArithmetic _ _) = ["${VAR}"] deadSimple (T_DollarArithmetic _ _) = ["${VAR}"]
deadSimple (T_DollarExpansion _ _) = ["${VAR}"] deadSimple (T_DollarExpansion _ _) = ["${VAR}"]
@ -82,7 +80,7 @@ checkUuoc (T_Pipeline _ (T_Redirecting _ _ f@(T_SimpleCommand id _ _):_:_)) =
checkUuoc _ = return () checkUuoc _ = return ()
isMagicInQuotes (T_DollarVariable _ "@") = True isMagicInQuotes (T_DollarBraced _ s) | '@' `elem` s = True
isMagicInQuotes _ = False isMagicInQuotes _ = False
prop_checkForInQuoted = verify checkForInQuoted "for f in \"$(ls)\"; do echo foo; done" prop_checkForInQuoted = verify checkForInQuoted "for f in \"$(ls)\"; do echo foo; done"
@ -109,7 +107,6 @@ checkMissingForQuotes (T_ForIn _ f words cmds) =
where where
markUnquoted f (T_NormalWord _ l) = mapM_ mu l markUnquoted f (T_NormalWord _ l) = mapM_ mu l
markUnquoted _ _ = return () markUnquoted _ _ = return ()
mu (T_DollarVariable id s) | s == f = warning id
mu (T_DollarBraced id s) | s == f = warning id mu (T_DollarBraced id s) | s == f = warning id
mu _ = return () mu _ = return ()
warning id = addNoteFor id $ Note WarningC $ "Variables that could contain spaces should be quoted" warning id = addNoteFor id $ Note WarningC $ "Variables that could contain spaces should be quoted"
@ -150,15 +147,15 @@ checkShorthandIf (T_AndIf id _ (T_OrIf _ _ _)) =
checkShorthandIf _ = return () checkShorthandIf _ = return ()
prop_checkForInDollarStar = verify checkForInDollarStar "for f in $*; do ..; done" prop_checkDollarStar = verify checkDollarStar "for f in $*; do ..; done"
checkForInDollarStar (T_ForIn _ var [T_NormalWord _ [(T_DollarVariable id "*")]] _) = checkDollarStar (T_NormalWord _ [(T_DollarBraced id "*")]) =
addNoteFor id $ Note WarningC $ "Use 'for " ++ var ++ " in \"$@\"; ..' if you want to loop over arguments." addNoteFor id $ Note WarningC $ "Use \"$@\" (with quotes) to prevent whitespace problems"
checkForInDollarStar _ = return () checkDollarStar _ = return ()
prop_checkUnquotedDollarAt = verify checkUnquotedDollarAt "ls $@" prop_checkUnquotedDollarAt = verify checkUnquotedDollarAt "ls $@"
prop_checkUnquotedDollarAt2 = verifyNot checkUnquotedDollarAt "ls \"$@\"" prop_checkUnquotedDollarAt2 = verifyNot checkUnquotedDollarAt "ls \"$@\""
checkUnquotedDollarAt (T_NormalWord _ [T_DollarVariable id "@"]) = checkUnquotedDollarAt (T_NormalWord _ [T_DollarBraced id "@"]) =
addNoteFor id $ Note ErrorC $ "Add double quotes around $@, otherwise it's just like $* and breaks on spaces" addNoteFor id $ Note ErrorC $ "Add double quotes around $@, otherwise it's just like $* and breaks on spaces"
checkUnquotedDollarAt _ = return () checkUnquotedDollarAt _ = return ()
@ -236,12 +233,12 @@ exportParamToLiteral (T_NormalWord _ ((T_Literal id s):_)) =
where prefix = takeWhile (/= '=') s where prefix = takeWhile (/= '=') s
exportParamToLiteral _ = [] exportParamToLiteral _ = []
getBracedReference s = s -- TODO -- TODO:
getBracedReference s = takeWhile (\x -> not $ x `elem` ":[#%/^,") $ dropWhile (== '#') s
getReferencedVariables t = getReferencedVariables t =
case t of case t of
T_DollarBraced id str -> map (\x -> (id, x)) $ [getBracedReference str] T_DollarBraced id str -> map (\x -> (id, x)) $ [getBracedReference str]
T_DollarVariable id str -> [(id, str)]
T_Arithmetic _ _ -> [] -- TODO T_Arithmetic _ _ -> [] -- TODO
_ -> [] _ -> []

View File

@ -146,7 +146,7 @@ acceptButWarn parser level note = do
) )
-- Horrifying AST -- Horrifying AST
data Token = T_AND_IF Id | T_OR_IF Id | T_DSEMI Id | T_Semi Id | T_DLESS Id | T_DGREAT Id | T_LESSAND Id | T_GREATAND Id | T_LESSGREAT Id | T_DLESSDASH Id | T_CLOBBER Id | T_If Id | T_Then Id | T_Else Id | T_Elif Id | T_Fi Id | T_Do Id | T_Done Id | T_Case Id | T_Esac Id | T_While Id | T_Until Id | T_For Id | T_Lbrace Id | T_Rbrace Id | T_Lparen Id | T_Rparen Id | T_Bang Id | T_In Id | T_NEWLINE Id | T_EOF Id | T_Less Id | T_Greater Id | T_SingleQuoted Id String | T_Literal Id String | T_NormalWord Id [Token] | T_DoubleQuoted Id [Token] | T_DollarExpansion Id [Token] | T_DollarBraced Id String | T_DollarVariable Id String | T_DollarArithmetic Id String | T_BraceExpansion Id String | T_IoFile Id Token Token | T_HereDoc Id Bool Bool String | T_HereString Id Token | T_FdRedirect Id String Token | T_Assignment Id String Token | T_Array Id [Token] | T_Redirecting Id [Token] Token | T_SimpleCommand Id [Token] [Token] | T_Pipeline Id [Token] | T_Banged Id Token | T_AndIf Id (Token) (Token) | T_OrIf Id (Token) (Token) | T_Backgrounded Id Token | T_IfExpression Id [([Token],[Token])] [Token] | T_Subshell Id [Token] | T_BraceGroup Id [Token] | T_WhileExpression Id [Token] [Token] | T_UntilExpression Id [Token] [Token] | T_ForIn Id String [Token] [Token] | T_CaseExpression Id Token [([Token],[Token])] | T_Function Id String Token | T_Arithmetic Id String | T_Script Id [Token] data Token = T_AND_IF Id | T_OR_IF Id | T_DSEMI Id | T_Semi Id | T_DLESS Id | T_DGREAT Id | T_LESSAND Id | T_GREATAND Id | T_LESSGREAT Id | T_DLESSDASH Id | T_CLOBBER Id | T_If Id | T_Then Id | T_Else Id | T_Elif Id | T_Fi Id | T_Do Id | T_Done Id | T_Case Id | T_Esac Id | T_While Id | T_Until Id | T_For Id | T_Lbrace Id | T_Rbrace Id | T_Lparen Id | T_Rparen Id | T_Bang Id | T_In Id | T_NEWLINE Id | T_EOF Id | T_Less Id | T_Greater Id | T_SingleQuoted Id String | T_Literal Id String | T_NormalWord Id [Token] | T_DoubleQuoted Id [Token] | T_DollarExpansion Id [Token] | T_DollarBraced Id String | T_DollarArithmetic Id String | T_BraceExpansion Id String | T_IoFile Id Token Token | T_HereDoc Id Bool Bool String | T_HereString Id Token | T_FdRedirect Id String Token | T_Assignment Id String Token | T_Array Id [Token] | T_Redirecting Id [Token] Token | T_SimpleCommand Id [Token] [Token] | T_Pipeline Id [Token] | T_Banged Id Token | T_AndIf Id (Token) (Token) | T_OrIf Id (Token) (Token) | T_Backgrounded Id Token | T_IfExpression Id [([Token],[Token])] [Token] | T_Subshell Id [Token] | T_BraceGroup Id [Token] | T_WhileExpression Id [Token] [Token] | T_UntilExpression Id [Token] [Token] | T_ForIn Id String [Token] [Token] | T_CaseExpression Id Token [([Token],[Token])] | T_Function Id String Token | T_Arithmetic Id String | T_Script Id [Token]
deriving (Show) deriving (Show)
analyzeScopes f g i = mapM (analyze f g i) analyzeScopes f g i = mapM (analyze f g i)
@ -518,7 +518,7 @@ readDollarVariable = do
id <- getNextId id <- getNextId
let singleCharred p = do let singleCharred p = do
n <- p n <- p
return (T_DollarVariable id [n]) `attempting` do return (T_DollarBraced id [n]) `attempting` do
pos <- getPosition pos <- getPosition
num <- lookAhead $ many1 p num <- lookAhead $ many1 p
parseNoteAt pos ErrorC $ "$" ++ (n:num) ++ " is equivalent to ${" ++ [n] ++ "}"++ num parseNoteAt pos ErrorC $ "$" ++ (n:num) ++ " is equivalent to ${" ++ [n] ++ "}"++ num
@ -528,7 +528,7 @@ readDollarVariable = do
let regular = do let regular = do
name <- readVariableName name <- readVariableName
return $ T_DollarVariable id (name) return $ T_DollarBraced id (name)
try $ char '$' >> (positional <|> special <|> regular) try $ char '$' >> (positional <|> special <|> regular)