module Snap.Internal.Debug where
import Control.Monad.Trans
#ifndef NODEBUG
import Control.Concurrent
import Control.DeepSeq
import Data.Either
import Control.Exception
import Data.Char
import Data.List
import Data.Maybe
import Foreign.C.Error
import System.Environment
import System.IO
import System.IO.Unsafe
import Text.Printf
#endif
debug, debugErrno :: MonadIO m => String -> m ()
#ifndef NODEBUG
debug = let !x = unsafePerformIO $! do
!e <- try $ getEnv "DEBUG"
!f <- either (\(_::SomeException) -> return debugIgnore)
(\y0 -> let y = map toLower y0
in if y == "1" || y == "on"
then return debugOn
else if y == "testsuite"
then return debugSeq
else return debugIgnore)
e
return $! f
in x
debugErrno = let !x = unsafePerformIO $ do
e <- try $ getEnv "DEBUG"
!f <- either (\(_::SomeException) -> return debugErrnoIgnore)
(\y0 -> let y = map toLower y0
in if y == "1" || y == "on"
then return debugErrnoOn
else if y == "testsuite"
then return debugErrnoSeq
else return debugErrnoIgnore)
e
return $! f
in x
debugSeq :: (MonadIO m) => String -> m ()
debugSeq !s = let !s' = rnf s in return $! s' `deepseq` ()
debugErrnoSeq :: (MonadIO m) => String -> m ()
debugErrnoSeq !s = let !s' = rnf s in return $! s' `deepseq` ()
_debugMVar :: MVar ()
_debugMVar = unsafePerformIO $ newMVar ()
debugOn :: (MonadIO m) => String -> m ()
debugOn s = liftIO $ withMVar _debugMVar $ \_ -> do
tid <- myThreadId
hPutStrLn stderr $ s' tid
hFlush stderr
where
chop x = let y = fromMaybe x $ stripPrefix "ThreadId " x
in printf "%8s" y
s' t = "[" ++ chop (show t) ++ "] " ++ s
debugErrnoOn :: (MonadIO m) => String -> m ()
debugErrnoOn loc = liftIO $ do
err <- getErrno
let ex = errnoToIOError loc err Nothing Nothing
debug $ show ex
#else
debug = debugIgnore
debugErrno = debugErrnoIgnore
#endif
debugIgnore :: (MonadIO m) => String -> m ()
debugIgnore _ = return ()
debugErrnoIgnore :: (MonadIO m) => String -> m ()
debugErrnoIgnore _ = return ()