module Base.Messages
(
MonadIO (..), status, putMsg, putErrLn, putErrsLn
, abortWith, abortWithMessage, abortWithMessages, warnOrAbort, internalError
, Message, message, posMessage
) where
import Control.Monad (unless, when)
import Control.Monad.IO.Class (MonadIO(..))
import Data.List (sort)
import System.IO (hFlush, hPutStrLn, stderr, stdout)
import System.Exit (exitFailure)
import Curry.Base.Message ( Message, message, posMessage, ppWarning
, ppMessages, ppError)
import Curry.Base.Pretty (Doc, text)
import CompilerOpts (Options (..), WarnOpts (..), Verbosity (..))
status :: MonadIO m => Options -> String -> m ()
status opts msg = unless (optVerbosity opts < VerbStatus) (putMsg msg)
putMsg :: MonadIO m => String -> m ()
putMsg msg = liftIO (putStrLn msg >> hFlush stdout)
putErrLn :: MonadIO m => String -> m ()
putErrLn msg = liftIO (hPutStrLn stderr msg >> hFlush stderr)
putErrsLn :: MonadIO m => [String] -> m ()
putErrsLn = mapM_ putErrLn
abortWith :: [String] -> IO a
abortWith errs = putErrsLn errs >> exitFailure
abortWithMessage :: Message -> IO a
abortWithMessage msg = abortWithMessages [msg]
abortWithMessages :: [Message] -> IO a
abortWithMessages msgs = printMessages ppError msgs >> exitFailure
warnOrAbort :: WarnOpts -> [Message] -> IO ()
warnOrAbort opts msgs = when (wnWarn opts && not (null msgs)) $ do
if wnWarnAsError opts
then abortWithMessages (msgs ++ [message $ text "Failed due to -Werror"])
else printMessages ppWarning msgs
printMessages :: (Message -> Doc) -> [Message] -> IO ()
printMessages msgType msgs
= unless (null msgs) $ putErrLn (show $ ppMessages msgType $ sort msgs)
internalError :: String -> a
internalError msg = error $ "Internal error: " ++ msg