    -- | @futhark check@
    module Futhark.CLI.Check (main) where

    import Control.Monad
    import Control.Monad.IO.Class
    import Futhark.Compiler
    import Futhark.Util.Options
    import Futhark.Util.Pretty (hPutDoc)
    import Language.Futhark.Warnings
    import System.Exit
    import System.IO

    data CheckConfig = CheckConfig {CheckConfig -> Bool
    checkWarn :: Bool, CheckConfig -> Bool
    checkWerror :: Bool}

    newCheckConfig :: CheckConfig
    newCheckConfig :: CheckConfig
    newCheckConfig = Bool -> Bool -> CheckConfig
    CheckConfig Bool
    True Bool
    False

    options :: [FunOptDescr CheckConfig]
    options :: [FunOptDescr CheckConfig]
    options =
      [ [Char]
    -> [[Char]]
    -> ArgDescr (Either (IO ()) (CheckConfig -> CheckConfig))
    -> [Char]
    -> FunOptDescr CheckConfig
    forall a. [Char] -> [[Char]] -> ArgDescr a -> [Char] -> OptDescr a
    Option
          [Char]
    "w"
          []
          (Either (IO ()) (CheckConfig -> CheckConfig)
    -> ArgDescr (Either (IO ()) (CheckConfig -> CheckConfig))
    forall a. a -> ArgDescr a
    NoArg (Either (IO ()) (CheckConfig -> CheckConfig)
     -> ArgDescr (Either (IO ()) (CheckConfig -> CheckConfig)))
    -> Either (IO ()) (CheckConfig -> CheckConfig)
    -> ArgDescr (Either (IO ()) (CheckConfig -> CheckConfig))
    forall a b. (a -> b) -> a -> b
    $ (CheckConfig -> CheckConfig)
    -> Either (IO ()) (CheckConfig -> CheckConfig)
    forall a b. b -> Either a b
    Right ((CheckConfig -> CheckConfig)
     -> Either (IO ()) (CheckConfig -> CheckConfig))
    -> (CheckConfig -> CheckConfig)
    -> Either (IO ()) (CheckConfig -> CheckConfig)
    forall a b. (a -> b) -> a -> b
    $ \CheckConfig
    cfg -> CheckConfig
    cfg {checkWarn = False})
          [Char]
    "Disable all warnings.",
        [Char]
    -> [[Char]]
    -> ArgDescr (Either (IO ()) (CheckConfig -> CheckConfig))
    -> [Char]
    -> FunOptDescr CheckConfig
    forall a. [Char] -> [[Char]] -> ArgDescr a -> [Char] -> OptDescr a
    Option
          []
          [[Char]
    "Werror"]
          (Either (IO ()) (CheckConfig -> CheckConfig)
    -> ArgDescr (Either (IO ()) (CheckConfig -> CheckConfig))
    forall a. a -> ArgDescr a
    NoArg (Either (IO ()) (CheckConfig -> CheckConfig)
     -> ArgDescr (Either (IO ()) (CheckConfig -> CheckConfig)))
    -> Either (IO ()) (CheckConfig -> CheckConfig)
    -> ArgDescr (Either (IO ()) (CheckConfig -> CheckConfig))
    forall a b. (a -> b) -> a -> b
    $ (CheckConfig -> CheckConfig)
    -> Either (IO ()) (CheckConfig -> CheckConfig)
    forall a b. b -> Either a b
    Right ((CheckConfig -> CheckConfig)
     -> Either (IO ()) (CheckConfig -> CheckConfig))
    -> (CheckConfig -> CheckConfig)
    -> Either (IO ()) (CheckConfig -> CheckConfig)
    forall a b. (a -> b) -> a -> b
    $ \CheckConfig
    cfg -> CheckConfig
    cfg {checkWerror = True})
          [Char]
    "Treat warnings as errors."
      ]

    -- | Run @futhark check@.
    main :: String -> [String] -> IO ()
    main :: [Char] -> [[Char]] -> IO ()
    main = CheckConfig
    -> [FunOptDescr CheckConfig]
    -> [Char]
    -> ([[Char]] -> CheckConfig -> Maybe (IO ()))
    -> [Char]
    -> [[Char]]
    -> IO ()
    forall cfg.
    cfg
    -> [FunOptDescr cfg]
    -> [Char]
    -> ([[Char]] -> cfg -> Maybe (IO ()))
    -> [Char]
    -> [[Char]]
    -> IO ()
    mainWithOptions CheckConfig
    newCheckConfig [FunOptDescr CheckConfig]
    options [Char]
    "program" (([[Char]] -> CheckConfig -> Maybe (IO ()))
     -> [Char] -> [[Char]] -> IO ())
    -> ([[Char]] -> CheckConfig -> Maybe (IO ()))
    -> [Char]
    -> [[Char]]
    -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \[[Char]]
    args CheckConfig
    cfg ->
      case [[Char]]
    args of
        [[Char]
    file] -> IO () -> Maybe (IO ())
    forall a. a -> Maybe a
    Just (IO () -> Maybe (IO ())) -> IO () -> Maybe (IO ())
    forall a b. (a -> b) -> a -> b
    $ do
          (warnings, _, _) <- [Char] -> IO (Warnings, Imports, VNameSource)
    forall (m :: * -> *).
    MonadIO m =>
    [Char] -> m (Warnings, Imports, VNameSource)
    readProgramOrDie [Char]
    file
          when (checkWarn cfg && anyWarnings warnings) $ do
            liftIO $ hPutDoc stderr $ prettyWarnings warnings
            when (checkWerror cfg) $ do
              hPutStrLn stderr "\nTreating above warnings as errors due to --Werror."
              exitWith $ ExitFailure 2
        [[Char]]
    _ -> Maybe (IO ())
    forall a. Maybe a
    Nothing