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
$cshowsPrec :: Int -> Options -> ShowS
showsPrec :: Int -> Options -> ShowS
$cshow :: Options -> String
show :: Options -> String
$cshowList :: [Options] -> ShowS
showList :: [Options] -> ShowS
Show)
defaultOptions :: Options
defaultOptions :: Options
defaultOptions =
Options
{ expression :: String
expression = String
""
, modules :: Maybe [String]
modules = [String] -> Maybe [String]
forall a. a -> Maybe a
Just [String]
defaultModules
, timeLimit :: Int
timeLimit = Int
5
, user :: String
user = String
""
, loadFile :: String
loadFile = String
""
, 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
String
"p"
[String
"password"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
u Options
opts -> Options
opts{user = u}) String
"PASSWORD")
String
"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
String
"t"
[String
"time-limit"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
t Options
opts -> Options
opts{timeLimit = read t :: Int}) String
"TIME")
String
"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
String
"l"
[String
"load-file"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
e Options
opts -> Options
opts{loadFile = e}) String
"FILE")
String
"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
String
"m"
[String
"module"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
m Options
opts -> Options
opts{modules = liftM (m :) (modules opts)}) String
"MODULE")
String
"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
String
"n"
[String
"no-imports"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\Options
opts -> Options
opts{noImports = True}))
String
"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
String
"E"
[String
"Extensions"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\Options
opts -> Options
opts{extensions = True}))
String
"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
String
"X"
[String
"extension"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
e Options
opts -> Options
opts{namedExtensions = e : namedExtensions opts}) String
"EXTENSION")
String
"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
String
"e"
[String
"expression"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
e Options
opts -> Options
opts{expression = e}) String
"EXPRESSION")
String
"The expression to be evaluated."
, String
-> [String]
-> ArgDescr (Options -> Options)
-> String
-> OptDescr (Options -> Options)
forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option
String
"i"
[String
"inferred-type"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\Options
opts -> Options
opts{printType = True}))
String
"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
String
"T"
[String
"type-only"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\Options
opts -> Options
opts{typeOnly = True}))
String
"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
String
"r"
[String
"resource-limits"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\Options
opts -> Options
opts{rLimits = True}))
String
"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
String
"S"
[String
"package-trust"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\Options
opts -> Options
opts{packageTrust = True, namedExtensions = "Safe" : namedExtensions opts}))
String
"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
String
"s"
[String
"trust"]
((String -> Options -> Options)
-> String -> ArgDescr (Options -> Options)
forall a. (String -> a) -> String -> ArgDescr a
ReqArg (\String
e Options
opts -> Options
opts{trustedPackages = e : trustedPackages opts}) String
"PACKAGE")
String
"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
String
"h"
[String
"help"]
((Options -> Options) -> ArgDescr (Options -> Options)
forall a. a -> ArgDescr a
NoArg (\Options
opts -> Options
opts{help = True}))
String
"Prints out usage info."
]
interpreterOpts :: [String] -> Either (Bool, String) Options
interpreterOpts :: [String] -> Either (Bool, String) Options
interpreterOpts [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 a. [a] -> 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
([Options -> Options]
o, [String]
_, [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 b a. (b -> a -> b) -> b -> [a] -> b
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
= String
"Usage: mueval [OPTION...] --expression EXPRESSION..."