Tweaked some messages and added more badcases
This commit is contained in:
parent
279e972b61
commit
67d27ea42d
6
Makefile
6
Makefile
|
@ -1,7 +1,7 @@
|
||||||
all: .tests shpell
|
all: .tests shpell
|
||||||
true
|
true
|
||||||
|
|
||||||
shpell:
|
shpell: regardless
|
||||||
ghc --make shpell #GHC handles the dependencies
|
ghc --make shpell #GHC handles the dependencies
|
||||||
|
|
||||||
.tests: *.hs */*.hs
|
.tests: *.hs */*.hs
|
||||||
|
@ -9,3 +9,7 @@ shpell:
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f .tests shpell *.hi *.o Shpell/*.hi Shpell/*.o
|
rm -f .tests shpell *.hi *.o Shpell/*.hi Shpell/*.o
|
||||||
|
|
||||||
|
regardless:
|
||||||
|
:
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ checkBasic f s = case parseShell "-" s of
|
||||||
|
|
||||||
prop_checkUuoc = verify checkUuoc "cat foo | grep bar"
|
prop_checkUuoc = verify checkUuoc "cat foo | grep bar"
|
||||||
checkUuoc (T_Pipeline _ (T_Redirecting _ _ f@(T_SimpleCommand id _ _):_:_)) =
|
checkUuoc (T_Pipeline _ (T_Redirecting _ _ f@(T_SimpleCommand id _ _):_:_)) =
|
||||||
case deadSimple f of ["cat", _] -> addNoteFor id $ Note InfoC "UUOC: 'cat foo | bar | baz' is better written as 'bar < foo | baz'"
|
case deadSimple f of ["cat", _] -> addNoteFor id $ Note StyleC "Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead."
|
||||||
_ -> return ()
|
_ -> return ()
|
||||||
checkUuoc _ = return ()
|
checkUuoc _ = return ()
|
||||||
|
|
||||||
|
|
|
@ -318,12 +318,13 @@ readSingleQuoted = do
|
||||||
id <- getNextId
|
id <- getNextId
|
||||||
singleQuote
|
singleQuote
|
||||||
s <- readSingleQuotedPart `reluctantlyTill` singleQuote
|
s <- readSingleQuotedPart `reluctantlyTill` singleQuote
|
||||||
|
pos <- getPosition
|
||||||
singleQuote <?> "End single quoted string"
|
singleQuote <?> "End single quoted string"
|
||||||
|
|
||||||
let string = concat s
|
let string = concat s
|
||||||
return (T_SingleQuoted id string) `attempting` do
|
return (T_SingleQuoted id string) `attempting` do
|
||||||
x <- lookAhead anyChar
|
x <- lookAhead anyChar
|
||||||
when (isAlpha x && isAlpha (last string)) $ parseProblem WarningC "This apostrophe terminated the single quoted string."
|
when (isAlpha x && isAlpha (last string)) $ parseProblemAt pos WarningC "This apostrophe terminated the single quoted string!"
|
||||||
|
|
||||||
readSingleQuotedLiteral = do
|
readSingleQuotedLiteral = do
|
||||||
singleQuote
|
singleQuote
|
||||||
|
@ -338,7 +339,7 @@ readSingleQuotedPart =
|
||||||
prop_readBackTicked = isWarning readBackTicked "`ls *.mp3`"
|
prop_readBackTicked = isWarning readBackTicked "`ls *.mp3`"
|
||||||
readBackTicked = do
|
readBackTicked = do
|
||||||
id <- getNextId
|
id <- getNextId
|
||||||
parseNote StyleC "Ignoring deprecated `..` backtick expansion. Use $(..) instead."
|
parseNote InfoC "Ignoring deprecated `..` backtick expansion. Use $(..) instead."
|
||||||
pos <- getPosition
|
pos <- getPosition
|
||||||
char '`'
|
char '`'
|
||||||
f <- readGenericLiteral (char '`')
|
f <- readGenericLiteral (char '`')
|
||||||
|
@ -381,15 +382,15 @@ readNormalLiteralPart = do
|
||||||
readNormalEscaped <|> (anyChar `reluctantlyTill1` quotable)
|
readNormalEscaped <|> (anyChar `reluctantlyTill1` quotable)
|
||||||
|
|
||||||
readNormalEscaped = do
|
readNormalEscaped = do
|
||||||
backslash
|
|
||||||
pos <- getPosition
|
pos <- getPosition
|
||||||
|
backslash
|
||||||
do
|
do
|
||||||
next <- (quotable <|> oneOf "?*[]")
|
next <- (quotable <|> oneOf "?*[]")
|
||||||
return $ if next == '\n' then "" else [next]
|
return $ if next == '\n' then "" else [next]
|
||||||
<|>
|
<|>
|
||||||
do
|
do
|
||||||
next <- anyChar <?> "No character after \\"
|
next <- anyChar <?> "No character after \\"
|
||||||
parseNoteAt pos WarningC $ "This character doesn't need escaping here, the \\ is ignored"
|
parseNoteAt pos WarningC $ "Did you mean \"$(printf \"\\" ++ [next] ++ "\")\"? The shell just ignores the \\ here."
|
||||||
return [next]
|
return [next]
|
||||||
|
|
||||||
readSingleEscaped = do
|
readSingleEscaped = do
|
||||||
|
@ -502,8 +503,7 @@ readDollarVariable = do
|
||||||
name <- readVariableName
|
name <- readVariableName
|
||||||
return $ T_DollarVariable id (name)
|
return $ T_DollarVariable id (name)
|
||||||
|
|
||||||
char '$'
|
try $ char '$' >> (positional <|> special <|> regular)
|
||||||
positional <|> special <|> regular
|
|
||||||
|
|
||||||
readVariableName = do
|
readVariableName = do
|
||||||
f <- variableStart
|
f <- variableStart
|
||||||
|
@ -512,7 +512,7 @@ readVariableName = do
|
||||||
|
|
||||||
readDollarLonely = do
|
readDollarLonely = do
|
||||||
id <- getNextId
|
id <- getNextId
|
||||||
parseNote ErrorC "$ is not used specially and should therefore be escaped"
|
parseNote StyleC "$ is not used specially and should therefore be escaped"
|
||||||
char '$'
|
char '$'
|
||||||
return $ T_Literal id "$"
|
return $ T_Literal id "$"
|
||||||
|
|
||||||
|
@ -543,15 +543,15 @@ 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 "When using << instead of <<-, the end tokens can't be indented"
|
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 (endToken ++ " was part of the here document, 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 (endToken ++ " appears in the here document, but with different case")
|
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 ")
|
||||||
|
|
||||||
|
|
||||||
|
@ -797,7 +797,7 @@ readInClause = do
|
||||||
|
|
||||||
do {
|
do {
|
||||||
lookAhead (g_Do);
|
lookAhead (g_Do);
|
||||||
parseNote ErrorC "You need a line feed or semicolon before the 'do' (in Bash)";
|
parseNote ErrorC "You need a line feed or semicolon before the 'do'";
|
||||||
} <|> do {
|
} <|> do {
|
||||||
optional $ g_Semi;
|
optional $ g_Semi;
|
||||||
disregard allspacing;
|
disregard allspacing;
|
||||||
|
@ -843,7 +843,7 @@ readFunctionDefinition = do
|
||||||
|
|
||||||
|
|
||||||
readFunctionSignature = do
|
readFunctionSignature = do
|
||||||
acceptButWarn (string "function" >> linewhitespace >> spacing) StyleC "Drop the keyword 'function'. It's optional in Bash but illegal in others."
|
acceptButWarn (string "function" >> linewhitespace >> spacing) InfoC "Drop the keyword 'function'. It's optional in Bash but invalid in other shells."
|
||||||
name <- readVariableName
|
name <- readVariableName
|
||||||
spacing
|
spacing
|
||||||
g_Lparen
|
g_Lparen
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
wget url &; echo "It's backgrounded."
|
|
@ -0,0 +1 @@
|
||||||
|
echo 'Shpell... It's the best!'
|
|
@ -0,0 +1,3 @@
|
||||||
|
for f in * do
|
||||||
|
echo "$f"
|
||||||
|
done
|
|
@ -0,0 +1 @@
|
||||||
|
echo hello\nword
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Caution, white space sensitive file!
|
||||||
|
if true
|
||||||
|
then
|
||||||
|
cat <<- FOO
|
||||||
|
Some text
|
||||||
|
FOO
|
||||||
|
fi
|
|
@ -0,0 +1,3 @@
|
||||||
|
cat << EOF
|
||||||
|
Hello world
|
||||||
|
Eof
|
|
@ -0,0 +1,2 @@
|
||||||
|
cat << EOF
|
||||||
|
Hello world EOF
|
|
@ -1 +1 @@
|
||||||
cat compile.sh |tr -d '\r' > compile.sh
|
sed 's/foo/bar/g' myfile > myfile
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
ls ... "9" "$10" # DOS 4ever
|
|
@ -0,0 +1 @@
|
||||||
|
echo `ls`
|
|
@ -0,0 +1 @@
|
||||||
|
echo "$ is special now?"
|
|
@ -0,0 +1,4 @@
|
||||||
|
for f in *.mp3
|
||||||
|
do
|
||||||
|
mv $f /music
|
||||||
|
done
|
|
@ -0,0 +1,5 @@
|
||||||
|
# There, I fixed it!
|
||||||
|
for f in "$(ls *.mp3)"
|
||||||
|
do
|
||||||
|
mv "$f" /music
|
||||||
|
done
|
|
@ -0,0 +1 @@
|
||||||
|
echo 'Shpell... It\'s the best!'
|
|
@ -0,0 +1 @@
|
||||||
|
function foo() { echo bar; }
|
|
@ -0,0 +1 @@
|
||||||
|
echo Your locales: $(locale)
|
|
@ -0,0 +1 @@
|
||||||
|
cat foo | grep bar
|
|
@ -0,0 +1,6 @@
|
||||||
|
if true
|
||||||
|
then
|
||||||
|
cat << FOO
|
||||||
|
Some text
|
||||||
|
FOO
|
||||||
|
fi
|
|
@ -14,7 +14,7 @@ ansi n = "\x1B[" ++ (show n) ++ "m"
|
||||||
colorForLevel "error" = 31 -- red
|
colorForLevel "error" = 31 -- red
|
||||||
colorForLevel "warning" = 33 -- yellow
|
colorForLevel "warning" = 33 -- yellow
|
||||||
colorForLevel "info" = 33 -- yellow
|
colorForLevel "info" = 33 -- yellow
|
||||||
colorForLevel "style" = 31 -- green
|
colorForLevel "style" = 32 -- green
|
||||||
colorForLevel "message" = 1 -- bold
|
colorForLevel "message" = 1 -- bold
|
||||||
colorForLevel "source" = 0 -- none
|
colorForLevel "source" = 0 -- none
|
||||||
colorForLevel _ = 0 -- none
|
colorForLevel _ = 0 -- none
|
||||||
|
|
Loading…
Reference in New Issue