-
Notifications
You must be signed in to change notification settings - Fork 13
Open
Description
Behaviour is at odds with usual shell quoting practices, violating principle of least surprise.
Examples of unexpected behaviour:
- no expectation that quotes are balanced (
f Quot []should be a failure state) - non-handling of
'-quoted strings """ == \"(usually, former is a longer spelling of")\\escapes only in front of"
In addition, some of the state complexity seems unwarranted.
Why not something along the lines of:
import Data.Bifunctor ( first )
import Data.Char ( isSpace )
import Data.List.NonEmpty ( NonEmpty((:|))
, (<|)
)
data IState = Lit | SingQ | DoubleQ
data OState = Break | Word
-- | split a string into quoted words
-- single/double quotes literal until next occurrence,
-- are escaped by prefixing \
-- \ is itself escaped by \
-- outside quotes, spaces break words and are coalesced
splitArgs :: String -> Maybe (NonEmpty String)
splitArgs s = snd <$> f Lit s
where
f :: IState -> String -> Maybe (OState, NonEmpty String)
f s ('\\' : x : xs) | x `elem` ['\\', '\'', '\"'] = push x <$> f s xs
f Lit ('\'' : xs) = f SingQ xs
f Lit ('\"' : xs) = f DoubleQ xs
f Lit (x : xs) | isSpace x = first (const Break) <$> f Lit xs
f SingQ ('\'' : xs) = f Lit xs
f DoubleQ ('\"' : xs) = f Lit xs
f s (x : xs) = push x <$> f s xs
f Lit [] = Just (Word, "" :| [])
f s [] = Nothing
push :: a -> (OState, NonEmpty [a]) -> (OState, NonEmpty [a])
push x (Break, xss ) = (Word, [x] <| xss)
push x (Word , xs :| xss) = (Word, (x : xs) :| xss)
Metadata
Metadata
Assignees
Labels
No labels