[project @ 2001-03-08 12:07:38 by simonpj]
[ghc-hetmet.git] / ghc / compiler / main / ErrUtils.lhs
1 %
2 % (c) The AQUA Project, Glasgow University, 1994-1998
3 %
4 \section[ErrsUtils]{Utilities for error reporting}
5
6 \begin{code}
7 module ErrUtils (
8         ErrMsg, WarnMsg, Message, Messages, errorsFound, warningsFound,
9
10         addShortErrLocLine, addShortWarnLocLine,
11         addErrLocHdrLine, addWarnLocHdrLine, dontAddErrLoc,
12
13         printErrorsAndWarnings, pprBagOfErrors, pprBagOfWarnings,
14
15         ghcExit,
16         doIfSet, doIfSet_dyn, 
17         dumpIfSet, dumpIfSet_core, dumpIfSet_dyn, dumpIfSet_dyn_or, 
18         showPass
19     ) where
20
21 #include "HsVersions.h"
22
23 import Bag              ( Bag, bagToList, isEmptyBag )
24 import SrcLoc           ( SrcLoc, noSrcLoc, isGoodSrcLoc )
25 import Util             ( sortLt )
26 import Outputable
27 import CmdLineOpts      ( DynFlags(..), DynFlag(..), dopt )
28
29 import System           ( ExitCode(..), exitWith )
30 import IO               ( hPutStr, stderr )
31 \end{code}
32
33 \begin{code}
34 type MsgWithLoc = (SrcLoc, SDoc)
35
36 type ErrMsg  = MsgWithLoc
37 type WarnMsg = MsgWithLoc
38 type Message = SDoc
39
40 addShortErrLocLine  :: SrcLoc -> Message -> ErrMsg
41 addErrLocHdrLine    :: SrcLoc -> Message -> Message -> ErrMsg
42 addWarnLocHdrLine    :: SrcLoc -> Message -> Message -> ErrMsg
43 addShortWarnLocLine :: SrcLoc -> Message -> WarnMsg
44
45 addShortErrLocLine locn rest_of_err_msg
46   | isGoodSrcLoc locn = (locn, hang (ppr locn <> colon) 4 
47                                     rest_of_err_msg)
48   | otherwise         = (locn, rest_of_err_msg)
49
50 addErrLocHdrLine locn hdr rest_of_err_msg
51   = ( locn
52     , hang (ppr locn <> colon<+> hdr) 
53          4 rest_of_err_msg
54     )
55
56 addWarnLocHdrLine locn hdr rest_of_err_msg
57   = ( locn
58     , hang (ppr locn <> colon <+> ptext SLIT("Warning:") <+> hdr) 
59          4 (rest_of_err_msg)
60     )
61
62 addShortWarnLocLine locn rest_of_err_msg
63   | isGoodSrcLoc locn = (locn, hang (ppr locn <> colon) 4 
64                                     (ptext SLIT("Warning:") <+> rest_of_err_msg))
65   | otherwise         = (locn, rest_of_err_msg)
66
67 dontAddErrLoc :: Message -> ErrMsg
68 dontAddErrLoc msg = (noSrcLoc, msg)
69
70 \end{code}
71
72
73 \begin{code}
74 type Messages = (Bag WarnMsg, Bag ErrMsg)
75
76 errorsFound :: Messages -> Bool
77 errorsFound (warns, errs) = not (isEmptyBag errs)
78
79 warningsFound :: Messages -> Bool
80 warningsFound (warns, errs) = not (isEmptyBag warns)
81
82 printErrorsAndWarnings :: PrintUnqualified -> Messages -> IO ()
83         -- Don't print any warnings if there are errors
84 printErrorsAndWarnings unqual (warns, errs)
85   | no_errs && no_warns  = return ()
86   | no_errs              = printErrs unqual (pprBagOfWarnings warns)
87   | otherwise            = printErrs unqual (pprBagOfErrors   errs)
88   where
89     no_warns = isEmptyBag warns
90     no_errs  = isEmptyBag errs
91
92 pprBagOfErrors :: Bag ErrMsg -> SDoc
93 pprBagOfErrors bag_of_errors
94   = vcat [text "" $$ p | (_,p) <- sorted_errs ]
95     where
96       bag_ls      = bagToList bag_of_errors
97       sorted_errs = sortLt occ'ed_before bag_ls
98
99       occ'ed_before (a,_) (b,_) = LT == compare a b
100
101 pprBagOfWarnings :: Bag WarnMsg -> SDoc
102 pprBagOfWarnings bag_of_warns = pprBagOfErrors bag_of_warns
103 \end{code}
104
105 \begin{code}
106 ghcExit :: Int -> IO ()
107 ghcExit val
108   | val == 0  = exitWith ExitSuccess
109   | otherwise = do hPutStr stderr "\nCompilation had errors\n\n"
110                    exitWith (ExitFailure val)
111 \end{code}
112
113 \begin{code}
114 doIfSet :: Bool -> IO () -> IO ()
115 doIfSet flag action | flag      = action
116                     | otherwise = return ()
117
118 doIfSet_dyn :: DynFlags -> DynFlag -> IO () -> IO()
119 doIfSet_dyn dflags flag action | dopt flag dflags = action
120                                | otherwise        = return ()
121 \end{code}
122
123 \begin{code}
124 showPass :: DynFlags -> String -> IO ()
125 showPass dflags what
126   | verbosity dflags >= 2 = hPutStr stderr ("*** "++what++":\n")
127   | otherwise             = return ()
128
129 dumpIfSet :: Bool -> String -> SDoc -> IO ()
130 dumpIfSet flag hdr doc
131   | not flag   = return ()
132   | otherwise  = printDump (dump hdr doc)
133
134 dumpIfSet_core :: DynFlags -> DynFlag -> String -> SDoc -> IO ()
135 dumpIfSet_core dflags flag hdr doc
136   | dopt flag dflags
137         || verbosity dflags >= 4
138         || dopt Opt_D_verbose_core2core dflags  = printDump (dump hdr doc)
139   | otherwise                                   = return ()
140
141 dumpIfSet_dyn :: DynFlags -> DynFlag -> String -> SDoc -> IO ()
142 dumpIfSet_dyn dflags flag hdr doc
143   | dopt flag dflags || verbosity dflags >= 4 = printDump (dump hdr doc)
144   | otherwise                                 = return ()
145
146 dumpIfSet_dyn_or :: DynFlags -> [DynFlag] -> String -> SDoc -> IO ()
147 dumpIfSet_dyn_or dflags flags hdr doc
148   | or [dopt flag dflags | flag <- flags]
149   || verbosity dflags >= 4 
150   = printDump (dump hdr doc)
151   | otherwise = return ()
152
153 dump hdr doc 
154    = vcat [text "", 
155            line <+> text hdr <+> line,
156            doc,
157            text ""]
158      where 
159         line = text (take 20 (repeat '='))
160 \end{code}