[project @ 2002-12-05 09:49:38 by simonmar]
[ghc-base.git] / System / IO / Error.hs
1 {-# OPTIONS -fno-implicit-prelude #-}
2
3 -----------------------------------------------------------------------------
4 -- |
5 -- Module      :  System.IO.Error
6 -- Copyright   :  (c) The University of Glasgow 2001
7 -- License     :  BSD-style (see the file libraries/base/LICENSE)
8 -- 
9 -- Maintainer  :  libraries@haskell.org
10 -- Stability   :  provisional
11 -- Portability :  portable
12 --
13 -- Standard IO Errors.
14 --
15 -----------------------------------------------------------------------------
16
17 module System.IO.Error (
18     IOError,                    -- abstract
19 #ifdef __GLASGOW_HASKELL__
20     IOErrorType,                -- abstract
21 #endif
22
23     ioError,                    -- :: IOError -> IO a
24     userError,                  -- :: String  -> IOError
25
26 #ifdef __GLASGOW_HASKELL__
27     mkIOError,                  -- :: IOErrorType -> String -> Maybe Handle
28                                 --    -> Maybe FilePath -> IOError
29
30     annotateIOError,            -- :: IOError -> String -> Maybe FilePath 
31                                 --    -> Maybe Handle -> IOError 
32
33     alreadyExistsErrorType,     -- :: IOErrorType
34     doesNotExistErrorType,
35     alreadyInUseErrorType,
36     fullErrorType,
37     eofErrorType,
38     illegalOperationErrorType, 
39     permissionErrorType,
40     userErrorType,
41
42     isAlreadyExistsErrorType,   -- :: IOErrorType -> Bool
43     isDoesNotExistErrorType,
44     isAlreadyInUseErrorType,
45     isFullErrorType, 
46     isEOFErrorType,
47     isIllegalOperationErrorType, 
48     isPermissionErrorType,
49     isUserErrorType, 
50 #endif  /* __GLASGOW_HASKELL__ */
51
52     isAlreadyExistsError,       -- :: IOError -> Bool
53     isDoesNotExistError,
54     isAlreadyInUseError,
55     isFullError, 
56     isEOFError,
57     isIllegalOperation, 
58     isPermissionError,
59     isUserError,
60
61 #ifdef __GLASGOW_HASKELL__
62     ioeGetErrorType,            -- :: IOError -> IOErrorType
63 #endif
64     ioeGetErrorString,          -- :: IOError -> String
65     ioeGetHandle,               -- :: IOError -> Maybe Handle
66     ioeGetFileName,             -- :: IOError -> Maybe FilePath
67
68   ) where
69
70
71 #ifdef __GLASGOW_HASKELL__
72 import GHC.Base
73 import Data.Maybe
74 import GHC.IOBase
75 import Text.Show
76 #endif
77
78 #ifdef __HUGS__
79 import Hugs.IO
80 #endif
81
82 #ifdef __NHC__
83 import IO
84   ( IOError ()
85   , ioError
86   , userError
87   , isAlreadyExistsError        -- :: IOError -> Bool
88   , isDoesNotExistError
89   , isAlreadyInUseError
90   , isFullError
91   , isEOFError
92   , isIllegalOperation
93   , isPermissionError
94   , isUserError
95   , ioeGetErrorString           -- :: IOError -> String
96   , ioeGetHandle                -- :: IOError -> Maybe Handle
97   , ioeGetFileName              -- :: IOError -> Maybe FilePath
98   )
99 --import Data.Maybe (fromJust)
100 --import Control.Monad (MonadPlus(mplus))
101 #endif
102
103 #ifdef __GLASGOW_HASKELL__
104 -- -----------------------------------------------------------------------------
105 -- Constructing an IOError
106
107 mkIOError :: IOErrorType -> String -> Maybe Handle -> Maybe FilePath -> IOError
108 mkIOError t location maybe_hdl maybe_filename =
109    IOException IOError{ ioe_type = t, 
110                         ioe_location = location,
111                         ioe_descr = "",
112                         ioe_handle = maybe_hdl, 
113                         ioe_filename = maybe_filename
114                         }
115 #ifdef __NHC__
116 mkIOError EOF       location maybe_hdl maybe_filename =
117     EOFError location (fromJust maybe_hdl)
118 mkIOError UserError location maybe_hdl maybe_filename =
119     UserError location ""
120 mkIOError t         location maybe_hdl maybe_filename =
121     NHC.FFI.mkIOError location maybe_filename maybe_handle (ioeTypeToInt t)
122   where
123     ioeTypeToInt AlreadyExists     = fromEnum EEXIST
124     ioeTypeToInt NoSuchThing       = fromEnum ENOENT
125     ioeTypeToInt ResourceBusy      = fromEnum EBUSY
126     ioeTypeToInt ResourceExhausted = fromEnum ENOSPC
127     ioeTypeToInt IllegalOperation  = fromEnum EPERM
128     ioeTypeToInt PermissionDenied  = fromEnum EACCES
129 #endif
130
131 -- -----------------------------------------------------------------------------
132 -- IOErrorType
133
134 isAlreadyExistsError, isDoesNotExistError, isAlreadyInUseError,
135  isFullError, isEOFError, isIllegalOperation, isPermissionError,
136  isUserError :: IOError -> Bool
137
138 isAlreadyExistsError = isAlreadyExistsErrorType    . ioeGetErrorType
139 isDoesNotExistError  = isDoesNotExistErrorType     . ioeGetErrorType
140 isAlreadyInUseError  = isAlreadyInUseErrorType     . ioeGetErrorType
141 isFullError          = isFullErrorType             . ioeGetErrorType
142 isEOFError           = isEOFErrorType              . ioeGetErrorType
143 isIllegalOperation   = isIllegalOperationErrorType . ioeGetErrorType
144 isPermissionError    = isPermissionErrorType       . ioeGetErrorType
145 isUserError          = isUserErrorType             . ioeGetErrorType
146 #endif
147
148 -- -----------------------------------------------------------------------------
149 -- IOErrorTypes
150
151 #ifdef __NHC__
152 data IOErrorType = AlreadyExists | NoSuchThing | ResourceBusy
153                  | ResourceExhausted | EOF | IllegalOperation
154                  | PermissionDenied | UserError
155 #endif
156
157 #ifdef __GLASGOW_HASKELL__
158 alreadyExistsErrorType, doesNotExistErrorType, alreadyInUseErrorType,
159  fullErrorType, eofErrorType, illegalOperationErrorType,
160  permissionErrorType, userErrorType :: IOErrorType
161
162 alreadyExistsErrorType    = AlreadyExists
163 doesNotExistErrorType     = NoSuchThing
164 alreadyInUseErrorType     = ResourceBusy
165 fullErrorType             = ResourceExhausted
166 eofErrorType              = EOF
167 illegalOperationErrorType = IllegalOperation
168 permissionErrorType       = PermissionDenied
169 userErrorType             = UserError
170 #endif
171
172 -- -----------------------------------------------------------------------------
173 -- IOErrorType predicates
174
175 #ifdef __GLASGOW_HASKELL__
176 isAlreadyExistsErrorType, isDoesNotExistErrorType, isAlreadyInUseErrorType,
177   isFullErrorType, isEOFErrorType, isIllegalOperationErrorType, 
178   isPermissionErrorType, isUserErrorType :: IOErrorType -> Bool
179 #endif
180
181 #ifdef __GLASGOW_HASKELL__
182 isAlreadyExistsErrorType AlreadyExists = True
183 isAlreadyExistsErrorType _ = False
184
185 isDoesNotExistErrorType NoSuchThing = True
186 isDoesNotExistErrorType _ = False
187
188 isAlreadyInUseErrorType ResourceBusy = True
189 isAlreadyInUseErrorType _ = False
190
191 isFullErrorType ResourceExhausted = True
192 isFullErrorType _ = False
193
194 isEOFErrorType EOF = True
195 isEOFErrorType _ = False
196
197 isIllegalOperationErrorType IllegalOperation = True
198 isIllegalOperationErrorType _ = False
199
200 isPermissionErrorType PermissionDenied = True
201 isPermissionErrorType _ = False
202
203 isUserErrorType UserError = True
204 isUserErrorType _ = False
205 #endif
206
207 -- -----------------------------------------------------------------------------
208 -- Miscellaneous
209
210 #ifdef __GLASGOW_HASKELL__
211 ioeGetErrorType       :: IOError -> IOErrorType
212 ioeGetHandle          :: IOError -> Maybe Handle
213 ioeGetErrorString     :: IOError -> String
214 ioeGetFileName        :: IOError -> Maybe FilePath
215
216 ioeGetErrorType (IOException ioe) = ioe_type ioe
217 ioeGetErrorType _ = error "System.IO.Error.ioeGetErrorType: not an IO error"
218
219 ioeGetHandle (IOException ioe) = ioe_handle ioe
220 ioeGetHandle _ = error "System.IO.Error.ioeGetHandle: not an IO error"
221
222 ioeGetErrorString (IOException ioe) 
223    | isUserErrorType (ioe_type ioe) = ioe_descr ioe
224    | otherwise                      = show (ioe_type ioe)
225 ioeGetErrorString _ = error "System.IO.Error.ioeGetErrorString: not an IO error"
226
227 ioeGetFileName (IOException ioe) = ioe_filename ioe
228 ioeGetFileName _ = error "System.IO.Error.ioeGetFileName: not an IO error"
229 #endif
230
231 -- -----------------------------------------------------------------------------
232 -- annotating an IOError
233
234 #ifdef __GLASGOW_HASKELL__
235 annotateIOError :: IOError 
236               -> String 
237               -> Maybe FilePath 
238               -> Maybe Handle 
239               -> IOError 
240 annotateIOError (IOException (IOError hdl errTy _ str path)) loc opath ohdl = 
241   IOException (IOError (hdl `mplus` ohdl) errTy loc str (path `mplus` opath))
242   where
243     Nothing `mplus` ys = ys
244     xs      `mplus` _  = xs
245 annotateIOError exc _ _ _ = 
246   exc
247 #endif
248
249 #ifdef 0 /*__NHC__*/
250 annotateIOError (IOError msg file hdl code) msg' file' hdl' =
251     IOError (msg++'\n':msg') (file`mplus`file') (hdl`mplus`hdl') code
252 annotateIOError (EOFError msg hdl) msg' file' hdl' =
253     EOFError (msg++'\n':msg') (hdl`mplus`hdl')
254 annotateIOError (UserError loc msg) msg' file' hdl' =
255     UserError loc (msg++'\n':msg')
256 annotateIOError (PatternError loc) msg' file' hdl' =
257     PatternError (loc++'\n':msg')
258 #endif