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