Update base for new Safe Haskell design
[ghc.git] / libraries / base / Debug / Trace.hs
1 {-# LANGUAGE Unsafe #-}
2 {-# LANGUAGE CPP, ForeignFunctionInterface #-}
3
4 -----------------------------------------------------------------------------
5 -- |
6 -- Module : Debug.Trace
7 -- Copyright : (c) The University of Glasgow 2001
8 -- License : BSD-style (see the file libraries/base/LICENSE)
9 --
10 -- Maintainer : libraries@haskell.org
11 -- Stability : provisional
12 -- Portability : portable
13 --
14 -- The 'trace' function.
15 --
16 -----------------------------------------------------------------------------
17
18 module Debug.Trace (
19 -- * Tracing
20 putTraceMsg, -- :: String -> IO ()
21 trace, -- :: String -> a -> a
22 traceShow
23 ) where
24
25 import Prelude
26 import System.IO.Unsafe
27
28 #ifdef __GLASGOW_HASKELL__
29 import Foreign.C.String
30 #else
31 import System.IO (hPutStrLn,stderr)
32 #endif
33
34 -- | 'putTraceMsg' function outputs the trace message from IO monad.
35 -- Usually the output stream is 'System.IO.stderr' but if the function is called
36 -- from Windows GUI application then the output will be directed to the Windows
37 -- debug console.
38 putTraceMsg :: String -> IO ()
39 putTraceMsg msg = do
40 #ifndef __GLASGOW_HASKELL__
41 hPutStrLn stderr msg
42 #else
43 withCString "%s\n" $ \cfmt ->
44 withCString msg $ \cmsg ->
45 debugBelch cfmt cmsg
46
47 -- don't use debugBelch() directly, because we cannot call varargs functions
48 -- using the FFI.
49 foreign import ccall unsafe "HsBase.h debugBelch2"
50 debugBelch :: CString -> CString -> IO ()
51 #endif
52
53 {-# NOINLINE trace #-}
54 {-|
55 When called, 'trace' outputs the string in its first argument, before
56 returning the second argument as its result. The 'trace' function is not
57 referentially transparent, and should only be used for debugging, or for
58 monitoring execution. Some implementations of 'trace' may decorate the string
59 that\'s output to indicate that you\'re tracing. The function is implemented on
60 top of 'putTraceMsg'.
61 -}
62 trace :: String -> a -> a
63 trace string expr = unsafePerformIO $ do
64 putTraceMsg string
65 return expr
66
67 {-|
68 Like 'trace', but uses 'show' on the argument to convert it to a 'String'.
69
70 > traceShow = trace . show
71 -}
72 traceShow :: (Show a) => a -> b -> b
73 traceShow = trace . show