Improve heredoc delimiter handling.
This commit is contained in:
parent
46e47dad45
commit
0a381be37b
|
@ -1534,40 +1534,32 @@ prop_readHereDoc8 = isOk readScript "cat <<foo>>bar\netc\nfoo"
|
||||||
prop_readHereDoc9 = isOk readScript "if true; then cat << foo; fi\nbar\nfoo\n"
|
prop_readHereDoc9 = isOk readScript "if true; then cat << foo; fi\nbar\nfoo\n"
|
||||||
prop_readHereDoc10= isOk readScript "if true; then cat << foo << bar; fi\nfoo\nbar\n"
|
prop_readHereDoc10= isOk readScript "if true; then cat << foo << bar; fi\nfoo\nbar\n"
|
||||||
prop_readHereDoc11= isOk readScript "cat << foo $(\nfoo\n)lol\nfoo\n"
|
prop_readHereDoc11= isOk readScript "cat << foo $(\nfoo\n)lol\nfoo\n"
|
||||||
|
prop_readHereDoc12= isOk readScript "cat << foo|cat\nbar\nfoo"
|
||||||
readHereDoc = called "here document" $ do
|
readHereDoc = called "here document" $ do
|
||||||
fid <- getNextId
|
fid <- getNextId
|
||||||
pos <- getPosition
|
pos <- getPosition
|
||||||
try $ string "<<"
|
try $ string "<<"
|
||||||
dashed <- (char '-' >> return Dashed) <|> return Undashed
|
dashed <- (char '-' >> return Dashed) <|> return Undashed
|
||||||
tokenPosition <- getPosition
|
|
||||||
sp <- spacing
|
sp <- spacing
|
||||||
optional $ do
|
optional $ do
|
||||||
try . lookAhead $ char '('
|
try . lookAhead $ char '('
|
||||||
let message = "Shells are space sensitive. Use '< <(cmd)', not '<<" ++ sp ++ "(cmd)'."
|
let message = "Shells are space sensitive. Use '< <(cmd)', not '<<" ++ sp ++ "(cmd)'."
|
||||||
parseProblemAt pos ErrorC 1038 message
|
parseProblemAt pos ErrorC 1038 message
|
||||||
hid <- getNextId
|
hid <- getNextId
|
||||||
(quoted, endToken) <-
|
(quoted, endToken) <- readToken
|
||||||
liftM (\ x -> (Quoted, stripLiteral x)) readDoubleQuotedLiteral
|
|
||||||
<|> liftM (\ x -> (Quoted, x)) readSingleQuotedLiteral
|
|
||||||
<|> (readToken >>= (\x -> return (Unquoted, x)))
|
|
||||||
|
|
||||||
-- add empty tokens for now, read the rest in readPendingHereDocs
|
-- add empty tokens for now, read the rest in readPendingHereDocs
|
||||||
let doc = T_HereDoc hid dashed quoted endToken []
|
let doc = T_HereDoc hid dashed quoted endToken []
|
||||||
addPendingHereDoc doc
|
addPendingHereDoc doc
|
||||||
return doc
|
return doc
|
||||||
where
|
where
|
||||||
stripLiteral (T_Literal _ x) = x
|
quotes = "\"'\\"
|
||||||
stripLiteral (T_SingleQuoted _ x) = x
|
-- Fun fact: bash considers << foo"" quoted, but not << <("foo").
|
||||||
|
-- Instead of replicating this, just read a token and strip quotes.
|
||||||
readToken =
|
readToken = do
|
||||||
liftM concat $ many1 (escaped <|> quoted <|> normal)
|
str <- readStringForParser readNormalWord
|
||||||
where
|
return (if any (`elem` quotes) str then Quoted else Unquoted,
|
||||||
quoted = liftM stripLiteral readDoubleQuotedLiteral <|> readSingleQuotedLiteral
|
filter (not . (`elem` quotes)) str)
|
||||||
normal = anyChar `reluctantlyTill1` (whitespace <|> oneOf "<>;&)'\"\\")
|
|
||||||
escaped = do -- surely the user must be doing something wrong at this point
|
|
||||||
char '\\'
|
|
||||||
c <- anyChar
|
|
||||||
return [c]
|
|
||||||
|
|
||||||
|
|
||||||
readPendingHereDocs = do
|
readPendingHereDocs = do
|
||||||
|
|
Loading…
Reference in New Issue