fortran-src-extras-0.1.0: src/Language/Fortran/Extras/RunOptions.hs
{-# LANGUAGE FlexibleInstances #-}
-- | This module is responsible for handling CLI options
module Language.Fortran.Extras.RunOptions
( FortranSrcRunOptions(..)
, getFortranSrcRunOptions
, unwrapFortranSrcOptions
, RunOptions(..)
, getRunOptions
)
where
import qualified Data.ByteString.Char8 as B
import Data.Char ( toLower )
import Data.List ( isInfixOf )
import Data.Semigroup ( (<>) )
import Language.Fortran.Version ( FortranVersion(..)
, selectFortranVersion
)
import Options.Applicative
import Language.Fortran.Util.Files
( flexReadFile )
-- | Holds fortran-src specific CLI options.
-- This includes the version of the parser, included files and the path
-- of the source
data FortranSrcRunOptions = FortranSrcRunOptions
{ version :: !FortranVersion
, includes :: ![String]
, path :: !String
} deriving Show
-- | Provided version, includes and path strings, this functon maps them to
-- 'FortranSrcRunOptions'
--
-- Note that this will throw an exception on an unrecognized version string.
toFortranSrcOptions :: String -> [String] -> String -> FortranSrcRunOptions
toFortranSrcOptions verStr =
let (Just ver) = selectFortranVersion verStr
in FortranSrcRunOptions ver
-- | Definition of parser for 'FortranSrcRunOptions'
fortranSrcRunOptionsParser :: Parser FortranSrcRunOptions
fortranSrcRunOptionsParser =
toFortranSrcOptions
<$> strOption
( short 'v'
<> long "fortranVersion"
<> metavar "VERSION"
<> help
"Fortran version to use, format: Fortran[66/77/77l/77e/90/95/03/08]"
)
<*> many
(strOption
(short 'I' <> long "include" <> metavar "DIRECTORY" <> help
"Directory to include files from"
)
)
<*> argument str (metavar "PATH")
-- | Given description and header, decorate fortran-src options parser with
-- info details
fortranSrcRunOptionsInfo :: String -> String -> ParserInfo FortranSrcRunOptions
fortranSrcRunOptionsInfo programDescription headerDescription = info
(helper <*> fortranSrcRunOptionsParser)
(fullDesc <> progDesc programDescription <> header headerDescription)
-- | Given description and header, execute fortran-src options parser
-- and get the 'FortranSrcRunOptions'
getFortranSrcRunOptions :: String -> String -> IO FortranSrcRunOptions
getFortranSrcRunOptions programDescription headerDescription =
execParser $ fortranSrcRunOptionsInfo programDescription headerDescription
-- | Obtain path, contents, include dirs and 'FortranVersion'
-- from 'FortranSrcRunOptions'
unwrapFortranSrcOptions
:: FortranSrcRunOptions -> IO (String, B.ByteString, [String], FortranVersion)
unwrapFortranSrcOptions options = do
let p = path options
c <- flexReadFile p
let i = includes options
v = version options
return (p, c, i, v)
-- | Holds 'FortranSrcRunOptions' and additional tool specific CLI options
data RunOptions a = RunOptions
{ fortranSrcOpts :: FortranSrcRunOptions
, toolOpts :: a
} deriving Show
-- | Given decription, header and tool options parser, decorate options
-- with info details
runOptionsInfo :: String -> String -> Parser a -> ParserInfo (RunOptions a)
runOptionsInfo programDescription headerDescription toolOptsParser = info
(helper <*> liftA2 RunOptions fortranSrcRunOptionsParser toolOptsParser)
(fullDesc <> progDesc programDescription <> header headerDescription)
-- | Given description, header and tool options parser, execute options parser
-- and get the 'RunOptions'
getRunOptions :: String -> String -> Parser a -> IO (RunOptions a)
getRunOptions programDescription headerDescription toolOptsParser =
execParser
$ runOptionsInfo programDescription headerDescription toolOptsParser