module Mueval.ArgsParse (Options(..), interpreterOpts) where
import Control.Monad (liftM)
import System.Console.GetOpt
import Mueval.Context (defaultModules, defaultPackages)
data Options = Options
{ Options -> Int
timeLimit :: Int
, Options -> Maybe [String]
modules :: Maybe [String]
, Options -> String
expression :: String
, Options -> String
loadFile :: String
, Options -> String
user :: String
, Options -> Bool
printType :: Bool
, Options -> Bool
typeOnly :: Bool
, Options -> Bool
extensions :: Bool
, Options -> [String]
namedExtensions :: [String]
, Options -> Bool
noImports :: Bool
, Options -> Bool
rLimits :: Bool
, Options -> Bool
packageTrust :: Bool
, Options -> [String]
trustedPackages :: [String]
, Options -> Bool
help :: Bool
} deriving Int -> Options -> ShowS
[Options] -> ShowS
Options -> String
(Int -> Options -> ShowS)
-> (Options -> String) -> ([Options] -> ShowS) -> Show Options
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Options] -> ShowS
$cshowList :: [Options] -> ShowS
show :: Options -> String
$cshow :: Options -> String
showsPrec :: Int -> Options -> ShowS
$cshowsPrec :: Int -> Options -> ShowS
Show
defaultOptions :: Options
defaultOptions :: Options
defaultOptions = Options :: Int
-> Maybe [String]
-> String
-> String
-> String
-> Bool
-> Bool
-> Bool
-> [String]
-> Bool
-> Bool
-> Bool
-> [String]
-> Bool
-> Options
Options { expression :: String
expression = ""
, modules :: Maybe [String]
modules = [String] -> Maybe [String]
forall a. a -> Maybe a
Just [String]
defaultModules
, timeLimit :: Int
timeLimit = 5
, user :: String
user = ""
, loadFile :: String
loadFile = ""
, printType :: Bool
printType = Bool
False
, typeOnly :: Bool
typeOnly = Bool
False
, extensions :: Bool
extensions = Bool
False
, namedExtensions :: [String]
namedExtensions = []
, noImports :: Bool
noImports = Bool
False
, rLimits :: Bool
rLimits = Bool
False
, packageTrust :: Bool
packageTrust = Bool
False
, trustedPackages :: [String]
trustedPackages = [String]
defaultPackages
, help :: Bool
help = Bool
False }
options :: [OptDescr (Options -> Options)]
options :: [OptDescr (Options -> Options)]
options = [String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "p" ["password"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\u :: String
u opts :: Options
opts -> Options
opts {user :: String
user = String
u}) "PASSWORD")
"The password for the mubot account. If this is set, mueval will attempt to setuid to the mubot user. This is optional, as it requires the mubot user to be set up properly. (Currently a null-op.)",
String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "t" ["time-limit"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\t :: String
t opts :: Options
opts -> Options
opts { timeLimit :: Int
timeLimit = String -> Int
forall a. Read a => String -> a
read String
t :: Int }) "TIME")
"Time limit for compilation and evaluation",
String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "l" ["load-file"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\e :: String
e opts :: Options
opts -> Options
opts { loadFile :: String
loadFile = String
e}) "FILE")
"A local file for Mueval to load, providing definitions. Contents are trusted! Do not put anything dubious in it!",
String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "m" ["module"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\m :: String
m opts :: Options
opts -> Options
opts { modules :: Maybe [String]
modules = ([String] -> [String]) -> Maybe [String] -> Maybe [String]
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (String
mString -> [String] -> [String]
forall a. a -> [a] -> [a]
:) (Options -> Maybe [String]
modules Options
opts)}) "MODULE")
"A module we should import functions from for evaluation. (Can be given multiple times.)",
String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "n" ["no-imports"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\opts :: Options
opts -> Options
opts { noImports :: Bool
noImports = Bool
True}))
"Whether to import any default modules, such as Prelude; this is useful if you are loading a file which, say, redefines Prelude operators. This can be subverted by using --load-file.",
String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "E" ["Extensions"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\opts :: Options
opts -> Options
opts { extensions :: Bool
extensions = Bool
True}))
"Whether to enable the Glasgow extensions to Haskell '98. Defaults to false, but enabling is useful for QuickCheck.",
String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "X" ["extension"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\e :: String
e opts :: Options
opts -> Options
opts { namedExtensions :: [String]
namedExtensions = String
e String -> [String] -> [String]
forall a. a -> [a] -> [a]
: Options -> [String]
namedExtensions Options
opts }) "EXTENSION")
"Pass additional flags enabling extensions just like you would to ghc. Example: -XViewPatterns",
String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "e" ["expression"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\e :: String
e opts :: Options
opts -> Options
opts { expression :: String
expression = String
e}) "EXPRESSION")
"The expression to be evaluated.",
String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "i" ["inferred-type"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\opts :: Options
opts -> Options
opts { printType :: Bool
printType = Bool
True}))
"Whether to enable printing of inferred type and the expression (as Mueval sees it). Defaults to false.",
String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "T" ["type-only"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\opts :: Options
opts -> Options
opts { typeOnly :: Bool
typeOnly = Bool
True}))
"Only print the expression and type, don't evaluate the expression. Defaults to false.",
String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "r" ["resource-limits"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\opts :: Options
opts -> Options
opts { rLimits :: Bool
rLimits = Bool
True}))
"Enable resource limits (using POSIX rlimits). Mueval does not by default since rlimits are broken on many systems.",
String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "S" ["package-trust"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\opts :: Options
opts -> Options
opts {packageTrust :: Bool
packageTrust = Bool
True, namedExtensions :: [String]
namedExtensions = "Safe" String -> [String] -> [String]
forall a. a -> [a] -> [a]
: Options -> [String]
namedExtensions Options
opts}))
"Enable Safe-Haskell package trust system",
String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "s" ["trust"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\e :: String
e opts :: Options
opts -> Options
opts {trustedPackages :: [String]
trustedPackages = String
e String -> [String] -> [String]
forall a. a -> [a] -> [a]
: Options -> [String]
trustedPackages Options
opts}) "PACKAGE")
"Specify a package to be trusted by Safe Haskell (ignored unless -S also present)",
String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option "h" ["help"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\opts :: Options
opts -> Options
opts { help :: Bool
help = Bool
True}))
"Prints out usage info."
]
interpreterOpts :: [String] -> Either (Bool, String) Options
interpreterOpts :: [String] -> Either (Bool, String) Options
interpreterOpts argv :: [String]
argv
| Options -> Bool
help Options
opts = (Bool, String) -> Either (Bool, String) Options
forall a b. a -> Either a b
Left (Bool
True,String
msg)
| Bool -> Bool
not ([String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
ers) = (Bool, String) -> Either (Bool, String) Options
forall a b. a -> Either a b
Left (Bool
False, [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
ers String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
msg)
| Bool
otherwise = Options -> Either (Bool, String) Options
forall a b. b -> Either a b
Right Options
opts
where (o :: [Options -> Options]
o,_,ers :: [String]
ers) = ArgOrder (Options -> Options)
-> [OptDescr (Options -> Options)]
-> [String]
-> ([Options -> Options], [String], [String])
forall a.
ArgOrder a -> [OptDescr a] -> [String] -> ([a], [String], [String])
getOpt ArgOrder (Options -> Options)
forall a. ArgOrder a
Permute [OptDescr (Options -> Options)]
options [String]
argv
msg :: String
msg = String -> [OptDescr (Options -> Options)] -> String
forall a. String -> [OptDescr a] -> String
usageInfo String
header [OptDescr (Options -> Options)]
options
opts :: Options
opts = (Options -> (Options -> Options) -> Options)
-> Options -> [Options -> Options] -> Options
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (((Options -> Options) -> Options -> Options)
-> Options -> (Options -> Options) -> Options
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Options -> Options) -> Options -> Options
forall a. a -> a
id) Options
defaultOptions [Options -> Options]
o
header :: String
= "Usage: mueval [OPTION...] --expression EXPRESSION..."