Skip to content

Commit 5b53624

Browse files
committed
Escaping in args parsing is now optional (#371)
1 parent 4eb4650 commit 5b53624

File tree

3 files changed

+34
-20
lines changed

3 files changed

+34
-20
lines changed

src/Data/Attoparsec/Args.hs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
-- | Parsing argument-like things.
2+
3+
module Data.Attoparsec.Args (EscapingMode(..), argsParser) where
4+
5+
import Control.Applicative
6+
import Data.Attoparsec.Text ((<?>))
7+
import qualified Data.Attoparsec.Text as P
8+
import Data.Attoparsec.Types (Parser)
9+
import Data.Text (Text)
10+
11+
-- | Mode for parsing escape characters.
12+
data EscapingMode
13+
= Escaping
14+
| NoEscaping
15+
deriving (Show,Eq,Enum)
16+
17+
-- | A basic argument parser. It supports space-separated text, and
18+
-- string quotation with identity escaping: \x -> x.
19+
argsParser :: EscapingMode -> Parser Text [String]
20+
argsParser mode = many (P.skipSpace *> (quoted <|> unquoted)) <*
21+
P.skipSpace <* (P.endOfInput <?> "unterminated string")
22+
where
23+
unquoted = P.many1 naked
24+
quoted = P.char '"' *> string <* P.char '"'
25+
string = many (case mode of
26+
Escaping -> escaped <|> nonquote
27+
NoEscaping -> nonquote)
28+
escaped = P.char '\\' *> P.anyChar
29+
nonquote = P.satisfy (not . (=='"'))
30+
naked = P.satisfy (not . flip elem ("\" " :: String))

src/Options/Applicative/Args.hs

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@
55
module Options.Applicative.Args
66
(argsArgument
77
,argsOption
8-
,parseArgsFromString
9-
,argsParser)
8+
,parseArgsFromString)
109
where
1110

12-
import Control.Applicative
13-
import Data.Attoparsec.Text ((<?>))
11+
import Data.Attoparsec.Args
1412
import qualified Data.Attoparsec.Text as P
15-
import Data.Attoparsec.Types (Parser)
16-
import Data.Text (Text)
1713
import qualified Data.Text as T
1814
import qualified Options.Applicative as O
1915

@@ -33,17 +29,4 @@ argsOption =
3329

3430
-- | Parse from a string.
3531
parseArgsFromString :: String -> Either String [String]
36-
parseArgsFromString = P.parseOnly argsParser . T.pack
37-
38-
-- | A basic argument parser. It supports space-separated text, and
39-
-- string quotation with identity escaping: \x -> x.
40-
argsParser :: Parser Text [String]
41-
argsParser = many (P.skipSpace *> (quoted <|> unquoted)) <*
42-
P.skipSpace <* (P.endOfInput <?> "unterminated string")
43-
where
44-
unquoted = P.many1 naked
45-
quoted = P.char '"' *> string <* P.char '"'
46-
string = many (escaped <|> nonquote)
47-
escaped = P.char '\\' *> P.anyChar
48-
nonquote = P.satisfy (not . (=='"'))
49-
naked = P.satisfy (not . flip elem ("\" " :: String))
32+
parseArgsFromString = P.parseOnly (argsParser Escaping) . T.pack

stack.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ library
8484
Data.Binary.VersionTagged
8585
Data.Set.Monad
8686
Data.Maybe.Extra
87+
Data.Attoparsec.Args
8788
build-depends: Cabal >= 1.18.1.5
8889
, aeson >= 0.8.0.2
8990
, async >= 2.0.2

0 commit comments

Comments
 (0)