{- | Module : $Header$ Copyright : (c) Simon Bergot License : BSD3 Maintainer : simon.bergot@gmail.com Stability : unstable Portability : portable Preprocess args from a list of words to a pair containing positional args/flag arguments. -} module System.Console.ArgParser.ArgsProcess (preprocess) where import Data.List import qualified Data.Map as M import System.Console.ArgParser.BaseType -- | Separate positional arguments from flag arguments preprocess :: Args -> NiceArgs preprocess args = (pos, flagArgs) where (pos, rest) = collectPos $ tokenize args flagArgs :: Flags flagArgs = M.fromListWith (flip (++)) $ unfoldr parseFlag rest data TokenType = Flag | Pos data Token = Token TokenType Arg isPos :: Token -> Bool isPos (Token tokenType _) = case tokenType of Pos -> True _ -> False getWord :: Token -> Arg getWord (Token _ word) = word tokenize :: Args -> [Token] tokenize = (concatMap arg2token) . (takeWhile (/= "--")) where arg2token :: Arg -> [Token] arg2token arg = case arg of '-':'-':word -> [Token Flag word] '-':word -> map (Token Flag . (:[]) ) word word -> [Token Pos word] collectPos :: [Token] -> (Args, [Token]) collectPos tokens = (pos, rest) where (posargs, rest) = span isPos tokens pos = map getWord posargs parseFlag :: [Token] -> Maybe ((Arg, Args), [Token]) parseFlag tokens = case tokens of Token Flag word : othertokens -> Just ((word, args), rest) where (args, rest) = collectPos othertokens _ -> Nothing