{-# LANGUAGE LambdaCase #-}
module Language.EFLINT.Options where
import Language.EFLINT.Util
import Control.Monad (when)
import System.Directory
import System.IO.Unsafe
import Data.IORef
type Options = IORef OptionsStruct
data OptionsStruct = OptionsStruct {
OptionsStruct -> [FilePath]
include_paths :: [FilePath]
, OptionsStruct -> [FilePath]
included_files :: [FilePath]
, OptionsStruct -> Maybe FilePath
filepath :: Maybe FilePath
, OptionsStruct -> [Bool]
input :: [Bool]
, OptionsStruct -> Bool
ignore_scenario :: Bool
, OptionsStruct -> Bool
debug :: Bool
, OptionsStruct -> Bool
accept_phrases :: Bool
, OptionsStruct -> Bool
test_mode :: Bool
}
find :: (OptionsStruct -> a) -> Options -> a
find :: forall a. (OptionsStruct -> a) -> Options -> a
find OptionsStruct -> a
proj = OptionsStruct -> a
proj forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IO a -> a
unsafePerformIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IORef a -> IO a
readIORef
defaultOptionsStruct :: OptionsStruct
defaultOptionsStruct = OptionsStruct {
include_paths :: [FilePath]
include_paths = []
, included_files :: [FilePath]
included_files = []
, filepath :: Maybe FilePath
filepath = forall a. Maybe a
Nothing
, input :: [Bool]
input = []
, ignore_scenario :: Bool
ignore_scenario = Bool
False
, debug :: Bool
debug = Bool
False
, test_mode :: Bool
test_mode = Bool
False
, accept_phrases :: Bool
accept_phrases = Bool
False
}
is_in_test_mode :: Options -> IO Bool
is_in_test_mode :: Options -> IO Bool
is_in_test_mode Options
opts = OptionsStruct -> Bool
test_mode forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. IORef a -> IO a
readIORef Options
opts
run_options :: [String] -> IO Options
run_options :: [FilePath] -> IO Options
run_options [FilePath]
args = do
Options
ref <- forall a. a -> IO (IORef a)
newIORef OptionsStruct
defaultOptionsStruct
[FilePath] -> Options -> IO ()
run_options' [FilePath]
args Options
ref
forall (m :: * -> *) a. Monad m => a -> m a
return Options
ref
where
run_options' :: [FilePath] -> Options -> IO ()
run_options' [] Options
opts = forall (m :: * -> *) a. Monad m => a -> m a
return ()
run_options' (FilePath
"--ignore-scenario":[FilePath]
args) Options
opts = do
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef Options
opts (\OptionsStruct
os -> OptionsStruct
os { ignore_scenario :: Bool
ignore_scenario = Bool
True } )
[FilePath] -> Options -> IO ()
run_options' [FilePath]
args Options
opts
run_options' (FilePath
"--debug":[FilePath]
args) Options
opts = do
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef Options
opts (\OptionsStruct
os -> OptionsStruct
os { debug :: Bool
debug = Bool
True })
[FilePath] -> Options -> IO ()
run_options' [FilePath]
args Options
opts
run_options' (FilePath
"--test-mode":[FilePath]
args) Options
opts = do
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef Options
opts (\OptionsStruct
os -> OptionsStruct
os { test_mode :: Bool
test_mode = Bool
True })
[FilePath] -> Options -> IO ()
run_options' [FilePath]
args Options
opts
run_options' (FilePath
"--accept-phrases":[FilePath]
args) Options
opts = do
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef Options
opts (\OptionsStruct
os -> OptionsStruct
os { accept_phrases :: Bool
accept_phrases = Bool
True })
[FilePath] -> Options -> IO ()
run_options' [FilePath]
args Options
opts
run_options' (FilePath
"-i":(FilePath
sdir:[FilePath]
args)) Options
opts = FilePath -> Options -> IO ()
add_include_path FilePath
sdir Options
opts forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [FilePath] -> Options -> IO ()
run_options' [FilePath]
args Options
opts
run_options' (FilePath
_:[FilePath]
args) Options
opts = [FilePath] -> Options -> IO ()
run_options' [FilePath]
args Options
opts
add_include_path :: String -> Options -> IO ()
add_include_path :: FilePath -> Options -> IO ()
add_include_path FilePath
fp Options
opts = FilePath -> IO Bool
doesDirectoryExist FilePath
fp forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
False -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
Bool
True -> forall a. IORef a -> (a -> a) -> IO ()
modifyIORef Options
opts (\OptionsStruct
os -> OptionsStruct
os {include_paths :: [FilePath]
include_paths = OptionsStruct -> [FilePath]
include_paths OptionsStruct
os forall a. [a] -> [a] -> [a]
++ [FilePath
fp] })
add_include :: String -> Options -> IO ()
add_include :: FilePath -> Options -> IO ()
add_include FilePath
fp Options
opts = FilePath -> IO Bool
doesFileExist FilePath
fp forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
False -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
Bool
True -> forall a. IORef a -> (a -> a) -> IO ()
modifyIORef Options
opts (\OptionsStruct
os -> OptionsStruct
os {included_files :: [FilePath]
included_files = OptionsStruct -> [FilePath]
included_files OptionsStruct
os forall a. [a] -> [a] -> [a]
++ [FilePath
fp] })
has_been_included :: FilePath -> Options -> Bool
has_been_included :: FilePath -> Options -> Bool
has_been_included FilePath
file Options
opts = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
[FilePath]
dirs <- OptionsStruct -> [FilePath]
include_paths forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. IORef a -> IO a
readIORef Options
opts
[FilePath]
files <- OptionsStruct -> [FilePath]
included_files forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. IORef a -> IO a
readIORef Options
opts
[FilePath] -> FilePath -> IO [FilePath]
find_included_file [FilePath]
dirs FilePath
file forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
[] -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
(FilePath
file:[FilePath]
_) -> forall (m :: * -> *) a. Monad m => a -> m a
return (FilePath
file forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [FilePath]
files)
add_filepath :: FilePath -> Options -> IO ()
add_filepath :: FilePath -> Options -> IO ()
add_filepath FilePath
fp Options
opts = do forall a. IORef a -> (a -> a) -> IO ()
modifyIORef Options
opts (\OptionsStruct
os -> OptionsStruct
os { filepath :: Maybe FilePath
filepath = forall a. a -> Maybe a
Just FilePath
fp })
add_input :: [String] -> Options -> IO ()
add_input :: [FilePath] -> Options -> IO ()
add_input [FilePath]
ss Options
opts = forall a. IORef a -> (a -> a) -> IO ()
modifyIORef Options
opts (\OptionsStruct
os -> OptionsStruct
os { input :: [Bool]
input = forall a b. (a -> b) -> [a] -> [b]
map FilePath -> Bool
readAssignmentMaybe [FilePath]
ss })
consume_input :: Options -> IO (Maybe Bool)
consume_input :: Options -> IO (Maybe Bool)
consume_input Options
opts = do
OptionsStruct
optss <- forall a. IORef a -> IO a
readIORef Options
opts
case OptionsStruct -> [Bool]
input OptionsStruct
optss of
[] -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
[Bool]
bs -> do forall a. IORef a -> (a -> a) -> IO ()
modifyIORef Options
opts (\OptionsStruct
os -> OptionsStruct
os { input :: [Bool]
input = forall a. [a] -> [a]
tail [Bool]
bs })
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. [a] -> a
head [Bool]
bs)
readAssignmentMaybe :: String -> Bool
readAssignmentMaybe :: FilePath -> Bool
readAssignmentMaybe FilePath
s = case FilePath
s of
FilePath
"True" -> Bool
True
FilePath
"true" -> Bool
True
FilePath
"t" -> Bool
True
FilePath
"T" -> Bool
True
FilePath
"y" -> Bool
True
FilePath
"Y" -> Bool
True
FilePath
"False" -> Bool
False
FilePath
"false" -> Bool
False
FilePath
"f" -> Bool
False
FilePath
"F" -> Bool
False
FilePath
"N" -> Bool
False
FilePath
"n" -> Bool
False
FilePath
_ -> Bool
False
verbosity :: Options -> Level -> IO () -> IO ()
verbosity :: Options -> Level -> IO () -> IO ()
verbosity Options
opts Level
loc_level IO ()
m = do
Level
limit <- OptionsStruct -> Level
limitM forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. IORef a -> IO a
readIORef Options
opts
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Level
loc_level forall a. Ord a => a -> a -> Bool
<= Level
limit) IO ()
m
where limitM :: OptionsStruct -> Level
limitM OptionsStruct
opts | OptionsStruct -> Bool
debug OptionsStruct
opts = Level
Verbose
| OptionsStruct -> Bool
test_mode OptionsStruct
opts = Level
TestMode
| Bool
otherwise = Level
Default
data Level = TestMode | Default | Verbose deriving (Eq Level
Level -> Level -> Bool
Level -> Level -> Ordering
Level -> Level -> Level
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Level -> Level -> Level
$cmin :: Level -> Level -> Level
max :: Level -> Level -> Level
$cmax :: Level -> Level -> Level
>= :: Level -> Level -> Bool
$c>= :: Level -> Level -> Bool
> :: Level -> Level -> Bool
$c> :: Level -> Level -> Bool
<= :: Level -> Level -> Bool
$c<= :: Level -> Level -> Bool
< :: Level -> Level -> Bool
$c< :: Level -> Level -> Bool
compare :: Level -> Level -> Ordering
$ccompare :: Level -> Level -> Ordering
Ord, Int -> Level
Level -> Int
Level -> [Level]
Level -> Level
Level -> Level -> [Level]
Level -> Level -> Level -> [Level]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Level -> Level -> Level -> [Level]
$cenumFromThenTo :: Level -> Level -> Level -> [Level]
enumFromTo :: Level -> Level -> [Level]
$cenumFromTo :: Level -> Level -> [Level]
enumFromThen :: Level -> Level -> [Level]
$cenumFromThen :: Level -> Level -> [Level]
enumFrom :: Level -> [Level]
$cenumFrom :: Level -> [Level]
fromEnum :: Level -> Int
$cfromEnum :: Level -> Int
toEnum :: Int -> Level
$ctoEnum :: Int -> Level
pred :: Level -> Level
$cpred :: Level -> Level
succ :: Level -> Level
$csucc :: Level -> Level
Enum, Level -> Level -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Level -> Level -> Bool
$c/= :: Level -> Level -> Bool
== :: Level -> Level -> Bool
$c== :: Level -> Level -> Bool
Eq)