hgom-0.5.1: Gom/Config.hs
-------------------------------------------------------------------
-- |
-- Module : Gom.Config
-- Copyright : (c) Paul Brauner 2009
-- (c) Emilie Balland 2009
-- (c) INRIA 2009
-- Licence : GPL (see COPYING)
--
-- Maintainer : paul.brauner@inria.fr
-- Stability : provisional
-- Portability : non-portable (requires generalized newtype deriving)
--
-- Handle user args.
--------------------------------------------------------------------
module Gom.Config (
Config(..),
CongrOpt(..),
gomOpts,
usage,
paramsError
) where
import Control.Monad.Error
import Data.Foldable(foldlM)
import System.Console.GetOpt
-- | Datatype representing the parameters passed to hgom by the user.
data Config =
Config {
help :: Bool, -- ^ display help message ?
version :: Bool, -- ^ display version information ?
package :: Maybe [String], -- ^ optional package prefix
prprint :: Bool, -- ^ pretty-print module and exit ?
#if TEST
utests :: Maybe [String], -- ^ run unit tests ?
#endif
haskell :: Bool, -- ^ generate @toHaskell@ methods ?
visit :: Bool, -- ^ implement @Visitable@ ?
checker :: Bool, -- ^ perform checks ?
congr :: CongrOpt, -- ^ generate congruence strategies ?
oomapping :: Bool, -- ^ generate oo mappings?
sharing :: Bool, -- ^ maximally share terms ?
compact :: Bool, -- ^ generate compact code ?
parsers :: Bool, -- ^ generate @from*@ methods ?
random :: Bool, -- ^ generate @makeRandom@ methods ?
depth :: Bool, -- ^ generate @depth@ methods ?
size :: Bool -- ^ generate @size@ methods ?
}
-- | Default configuration.
defaultConfig :: Config
defaultConfig =
Config {
help = False,
version = False,
package = Nothing,
prprint = False,
#if TEST
utests = Nothing,
#endif
haskell = False,
visit = True,
checker = True,
congr = NoCongr,
oomapping = False,
sharing = True,
compact = False,
parsers = True,
random = False,
depth = False,
size = False
}
-- | Represents the three options values for @--withCongruenceStrategies@
data CongrOpt = NoCongr | SameFile | SeparateFile
-- | Pyhton-like split function.
-- @split \'x\' \"aaxbbxcc\" = [\"aa\",\"bb\",\"cc\"]@
split :: Char -> String -> [String]
split _ [] = []
split c (x:xs)
| x == c = split c xs
| otherwise = let (xs1,xs2) = break (== c) (x:xs)
in xs1:split c xs2
-- | Options description for 'getOpt'.
options :: [OptDescr (Config -> Either String Config)]
options =
[Option [] ["help"] (NoArg chelp)
"show this message and exit"
,Option ['V'] ["version"] (NoArg cversion)
"show version number and exit"
,Option ['P'] ["pretty"] (NoArg cpretty)
"pretty-print the module and exit"
#if TEST
,Option [] ["test"] (ReqArg cutests "args")
(unlines ["run test suite with args"])
#endif
,Option ['p'] ["package"] (ReqArg cpackage "packageName")
"specify package name"
,Option ['c'] ["congruence"] (ReqArg ccongr "(same|sep)")
(unlines ["generate congruence strategies in",
"the same or in a separate .tom file"])
,Option ['r'] ["random"] (NoArg crandom)
"generate makeRamdom methods"
,Option ['j'] ["oomappings"] (NoArg coomapping)
"generate only Java OO mappings"
,Option ['d'] ["depth"] (NoArg cdepth)
"generate depth methods"
,Option ['s'] ["size"] (NoArg csize)
"generate size methods"
,Option ['h'] ["haskell"] (NoArg chaskell)
"generate 'toHaskell' methods"
,Option [] ["noSharing"] (NoArg csharing)
"don't share structurally equal terms"
,Option [] ["noVisitable"] (NoArg cvisit)
"don't implement Visitable"
,Option [] ["noParsers"] (NoArg cparsers)
"don't generate from* methods"
,Option [] ["noCheck"] (NoArg ccheck)
"don't perform consistency checks"
,Option [] ["compact"] (NoArg ccompact)
"generate compact code (no indentation)"]
where chelp c = return $ c { help = True }
cversion c = return $ c { version = True }
cpretty c = return $ c { prprint = True }
chaskell c = return $ c { haskell = True }
cvisit c = return $ c { visit = False }
ccheck c = return $ c { checker = False }
csharing c = return $ c { sharing = False }
ccompact c = return $ c { compact = True }
cparsers c = return $ c { parsers = False }
crandom c = return $ c { random = True }
coomapping c = return $ c { oomapping = True }
cdepth c = return $ c { depth = True }
csize c = return $ c { size = True }
#if TEST
cutests s c = return $ c { utests = Just (words s) }
#endif
cpackage p c = return $ c { package = Just (split '.' p) }
ccongr "same" c = return $ c { congr = SameFile }
ccongr "sep" c = return $ c { congr = SeparateFile }
ccongr _ _ = throwError
"'--congruence' argument must be 'same' or 'sep'.\n"
-- | Usage info message header : @Usage: hgom [OPTION...] file@.
header :: String
header = "Usage: hgom [OPTION...] file"
-- | Usage info message.
usage :: String
usage = usageInfo header options
-- | Parse user args. Returns either an error message,
-- either a configuration along with unparsed arguments.
gomOpts :: [String] -> Either String (Config,[String])
gomOpts argv =
case getOpt Permute options argv of
(o,n,[] ) -> do conf <- foldlM (\c f -> f c) defaultConfig o
return (conf,n)
(_,_,errs) -> throwError $ concat errs
-- | Report an error concerning user args (includes usage info reminder).
paramsError :: String -> IO a
paramsError err = error (err ++ usageInfo header options)