module UHC.Light.Compiler.Opts.CommandLine ( CmdFlag (..), Cmd (..), CmdLineOpt (..), CmdLineOpts , cppOpt, cppOptF, cppOptI, cppArg , gccOpt, gccArg, gccOptF, gccOptOutput, gccOptLib , showCmdLineOpts, showCmdLineOpts' , parseCmdLineOpts ) where import Data.List import Data.Typeable (Typeable) import UHC.Util.Binary import UHC.Util.Serialize import Control.Monad {-# LINE 29 "src/ehc/Opts/CommandLine.chs" #-} data CmdFlag = CmdFlag_Define String (Maybe String) | CmdFlag_Undefine String | CmdFlag_Flag String | CmdFlag_KeyEqualsVal String String | CmdFlag_KeyWithVal String String | CmdFlag_IncludeDir String | CmdFlag_Lib String -- (plain) args | CmdFlag_Arg String -- modifiers | CmdFlag_ModfMin CmdFlag -- double '-' deriving (Eq,Typeable) data Cmd = Cmd_CPP_Preprocessing | Cmd_CPP | Cmd_C deriving (Eq,Ord,Enum,Bounded,Typeable) data CmdLineOpt = CmdLineOpt { cloptForCmd :: Cmd , cloptFlag :: CmdFlag } deriving (Eq,Typeable) type CmdLineOpts = [CmdLineOpt] {-# LINE 66 "src/ehc/Opts/CommandLine.chs" #-} cppOpt :: CmdFlag -> CmdLineOpt cppOpt = CmdLineOpt Cmd_CPP cppArg :: String -> CmdLineOpt cppArg = cppOpt . CmdFlag_Arg cppOptF :: String -> CmdLineOpt cppOptF = cppOpt . CmdFlag_Flag cppOptI :: String -> CmdLineOpt cppOptI = cppOpt . CmdFlag_IncludeDir {-# LINE 80 "src/ehc/Opts/CommandLine.chs" #-} gccOpt :: CmdFlag -> CmdLineOpt gccOpt = CmdLineOpt Cmd_C gccArg :: String -> CmdLineOpt gccArg = gccOpt . CmdFlag_Arg gccOptF :: String -> CmdLineOpt gccOptF = gccOpt . CmdFlag_Flag gccOptOutput :: String -> CmdLineOpt gccOptOutput = gccOpt . CmdFlag_KeyWithVal "o" gccOptLib :: String -> CmdLineOpt gccOptLib = gccOpt . CmdFlag_Lib {-# LINE 101 "src/ehc/Opts/CommandLine.chs" #-} showCmdLineOpts' :: [Cmd] -> CmdLineOpts -> [String] showCmdLineOpts' forCmds opts = map show $ filter (\o -> cloptForCmd o `elem` forCmds) opts showCmdLineOpts :: CmdLineOpts -> String showCmdLineOpts = concat . intersperse " " . showCmdLineOpts' [minBound::Cmd .. maxBound] -- | Show key + value kv :: String -> String -> Maybe String -> String kv k sep mv = k ++ maybe "" (\v -> sep ++ v) mv instance Show CmdFlag where show (CmdFlag_Define k mv) = "-D" ++ kv k "=" mv show (CmdFlag_Undefine k ) = "-U" ++ k show (CmdFlag_Flag f ) = "-" ++ f show (CmdFlag_KeyEqualsVal k v) = "-" ++ kv k "=" (Just v) show (CmdFlag_KeyWithVal k v) = "-" ++ kv k " " (Just v) show (CmdFlag_IncludeDir d ) = "-I" ++ d show (CmdFlag_Lib l ) = "-l" ++ l show (CmdFlag_Arg a ) = a show (CmdFlag_ModfMin f ) = "-" ++ show f instance Show CmdLineOpt where show = show . cloptFlag {-# LINE 131 "src/ehc/Opts/CommandLine.chs" #-} -- | Parse commandline options into CmdLineOpts parseCmdLineOpts :: Cmd -> String -> (CmdLineOpts,[String]) parseCmdLineOpts cmd s = ([ CmdLineOpt cmd $ pOpt o | ('-':o) <- opts ],rest) where (opts,rest) = partition isOpt $ words s isOpt ('-':_) = True isOpt _ = False pOpt ('-':opt) = CmdFlag_ModfMin $ pOpt opt pOpt ('D':def) = uncurry CmdFlag_Define $ pDef def pOpt ('I':dir) = CmdFlag_IncludeDir dir pOpt ('l':lib) = CmdFlag_Lib lib pOpt s = case pDef s of (k, Just v) -> CmdFlag_KeyEqualsVal k v (k, _ ) -> CmdFlag_Flag k pDef s = case break (== '=') s of (k,'=':v) -> (k, Just v) _ -> (s, Nothing)