diff options
author | Roman Smrž <roman.smrz@seznam.cz> | 2025-08-02 16:30:13 +0200 |
---|---|---|
committer | Roman Smrž <roman.smrz@seznam.cz> | 2025-08-02 16:30:13 +0200 |
commit | 07a95fc6138446529384b08ecd1ecc2d54861761 (patch) | |
tree | d03e1be0128b4ac950fb609991074057029c615c | |
parent | 387b02e41cc835541dcfc31af5f96873d5576e37 (diff) |
Shell: support backslash-escaped spaces
-rw-r--r-- | src/Parser/Shell.hs | 19 | ||||
-rw-r--r-- | test/asset/shell/echo.et | 1 | ||||
-rw-r--r-- | test/script/shell.et | 1 |
3 files changed, 17 insertions, 4 deletions
diff --git a/src/Parser/Shell.hs b/src/Parser/Shell.hs index 89595e8..37b4e79 100644 --- a/src/Parser/Shell.hs +++ b/src/Parser/Shell.hs @@ -24,7 +24,7 @@ parseArgument :: TestParser (Expr Text) parseArgument = lexeme $ fmap (App AnnNone (Pure T.concat) <$> foldr (liftA2 (:)) (Pure [])) $ some $ choice [ doubleQuotedString , singleQuotedString - , escapedChar + , standaloneEscapedChar , stringExpansion , unquotedString ] @@ -41,7 +41,7 @@ parseArgument = lexeme $ fmap (App AnnNone (Pure T.concat) <$> foldr (liftA2 (:) let inner = choice [ char '"' >> return [] , (:) <$> (Pure . TL.toStrict <$> takeWhile1P Nothing (`notElem` specialChars)) <*> inner - , (:) <$> escapedChar <*> inner + , (:) <$> stringEscapedChar <*> inner , (:) <$> stringExpansion <*> inner ] App AnnNone (Pure T.concat) . foldr (liftA2 (:)) (Pure []) <$> inner @@ -50,8 +50,8 @@ parseArgument = lexeme $ fmap (App AnnNone (Pure T.concat) <$> foldr (liftA2 (:) singleQuotedString = do Pure . TL.toStrict <$> (char '\'' *> takeWhileP Nothing (/= '\'') <* char '\'') - escapedChar :: TestParser (Expr Text) - escapedChar = do + stringEscapedChar :: TestParser (Expr Text) + stringEscapedChar = do void $ char '\\' Pure <$> choice [ char '\\' >> return "\\" @@ -60,6 +60,17 @@ parseArgument = lexeme $ fmap (App AnnNone (Pure T.concat) <$> foldr (liftA2 (:) , char 'n' >> return "\n" , char 'r' >> return "\r" , char 't' >> return "\t" + , return "\\" + ] + + standaloneEscapedChar :: TestParser (Expr Text) + standaloneEscapedChar = do + void $ char '\\' + Pure <$> choice + [ char '\\' >> return "\\" + , char '"' >> return "\"" + , char '$' >> return "$" + , char ' ' >> return " " ] parseArguments :: TestParser (Expr [ Text ]) diff --git a/test/asset/shell/echo.et b/test/asset/shell/echo.et index 4da319e..c2174a0 100644 --- a/test/asset/shell/echo.et +++ b/test/asset/shell/echo.et @@ -20,3 +20,4 @@ test Echo: echo \$ \" \\ echo "\""\""a" echo "'" '"' '\\\' "\\" + echo a\ b\ \ c diff --git a/test/script/shell.et b/test/script/shell.et index 5cc11fb..12a5a73 100644 --- a/test/script/shell.et +++ b/test/script/shell.et @@ -51,6 +51,7 @@ test ShellEcho: "\$ \" \\" "\"\"a" "' \" \\\\\\ \\" + "a b c" with p: expect /run-test-result Echo done/ |