\subsection{Option handling} You know the drill... \begin{code} module Options (version,usage,getOptions,Opts(..),parseargs,MaskWith(..)) where import System (getArgs) import System.Console.GetOpt import System.Exit version, usagemsg :: String version = "0.8" 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 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 ['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 ['D'] ["distribution"] (NoArg (\opt -> return opt { distr = True })) "Distribution output" ,Option ['l'] ["library"] (ReqArg (\arg opt -> return opt {lib = Just arg}) "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 [] ["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 :: Bool , thresh, string :: Double , gap :: Int , lower :: MaskWith , distr, verb, server :: Bool , lib :: Maybe FilePath , skip :: Int } defaultopts :: Opts defaultopts = Opts 16 Nothing True 0 0 0 Lower False False False Nothing 0 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,Lower) -> opts { string = 1.1 } _ -> opts fixT opts = return $ case (thresh opts,lower opts) of -- sensible(?) defaults (0,Ns) -> opts { thresh = 8.0 } (0,Lower) -> opts { thresh = 5.0 } _ -> opts \end{code}