\subsection{Option handling} You know the drill... \begin{code} module Lib.Options (version,usage,getOptions,Opts(..),parseargs,MaskWith(..)) where import System.Environment (getArgs) import System.Console.GetOpt import System.Exit version, usagemsg :: String version = "0.8.6" usagemsg = "Usage: rbr [-k ] [options] FILE.." getOptions :: IO ([Opts -> IO Opts], [String], [String]) getOptions = getArgs >>= (return . getOpt Permute options) usage :: [String] -> String usage errs = usageInfo (concat errs ++ usagemsg) options data MaskWith = Lower | Ns | Xs options :: [OptDescr (Opts -> IO Opts)] options = [Option ['k'] ["word-size"] (ReqArg (\arg opt -> return opt { kval = read arg }) "Int") "Word size" ,Option [] ["sparse-keys"] (ReqArg (\arg opt -> return opt { skip = read arg }) "Int") "Skip length" -- ,Option [] ["shape"] (ReqArg ...) "Key shape" ,Option ['N'] ["no-stats"] (NoArg (\opt -> return opt { stats = False })) "Omit statistical masking" ,Option ['M'] ["mask-sample"] (ReqArg (\arg opt -> return opt { masksample = Just arg }) "file") "Sample to use for building masking index" ,Option ['g'] ["gapclosing"] (ReqArg (\arg opt -> return opt { gap = read arg }) "Int") "Close gaps" ,Option ['s'] ["stringency"] (ReqArg (\arg opt -> return opt { string = read arg }) "Float") "Mask stringecy" ,Option ['t'] ["threshold"] (ReqArg (\arg opt -> return opt { thresh = read arg }) "Float") "Mask threshold" ,Option [] ["preserve-lower-case"] (NoArg (\opt -> return opt { preserve_lower = True })) "Preserve lower case in input sequences" ,Option ['D'] ["distribution"] (NoArg (\opt -> return opt { distr = True })) "Distribution output" ,Option ['l'] ["library"] (ReqArg (\arg opt -> return opt {lib = arg : lib opt}) "file") "Mask words from library" ,Option ['L'] ["lower-case"] (NoArg (\opt -> return opt { lower = Lower })) "Mask using lower case letters" ,Option ['n'] ["n-mask"] (NoArg (\opt -> return opt { lower = Ns })) "Mask using 'n's" ,Option ['x'] ["x-mask"] (NoArg (\opt -> return opt { lower = Xs })) "Mask using 'X's" ,Option [] ["server"] (NoArg (\opt -> return opt { server = True })) "Run in server mode" ,Option ['o'] ["output-file"] (ReqArg (\arg opt -> return opt { ofile = Just arg }) "file") "Output file" ,Option ['v'] ["verbose"] (NoArg (\opt -> return opt { verb = True })) "Display progress" ,Option ['h'] ["help"] (NoArg (\_ -> do {putStrLn $ usage []; exitWith ExitSuccess })) "Display help" ,Option ['V'] ["version"] (NoArg (\_ -> do {putStrLn $ "rbr version "++version; exitWith ExitSuccess })) "Display version" ] data Opts = Opts { kval :: Int, ofile :: Maybe FilePath , stats, preserve_lower :: Bool , thresh, string :: Double , gap :: Int , lower :: MaskWith , distr, verb, server :: Bool , lib :: [FilePath] , skip :: Int , masksample :: Maybe FilePath } defaultopts :: Opts defaultopts = Opts 16 Nothing True False 0 0 0 Lower False False False [] 0 Nothing parseargs :: [Opts -> IO Opts] -> IO Opts parseargs args = foldl (>>=) (return defaultopts) args >>= fixS >>= fixT where fixS opts = return $ case (string opts,lower opts) of -- sensible(?) defaults (0,Ns) -> opts { string = 2.0 } (0,Xs) -> opts { string = 2.0 } (0,Lower) -> opts { string = 1.1 } _ -> opts fixT opts = return $ case (thresh opts,lower opts) of -- sensible(?) defaults (0,Ns) -> opts { thresh = 8.0 } (0,Xs) -> opts { thresh = 8.0 } (0,Lower) -> opts { thresh = 5.0 } _ -> opts \end{code}