summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2025-08-02 16:30:13 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2025-08-02 16:30:13 +0200
commit07a95fc6138446529384b08ecd1ecc2d54861761 (patch)
treed03e1be0128b4ac950fb609991074057029c615c
parent387b02e41cc835541dcfc31af5f96873d5576e37 (diff)
Shell: support backslash-escaped spaces
-rw-r--r--src/Parser/Shell.hs19
-rw-r--r--test/asset/shell/echo.et1
-rw-r--r--test/script/shell.et1
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/