Homogenized punctuation across messages.
This commit is contained in:
parent
45d5896cf8
commit
9eac0bfab9
|
@ -123,14 +123,14 @@ prop_checkForInQuoted = verify checkForInQuoted "for f in \"$(ls)\"; do echo foo
|
||||||
prop_checkForInQuoted2 = verifyNot checkForInQuoted "for f in \"$@\"; do echo foo; done"
|
prop_checkForInQuoted2 = verifyNot checkForInQuoted "for f in \"$@\"; do echo foo; done"
|
||||||
checkForInQuoted (T_ForIn _ f [T_NormalWord _ [T_DoubleQuoted id list]] _) =
|
checkForInQuoted (T_ForIn _ f [T_NormalWord _ [T_DoubleQuoted id list]] _) =
|
||||||
when (any (\x -> willSplit x && not (isMagicInQuotes x)) list) $
|
when (any (\x -> willSplit x && not (isMagicInQuotes x)) list) $
|
||||||
err id $ "Since you double quoted this, it will not word split, and the loop will only run once"
|
err id $ "Since you double quoted this, it will not word split, and the loop will only run once."
|
||||||
checkForInQuoted _ = return ()
|
checkForInQuoted _ = return ()
|
||||||
|
|
||||||
|
|
||||||
prop_checkForInLs = verify checkForInLs "for f in $(ls *.mp3); do mplayer \"$f\"; done"
|
prop_checkForInLs = verify checkForInLs "for f in $(ls *.mp3); do mplayer \"$f\"; done"
|
||||||
checkForInLs (T_ForIn _ f [T_NormalWord _ [T_DollarExpansion id [x]]] _) =
|
checkForInLs (T_ForIn _ f [T_NormalWord _ [T_DollarExpansion id [x]]] _) =
|
||||||
case deadSimple x of ("ls":n) -> let args = (if n == [] then ["*"] else n) in
|
case deadSimple x of ("ls":n) -> let args = (if n == [] then ["*"] else n) in
|
||||||
err id $ "Don't use 'for "++f++" in $(ls " ++ (intercalate " " n) ++ ")'. Use 'for "++f++" in "++ (intercalate " " args) ++ "'"
|
err id $ "Don't use 'for "++f++" in $(ls " ++ (intercalate " " n) ++ ")'. Use 'for "++f++" in "++ (intercalate " " args) ++ "' ."
|
||||||
_ -> return ()
|
_ -> return ()
|
||||||
checkForInLs _ = return ()
|
checkForInLs _ = return ()
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ checkMissingForQuotes t m =
|
||||||
markUnquoted _ _ = return ()
|
markUnquoted _ _ = return ()
|
||||||
mu (T_DollarBraced id s) | s == f = warning id
|
mu (T_DollarBraced id s) | s == f = warning id
|
||||||
mu _ = return ()
|
mu _ = return ()
|
||||||
warning id = warn id $ "Variables that could contain spaces should be quoted"
|
warning id = warn id $ "Variables that could contain spaces should be quoted."
|
||||||
cq _ = return ()
|
cq _ = return ()
|
||||||
parents = getParentTree t
|
parents = getParentTree t
|
||||||
|
|
||||||
|
@ -163,14 +163,14 @@ checkMissingPositionalQuotes t m =
|
||||||
cq l@(T_NormalWord _ list) =
|
cq l@(T_NormalWord _ list) =
|
||||||
unless (inUnquotableContext parents l) $ mapM_ checkPos list
|
unless (inUnquotableContext parents l) $ mapM_ checkPos list
|
||||||
where checkPos (T_DollarBraced id s) | all isDigit (getBracedReference s) =
|
where checkPos (T_DollarBraced id s) | all isDigit (getBracedReference s) =
|
||||||
warn id $ "Positional parameters should be quoted to avoid whitespace trouble"
|
warn id $ "Positional parameters should be quoted to avoid whitespace trouble."
|
||||||
checkPos _ = return ()
|
checkPos _ = return ()
|
||||||
cq _ = return ()
|
cq _ = return ()
|
||||||
parents = getParentTree t
|
parents = getParentTree t
|
||||||
|
|
||||||
prop_checkUnquotedExpansions = verify checkUnquotedExpansions "rm $(ls)"
|
prop_checkUnquotedExpansions = verify checkUnquotedExpansions "rm $(ls)"
|
||||||
checkUnquotedExpansions (T_SimpleCommand _ _ cmds) = mapM_ check cmds
|
checkUnquotedExpansions (T_SimpleCommand _ _ cmds) = mapM_ check cmds
|
||||||
where check (T_NormalWord _ [T_DollarExpansion id _]) = warn id "Quote the expansion to prevent word splitting"
|
where check (T_NormalWord _ [T_DollarExpansion id _]) = warn id "Quote the expansion to prevent word splitting."
|
||||||
check _ = return ()
|
check _ = return ()
|
||||||
checkUnquotedExpansions _ = return ()
|
checkUnquotedExpansions _ = return ()
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ checkRedirectToSame s@(T_Pipeline _ list) =
|
||||||
mapM_ (\l -> (mapM_ (\x -> doAnalysis (checkOccurences x) l) (getAllRedirs list))) list
|
mapM_ (\l -> (mapM_ (\x -> doAnalysis (checkOccurences x) l) (getAllRedirs list))) list
|
||||||
where checkOccurences (T_NormalWord exceptId x) (T_NormalWord newId y) =
|
where checkOccurences (T_NormalWord exceptId x) (T_NormalWord newId y) =
|
||||||
when (x == y && exceptId /= newId) (do
|
when (x == y && exceptId /= newId) (do
|
||||||
let note = Note InfoC $ "Make sure not to read and write the same file in the same pipeline"
|
let note = Note InfoC $ "Make sure not to read and write the same file in the same pipeline."
|
||||||
addNoteFor newId $ note
|
addNoteFor newId $ note
|
||||||
addNoteFor exceptId $ note)
|
addNoteFor exceptId $ note)
|
||||||
checkOccurences _ _ = return ()
|
checkOccurences _ _ = return ()
|
||||||
|
@ -204,14 +204,14 @@ checkShorthandIf _ = return ()
|
||||||
|
|
||||||
prop_checkDollarStar = verify checkDollarStar "for f in $*; do ..; done"
|
prop_checkDollarStar = verify checkDollarStar "for f in $*; do ..; done"
|
||||||
checkDollarStar (T_NormalWord _ [(T_DollarBraced id "*")]) =
|
checkDollarStar (T_NormalWord _ [(T_DollarBraced id "*")]) =
|
||||||
warn id $ "Use \"$@\" (with quotes) to prevent whitespace problems"
|
warn id $ "Use \"$@\" (with quotes) to prevent whitespace problems."
|
||||||
checkDollarStar _ = 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_DollarBraced id "@"]) =
|
checkUnquotedDollarAt (T_NormalWord _ [T_DollarBraced id "@"]) =
|
||||||
err id $ "Add double quotes around $@, otherwise it's just like $* and breaks on spaces"
|
err id $ "Add double quotes around $@, otherwise it's just like $* and breaks on spaces."
|
||||||
checkUnquotedDollarAt _ = return ()
|
checkUnquotedDollarAt _ = return ()
|
||||||
|
|
||||||
prop_checkStderrRedirect = verify checkStderrRedirect "test 2>&1 > cow"
|
prop_checkStderrRedirect = verify checkStderrRedirect "test 2>&1 > cow"
|
||||||
|
@ -254,7 +254,7 @@ prop_checkNumberComparisons4 = verify checkNumberComparisons "[ $foo > $bar ]"
|
||||||
prop_checkNumberComparisons5 = verify checkNumberComparisons "until [ $n <= $z ]; do echo foo; done"
|
prop_checkNumberComparisons5 = verify checkNumberComparisons "until [ $n <= $z ]; do echo foo; done"
|
||||||
checkNumberComparisons (TC_Binary id typ op lhs rhs)
|
checkNumberComparisons (TC_Binary id typ op lhs rhs)
|
||||||
| op `elem` ["<", ">", "<=", ">="] = do
|
| op `elem` ["<", ">", "<=", ">="] = do
|
||||||
when (isNum lhs || isNum rhs) $ err id $ "\"" ++ op ++ "\" is for string comparisons. Use " ++ (eqv op)
|
when (isNum lhs || isNum rhs) $ err id $ "\"" ++ op ++ "\" is for string comparisons. Use " ++ (eqv op) ++" ."
|
||||||
when (typ == SingleBracket) $ err id $ "Can't use " ++ op ++" in [ ]. Use [[ ]]."
|
when (typ == SingleBracket) $ err id $ "Can't use " ++ op ++" in [ ]. Use [[ ]]."
|
||||||
where
|
where
|
||||||
isNum t = case deadSimple t of [v] -> all isDigit v
|
isNum t = case deadSimple t of [v] -> all isDigit v
|
||||||
|
@ -270,7 +270,7 @@ prop_checkNoaryWasBinary = verify checkNoaryWasBinary "[[ a==$foo ]]"
|
||||||
prop_checkNoaryWasBinary2 = verify checkNoaryWasBinary "[ $foo=3 ]"
|
prop_checkNoaryWasBinary2 = verify checkNoaryWasBinary "[ $foo=3 ]"
|
||||||
checkNoaryWasBinary (TC_Noary _ _ t@(T_NormalWord id l)) = do
|
checkNoaryWasBinary (TC_Noary _ _ t@(T_NormalWord id l)) = do
|
||||||
let str = concat $ deadSimple t
|
let str = concat $ deadSimple t
|
||||||
when ('=' `elem` str) $ err id $ "Always true because you didn't put spaces around the ="
|
when ('=' `elem` str) $ err id $ "Always true because you didn't put spaces around the = ."
|
||||||
checkNoaryWasBinary _ = return ()
|
checkNoaryWasBinary _ = return ()
|
||||||
|
|
||||||
prop_checkBraceExpansionVars = verify checkBraceExpansionVars "echo {1..$n}"
|
prop_checkBraceExpansionVars = verify checkBraceExpansionVars "echo {1..$n}"
|
||||||
|
@ -286,7 +286,7 @@ checkForDecimals _ = return ()
|
||||||
prop_checkDivBeforeMult = verify checkDivBeforeMult "echo $((c/n*100))"
|
prop_checkDivBeforeMult = verify checkDivBeforeMult "echo $((c/n*100))"
|
||||||
prop_checkDivBeforeMult2 = verifyNot checkDivBeforeMult "echo $((c*100/n))"
|
prop_checkDivBeforeMult2 = verifyNot checkDivBeforeMult "echo $((c*100/n))"
|
||||||
checkDivBeforeMult (TA_Binary _ "*" (TA_Binary id "/" _ _) _) = do
|
checkDivBeforeMult (TA_Binary _ "*" (TA_Binary id "/" _ _) _) = do
|
||||||
info id $ "Increase precision by replacing a/b*c with a*c/b"
|
info id $ "Increase precision by replacing a/b*c with a*c/b."
|
||||||
checkDivBeforeMult _ = return ()
|
checkDivBeforeMult _ = return ()
|
||||||
|
|
||||||
prop_checkArithmeticDeref = verify checkArithmeticDeref "echo $((3+$foo))"
|
prop_checkArithmeticDeref = verify checkArithmeticDeref "echo $((3+$foo))"
|
||||||
|
@ -294,14 +294,14 @@ prop_checkArithmeticDeref2 = verify checkArithmeticDeref "cow=14; (( s+= $cow ))
|
||||||
prop_checkArithmeticDeref3 = verifyNot checkArithmeticDeref "cow=1/40; (( s+= ${cow%%/*} ))"
|
prop_checkArithmeticDeref3 = verifyNot checkArithmeticDeref "cow=1/40; (( s+= ${cow%%/*} ))"
|
||||||
prop_checkArithmeticDeref4 = verifyNot checkArithmeticDeref "(( ! $? ))"
|
prop_checkArithmeticDeref4 = verifyNot checkArithmeticDeref "(( ! $? ))"
|
||||||
checkArithmeticDeref (TA_Expansion _ (T_DollarBraced id str)) | not $ any (`elem` "/.:#%?*@") $ str =
|
checkArithmeticDeref (TA_Expansion _ (T_DollarBraced id str)) | not $ any (`elem` "/.:#%?*@") $ str =
|
||||||
warn id $ "Don't use $ on variables in (( )) unless you want to dereference twice"
|
style id $ "Don't use $ on variables in (( ))."
|
||||||
checkArithmeticDeref _ = return ()
|
checkArithmeticDeref _ = return ()
|
||||||
|
|
||||||
|
|
||||||
prop_checkComparisonAgainstGlob = verify checkComparisonAgainstGlob "[[ $cow == $bar ]]"
|
prop_checkComparisonAgainstGlob = verify checkComparisonAgainstGlob "[[ $cow == $bar ]]"
|
||||||
prop_checkComparisonAgainstGlob2 = verifyNot checkComparisonAgainstGlob "[[ $cow == \"$bar\" ]]"
|
prop_checkComparisonAgainstGlob2 = verifyNot checkComparisonAgainstGlob "[[ $cow == \"$bar\" ]]"
|
||||||
checkComparisonAgainstGlob (TC_Binary _ DoubleBracket op _ (T_NormalWord id [T_DollarBraced _ _])) | op == "=" || op == "==" =
|
checkComparisonAgainstGlob (TC_Binary _ DoubleBracket op _ (T_NormalWord id [T_DollarBraced _ _])) | op == "=" || op == "==" =
|
||||||
warn id $ "Quote the rhs of = in [[ ]] to prevent glob interpretation"
|
warn id $ "Quote the rhs of = in [[ ]] to prevent glob interpretation."
|
||||||
checkComparisonAgainstGlob _ = return ()
|
checkComparisonAgainstGlob _ = return ()
|
||||||
|
|
||||||
prop_checkCommarrays1 = verify checkCommarrays "a=(1, 2)"
|
prop_checkCommarrays1 = verify checkCommarrays "a=(1, 2)"
|
||||||
|
@ -309,7 +309,7 @@ prop_checkCommarrays2 = verify checkCommarrays "a+=(1,2,3)"
|
||||||
prop_checkCommarrays3 = verifyNot checkCommarrays "cow=(1 \"foo,bar\" 3)"
|
prop_checkCommarrays3 = verifyNot checkCommarrays "cow=(1 \"foo,bar\" 3)"
|
||||||
checkCommarrays (T_Array id l) =
|
checkCommarrays (T_Array id l) =
|
||||||
if any ("," `isSuffixOf`) (concatMap deadSimple l) || (length $ filter (==',') (concat $ concatMap deadSimple l)) > 1
|
if any ("," `isSuffixOf`) (concatMap deadSimple l) || (length $ filter (==',') (concat $ concatMap deadSimple l)) > 1
|
||||||
then warn id "Use spaces, not commas, to separate array elements"
|
then warn id "Use spaces, not commas, to separate array elements."
|
||||||
else return ()
|
else return ()
|
||||||
checkCommarrays _ = return ()
|
checkCommarrays _ = return ()
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ checkPrintfVar = checkCommand "printf" f where
|
||||||
f _ = return ()
|
f _ = return ()
|
||||||
check format =
|
check format =
|
||||||
if not $ isLiteral format
|
if not $ isLiteral format
|
||||||
then warn (getId format) $ "Don't use printf \"$foo\", use printf \"%s\" \"$foo\""
|
then warn (getId format) $ "Don't use variables in the printf format string. Use printf \"%s\" \"$foo\"."
|
||||||
else return ()
|
else return ()
|
||||||
|
|
||||||
--- Subshell detection
|
--- Subshell detection
|
||||||
|
|
|
@ -61,7 +61,7 @@ allspacing = do
|
||||||
when x allspacing
|
when x allspacing
|
||||||
|
|
||||||
carriageReturn = do
|
carriageReturn = do
|
||||||
parseNote ErrorC "Literal carriage return. Run script through tr -d '\\r' "
|
parseNote ErrorC "Literal carriage return. Run script through tr -d '\\r' ."
|
||||||
char '\r'
|
char '\r'
|
||||||
|
|
||||||
--------- Message/position annotation on top of user state
|
--------- Message/position annotation on top of user state
|
||||||
|
@ -186,7 +186,7 @@ readConditionContents single = do
|
||||||
arg <- readCondWord
|
arg <- readCondWord
|
||||||
return $ op arg)
|
return $ op arg)
|
||||||
<|> (do
|
<|> (do
|
||||||
parseProblemAt pos ErrorC $ "Expected this to be an argument to the unary condition"
|
parseProblemAt pos ErrorC $ "Expected this to be an argument to the unary condition."
|
||||||
fail "oops")
|
fail "oops")
|
||||||
|
|
||||||
readCondUnaryOp = try $ do
|
readCondUnaryOp = try $ do
|
||||||
|
@ -207,7 +207,7 @@ readConditionContents single = do
|
||||||
if (endedWithBracket x)
|
if (endedWithBracket x)
|
||||||
then do
|
then do
|
||||||
lookAhead (try $ (many whitespace) >> (eof <|> disregard readSeparator <|> disregard (g_Then <|> g_Do)))
|
lookAhead (try $ (many whitespace) >> (eof <|> disregard readSeparator <|> disregard (g_Then <|> g_Do)))
|
||||||
parseProblemAt pos ErrorC $ "You need a space before the " ++ if single then "]" else "]]"
|
parseProblemAt pos ErrorC $ "You need a space before the " ++ (if single then "]" else "]]") ++ "."
|
||||||
else
|
else
|
||||||
disregard spacing
|
disregard spacing
|
||||||
return x
|
return x
|
||||||
|
@ -220,7 +220,7 @@ readConditionContents single = do
|
||||||
id <- getNextId
|
id <- getNextId
|
||||||
x <- try (string "&&" <|> string "-a")
|
x <- try (string "&&" <|> string "-a")
|
||||||
when (single && x == "&&") $ addNoteFor id $ Note ErrorC "You can't use && inside [..]. Use [[..]] instead."
|
when (single && x == "&&") $ addNoteFor id $ Note ErrorC "You can't use && inside [..]. Use [[..]] instead."
|
||||||
when (not single && x == "-a") $ addNoteFor id $ Note ErrorC "In [[..]], use && instead of -a"
|
when (not single && x == "-a") $ addNoteFor id $ Note ErrorC "In [[..]], use && instead of -a."
|
||||||
softCondSpacing
|
softCondSpacing
|
||||||
return $ TC_And id typ x
|
return $ TC_And id typ x
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ readConditionContents single = do
|
||||||
id <- getNextId
|
id <- getNextId
|
||||||
x <- try (string "||" <|> string "-o")
|
x <- try (string "||" <|> string "-o")
|
||||||
when (single && x == "||") $ addNoteFor id $ Note ErrorC "You can't use || inside [..]. Use [[..]] instead."
|
when (single && x == "||") $ addNoteFor id $ Note ErrorC "You can't use || inside [..]. Use [[..]] instead."
|
||||||
when (not single && x == "-o") $ addNoteFor id $ Note ErrorC "In [[..]], use && instead of -o"
|
when (not single && x == "-o") $ addNoteFor id $ Note ErrorC "In [[..]], use && instead of -o."
|
||||||
softCondSpacing
|
softCondSpacing
|
||||||
return $ TC_Or id typ x
|
return $ TC_Or id typ x
|
||||||
|
|
||||||
|
@ -239,13 +239,13 @@ readConditionContents single = do
|
||||||
pos <- getPosition
|
pos <- getPosition
|
||||||
lookAhead (char '[')
|
lookAhead (char '[')
|
||||||
parseProblemAt pos ErrorC $ if single
|
parseProblemAt pos ErrorC $ if single
|
||||||
then "Don't use [] for grouping. Use \\( .. \\) "
|
then "Don't use [] for grouping. Use \\( .. \\)."
|
||||||
else "Don't use [] for grouping. Use ()."
|
else "Don't use [] for grouping. Use ()."
|
||||||
)
|
)
|
||||||
(do
|
(do
|
||||||
pos <- getPosition
|
pos <- getPosition
|
||||||
op <- readCondBinaryOp
|
op <- readCondBinaryOp
|
||||||
y <- readCondWord <|> ( (parseProblemAt pos ErrorC $ "Expected another argument for this operator") >> mzero)
|
y <- readCondWord <|> ( (parseProblemAt pos ErrorC $ "Expected another argument for this operator.") >> mzero)
|
||||||
return (x `op` y)
|
return (x `op` y)
|
||||||
) <|> (return $ TC_Noary id typ x)
|
) <|> (return $ TC_Noary id typ x)
|
||||||
|
|
||||||
|
@ -489,7 +489,7 @@ readBackTicked = do
|
||||||
pos <- getPosition
|
pos <- getPosition
|
||||||
char '`'
|
char '`'
|
||||||
f <- readGenericLiteral (char '`')
|
f <- readGenericLiteral (char '`')
|
||||||
char '`' `attempting` (eof >> parseProblemAt pos ErrorC "Can't find terminating backtick for this one")
|
char '`' `attempting` (eof >> parseProblemAt pos ErrorC "Can't find terminating backtick for this one.")
|
||||||
return $ T_Literal id f
|
return $ T_Literal id f
|
||||||
|
|
||||||
|
|
||||||
|
@ -638,7 +638,7 @@ readDollarVariable = do
|
||||||
return (T_DollarBraced 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 ++"."
|
||||||
|
|
||||||
let positional = singleCharred digit
|
let positional = singleCharred digit
|
||||||
let special = singleCharred specialVariable
|
let special = singleCharred specialVariable
|
||||||
|
@ -658,7 +658,7 @@ readDollarLonely = do
|
||||||
id <- getNextId
|
id <- getNextId
|
||||||
char '$'
|
char '$'
|
||||||
n <- lookAhead (anyChar <|> (eof >> return '_'))
|
n <- lookAhead (anyChar <|> (eof >> return '_'))
|
||||||
when (n /= '\'') $ parseNote StyleC "$ is not used specially and should therefore be escaped"
|
when (n /= '\'') $ parseNote StyleC "$ is not used specially and should therefore be escaped."
|
||||||
return $ T_Literal id "$"
|
return $ T_Literal id "$"
|
||||||
|
|
||||||
prop_readHereDoc = isOk readHereDoc "<< foo\nlol\ncow\nfoo"
|
prop_readHereDoc = isOk readHereDoc "<< foo\nlol\ncow\nfoo"
|
||||||
|
@ -688,16 +688,16 @@ readHereDoc = do
|
||||||
`attempting` (eof >> debugHereDoc tokenPosition endToken hereInfo)
|
`attempting` (eof >> debugHereDoc tokenPosition endToken hereInfo)
|
||||||
|
|
||||||
verifyHereDoc dashed quoted spacing hereInfo = do
|
verifyHereDoc dashed quoted spacing hereInfo = do
|
||||||
when (not dashed && spacing /= "") $ parseNote ErrorC "Use <<- instead of << if you want to indent the end token"
|
when (not dashed && spacing /= "") $ parseNote ErrorC "Use <<- instead of << if you want to indent the end token."
|
||||||
when (dashed && filter (/= '\t') spacing /= "" ) $ parseNote ErrorC "When using <<-, you can only indent with tabs"
|
when (dashed && filter (/= '\t') spacing /= "" ) $ parseNote ErrorC "When using <<-, you can only indent with tabs."
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
debugHereDoc pos endToken doc =
|
debugHereDoc pos endToken doc =
|
||||||
if endToken `isInfixOf` doc
|
if endToken `isInfixOf` doc
|
||||||
then parseProblemAt pos ErrorC ("Found " ++ endToken ++ " further down, but not by itself at the start of the line")
|
then parseProblemAt pos ErrorC ("Found " ++ endToken ++ " further down, but not by itself at the start of the line.")
|
||||||
else if (map toLower endToken) `isInfixOf` (map toLower doc)
|
else if (map toLower endToken) `isInfixOf` (map toLower doc)
|
||||||
then parseProblemAt pos ErrorC ("Found " ++ endToken ++ " further down, but with wrong casing.")
|
then parseProblemAt pos ErrorC ("Found " ++ endToken ++ " further down, but with wrong casing.")
|
||||||
else parseProblemAt pos ErrorC ("Couldn't find end token `" ++ endToken ++ "' in the here document ")
|
else parseProblemAt pos ErrorC ("Couldn't find end token `" ++ endToken ++ "' in the here document.")
|
||||||
|
|
||||||
|
|
||||||
readFilename = readNormalWord
|
readFilename = readNormalWord
|
||||||
|
@ -857,14 +857,14 @@ readIfClause = do
|
||||||
elses <- option [] readElsePart
|
elses <- option [] readElsePart
|
||||||
g_Fi <|> (do
|
g_Fi <|> (do
|
||||||
eof
|
eof
|
||||||
parseProblemAt pos ErrorC "Can't find 'fi' for this if. Make sure it's preceeded by a ; or \\n"
|
parseProblemAt pos ErrorC "Can't find 'fi' for this if. Make sure it's preceeded by a ; or \\n."
|
||||||
fail "lol"
|
fail "lol"
|
||||||
)
|
)
|
||||||
return $ T_IfExpression id ((condition, action):elifs) elses
|
return $ T_IfExpression id ((condition, action):elifs) elses
|
||||||
|
|
||||||
checkIfNotSpecial pos key stuff = do
|
checkIfNotSpecial pos key stuff = do
|
||||||
eof
|
eof
|
||||||
let f (T_Literal id str) | str == key = parseProblemAt pos ErrorC $ "You need a \\n or ; before '"++ key ++ "' to make it special"
|
let f (T_Literal id str) | str == key = parseProblemAt pos ErrorC $ "You need a \\n or ; before '"++ key ++ "' to make it special."
|
||||||
f t = return ()
|
f t = return ()
|
||||||
mapM (doAnalysis f) stuff
|
mapM (doAnalysis f) stuff
|
||||||
fail "lol"
|
fail "lol"
|
||||||
|
@ -875,7 +875,7 @@ readIfPart = do
|
||||||
pos <- getPosition
|
pos <- getPosition
|
||||||
condition <- readTerm
|
condition <- readTerm
|
||||||
g_Then <|> (checkIfNotSpecial pos "then" condition)
|
g_Then <|> (checkIfNotSpecial pos "then" condition)
|
||||||
acceptButWarn g_Semi ErrorC "No semicolons directly after 'then'"
|
acceptButWarn g_Semi ErrorC "No semicolons directly after 'then'."
|
||||||
allspacing
|
allspacing
|
||||||
action <- readTerm
|
action <- readTerm
|
||||||
return (condition, action)
|
return (condition, action)
|
||||||
|
@ -886,14 +886,14 @@ readElifPart = do
|
||||||
allspacing
|
allspacing
|
||||||
condition <- readTerm
|
condition <- readTerm
|
||||||
g_Then <|> (checkIfNotSpecial pos "then" condition)
|
g_Then <|> (checkIfNotSpecial pos "then" condition)
|
||||||
acceptButWarn g_Semi ErrorC "No semicolons directly after 'then'"
|
acceptButWarn g_Semi ErrorC "No semicolons directly after 'then'."
|
||||||
allspacing
|
allspacing
|
||||||
action <- readTerm
|
action <- readTerm
|
||||||
return (condition, action)
|
return (condition, action)
|
||||||
|
|
||||||
readElsePart = do
|
readElsePart = do
|
||||||
g_Else
|
g_Else
|
||||||
acceptButWarn g_Semi ErrorC "No semicolons directly after 'else'"
|
acceptButWarn g_Semi ErrorC "No semicolons directly after 'else'."
|
||||||
allspacing
|
allspacing
|
||||||
readTerm
|
readTerm
|
||||||
|
|
||||||
|
@ -946,12 +946,12 @@ readDoGroup = do
|
||||||
disregard g_Done <|> (do
|
disregard g_Done <|> (do
|
||||||
eof
|
eof
|
||||||
case hasFinal "done" commands of
|
case hasFinal "done" commands of
|
||||||
Nothing -> parseProblemAt pos ErrorC "Couldn't find a 'done' for this 'do'"
|
Nothing -> parseProblemAt pos ErrorC "Couldn't find a 'done' for this 'do'."
|
||||||
Just (id) -> addNoteFor id $ Note ErrorC "Put a ; or \\n before the done"
|
Just (id) -> addNoteFor id $ Note ErrorC "Put a ; or \\n before the done."
|
||||||
)
|
)
|
||||||
return commands
|
return commands
|
||||||
<|> do
|
<|> do
|
||||||
parseProblemAt pos ErrorC "Can't find the 'done' for this 'do'"
|
parseProblemAt pos ErrorC "Can't find the 'done' for this 'do'."
|
||||||
fail "No done"
|
fail "No done"
|
||||||
|
|
||||||
hasFinal s [] = Nothing
|
hasFinal s [] = Nothing
|
||||||
|
@ -979,7 +979,7 @@ readForClause = do
|
||||||
group <- readDoGroup <|> (
|
group <- readDoGroup <|> (
|
||||||
allspacing >>
|
allspacing >>
|
||||||
eof >>
|
eof >>
|
||||||
parseProblem ErrorC "Missing 'do'" >>
|
parseProblem ErrorC "Missing 'do'." >>
|
||||||
return [])
|
return [])
|
||||||
return $ T_ForIn id name values group
|
return $ T_ForIn id name values group
|
||||||
|
|
||||||
|
@ -990,7 +990,7 @@ readInClause = do
|
||||||
|
|
||||||
do {
|
do {
|
||||||
lookAhead (g_Do);
|
lookAhead (g_Do);
|
||||||
parseNote ErrorC "You need a line feed or semicolon before the 'do'";
|
parseNote ErrorC "You need a line feed or semicolon before the 'do'.";
|
||||||
} <|> do {
|
} <|> do {
|
||||||
optional $ g_Semi;
|
optional $ g_Semi;
|
||||||
disregard allspacing;
|
disregard allspacing;
|
||||||
|
@ -1030,7 +1030,7 @@ readFunctionDefinition = do
|
||||||
id <- getNextId
|
id <- getNextId
|
||||||
name <- try readFunctionSignature
|
name <- try readFunctionSignature
|
||||||
allspacing
|
allspacing
|
||||||
(disregard (lookAhead g_Lbrace) <|> parseProblem ErrorC "Expected a { to open the function definition")
|
(disregard (lookAhead g_Lbrace) <|> parseProblem ErrorC "Expected a { to open the function definition.")
|
||||||
group <- readBraceGroup
|
group <- readBraceGroup
|
||||||
return $ T_Function id name group
|
return $ T_Function id name group
|
||||||
|
|
||||||
|
@ -1068,7 +1068,7 @@ prop_readAssignmentWord5 = isOk readAssignmentWord "b+=lol"
|
||||||
prop_readAssignmentWord6 = isWarning readAssignmentWord "b += (1 2 3)"
|
prop_readAssignmentWord6 = isWarning readAssignmentWord "b += (1 2 3)"
|
||||||
readAssignmentWord = try $ do
|
readAssignmentWord = try $ do
|
||||||
id <- getNextId
|
id <- getNextId
|
||||||
optional (char '$' >> parseNote ErrorC "Don't use $ on the left side of assignments")
|
optional (char '$' >> parseNote ErrorC "Don't use $ on the left side of assignments.")
|
||||||
variable <- readVariableName
|
variable <- readVariableName
|
||||||
space <- spacing
|
space <- spacing
|
||||||
pos <- getPosition
|
pos <- getPosition
|
||||||
|
@ -1076,7 +1076,7 @@ readAssignmentWord = try $ do
|
||||||
space2 <- spacing
|
space2 <- spacing
|
||||||
value <- readArray <|> readNormalWord
|
value <- readArray <|> readNormalWord
|
||||||
spacing
|
spacing
|
||||||
when (space ++ space2 /= "") $ parseNoteAt pos ErrorC "Don't put spaces around the = in assignments"
|
when (space ++ space2 /= "") $ parseNoteAt pos ErrorC "Don't put spaces around the = in assignments."
|
||||||
return $ T_Assignment id variable value
|
return $ T_Assignment id variable value
|
||||||
|
|
||||||
readArray = do
|
readArray = do
|
||||||
|
@ -1156,7 +1156,7 @@ readScript = do
|
||||||
eof <|> (parseProblem ErrorC "Parsing stopped here because of parsing errors.");
|
eof <|> (parseProblem ErrorC "Parsing stopped here because of parsing errors.");
|
||||||
return $ T_Script id commands;
|
return $ T_Script id commands;
|
||||||
} <|> do {
|
} <|> do {
|
||||||
parseProblem WarningC "Couldn't read any commands";
|
parseProblem WarningC "Couldn't read any commands.";
|
||||||
return $ T_Script id $ [T_EOF id];
|
return $ T_Script id $ [T_EOF id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue