    {-# LANGUAGE DeriveAnyClass #-}
    {-# LANGUAGE DeriveFunctor #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE RecordWildCards #-}

    module Test.DocTest.Internal.Options where

    import           Prelude ()
    import           Prelude.Compat

    import           Control.DeepSeq (NFData)
    import           Data.List.Compat
    import           GHC.Generics (Generic)
    import           Text.Read (readMaybe)

    import qualified Paths_doctest_parallel
    import           Data.Version (showVersion)

    import           GHC.Settings.Config as GHC

    import           Test.DocTest.Internal.Location (Located (Located), Location)
    import           Test.DocTest.Internal.Interpreter (ghc)
    import           Test.DocTest.Internal.Logging (LogLevel(..))
    import qualified Test.DocTest.Internal.Logging as Logging

    usage :: String
    usage :: [Char]
    usage = [[Char]] -> [Char]
    unlines [
        [Char]
    "Usage:"
      , [Char]
    "  doctest [ options ]... [<module>]..."
      , [Char]
    "  doctest --help"
      , [Char]
    "  doctest --version"
      , [Char]
    "  doctest --info"
      , [Char]
    ""
      , [Char]
    "Options:"
      , [Char]
    "   -jN                      number of threads to use"
      , [Char]
    "   --log-level=LEVEL        one of: debug, verbose, info, warning, error. Default: info."
      , [Char]
    "   --ghc-arg=ARG            pass argument to GHC when parsing, pass multiple times for multiple flags"
      , [Char]
    "†  --implicit-module-import import module before testing it (default)"
      , [Char]
    "†  --randomize-order        randomize order in which tests are run"
      , [Char]
    "†  --seed=N                 use a specific seed to randomize test order"
      , [Char]
    "†  --preserve-it            preserve the `it` variable between examples"
      , [Char]
    "   --nix                    account for Nix build environments (default)"
      , [Char]
    "   --quiet                  set log level to `Error`, shorthand for `--log-level=error`"
      , [Char]
    "   --verbose                set log level to `Verbose`, shorthand for `--log-level=verbose`"
      , [Char]
    "   --debug                  set log level to `Debug`, shorthand for `--log-level=debug`"
      , [Char]
    "   --help                   display this help and exit"
      , [Char]
    "   --version                output version information and exit"
      , [Char]
    "   --info                   output machine-readable version information and exit"
      , [Char]
    ""
      , [Char]
    "Supported inverted options:"
      , [Char]
    "   --no-nix"
      , [Char]
    "†  --no-implicit-module-import"
      , [Char]
    "†  --no-randomize-order (default)"
      , [Char]
    "†  --no-preserve-it (default)"
      , [Char]
    ""
      , [Char]
    "Options marked with a dagger (†) can also be used to set module level options, using"
      , [Char]
    "an ANN pragma like this:"
      , [Char]
    ""
      , [Char]
    "  {-# ANN module \"doctest-parallel: --no-randomize-order\" #-} "
      , [Char]
    ""
      ]

    version :: String
    version :: [Char]
    version = Version -> [Char]
    showVersion Version
    Paths_doctest_parallel.version

    ghcVersion :: String
    ghcVersion :: [Char]
    ghcVersion = [Char]
    GHC.cProjectVersion

    versionInfo :: String
    versionInfo :: [Char]
    versionInfo = [[Char]] -> [Char]
    unlines [
        [Char]
    "doctest version " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    version
      , [Char]
    "using version " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ghcVersion [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " of the GHC API"
      , [Char]
    "using " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ghc
      ]

    info :: String
    info :: [Char]
    info = [Char]
    "[ " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ ([Char] -> [[Char]] -> [Char]
    forall a. [a] -> [[a]] -> [a]
    intercalate [Char]
    "\n, " ([[Char]] -> [Char])
    -> ([([Char], [Char])] -> [[Char]]) -> [([Char], [Char])] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (([Char], [Char]) -> [Char]) -> [([Char], [Char])] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map ([Char], [Char]) -> [Char]
    forall a. Show a => a -> [Char]
    show ([([Char], [Char])] -> [Char]) -> [([Char], [Char])] -> [Char]
    forall a b. (a -> b) -> a -> b
    $ [
        ([Char]
    "version", [Char]
    version)
      , ([Char]
    "ghc_version", [Char]
    ghcVersion)
      , ([Char]
    "ghc", [Char]
    ghc)
      ]) [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "\n]\n"

    data Result a
      = ResultStderr String
      | ResultStdout String
      | Result a
      deriving (Result a -> Result a -> Bool
    (Result a -> Result a -> Bool)
    -> (Result a -> Result a -> Bool) -> Eq (Result a)
    forall a. Eq a => Result a -> Result a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. Eq a => Result a -> Result a -> Bool
    == :: Result a -> Result a -> Bool
    $c/= :: forall a. Eq a => Result a -> Result a -> Bool
    /= :: Result a -> Result a -> Bool
    Eq, Int -> Result a -> [Char] -> [Char]
    [Result a] -> [Char] -> [Char]
    Result a -> [Char]
    (Int -> Result a -> [Char] -> [Char])
    -> (Result a -> [Char])
    -> ([Result a] -> [Char] -> [Char])
    -> Show (Result a)
    forall a. Show a => Int -> Result a -> [Char] -> [Char]
    forall a. Show a => [Result a] -> [Char] -> [Char]
    forall a. Show a => Result a -> [Char]
    forall a.
    (Int -> a -> [Char] -> [Char])
    -> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
    $cshowsPrec :: forall a. Show a => Int -> Result a -> [Char] -> [Char]
    showsPrec :: Int -> Result a -> [Char] -> [Char]
    $cshow :: forall a. Show a => Result a -> [Char]
    show :: Result a -> [Char]
    $cshowList :: forall a. Show a => [Result a] -> [Char] -> [Char]
    showList :: [Result a] -> [Char] -> [Char]
    Show, (forall a b. (a -> b) -> Result a -> Result b)
    -> (forall a b. a -> Result b -> Result a) -> Functor Result
    forall a b. a -> Result b -> Result a
    forall a b. (a -> b) -> Result a -> Result b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall a b. (a -> b) -> Result a -> Result b
    fmap :: forall a b. (a -> b) -> Result a -> Result b
    $c<$ :: forall a b. a -> Result b -> Result a
    <$ :: forall a b. a -> Result b -> Result a
    Functor)

    type Warning = String
    type ModuleName = String

    data Config = Config
      { Config -> LogLevel
    cfgLogLevel :: LogLevel
      -- ^ Verbosity level.
      , Config -> [[Char]]
    cfgModules :: [ModuleName]
      -- ^ Module names to test. An empty list means "test all modules".
      , Config -> Maybe Int
    cfgThreads :: Maybe Int
      -- ^ Number of threads to use. Defaults to autodetection based on the number
      -- of cores.
      , Config -> ModuleConfig
    cfgModuleConfig :: ModuleConfig
      -- ^ Options specific to modules
      , Config -> Bool
    cfgNix :: Bool
      -- ^ Detect Nix build environment and try to make GHC aware of the local package
      -- being tested.
      , Config -> [[Char]]
    cfgGhcArgs :: [String]
      -- ^ Extra arguments passed to GHC when parsing
      } deriving (Int -> Config -> [Char] -> [Char]
    [Config] -> [Char] -> [Char]
    Config -> [Char]
    (Int -> Config -> [Char] -> [Char])
    -> (Config -> [Char])
    -> ([Config] -> [Char] -> [Char])
    -> Show Config
    forall a.
    (Int -> a -> [Char] -> [Char])
    -> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
    $cshowsPrec :: Int -> Config -> [Char] -> [Char]
    showsPrec :: Int -> Config -> [Char] -> [Char]
    $cshow :: Config -> [Char]
    show :: Config -> [Char]
    $cshowList :: [Config] -> [Char] -> [Char]
    showList :: [Config] -> [Char] -> [Char]
    Show, Config -> Config -> Bool
    (Config -> Config -> Bool)
    -> (Config -> Config -> Bool) -> Eq Config
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Config -> Config -> Bool
    == :: Config -> Config -> Bool
    $c/= :: Config -> Config -> Bool
    /= :: Config -> Config -> Bool
    Eq, (forall x. Config -> Rep Config x)
    -> (forall x. Rep Config x -> Config) -> Generic Config
    forall x. Rep Config x -> Config
    forall x. Config -> Rep Config x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Config -> Rep Config x
    from :: forall x. Config -> Rep Config x
    $cto :: forall x. Rep Config x -> Config
    to :: forall x. Rep Config x -> Config
    Generic, Config -> ()
    (Config -> ()) -> NFData Config
    forall a. (a -> ()) -> NFData a
    $crnf :: Config -> ()
    rnf :: Config -> ()
    NFData)

    data ModuleConfig = ModuleConfig
      { ModuleConfig -> Bool
    cfgPreserveIt :: Bool
      -- ^ Preserve the @it@ variable between examples (default: @False@)
      , ModuleConfig -> Bool
    cfgRandomizeOrder :: Bool
      -- ^ Randomize the order in which test cases in a module are run (default: @False@)
      , ModuleConfig -> Maybe Int
    cfgSeed :: Maybe Int
      -- ^ Initialize random number generator used to randomize test cases when
      -- 'cfgRandomizeOrder' is set. If set to 'Nothing', a random seed is picked
      -- from a system RNG source on startup.
      , ModuleConfig -> Bool
    cfgImplicitModuleImport :: Bool
      -- ^ Import a module before testing it. Can be disabled to enabled to test
      -- non-exposed modules.
      } deriving (Int -> ModuleConfig -> [Char] -> [Char]
    [ModuleConfig] -> [Char] -> [Char]
    ModuleConfig -> [Char]
    (Int -> ModuleConfig -> [Char] -> [Char])
    -> (ModuleConfig -> [Char])
    -> ([ModuleConfig] -> [Char] -> [Char])
    -> Show ModuleConfig
    forall a.
    (Int -> a -> [Char] -> [Char])
    -> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
    $cshowsPrec :: Int -> ModuleConfig -> [Char] -> [Char]
    showsPrec :: Int -> ModuleConfig -> [Char] -> [Char]
    $cshow :: ModuleConfig -> [Char]
    show :: ModuleConfig -> [Char]
    $cshowList :: [ModuleConfig] -> [Char] -> [Char]
    showList :: [ModuleConfig] -> [Char] -> [Char]
    Show, ModuleConfig -> ModuleConfig -> Bool
    (ModuleConfig -> ModuleConfig -> Bool)
    -> (ModuleConfig -> ModuleConfig -> Bool) -> Eq ModuleConfig
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ModuleConfig -> ModuleConfig -> Bool
    == :: ModuleConfig -> ModuleConfig -> Bool
    $c/= :: ModuleConfig -> ModuleConfig -> Bool
    /= :: ModuleConfig -> ModuleConfig -> Bool
    Eq, (forall x. ModuleConfig -> Rep ModuleConfig x)
    -> (forall x. Rep ModuleConfig x -> ModuleConfig)
    -> Generic ModuleConfig
    forall x. Rep ModuleConfig x -> ModuleConfig
    forall x. ModuleConfig -> Rep ModuleConfig x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. ModuleConfig -> Rep ModuleConfig x
    from :: forall x. ModuleConfig -> Rep ModuleConfig x
    $cto :: forall x. Rep ModuleConfig x -> ModuleConfig
    to :: forall x. Rep ModuleConfig x -> ModuleConfig
    Generic, ModuleConfig -> ()
    (ModuleConfig -> ()) -> NFData ModuleConfig
    forall a. (a -> ()) -> NFData a
    $crnf :: ModuleConfig -> ()
    rnf :: ModuleConfig -> ()
    NFData)

    defaultModuleConfig :: ModuleConfig
    defaultModuleConfig :: ModuleConfig
    defaultModuleConfig = ModuleConfig
      { cfgPreserveIt :: Bool
    cfgPreserveIt = Bool
    False
      , cfgRandomizeOrder :: Bool
    cfgRandomizeOrder = Bool
    False
      , cfgSeed :: Maybe Int
    cfgSeed = Maybe Int
    forall a. Maybe a
    Nothing
      , cfgImplicitModuleImport :: Bool
    cfgImplicitModuleImport = Bool
    True
      }

    defaultConfig :: Config
    defaultConfig :: Config
    defaultConfig = Config
      { cfgModules :: [[Char]]
    cfgModules = []
      , cfgThreads :: Maybe Int
    cfgThreads = Maybe Int
    forall a. Maybe a
    Nothing
      , cfgLogLevel :: LogLevel
    cfgLogLevel = LogLevel
    Info
      , cfgModuleConfig :: ModuleConfig
    cfgModuleConfig = ModuleConfig
    defaultModuleConfig
      , cfgNix :: Bool
    cfgNix = Bool
    True
      , cfgGhcArgs :: [[Char]]
    cfgGhcArgs = []
      }

    parseLocatedModuleOptions ::
      ModuleName ->
      ModuleConfig ->
      [Located String] ->
      Either (Location, String) ModuleConfig
    parseLocatedModuleOptions :: [Char]
    -> ModuleConfig
    -> [Located [Char]]
    -> Either (Location, [Char]) ModuleConfig
    parseLocatedModuleOptions [Char]
    _modName ModuleConfig
    modConfig [] = ModuleConfig -> Either (Location, [Char]) ModuleConfig
    forall a b. b -> Either a b
    Right ModuleConfig
    modConfig
    parseLocatedModuleOptions [Char]
    modName ModuleConfig
    modConfig0 (Located Location
    loc [Char]
    o:[Located [Char]]
    os) =
      case ModuleConfig -> [Char] -> Maybe ModuleConfig
    parseModuleOption ModuleConfig
    modConfig0 [Char]
    o of
        Maybe ModuleConfig
    Nothing ->
          (Location, [Char]) -> Either (Location, [Char]) ModuleConfig
    forall a b. a -> Either a b
    Left (Location
    loc, [Char]
    o)
        Just ModuleConfig
    modConfig1 ->
          [Char]
    -> ModuleConfig
    -> [Located [Char]]
    -> Either (Location, [Char]) ModuleConfig
    parseLocatedModuleOptions [Char]
    modName ModuleConfig
    modConfig1 [Located [Char]]
    os

    parseModuleOption :: ModuleConfig -> String -> Maybe ModuleConfig
    parseModuleOption :: ModuleConfig -> [Char] -> Maybe ModuleConfig
    parseModuleOption ModuleConfig
    config [Char]
    arg =
      case [Char]
    arg of
        [Char]
    "--randomize-order" -> ModuleConfig -> Maybe ModuleConfig
    forall a. a -> Maybe a
    Just ModuleConfig
    config{cfgRandomizeOrder=True}
        [Char]
    "--no-randomize-order" -> ModuleConfig -> Maybe ModuleConfig
    forall a. a -> Maybe a
    Just ModuleConfig
    config{cfgRandomizeOrder=False}
        [Char]
    "--preserve-it" -> ModuleConfig -> Maybe ModuleConfig
    forall a. a -> Maybe a
    Just ModuleConfig
    config{cfgPreserveIt=True}
        [Char]
    "--no-preserve-it" -> ModuleConfig -> Maybe ModuleConfig
    forall a. a -> Maybe a
    Just ModuleConfig
    config{cfgPreserveIt=False}
        [Char]
    "--implicit-module-import" -> ModuleConfig -> Maybe ModuleConfig
    forall a. a -> Maybe a
    Just ModuleConfig
    config{cfgImplicitModuleImport=True}
        [Char]
    "--no-implicit-module-import" -> ModuleConfig -> Maybe ModuleConfig
    forall a. a -> Maybe a
    Just ModuleConfig
    config{cfgImplicitModuleImport=False}
        (Char
    '-':[Char]
    _) | Just Int
    n <- [Char] -> Maybe Int
    parseSeed [Char]
    arg -> ModuleConfig -> Maybe ModuleConfig
    forall a. a -> Maybe a
    Just ModuleConfig
    config{cfgSeed=Just n}
        [Char]
    _ -> Maybe ModuleConfig
    forall a. Maybe a
    Nothing

    parseOptions :: [String] -> Result Config
    parseOptions :: [[Char]] -> Result Config
    parseOptions = (Config -> Config) -> Result Config -> Result Config
    forall a b. (a -> b) -> Result a -> Result b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Config -> Config
    revGhcArgs (Result Config -> Result Config)
    -> ([[Char]] -> Result Config) -> [[Char]] -> Result Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Config -> [[Char]] -> Result Config
    go Config
    defaultConfig
     where
      go :: Config -> [[Char]] -> Result Config
    go Config
    config [] = Config -> Result Config
    forall a. a -> Result a
    Result Config
    config
      go Config
    config ([Char]
    arg:[[Char]]
    args) =
        case [Char]
    arg of
          [Char]
    "--help" -> [Char] -> Result Config
    forall a. [Char] -> Result a
    ResultStdout [Char]
    usage
          [Char]
    "--info" -> [Char] -> Result Config
    forall a. [Char] -> Result a
    ResultStdout [Char]
    info
          [Char]
    "--version" -> [Char] -> Result Config
    forall a. [Char] -> Result a
    ResultStdout [Char]
    versionInfo
          [Char]
    "--quiet" -> Config -> [[Char]] -> Result Config
    go Config
    config{cfgLogLevel=Error} [[Char]]
    args
          [Char]
    "--verbose" -> Config -> [[Char]] -> Result Config
    go Config
    config{cfgLogLevel=Verbose} [[Char]]
    args
          [Char]
    "--debug" -> Config -> [[Char]] -> Result Config
    go Config
    config{cfgLogLevel=Debug} [[Char]]
    args
          [Char]
    "--nix" -> Config -> [[Char]] -> Result Config
    go Config
    config{cfgNix=True} [[Char]]
    args
          [Char]
    "--no-nix" -> Config -> [[Char]] -> Result Config
    go Config
    config{cfgNix=False} [[Char]]
    args
          (Char
    '-':[Char]
    _) | Just Int
    n <- [Char] -> Maybe Int
    parseThreads [Char]
    arg -> Config -> [[Char]] -> Result Config
    go Config
    config{cfgThreads=Just n} [[Char]]
    args
          (Char
    '-':[Char]
    _) | Just LogLevel
    l <- [Char] -> Maybe LogLevel
    parseLogLevel [Char]
    arg -> Config -> [[Char]] -> Result Config
    go Config
    config{cfgLogLevel=l} [[Char]]
    args
          (Char
    '-':[Char]
    _) | Just [Char]
    a <- [Char] -> Maybe [Char]
    parseGhcArg [Char]
    arg -> Config -> [[Char]] -> Result Config
    go ([Char] -> Config -> Config
    addGhcArg [Char]
    a Config
    config) [[Char]]
    args
          (Char
    '-':[Char]
    _)
            -- Module specific configuration options
            | Just ModuleConfig
    modCfg <- ModuleConfig -> [Char] -> Maybe ModuleConfig
    parseModuleOption (Config -> ModuleConfig
    cfgModuleConfig Config
    config) [Char]
    arg
           -> Config -> [[Char]] -> Result Config
    go Config
    config{cfgModuleConfig=modCfg} [[Char]]
    args
          (Char
    '-':[Char]
    _) -> [Char] -> Result Config
    forall a. [Char] -> Result a
    ResultStderr ([Char]
    "Unknown command line argument: " [Char] -> [Char] -> [Char]
    forall a. Semigroup a => a -> a -> a
    <> [Char]
    arg)
          [Char]
    mod_ -> Config -> [[Char]] -> Result Config
    go Config
    config{cfgModules=mod_ : cfgModules config} [[Char]]
    args

      addGhcArg :: String -> Config -> Config
      addGhcArg :: [Char] -> Config -> Config
    addGhcArg [Char]
    arg Config{Bool
    [[Char]]
    Maybe Int
    LogLevel
    ModuleConfig
    cfgLogLevel :: Config -> LogLevel
    cfgModules :: Config -> [[Char]]
    cfgThreads :: Config -> Maybe Int
    cfgModuleConfig :: Config -> ModuleConfig
    cfgNix :: Config -> Bool
    cfgGhcArgs :: Config -> [[Char]]
    cfgLogLevel :: LogLevel
    cfgModules :: [[Char]]
    cfgThreads :: Maybe Int
    cfgModuleConfig :: ModuleConfig
    cfgNix :: Bool
    cfgGhcArgs :: [[Char]]
    ..} = Config{cfgGhcArgs :: [[Char]]
    cfgGhcArgs=[Char]
    arg[Char] -> [[Char]] -> [[Char]]
    forall a. a -> [a] -> [a]
    :[[Char]]
    cfgGhcArgs, Bool
    [[Char]]
    Maybe Int
    LogLevel
    ModuleConfig
    cfgLogLevel :: LogLevel
    cfgModules :: [[Char]]
    cfgThreads :: Maybe Int
    cfgModuleConfig :: ModuleConfig
    cfgNix :: Bool
    cfgLogLevel :: LogLevel
    cfgModules :: [[Char]]
    cfgThreads :: Maybe Int
    cfgModuleConfig :: ModuleConfig
    cfgNix :: Bool
    ..}

      revGhcArgs :: Config -> Config
      revGhcArgs :: Config -> Config
    revGhcArgs Config{Bool
    [[Char]]
    Maybe Int
    LogLevel
    ModuleConfig
    cfgLogLevel :: Config -> LogLevel
    cfgModules :: Config -> [[Char]]
    cfgThreads :: Config -> Maybe Int
    cfgModuleConfig :: Config -> ModuleConfig
    cfgNix :: Config -> Bool
    cfgGhcArgs :: Config -> [[Char]]
    cfgLogLevel :: LogLevel
    cfgModules :: [[Char]]
    cfgThreads :: Maybe Int
    cfgModuleConfig :: ModuleConfig
    cfgNix :: Bool
    cfgGhcArgs :: [[Char]]
    ..} = Config{cfgGhcArgs :: [[Char]]
    cfgGhcArgs=[[Char]] -> [[Char]]
    forall a. [a] -> [a]
    reverse [[Char]]
    cfgGhcArgs, Bool
    [[Char]]
    Maybe Int
    LogLevel
    ModuleConfig
    cfgLogLevel :: LogLevel
    cfgModules :: [[Char]]
    cfgThreads :: Maybe Int
    cfgModuleConfig :: ModuleConfig
    cfgNix :: Bool
    cfgLogLevel :: LogLevel
    cfgModules :: [[Char]]
    cfgThreads :: Maybe Int
    cfgModuleConfig :: ModuleConfig
    cfgNix :: Bool
    ..}

    -- | Parse ghc-arg argument
    --
    -- >>> parseGhcArg "--ghc-arg=foobar"
    -- Just "foobar"

    -- >>> parseGhcArg "--ghc-arg=-DFOO=3"
    -- Just "-DFOO=3"
    --
    parseGhcArg :: String -> Maybe String
    parseGhcArg :: [Char] -> Maybe [Char]
    parseGhcArg [Char]
    arg = [Char] -> [Char] -> Maybe [Char]
    parseSpecificFlag [Char]
    arg [Char]
    "ghc-arg"

    -- | Parse seed argument
    --
    -- >>> parseSeed "--seed=6"
    -- Just 6
    -- >>> parseSeed "--seeeed=6"
    -- Nothing
    --
    parseSeed :: String -> Maybe Int
    parseSeed :: [Char] -> Maybe Int
    parseSeed [Char]
    arg = [Char] -> Maybe Int
    forall a. Read a => [Char] -> Maybe a
    readMaybe ([Char] -> Maybe Int) -> Maybe [Char] -> Maybe Int
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< [Char] -> [Char] -> Maybe [Char]
    parseSpecificFlag [Char]
    arg [Char]
    "seed"

    -- | Parse seed argument
    --
    -- >>> parseLogLevel "--log-level=Debug"
    -- Just Debug
    -- >>> parseLogLevel "--log-level=debug"
    -- Just Debug
    -- >>> parseSeed "---log-level=debug"
    -- Nothing
    parseLogLevel  :: String -> Maybe LogLevel
    parseLogLevel :: [Char] -> Maybe LogLevel
    parseLogLevel [Char]
    arg = [Char] -> Maybe LogLevel
    Logging.parseLogLevel ([Char] -> Maybe LogLevel) -> Maybe [Char] -> Maybe LogLevel
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< [Char] -> [Char] -> Maybe [Char]
    parseSpecificFlag [Char]
    arg [Char]
    "log-level"

    -- | Parse number of threads argument
    --
    -- >>> parseThreads "-j6"
    -- Just 6
    -- >>> parseThreads "-j-2"
    -- Nothing
    -- >>> parseThreads "-jA"
    -- Nothing
    --
    parseThreads :: String -> Maybe Int
    parseThreads :: [Char] -> Maybe Int
    parseThreads (Char
    '-':Char
    'j':[Char]
    n0) = do
      n1 <- [Char] -> Maybe Int
    forall a. Read a => [Char] -> Maybe a
    readMaybe [Char]
    n0
      if n1 > 0 then Just n1 else Nothing
    parseThreads [Char]
    _ = Maybe Int
    forall a. Maybe a
    Nothing

    -- | Parse a specific flag with a value, or return 'Nothing'
    --
    -- >>> parseSpecificFlag "--foo" "foo"
    -- Nothing
    -- >>> parseSpecificFlag "--foo=" "foo"
    -- Nothing
    -- >>> parseSpecificFlag "--foo=5" "foo"
    -- Just "5"
    -- >>> parseSpecificFlag "--foo=5" "bar"
    -- Nothing
    parseSpecificFlag :: String -> String -> Maybe String
    parseSpecificFlag :: [Char] -> [Char] -> Maybe [Char]
    parseSpecificFlag [Char]
    arg [Char]
    flag = do
      case [Char] -> ([Char], Maybe [Char])
    parseFlag [Char]
    arg of
        (Char
    '-':Char
    '-':[Char]
    f, Maybe [Char]
    value) | [Char]
    f [Char] -> [Char] -> Bool
    forall a. Eq a => a -> a -> Bool
    == [Char]
    flag -> Maybe [Char]
    value
        ([Char], Maybe [Char])
    _ -> Maybe [Char]
    forall a. Maybe a
    Nothing

    -- | Parse a flag into its flag and argument component.
    --
    -- Example:
    --
    -- >>> parseFlag "--optghc=foo"
    -- ("--optghc",Just "foo")
    -- >>> parseFlag "--optghc="
    -- ("--optghc",Nothing)
    -- >>> parseFlag "--fast"
    -- ("--fast",Nothing)
    parseFlag :: String -> (String, Maybe String)
    parseFlag :: [Char] -> ([Char], Maybe [Char])
    parseFlag [Char]
    arg =
      case (Char -> Bool) -> [Char] -> ([Char], [Char])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '=') [Char]
    arg of
        ([Char]
    flag, [Char
    '=']) -> ([Char]
    flag, Maybe [Char]
    forall a. Maybe a
    Nothing)
        ([Char]
    flag, Char
    '=':[Char]
    opt) -> ([Char]
    flag, [Char] -> Maybe [Char]
    forall a. a -> Maybe a
    Just [Char]
    opt)
        ([Char]
    flag, [Char]
    _) -> ([Char]
    flag, Maybe [Char]
    forall a. Maybe a
    Nothing)