From: Don Stewart Date: Wed, 5 Mar 2008 01:02:55 +0000 (+0000) Subject: untabify X-Git-Tag: 2008-05-28~45 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=55fb0382ef8d4a08424ab4751106e9f588a8a6f7;p=ghc-base.git untabify --- diff --git a/GHC/Conc.lhs b/GHC/Conc.lhs index 6ec6c76..460a98a 100644 --- a/GHC/Conc.lhs +++ b/GHC/Conc.lhs @@ -24,68 +24,68 @@ -- #not-home module GHC.Conc - ( ThreadId(..) + ( ThreadId(..) - -- * Forking and suchlike - , forkIO -- :: IO a -> IO ThreadId - , forkOnIO -- :: Int -> IO a -> IO ThreadId + -- * Forking and suchlike + , forkIO -- :: IO a -> IO ThreadId + , forkOnIO -- :: Int -> IO a -> IO ThreadId , numCapabilities -- :: Int - , childHandler -- :: Exception -> IO () - , myThreadId -- :: IO ThreadId - , killThread -- :: ThreadId -> IO () - , throwTo -- :: ThreadId -> Exception -> IO () - , par -- :: a -> b -> b - , pseq -- :: a -> b -> b - , yield -- :: IO () - , labelThread -- :: ThreadId -> String -> IO () - - -- * Waiting - , threadDelay -- :: Int -> IO () - , registerDelay -- :: Int -> IO (TVar Bool) - , threadWaitRead -- :: Int -> IO () - , threadWaitWrite -- :: Int -> IO () - - -- * MVars - , MVar(..) - , newMVar -- :: a -> IO (MVar a) - , newEmptyMVar -- :: IO (MVar a) - , takeMVar -- :: MVar a -> IO a - , putMVar -- :: MVar a -> a -> IO () - , tryTakeMVar -- :: MVar a -> IO (Maybe a) - , tryPutMVar -- :: MVar a -> a -> IO Bool - , isEmptyMVar -- :: MVar a -> IO Bool - , addMVarFinalizer -- :: MVar a -> IO () -> IO () - - -- * TVars - , STM(..) - , atomically -- :: STM a -> IO a - , retry -- :: STM a - , orElse -- :: STM a -> STM a -> STM a + , childHandler -- :: Exception -> IO () + , myThreadId -- :: IO ThreadId + , killThread -- :: ThreadId -> IO () + , throwTo -- :: ThreadId -> Exception -> IO () + , par -- :: a -> b -> b + , pseq -- :: a -> b -> b + , yield -- :: IO () + , labelThread -- :: ThreadId -> String -> IO () + + -- * Waiting + , threadDelay -- :: Int -> IO () + , registerDelay -- :: Int -> IO (TVar Bool) + , threadWaitRead -- :: Int -> IO () + , threadWaitWrite -- :: Int -> IO () + + -- * MVars + , MVar(..) + , newMVar -- :: a -> IO (MVar a) + , newEmptyMVar -- :: IO (MVar a) + , takeMVar -- :: MVar a -> IO a + , putMVar -- :: MVar a -> a -> IO () + , tryTakeMVar -- :: MVar a -> IO (Maybe a) + , tryPutMVar -- :: MVar a -> a -> IO Bool + , isEmptyMVar -- :: MVar a -> IO Bool + , addMVarFinalizer -- :: MVar a -> IO () -> IO () + + -- * TVars + , STM(..) + , atomically -- :: STM a -> IO a + , retry -- :: STM a + , orElse -- :: STM a -> STM a -> STM a , catchSTM -- :: STM a -> (Exception -> STM a) -> STM a - , alwaysSucceeds -- :: STM a -> STM () - , always -- :: STM Bool -> STM () - , TVar(..) - , newTVar -- :: a -> STM (TVar a) - , newTVarIO -- :: a -> STM (TVar a) - , readTVar -- :: TVar a -> STM a - , writeTVar -- :: a -> TVar a -> STM () - , unsafeIOToSTM -- :: IO a -> STM a - - -- * Miscellaneous + , alwaysSucceeds -- :: STM a -> STM () + , always -- :: STM Bool -> STM () + , TVar(..) + , newTVar -- :: a -> STM (TVar a) + , newTVarIO -- :: a -> STM (TVar a) + , readTVar -- :: TVar a -> STM a + , writeTVar -- :: a -> TVar a -> STM () + , unsafeIOToSTM -- :: IO a -> STM a + + -- * Miscellaneous #ifdef mingw32_HOST_OS - , asyncRead -- :: Int -> Int -> Int -> Ptr a -> IO (Int, Int) - , asyncWrite -- :: Int -> Int -> Int -> Ptr a -> IO (Int, Int) - , asyncDoProc -- :: FunPtr (Ptr a -> IO Int) -> Ptr a -> IO Int + , asyncRead -- :: Int -> Int -> Int -> Ptr a -> IO (Int, Int) + , asyncWrite -- :: Int -> Int -> Int -> Ptr a -> IO (Int, Int) + , asyncDoProc -- :: FunPtr (Ptr a -> IO Int) -> Ptr a -> IO Int - , asyncReadBA -- :: Int -> Int -> Int -> Int -> MutableByteArray# RealWorld -> IO (Int, Int) - , asyncWriteBA -- :: Int -> Int -> Int -> Int -> MutableByteArray# RealWorld -> IO (Int, Int) + , asyncReadBA -- :: Int -> Int -> Int -> Int -> MutableByteArray# RealWorld -> IO (Int, Int) + , asyncWriteBA -- :: Int -> Int -> Int -> Int -> MutableByteArray# RealWorld -> IO (Int, Int) #endif #ifndef mingw32_HOST_OS , signalHandlerLock #endif - , ensureIOManagerIsRunning + , ensureIOManagerIsRunning #ifdef mingw32_HOST_OS , ConsoleEvent(..) @@ -109,29 +109,29 @@ import Data.Maybe import GHC.Base import GHC.IOBase -import GHC.Num ( Num(..) ) -import GHC.Real ( fromIntegral, div ) +import GHC.Num ( Num(..) ) +import GHC.Real ( fromIntegral, div ) #ifndef mingw32_HOST_OS -import GHC.Base ( Int(..) ) +import GHC.Base ( Int(..) ) #endif #ifdef mingw32_HOST_OS import GHC.Read ( Read ) import GHC.Enum ( Enum ) #endif import GHC.Exception -import GHC.Pack ( packCString# ) +import GHC.Pack ( packCString# ) import GHC.Ptr ( Ptr(..), plusPtr, FunPtr(..) ) import GHC.STRef -import GHC.Show ( Show(..), showString ) +import GHC.Show ( Show(..), showString ) import Data.Typeable infixr 0 `par`, `pseq` \end{code} %************************************************************************ -%* * +%* * \subsection{@ThreadId@, @par@, and @fork@} -%* * +%* * %************************************************************************ \begin{code} @@ -159,7 +159,7 @@ it defines 'ThreadId' as a synonym for (). instance Show ThreadId where showsPrec d t = - showString "ThreadId " . + showString "ThreadId " . showsPrec d (getThreadId (id2TSO t)) foreign import ccall unsafe "rts_getThreadId" getThreadId :: ThreadId# -> CInt @@ -239,14 +239,14 @@ childHandler err = catchException (real_handler err) childHandler real_handler :: Exception -> IO () real_handler ex = case ex of - -- ignore thread GC and killThread exceptions: - BlockedOnDeadMVar -> return () - BlockedIndefinitely -> return () - AsyncException ThreadKilled -> return () + -- ignore thread GC and killThread exceptions: + BlockedOnDeadMVar -> return () + BlockedIndefinitely -> return () + AsyncException ThreadKilled -> return () - -- report all others: - AsyncException StackOverflow -> reportStackOverflow - other -> reportError other + -- report all others: + AsyncException StackOverflow -> reportStackOverflow + other -> reportError other {- | 'killThread' terminates the given thread (GHC only). Any work already done by the thread isn\'t @@ -325,8 +325,8 @@ labelThread (ThreadId t) str = IO $ \ s -> adr = byteArrayContents# ps in case (labelThread# t adr s) of s1 -> (# s1, () #) --- Nota Bene: 'pseq' used to be 'seq' --- but 'seq' is now defined in PrelGHC +-- Nota Bene: 'pseq' used to be 'seq' +-- but 'seq' is now defined in PrelGHC -- -- "pseq" is defined a bit weirdly (see below) -- @@ -347,9 +347,9 @@ par x y = case (par# x) of { _ -> lazy y } %************************************************************************ -%* * +%* * \subsection[stm]{Transactional heap operations} -%* * +%* * %************************************************************************ TVars are shared memory locations which support atomic memory @@ -372,7 +372,7 @@ instance Monad STM where {-# INLINE (>>) #-} {-# INLINE (>>=) #-} m >> k = thenSTM m k - return x = returnSTM x + return x = returnSTM x m >>= k = bindSTM m k bindSTM :: STM a -> (a -> STM b) -> STM b @@ -457,13 +457,13 @@ data TVar a = TVar (TVar# RealWorld a) INSTANCE_TYPEABLE1(TVar,tvarTc,"TVar") instance Eq (TVar a) where - (TVar tvar1#) == (TVar tvar2#) = sameTVar# tvar1# tvar2# + (TVar tvar1#) == (TVar tvar2#) = sameTVar# tvar1# tvar2# -- |Create a new TVar holding a value supplied newTVar :: a -> STM (TVar a) newTVar val = STM $ \s1# -> case newTVar# val s1# of - (# s2#, tvar# #) -> (# s2#, TVar tvar# #) + (# s2#, tvar# #) -> (# s2#, TVar tvar# #) -- |@IO@ version of 'newTVar'. This is useful for creating top-level -- 'TVar's using 'System.IO.Unsafe.unsafePerformIO', because using @@ -472,7 +472,7 @@ newTVar val = STM $ \s1# -> newTVarIO :: a -> IO (TVar a) newTVarIO val = IO $ \s1# -> case newTVar# val s1# of - (# s2#, tvar# #) -> (# s2#, TVar tvar# #) + (# s2#, tvar# #) -> (# s2#, TVar tvar# #) -- |Return the current value stored in a TVar readTVar :: TVar a -> STM a @@ -482,14 +482,14 @@ readTVar (TVar tvar#) = STM $ \s# -> readTVar# tvar# s# writeTVar :: TVar a -> a -> STM () writeTVar (TVar tvar#) val = STM $ \s1# -> case writeTVar# tvar# val s1# of - s2# -> (# s2#, () #) + s2# -> (# s2#, () #) \end{code} %************************************************************************ -%* * +%* * \subsection[mvars]{M-Structures} -%* * +%* * %************************************************************************ M-Vars are rendezvous points for concurrent threads. They begin @@ -512,8 +512,8 @@ newEmptyMVar = IO $ \ s# -> -- |Create an 'MVar' which contains the supplied value. newMVar :: a -> IO (MVar a) newMVar value = - newEmptyMVar >>= \ mvar -> - putMVar mvar value >> + newEmptyMVar >>= \ mvar -> + putMVar mvar value >> return mvar -- |Return the contents of the 'MVar'. If the 'MVar' is currently @@ -560,8 +560,8 @@ putMVar (MVar mvar#) x = IO $ \ s# -> tryTakeMVar :: MVar a -> IO (Maybe a) tryTakeMVar (MVar m) = IO $ \ s -> case tryTakeMVar# m s of - (# s, 0#, _ #) -> (# s, Nothing #) -- MVar is empty - (# s, _, a #) -> (# s, Just a #) -- MVar is full + (# s, 0#, _ #) -> (# s, Nothing #) -- MVar is empty + (# s, _, a #) -> (# s, Just a #) -- MVar is full -- |A non-blocking version of 'putMVar'. The 'tryPutMVar' function -- attempts to put the value @a@ into the 'MVar', returning 'True' if @@ -594,16 +594,16 @@ withMVar m io = block $ do a <- takeMVar m b <- catchException (unblock (io a)) - (\e -> do putMVar m a; throw e) + (\e -> do putMVar m a; throw e) putMVar m a return b \end{code} %************************************************************************ -%* * +%* * \subsection{Thread waiting} -%* * +%* * %************************************************************************ \begin{code} @@ -616,19 +616,19 @@ withMVar m io = asyncRead :: Int -> Int -> Int -> Ptr a -> IO (Int, Int) asyncRead (I# fd) (I# isSock) (I# len) (Ptr buf) = IO $ \s -> case asyncRead# fd isSock len buf s of - (# s, len#, err# #) -> (# s, (I# len#, I# err#) #) + (# s, len#, err# #) -> (# s, (I# len#, I# err#) #) asyncWrite :: Int -> Int -> Int -> Ptr a -> IO (Int, Int) asyncWrite (I# fd) (I# isSock) (I# len) (Ptr buf) = IO $ \s -> case asyncWrite# fd isSock len buf s of - (# s, len#, err# #) -> (# s, (I# len#, I# err#) #) + (# s, len#, err# #) -> (# s, (I# len#, I# err#) #) asyncDoProc :: FunPtr (Ptr a -> IO Int) -> Ptr a -> IO Int asyncDoProc (FunPtr proc) (Ptr param) = -- the 'length' value is ignored; simplifies implementation of -- the async*# primops to have them all return the same result. IO $ \s -> case asyncDoProc# proc param s of - (# s, len#, err# #) -> (# s, I# err# #) + (# s, len#, err# #) -> (# s, I# err# #) -- to aid the use of these primops by the IO Handle implementation, -- provide the following convenience funs: @@ -655,9 +655,9 @@ threadWaitRead fd | threaded = waitForReadEvent fd #endif | otherwise = IO $ \s -> - case fromIntegral fd of { I# fd# -> - case waitRead# fd# s of { s -> (# s, () #) - }} + case fromIntegral fd of { I# fd# -> + case waitRead# fd# s of { s -> (# s, () #) + }} -- | Block the current thread until data can be written to the -- given file descriptor (GHC only). @@ -667,9 +667,9 @@ threadWaitWrite fd | threaded = waitForWriteEvent fd #endif | otherwise = IO $ \s -> - case fromIntegral fd of { I# fd# -> - case waitWrite# fd# s of { s -> (# s, () #) - }} + case fromIntegral fd of { I# fd# -> + case waitWrite# fd# s of { s -> (# s, () #) + }} -- | Suspends the current thread for a given number of microseconds -- (GHC only). @@ -682,9 +682,9 @@ threadDelay :: Int -> IO () threadDelay time | threaded = waitForDelayEvent time | otherwise = IO $ \s -> - case fromIntegral time of { I# time# -> - case delay# time# s of { s -> (# s, () #) - }} + case fromIntegral time of { I# time# -> + case delay# time# s of { s -> (# s, () #) + }} -- | Set the value of returned TVar to True after a given number of @@ -737,20 +737,20 @@ calculateTarget usecs = do -- Issues, possible problems: -- --- - we might want bound threads to just do the blocking --- operation rather than communicating with the IO manager --- thread. This would prevent simgle-threaded programs which do --- IO from requiring multiple OS threads. However, it would also --- prevent bound threads waiting on IO from being killed or sent --- exceptions. +-- - we might want bound threads to just do the blocking +-- operation rather than communicating with the IO manager +-- thread. This would prevent simgle-threaded programs which do +-- IO from requiring multiple OS threads. However, it would also +-- prevent bound threads waiting on IO from being killed or sent +-- exceptions. -- --- - Apprently exec() doesn't work on Linux in a multithreaded program. --- I couldn't repeat this. +-- - Apprently exec() doesn't work on Linux in a multithreaded program. +-- I couldn't repeat this. -- --- - How do we handle signal delivery in the multithreaded RTS? +-- - How do we handle signal delivery in the multithreaded RTS? -- --- - forkProcess will kill the IO manager thread. Let's just --- hope we don't need to do any blocking IO between fork & exec. +-- - forkProcess will kill the IO manager thread. Let's just +-- hope we don't need to do any blocking IO between fork & exec. #ifndef mingw32_HOST_OS data IOReq @@ -766,7 +766,7 @@ data DelayReq pendingEvents :: IORef [IOReq] #endif pendingDelays :: IORef [DelayReq] - -- could use a strict list or array here + -- could use a strict list or array here {-# NOINLINE pendingEvents #-} {-# NOINLINE pendingDelays #-} (pendingEvents,pendingDelays) = unsafePerformIO $ do @@ -774,8 +774,8 @@ pendingDelays :: IORef [DelayReq] reqs <- newIORef [] dels <- newIORef [] return (reqs, dels) - -- the first time we schedule an IO request, the service thread - -- will be created (cool, huh?) + -- the first time we schedule an IO request, the service thread + -- will be created (cool, huh?) ensureIOManagerIsRunning :: IO () ensureIOManagerIsRunning @@ -838,11 +838,11 @@ service_loop wakeup old_delays = do 0 -> do r <- c_readIOManagerEvent exit <- - case r of - _ | r == io_MANAGER_WAKEUP -> return False - _ | r == io_MANAGER_DIE -> return True + case r of + _ | r == io_MANAGER_WAKEUP -> return False + _ | r == io_MANAGER_DIE -> return True 0 -> return False -- spurious wakeup - r -> do start_console_handler (r `shiftR` 1); return False + r -> do start_console_handler (r `shiftR` 1); return False if exit then return () else service_cont wakeup delays' @@ -902,11 +902,11 @@ getDelay now [] = return ([], iNFINITE) getDelay now all@(d : rest) = case d of Delay time m | now >= time -> do - putMVar m () - getDelay now rest + putMVar m () + getDelay now rest DelaySTM time t | now >= time -> do - atomically $ writeTVar t True - getDelay now rest + atomically $ writeTVar t True + getDelay now rest _otherwise -> -- delay is in millisecs for WaitForSingleObject let micro_seconds = delayTime d - now @@ -943,20 +943,20 @@ foreign import stdcall "WaitForSingleObject" startIOManagerThread :: IO () startIOManagerThread = do allocaArray 2 $ \fds -> do - throwErrnoIfMinus1 "startIOManagerThread" (c_pipe fds) - rd_end <- peekElemOff fds 0 - wr_end <- peekElemOff fds 1 - writeIORef stick (fromIntegral wr_end) - c_setIOManagerPipe wr_end - forkIO $ do - allocaBytes sizeofFdSet $ \readfds -> do - allocaBytes sizeofFdSet $ \writefds -> do - allocaBytes sizeofTimeVal $ \timeval -> do - service_loop (fromIntegral rd_end) readfds writefds timeval [] [] - return () + throwErrnoIfMinus1 "startIOManagerThread" (c_pipe fds) + rd_end <- peekElemOff fds 0 + wr_end <- peekElemOff fds 1 + writeIORef stick (fromIntegral wr_end) + c_setIOManagerPipe wr_end + forkIO $ do + allocaBytes sizeofFdSet $ \readfds -> do + allocaBytes sizeofFdSet $ \writefds -> do + allocaBytes sizeofTimeVal $ \timeval -> do + service_loop (fromIntegral rd_end) readfds writefds timeval [] [] + return () service_loop - :: Fd -- listen to this for wakeup calls + :: Fd -- listen to this for wakeup calls -> Ptr CFdSet -> Ptr CFdSet -> Ptr CTimeVal @@ -981,28 +981,28 @@ service_loop wakeup readfds writefds ptimeval old_reqs old_delays = do -- perform the select() let do_select delays = do - -- check the current time and wake up any thread in - -- threadDelay whose timeout has expired. Also find the - -- timeout value for the select() call. - now <- getUSecOfDay - (delays', timeout) <- getDelay now ptimeval delays - - res <- c_select (fromIntegral ((max wakeup maxfd)+1)) readfds writefds - nullPtr timeout - if (res == -1) - then do - err <- getErrno - case err of - _ | err == eINTR -> do_select delays' - -- EINTR: just redo the select() - _ | err == eBADF -> return (True, delays) - -- EBADF: one of the file descriptors is closed or bad, - -- we don't know which one, so wake everyone up. - _ | otherwise -> throwErrno "select" - -- otherwise (ENOMEM or EINVAL) something has gone - -- wrong; report the error. - else - return (False,delays') + -- check the current time and wake up any thread in + -- threadDelay whose timeout has expired. Also find the + -- timeout value for the select() call. + now <- getUSecOfDay + (delays', timeout) <- getDelay now ptimeval delays + + res <- c_select (fromIntegral ((max wakeup maxfd)+1)) readfds writefds + nullPtr timeout + if (res == -1) + then do + err <- getErrno + case err of + _ | err == eINTR -> do_select delays' + -- EINTR: just redo the select() + _ | err == eBADF -> return (True, delays) + -- EBADF: one of the file descriptors is closed or bad, + -- we don't know which one, so wake everyone up. + _ | otherwise -> throwErrno "select" + -- otherwise (ENOMEM or EINVAL) something has gone + -- wrong; report the error. + else + return (False,delays') (wakeup_all,delays') <- do_select delays @@ -1013,24 +1013,24 @@ service_loop wakeup readfds writefds ptimeval old_reqs old_delays = do if b == 0 then return False else alloca $ \p -> do - c_read (fromIntegral wakeup) p 1; return () - s <- peek p - case s of - _ | s == io_MANAGER_WAKEUP -> return False - _ | s == io_MANAGER_DIE -> return True - _ -> withMVar signalHandlerLock $ \_ -> do + c_read (fromIntegral wakeup) p 1; return () + s <- peek p + case s of + _ | s == io_MANAGER_WAKEUP -> return False + _ | s == io_MANAGER_DIE -> return True + _ -> withMVar signalHandlerLock $ \_ -> do handler_tbl <- peek handlers - sp <- peekElemOff handler_tbl (fromIntegral s) + sp <- peekElemOff handler_tbl (fromIntegral s) io <- deRefStablePtr sp - forkIO io - return False + forkIO io + return False if exit then return () else do atomicModifyIORef prodding (\_ -> (False,False)) reqs' <- if wakeup_all then do wakeupAll reqs; return [] - else completeRequests reqs readfds writefds [] + else completeRequests reqs readfds writefds [] service_loop wakeup readfds writefds ptimeval reqs' delays' @@ -1065,13 +1065,13 @@ buildFdSets maxfd readfds writefds [] = return maxfd buildFdSets maxfd readfds writefds (Read fd m : reqs) | fd >= fD_SETSIZE = error "buildFdSets: file descriptor out of range" | otherwise = do - fdSet fd readfds + fdSet fd readfds buildFdSets (max maxfd fd) readfds writefds reqs buildFdSets maxfd readfds writefds (Write fd m : reqs) | fd >= fD_SETSIZE = error "buildFdSets: file descriptor out of range" | otherwise = do - fdSet fd writefds - buildFdSets (max maxfd fd) readfds writefds reqs + fdSet fd writefds + buildFdSets (max maxfd fd) readfds writefds reqs completeRequests [] _ _ reqs' = return reqs' completeRequests (Read fd m : reqs) readfds writefds reqs' = do @@ -1114,14 +1114,14 @@ getDelay now ptimeval [] = return ([],nullPtr) getDelay now ptimeval all@(d : rest) = case d of Delay time m | now >= time -> do - putMVar m () - getDelay now ptimeval rest + putMVar m () + getDelay now ptimeval rest DelaySTM time t | now >= time -> do - atomically $ writeTVar t True - getDelay now ptimeval rest + atomically $ writeTVar t True + getDelay now ptimeval rest _otherwise -> do - setTimevalTicks ptimeval (delayTime d - now) - return (all,ptimeval) + setTimevalTicks ptimeval (delayTime d - now) + return (all,ptimeval) newtype CTimeVal = CTimeVal () diff --git a/GHC/ConsoleHandler.hs b/GHC/ConsoleHandler.hs index 42ec54f..8cd5d5e 100644 --- a/GHC/ConsoleHandler.hs +++ b/GHC/ConsoleHandler.hs @@ -17,14 +17,14 @@ module GHC.ConsoleHandler #if !defined(mingw32_HOST_OS) && !defined(__HADDOCK__) - where + where import Prelude -- necessary to get dependencies right #else /* whole file */ - ( Handler(..) - , installHandler - , ConsoleEvent(..) - , flushConsole - ) where + ( Handler(..) + , installHandler + , ConsoleEvent(..) + , flushConsole + ) where {- #include "Signals.h" @@ -65,10 +65,10 @@ data Handler -- it in one of these environments. -- installHandler :: Handler -> IO Handler -installHandler handler +installHandler handler | threaded = modifyMVar win32ConsoleHandler $ \old_h -> do - (new_h,rc) <- + (new_h,rc) <- case handler of Default -> do r <- rts_installHandler STG_SIG_DFL nullPtr @@ -79,7 +79,7 @@ installHandler handler Catch h -> do r <- rts_installHandler STG_SIG_HAN nullPtr return (h, r) - prev_handler <- + prev_handler <- case rc of STG_SIG_DFL -> return Default STG_SIG_IGN -> return Ignore @@ -88,25 +88,25 @@ installHandler handler | otherwise = alloca $ \ p_sp -> do - rc <- + rc <- case handler of Default -> rts_installHandler STG_SIG_DFL p_sp Ignore -> rts_installHandler STG_SIG_IGN p_sp Catch h -> do v <- newStablePtr (toHandler h) - poke p_sp v - rts_installHandler STG_SIG_HAN p_sp + poke p_sp v + rts_installHandler STG_SIG_HAN p_sp case rc of STG_SIG_DFL -> return Default STG_SIG_IGN -> return Ignore STG_SIG_HAN -> do osptr <- peek p_sp oldh <- deRefStablePtr osptr - -- stable pointer is no longer in use, free it. - freeStablePtr osptr - return (Catch (\ ev -> oldh (fromConsoleEvent ev))) + -- stable pointer is no longer in use, free it. + freeStablePtr osptr + return (Catch (\ ev -> oldh (fromConsoleEvent ev))) where - fromConsoleEvent ev = + fromConsoleEvent ev = case ev of ControlC -> 0 {- CTRL_C_EVENT-} Break -> 1 {- CTRL_BREAK_EVENT-} @@ -116,10 +116,10 @@ installHandler handler toHandler hdlr ev = do case toWin32ConsoleEvent ev of - -- see rts/win32/ConsoleHandler.c for comments as to why - -- rts_ConsoleHandlerDone is called here. + -- see rts/win32/ConsoleHandler.c for comments as to why + -- rts_ConsoleHandlerDone is called here. Just x -> hdlr x >> rts_ConsoleHandlerDone ev - Nothing -> return () -- silently ignore.. + Nothing -> return () -- silently ignore.. no_handler = error "win32ConsoleHandler" @@ -132,11 +132,11 @@ foreign import ccall unsafe "RtsExternal.h rts_ConsoleHandlerDone" flushConsole :: Handle -> IO () -flushConsole h = - wantReadableHandle "flushConsole" h $ \ h_ -> +flushConsole h = + wantReadableHandle "flushConsole" h $ \ h_ -> throwErrnoIfMinus1Retry_ "flushConsole" (flush_console_fd (fromIntegral (haFD h_))) foreign import ccall unsafe "consUtils.h flush_input_console__" - flush_console_fd :: CInt -> IO CInt + flush_console_fd :: CInt -> IO CInt #endif /* mingw32_HOST_OS */ diff --git a/GHC/Dotnet.hs b/GHC/Dotnet.hs index 43edd57..44ca423 100644 --- a/GHC/Dotnet.hs +++ b/GHC/Dotnet.hs @@ -13,14 +13,14 @@ -- ----------------------------------------------------------------------------- -module GHC.Dotnet - ( Object - , unmarshalObject - , marshalObject - , unmarshalString - , marshalString - , checkResult - ) where +module GHC.Dotnet + ( Object + , unmarshalObject + , marshalObject + , unmarshalString + , marshalString + , checkResult + ) where import GHC.Prim import GHC.Base @@ -32,17 +32,17 @@ import Foreign.Marshal.Alloc import Foreign.Storable import Foreign.C.String -data Object a +data Object a = Object Addr# checkResult :: (State# RealWorld -> (# State# RealWorld, a, Addr# #)) - -> IO a -checkResult fun = IO $ \ st -> + -> IO a +checkResult fun = IO $ \ st -> case fun st of - (# st1, res, err #) + (# st1, res, err #) | err `eqAddr#` nullAddr# -> (# st1, res #) | otherwise -> throw (IOException (raiseError err)) st1 - + -- ToDo: attach finaliser. unmarshalObject :: Addr# -> Object a unmarshalObject x = Object x @@ -52,9 +52,9 @@ marshalObject (Object x) cont = cont x -- dotnet interop support passing and returning -- strings. -marshalString :: String - -> (Addr# -> IO a) - -> IO a +marshalString :: String + -> (Addr# -> IO a) + -> IO a marshalString str cont = withCString str (\ (Ptr x) -> cont x) -- char** received back from a .NET interop layer. diff --git a/GHC/Enum.lhs b/GHC/Enum.lhs index a2592b3..bb8df9b 100644 --- a/GHC/Enum.lhs +++ b/GHC/Enum.lhs @@ -17,23 +17,23 @@ -- #hide module GHC.Enum( - Bounded(..), Enum(..), - boundedEnumFrom, boundedEnumFromThen, + Bounded(..), Enum(..), + boundedEnumFrom, boundedEnumFromThen, - -- Instances for Bounded and Enum: (), Char, Int + -- Instances for Bounded and Enum: (), Char, Int ) where import GHC.Base -import Data.Tuple () -- for dependencies -default () -- Double isn't available yet +import Data.Tuple () -- for dependencies +default () -- Double isn't available yet \end{code} %********************************************************* -%* * +%* * \subsection{Class declarations} -%* * +%* * %********************************************************* \begin{code} @@ -73,17 +73,17 @@ class Bounded a where -- * 'enumFrom' and 'enumFromThen' should be defined with an implicit bound, -- thus: -- --- > enumFrom x = enumFromTo x maxBound --- > enumFromThen x y = enumFromThenTo x y bound --- > where --- > bound | fromEnum y >= fromEnum x = maxBound --- > | otherwise = minBound +-- > enumFrom x = enumFromTo x maxBound +-- > enumFromThen x y = enumFromThenTo x y bound +-- > where +-- > bound | fromEnum y >= fromEnum x = maxBound +-- > | otherwise = minBound -- -class Enum a where +class Enum a where -- | the successor of a value. For numeric types, 'succ' adds 1. - succ :: a -> a + succ :: a -> a -- | the predecessor of a value. For numeric types, 'pred' subtracts 1. - pred :: a -> a + pred :: a -> a -- | Convert from an 'Int'. toEnum :: Int -> a -- | Convert to an 'Int'. @@ -92,18 +92,18 @@ class Enum a where fromEnum :: a -> Int -- | Used in Haskell's translation of @[n..]@. - enumFrom :: a -> [a] + enumFrom :: a -> [a] -- | Used in Haskell's translation of @[n,n'..]@. - enumFromThen :: a -> a -> [a] + enumFromThen :: a -> a -> [a] -- | Used in Haskell's translation of @[n..m]@. - enumFromTo :: a -> a -> [a] + enumFromTo :: a -> a -> [a] -- | Used in Haskell's translation of @[n,n'..m]@. - enumFromThenTo :: a -> a -> a -> [a] + enumFromThenTo :: a -> a -> a -> [a] - succ = toEnum . (`plusInt` oneInt) . fromEnum - pred = toEnum . (`minusInt` oneInt) . fromEnum - enumFrom x = map toEnum [fromEnum x ..] - enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] + succ = toEnum . (`plusInt` oneInt) . fromEnum + pred = toEnum . (`minusInt` oneInt) . fromEnum + enumFrom x = map toEnum [fromEnum x ..] + enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y] @@ -122,9 +122,9 @@ boundedEnumFromThen n1 n2 %********************************************************* -%* * +%* * \subsection{Tuples} -%* * +%* * %********************************************************* \begin{code} @@ -140,9 +140,9 @@ instance Enum () where | otherwise = error "Prelude.Enum.().toEnum: bad argument" fromEnum () = zeroInt - enumFrom () = [()] - enumFromThen () () = let many = ():many in many - enumFromTo () () = [()] + enumFrom () = [()] + enumFromThen () () = let many = ():many in many + enumFromTo () () = [()] enumFromThenTo () () () = let many = ():many in many \end{code} @@ -165,83 +165,83 @@ instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e) => Bounded (a,b maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound) instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f) - => Bounded (a,b,c,d,e,f) where + => Bounded (a,b,c,d,e,f) where minBound = (minBound, minBound, minBound, minBound, minBound, minBound) maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound) instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g) - => Bounded (a,b,c,d,e,f,g) where + => Bounded (a,b,c,d,e,f,g) where minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound) maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound) instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, - Bounded h) - => Bounded (a,b,c,d,e,f,g,h) where + Bounded h) + => Bounded (a,b,c,d,e,f,g,h) where minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound) maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound) instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, - Bounded h, Bounded i) - => Bounded (a,b,c,d,e,f,g,h,i) where + Bounded h, Bounded i) + => Bounded (a,b,c,d,e,f,g,h,i) where minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound, - minBound) + minBound) maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, - maxBound) + maxBound) instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, - Bounded h, Bounded i, Bounded j) - => Bounded (a,b,c,d,e,f,g,h,i,j) where + Bounded h, Bounded i, Bounded j) + => Bounded (a,b,c,d,e,f,g,h,i,j) where minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound, - minBound, minBound) + minBound, minBound) maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, - maxBound, maxBound) + maxBound, maxBound) instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, - Bounded h, Bounded i, Bounded j, Bounded k) - => Bounded (a,b,c,d,e,f,g,h,i,j,k) where + Bounded h, Bounded i, Bounded j, Bounded k) + => Bounded (a,b,c,d,e,f,g,h,i,j,k) where minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound, - minBound, minBound, minBound) + minBound, minBound, minBound) maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, - maxBound, maxBound, maxBound) + maxBound, maxBound, maxBound) instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, - Bounded h, Bounded i, Bounded j, Bounded k, Bounded l) - => Bounded (a,b,c,d,e,f,g,h,i,j,k,l) where + Bounded h, Bounded i, Bounded j, Bounded k, Bounded l) + => Bounded (a,b,c,d,e,f,g,h,i,j,k,l) where minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound, - minBound, minBound, minBound, minBound) + minBound, minBound, minBound, minBound) maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, - maxBound, maxBound, maxBound, maxBound) + maxBound, maxBound, maxBound, maxBound) instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, - Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m) - => Bounded (a,b,c,d,e,f,g,h,i,j,k,l,m) where + Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m) + => Bounded (a,b,c,d,e,f,g,h,i,j,k,l,m) where minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound, - minBound, minBound, minBound, minBound, minBound) + minBound, minBound, minBound, minBound, minBound) maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, - maxBound, maxBound, maxBound, maxBound, maxBound) + maxBound, maxBound, maxBound, maxBound, maxBound) instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, - Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m, Bounded n) - => Bounded (a,b,c,d,e,f,g,h,i,j,k,l,m,n) where + Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m, Bounded n) + => Bounded (a,b,c,d,e,f,g,h,i,j,k,l,m,n) where minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound, - minBound, minBound, minBound, minBound, minBound, minBound) + minBound, minBound, minBound, minBound, minBound, minBound) maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, - maxBound, maxBound, maxBound, maxBound, maxBound, maxBound) + maxBound, maxBound, maxBound, maxBound, maxBound, maxBound) instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g, - Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m, Bounded n, Bounded o) - => Bounded (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) where + Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m, Bounded n, Bounded o) + => Bounded (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) where minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound, - minBound, minBound, minBound, minBound, minBound, minBound, minBound) + minBound, minBound, minBound, minBound, minBound, minBound, minBound) maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, - maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound) + maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound) \end{code} %********************************************************* -%* * +%* * \subsection{Type @Bool@} -%* * +%* * %********************************************************* \begin{code} @@ -257,8 +257,8 @@ instance Enum Bool where pred False = error "Prelude.Enum.Bool.pred: bad argument" toEnum n | n == zeroInt = False - | n == oneInt = True - | otherwise = error "Prelude.Enum.Bool.toEnum: bad argument" + | n == oneInt = True + | otherwise = error "Prelude.Enum.Bool.toEnum: bad argument" fromEnum False = zeroInt fromEnum True = oneInt @@ -269,9 +269,9 @@ instance Enum Bool where \end{code} %********************************************************* -%* * +%* * \subsection{Type @Ordering@} -%* * +%* * %********************************************************* \begin{code} @@ -289,8 +289,8 @@ instance Enum Ordering where pred LT = error "Prelude.Enum.Ordering.pred: bad argument" toEnum n | n == zeroInt = LT - | n == oneInt = EQ - | n == twoInt = GT + | n == oneInt = EQ + | n == twoInt = GT toEnum _ = error "Prelude.Enum.Ordering.toEnum: bad argument" fromEnum LT = zeroInt @@ -303,9 +303,9 @@ instance Enum Ordering where \end{code} %********************************************************* -%* * +%* * \subsection{Type @Char@} -%* * +%* * %********************************************************* \begin{code} @@ -316,17 +316,17 @@ instance Bounded Char where instance Enum Char where succ (C# c#) | not (ord# c# ==# 0x10FFFF#) = C# (chr# (ord# c# +# 1#)) - | otherwise = error ("Prelude.Enum.Char.succ: bad argument") + | otherwise = error ("Prelude.Enum.Char.succ: bad argument") pred (C# c#) | not (ord# c# ==# 0#) = C# (chr# (ord# c# -# 1#)) - | otherwise = error ("Prelude.Enum.Char.pred: bad argument") + | otherwise = error ("Prelude.Enum.Char.pred: bad argument") toEnum = chr fromEnum = ord {-# INLINE enumFrom #-} enumFrom (C# x) = eftChar (ord# x) 0x10FFFF# - -- Blarg: technically I guess enumFrom isn't strict! + -- Blarg: technically I guess enumFrom isn't strict! {-# INLINE enumFromTo #-} enumFromTo (C# x) (C# y) = eftChar (ord# x) (ord# y) @@ -338,12 +338,12 @@ instance Enum Char where enumFromThenTo (C# x1) (C# x2) (C# y) = efdtChar (ord# x1) (ord# x2) (ord# y) {-# RULES -"eftChar" [~1] forall x y. eftChar x y = build (\c n -> eftCharFB c n x y) -"efdChar" [~1] forall x1 x2. efdChar x1 x2 = build (\ c n -> efdCharFB c n x1 x2) -"efdtChar" [~1] forall x1 x2 l. efdtChar x1 x2 l = build (\ c n -> efdtCharFB c n x1 x2 l) -"eftCharList" [1] eftCharFB (:) [] = eftChar -"efdCharList" [1] efdCharFB (:) [] = efdChar -"efdtCharList" [1] efdtCharFB (:) [] = efdtChar +"eftChar" [~1] forall x y. eftChar x y = build (\c n -> eftCharFB c n x y) +"efdChar" [~1] forall x1 x2. efdChar x1 x2 = build (\ c n -> efdCharFB c n x1 x2) +"efdtChar" [~1] forall x1 x2 l. efdtChar x1 x2 l = build (\ c n -> efdtCharFB c n x1 x2 l) +"eftCharList" [1] eftCharFB (:) [] = eftChar +"efdCharList" [1] efdCharFB (:) [] = efdChar +"efdtCharList" [1] efdtCharFB (:) [] = efdtChar #-} @@ -351,12 +351,12 @@ instance Enum Char where -- have hassles about arithmetic overflow at maxBound {-# INLINE [0] eftCharFB #-} eftCharFB c n x y = go x - where - go x | x ># y = n - | otherwise = C# (chr# x) `c` go (x +# 1#) + where + go x | x ># y = n + | otherwise = C# (chr# x) `c` go (x +# 1#) eftChar x y | x ># y = [] - | otherwise = C# (chr# x) : eftChar (x +# 1#) y + | otherwise = C# (chr# x) : eftChar (x +# 1#) y -- For enumFromThenTo we give up on inlining @@ -390,41 +390,41 @@ go_up_char_fb c n x delta lim = go_up x where go_up x | x ># lim = n - | otherwise = C# (chr# x) `c` go_up (x +# delta) + | otherwise = C# (chr# x) `c` go_up (x +# delta) go_dn_char_fb c n x delta lim = go_dn x where go_dn x | x <# lim = n - | otherwise = C# (chr# x) `c` go_dn (x +# delta) + | otherwise = C# (chr# x) `c` go_dn (x +# delta) go_up_char_list x delta lim = go_up x where go_up x | x ># lim = [] - | otherwise = C# (chr# x) : go_up (x +# delta) + | otherwise = C# (chr# x) : go_up (x +# delta) go_dn_char_list x delta lim = go_dn x where go_dn x | x <# lim = [] - | otherwise = C# (chr# x) : go_dn (x +# delta) + | otherwise = C# (chr# x) : go_dn (x +# delta) \end{code} %********************************************************* -%* * +%* * \subsection{Type @Int@} -%* * +%* * %********************************************************* Be careful about these instances. - (a) remember that you have to count down as well as up e.g. [13,12..0] - (b) be careful of Int overflow - (c) remember that Int is bounded, so [1..] terminates at maxInt + (a) remember that you have to count down as well as up e.g. [13,12..0] + (b) be careful of Int overflow + (c) remember that Int is bounded, so [1..] terminates at maxInt Also NB that the Num class isn't available in this module. - + \begin{code} instance Bounded Int where minBound = minInt @@ -444,7 +444,7 @@ instance Enum Int where {-# INLINE enumFrom #-} enumFrom (I# x) = eftInt x maxInt# where I# maxInt# = maxInt - -- Blarg: technically I guess enumFrom isn't strict! + -- Blarg: technically I guess enumFrom isn't strict! {-# INLINE enumFromTo #-} enumFromTo (I# x) (I# y) = eftInt x y @@ -462,27 +462,27 @@ instance Enum Int where -- In particular, we have rules for deforestation {-# RULES -"eftInt" [~1] forall x y. eftInt x y = build (\ c n -> eftIntFB c n x y) -"eftIntList" [1] eftIntFB (:) [] = eftInt +"eftInt" [~1] forall x y. eftInt x y = build (\ c n -> eftIntFB c n x y) +"eftIntList" [1] eftIntFB (:) [] = eftInt #-} eftInt :: Int# -> Int# -> [Int] -- [x1..x2] eftInt x y | x ># y = [] - | otherwise = go x - where - go x = I# x : if x ==# y then [] else go (x +# 1#) + | otherwise = go x + where + go x = I# x : if x ==# y then [] else go (x +# 1#) {-# INLINE [0] eftIntFB #-} eftIntFB :: (Int -> r -> r) -> r -> Int# -> Int# -> r -eftIntFB c n x y | x ># y = n - | otherwise = go x - where - go x = I# x `c` if x ==# y then n else go (x +# 1#) - -- Watch out for y=maxBound; hence ==, not > - -- Be very careful not to have more than one "c" - -- so that when eftInfFB is inlined we can inline - -- whatever is bound to "c" +eftIntFB c n x y | x ># y = n + | otherwise = go x + where + go x = I# x `c` if x ==# y then n else go (x +# 1#) + -- Watch out for y=maxBound; hence ==, not > + -- Be very careful not to have more than one "c" + -- so that when eftInfFB is inlined we can inline + -- whatever is bound to "c" ----------------------------------------------------- diff --git a/GHC/Err.lhs b/GHC/Err.lhs index d997476..c1c9774 100644 --- a/GHC/Err.lhs +++ b/GHC/Err.lhs @@ -21,7 +21,7 @@ ----------------------------------------------------------------------------- -- #hide -module GHC.Err +module GHC.Err ( irrefutPatError , noMethodBindingError @@ -29,16 +29,16 @@ module GHC.Err , patError , recSelError , recConError - , runtimeError -- :: Addr# -> a -- Addr# points to UTF8 encoded C string + , runtimeError -- :: Addr# -> a -- Addr# points to UTF8 encoded C string - , absentErr -- :: a - , divZeroError -- :: a - , overflowError -- :: a + , absentErr -- :: a + , divZeroError -- :: a + , overflowError -- :: a - , error -- :: String -> a - , assertError -- :: String -> Bool -> a -> a - - , undefined -- :: a + , error -- :: String -> a + , assertError -- :: String -> Bool -> a -> a + + , undefined -- :: a ) where #ifndef __HADDOCK__ @@ -49,9 +49,9 @@ import GHC.Exception \end{code} %********************************************************* -%* * +%* * \subsection{Error-ish functions} -%* * +%* * %********************************************************* \begin{code} @@ -69,9 +69,9 @@ undefined = error "Prelude.undefined" \end{code} %********************************************************* -%* * +%* * \subsection{Compiler generated errors + local utils} -%* * +%* * %********************************************************* Used for compiler-generated error message; @@ -85,17 +85,17 @@ absentErr = error "Oops! The program has entered an `absent' argument!\n" \begin{code} recSelError, recConError, irrefutPatError, runtimeError, - nonExhaustiveGuardsError, patError, noMethodBindingError - :: Addr# -> a -- All take a UTF8-encoded C string + nonExhaustiveGuardsError, patError, noMethodBindingError + :: Addr# -> a -- All take a UTF8-encoded C string -recSelError s = throw (RecSelError (unpackCStringUtf8# s)) -- No location info unfortunately -runtimeError s = error (unpackCStringUtf8# s) -- No location info unfortunately +recSelError s = throw (RecSelError (unpackCStringUtf8# s)) -- No location info unfortunately +runtimeError s = error (unpackCStringUtf8# s) -- No location info unfortunately nonExhaustiveGuardsError s = throw (PatternMatchFail (untangle s "Non-exhaustive guards in")) -irrefutPatError s = throw (PatternMatchFail (untangle s "Irrefutable pattern failed for pattern")) -recConError s = throw (RecConError (untangle s "Missing field in record construction")) +irrefutPatError s = throw (PatternMatchFail (untangle s "Irrefutable pattern failed for pattern")) +recConError s = throw (RecConError (untangle s "Missing field in record construction")) noMethodBindingError s = throw (NoMethodError (untangle s "No instance nor default method for class operation")) -patError s = throw (PatternMatchFail (untangle s "Non-exhaustive patterns in")) +patError s = throw (PatternMatchFail (untangle s "Non-exhaustive patterns in")) assertError :: Addr# -> Bool -> a -> a assertError str pred v @@ -106,11 +106,11 @@ assertError str pred v (untangle coded message) expects "coded" to be of the form - "location|details" + "location|details" It prints - location message details + location message details \begin{code} untangle :: Addr# -> String -> String @@ -125,10 +125,10 @@ untangle coded message (location, details) = case (span not_bar coded_str) of { (loc, rest) -> - case rest of - ('|':det) -> (loc, ' ' : det) - _ -> (loc, "") - } + case rest of + ('|':det) -> (loc, ' ' : det) + _ -> (loc, "") + } not_bar c = c /= '|' \end{code} diff --git a/GHC/Exception.lhs b/GHC/Exception.lhs index c2aa95f..852f465 100644 --- a/GHC/Exception.lhs +++ b/GHC/Exception.lhs @@ -16,11 +16,11 @@ ----------------------------------------------------------------------------- -- #hide -module GHC.Exception - ( module GHC.Exception, - Exception(..), AsyncException(..), - IOException(..), ArithException(..), ArrayException(..), - throw, throwIO, ioError ) +module GHC.Exception + ( module GHC.Exception, + Exception(..), AsyncException(..), + IOException(..), ArithException(..), ArrayException(..), + throw, throwIO, ioError ) where import GHC.Base @@ -28,9 +28,9 @@ import GHC.IOBase \end{code} %********************************************************* -%* * +%* * \subsection{Primitive catch} -%* * +%* * %********************************************************* catchException used to handle the passing around of the state to the @@ -68,16 +68,16 @@ catchException (IO m) k = IO $ \s -> catch# m (\ex -> unIO (k ex)) s -- Non-I\/O exceptions are not caught by this variant; to catch all -- exceptions, use 'Control.Exception.catch' from "Control.Exception". catch :: IO a -> (IOError -> IO a) -> IO a -catch m k = catchException m handler +catch m k = catchException m handler where handler (IOException err) = k err - handler other = throw other + handler other = throw other \end{code} %********************************************************* -%* * +%* * \subsection{Controlling asynchronous exception delivery} -%* * +%* * %********************************************************* \begin{code} diff --git a/GHC/Exts.hs b/GHC/Exts.hs index 27fecae..2baf420 100644 --- a/GHC/Exts.hs +++ b/GHC/Exts.hs @@ -16,25 +16,25 @@ module GHC.Exts ( -- * Representations of some basic types Int(..),Word(..),Float(..),Double(..),Integer(..),Char(..), - Ptr(..), FunPtr(..), + Ptr(..), FunPtr(..), -- * Primitive operations module GHC.Prim, - shiftL#, shiftRL#, iShiftL#, iShiftRA#, iShiftRL#, + shiftL#, shiftRL#, iShiftL#, iShiftRA#, iShiftRL#, uncheckedShiftL64#, uncheckedShiftRL64#, uncheckedIShiftL64#, uncheckedIShiftRA64#, - -- * Fusion - build, augment, + -- * Fusion + build, augment, - -- * Overloaded string literals - IsString(..), + -- * Overloaded string literals + IsString(..), - -- * Debugging - breakpoint, breakpointCond, + -- * Debugging + breakpoint, breakpointCond, - -- * Ids with special behaviour - lazy, inline, + -- * Ids with special behaviour + lazy, inline, -- * Transform comprehensions Down(..), groupWith, sortWith, the @@ -67,7 +67,7 @@ instance Ord a => Ord (Down a) where -- | 'the' ensures that all the elements of the list are identical -- and then returns that unique element the :: Eq a => [a] -> a -the (x:xs) +the (x:xs) | all (x ==) xs = x | otherwise = error "GHC.Exts.the: non-identical elements" the [] = error "GHC.Exts.the: empty list" diff --git a/GHC/Handle.hs b/GHC/Handle.hs index 8a79efa..3ccda18 100644 --- a/GHC/Handle.hs +++ b/GHC/Handle.hs @@ -22,9 +22,9 @@ module GHC.Handle ( withHandle, withHandle', withHandle_, wantWritableHandle, wantReadableHandle, wantSeekableHandle, - + newEmptyBuffer, allocateBuffer, readCharFromBuffer, writeCharIntoBuffer, - flushWriteBufferOnly, flushWriteBuffer, flushReadBuffer, + flushWriteBufferOnly, flushWriteBuffer, flushReadBuffer, fillReadBuffer, fillReadBufferWithoutBlocking, readRawBuffer, readRawBufferPtr, readRawBufferNoBlock, readRawBufferPtrNoBlock, @@ -70,14 +70,14 @@ import GHC.Real import GHC.Arr import GHC.Base -import GHC.Read ( Read ) +import GHC.Read ( Read ) import GHC.List import GHC.IOBase import GHC.Exception import GHC.Enum -import GHC.Num ( Integer(..), Num(..) ) +import GHC.Num ( Integer(..), Num(..) ) import GHC.Show -import GHC.Real ( toInteger ) +import GHC.Real ( toInteger ) #if defined(DEBUG_DUMP) import GHC.Pack #endif @@ -92,7 +92,7 @@ import GHC.Conc -- unbuffered hGetLine is a bit dodgy -- hSetBuffering: can't change buffering on a stream, --- when the read buffer is non-empty? (no way to flush the buffer) +-- when the read buffer is non-empty? (no way to flush the buffer) -- --------------------------------------------------------------------------- -- Are files opened by default in text or binary mode, if the user doesn't @@ -104,7 +104,7 @@ dEFAULT_OPEN_IN_BINARY_MODE = False :: Bool -- Creating a new handle newFileHandle :: FilePath -> (MVar Handle__ -> IO ()) -> Handle__ -> IO Handle -newFileHandle filepath finalizer hc = do +newFileHandle filepath finalizer hc = do m <- newMVar hc addMVarFinalizer m (finalizer m) return (FileHandle filepath m) @@ -126,8 +126,8 @@ operation: in these cases we also want to relinquish the lock. There are three versions of @withHandle@: corresponding to the three possible combinations of: - - the operation may side-effect the handle - - the operation may return a result + - the operation may side-effect the handle + - the operation may return a result If the operation generates an error or an exception is raised, the original handle is always replaced [ this is the case at the moment, @@ -141,15 +141,15 @@ withHandle fun h@(DuplexHandle _ m _) act = withHandle' fun h m act withHandle' :: String -> Handle -> MVar Handle__ -> (Handle__ -> IO (Handle__,a)) -> IO a -withHandle' fun h m act = +withHandle' fun h m act = block $ do h_ <- takeMVar m checkBufferInvariants h_ - (h',v) <- catchException (act h_) - (\ err -> putMVar m h_ >> - case err of - IOException ex -> ioError (augmentIOError ex fun h) - _ -> throw err) + (h',v) <- catchException (act h_) + (\ err -> putMVar m h_ >> + case err of + IOException ex -> ioError (augmentIOError ex fun h) + _ -> throw err) checkBufferInvariants h' putMVar m h' return v @@ -160,15 +160,15 @@ withHandle_ fun h@(FileHandle _ m) act = withHandle_' fun h m act withHandle_ fun h@(DuplexHandle _ m _) act = withHandle_' fun h m act withHandle_' :: String -> Handle -> MVar Handle__ -> (Handle__ -> IO a) -> IO a -withHandle_' fun h m act = +withHandle_' fun h m act = block $ do h_ <- takeMVar m checkBufferInvariants h_ - v <- catchException (act h_) - (\ err -> putMVar m h_ >> - case err of - IOException ex -> ioError (augmentIOError ex fun h) - _ -> throw err) + v <- catchException (act h_) + (\ err -> putMVar m h_ >> + case err of + IOException ex -> ioError (augmentIOError ex fun h) + _ -> throw err) checkBufferInvariants h_ putMVar m h_ return v @@ -179,15 +179,15 @@ withAllHandles__ fun h@(DuplexHandle _ r w) act = do withHandle__' fun h r act withHandle__' fun h w act -withHandle__' fun h m act = +withHandle__' fun h m act = block $ do h_ <- takeMVar m checkBufferInvariants h_ h' <- catchException (act h_) - (\ err -> putMVar m h_ >> - case err of - IOException ex -> ioError (augmentIOError ex fun h) - _ -> throw err) + (\ err -> putMVar m h_ >> + case err of + IOException ex -> ioError (augmentIOError ex fun h) + _ -> throw err) checkBufferInvariants h' putMVar m h' return () @@ -195,10 +195,10 @@ withHandle__' fun h m act = augmentIOError (IOError _ iot _ str fp) fun h = IOError (Just h) iot fun str filepath where filepath - | Just _ <- fp = fp - | otherwise = case h of - FileHandle fp _ -> Just fp - DuplexHandle fp _ _ -> Just fp + | Just _ <- fp = fp + | otherwise = case h of + FileHandle fp _ -> Just fp + DuplexHandle fp _ _ -> Just fp -- --------------------------------------------------------------------------- -- Wrapper for write operations. @@ -211,27 +211,27 @@ wantWritableHandle fun h@(DuplexHandle _ _ m) act -- ToDo: in the Duplex case, we don't need to checkWritableHandle wantWritableHandle' - :: String -> Handle -> MVar Handle__ - -> (Handle__ -> IO a) -> IO a + :: String -> Handle -> MVar Handle__ + -> (Handle__ -> IO a) -> IO a wantWritableHandle' fun h m act = withHandle_' fun h m (checkWritableHandle act) checkWritableHandle act handle_ - = case haType handle_ of - ClosedHandle -> ioe_closedHandle - SemiClosedHandle -> ioe_closedHandle - ReadHandle -> ioe_notWritable - ReadWriteHandle -> do - let ref = haBuffer handle_ - buf <- readIORef ref - new_buf <- - if not (bufferIsWritable buf) - then do b <- flushReadBuffer (haFD handle_) buf - return b{ bufState=WriteBuffer } - else return buf - writeIORef ref new_buf - act handle_ - _other -> act handle_ + = case haType handle_ of + ClosedHandle -> ioe_closedHandle + SemiClosedHandle -> ioe_closedHandle + ReadHandle -> ioe_notWritable + ReadWriteHandle -> do + let ref = haBuffer handle_ + buf <- readIORef ref + new_buf <- + if not (bufferIsWritable buf) + then do b <- flushReadBuffer (haFD handle_) buf + return b{ bufState=WriteBuffer } + else return buf + writeIORef ref new_buf + act handle_ + _other -> act handle_ -- --------------------------------------------------------------------------- -- Wrapper for read operations. @@ -244,79 +244,79 @@ wantReadableHandle fun h@(DuplexHandle _ m _) act -- ToDo: in the Duplex case, we don't need to checkReadableHandle wantReadableHandle' - :: String -> Handle -> MVar Handle__ - -> (Handle__ -> IO a) -> IO a + :: String -> Handle -> MVar Handle__ + -> (Handle__ -> IO a) -> IO a wantReadableHandle' fun h m act = withHandle_' fun h m (checkReadableHandle act) -checkReadableHandle act handle_ = - case haType handle_ of - ClosedHandle -> ioe_closedHandle - SemiClosedHandle -> ioe_closedHandle - AppendHandle -> ioe_notReadable - WriteHandle -> ioe_notReadable - ReadWriteHandle -> do - let ref = haBuffer handle_ - buf <- readIORef ref - when (bufferIsWritable buf) $ do - new_buf <- flushWriteBuffer (haFD handle_) (haIsStream handle_) buf - writeIORef ref new_buf{ bufState=ReadBuffer } - act handle_ - _other -> act handle_ +checkReadableHandle act handle_ = + case haType handle_ of + ClosedHandle -> ioe_closedHandle + SemiClosedHandle -> ioe_closedHandle + AppendHandle -> ioe_notReadable + WriteHandle -> ioe_notReadable + ReadWriteHandle -> do + let ref = haBuffer handle_ + buf <- readIORef ref + when (bufferIsWritable buf) $ do + new_buf <- flushWriteBuffer (haFD handle_) (haIsStream handle_) buf + writeIORef ref new_buf{ bufState=ReadBuffer } + act handle_ + _other -> act handle_ -- --------------------------------------------------------------------------- -- Wrapper for seek operations. wantSeekableHandle :: String -> Handle -> (Handle__ -> IO a) -> IO a wantSeekableHandle fun h@(DuplexHandle _ _ _) _act = - ioException (IOError (Just h) IllegalOperation fun - "handle is not seekable" Nothing) + ioException (IOError (Just h) IllegalOperation fun + "handle is not seekable" Nothing) wantSeekableHandle fun h@(FileHandle _ m) act = withHandle_' fun h m (checkSeekableHandle act) - -checkSeekableHandle act handle_ = - case haType handle_ of - ClosedHandle -> ioe_closedHandle - SemiClosedHandle -> ioe_closedHandle + +checkSeekableHandle act handle_ = + case haType handle_ of + ClosedHandle -> ioe_closedHandle + SemiClosedHandle -> ioe_closedHandle AppendHandle -> ioe_notSeekable _ | haIsBin handle_ || tEXT_MODE_SEEK_ALLOWED -> act handle_ | otherwise -> ioe_notSeekable_notBin - + -- ----------------------------------------------------------------------------- -- Handy IOErrors -ioe_closedHandle, ioe_EOF, - ioe_notReadable, ioe_notWritable, +ioe_closedHandle, ioe_EOF, + ioe_notReadable, ioe_notWritable, ioe_notSeekable, ioe_notSeekable_notBin :: IO a -ioe_closedHandle = ioException - (IOError Nothing IllegalOperation "" - "handle is closed" Nothing) -ioe_EOF = ioException +ioe_closedHandle = ioException + (IOError Nothing IllegalOperation "" + "handle is closed" Nothing) +ioe_EOF = ioException (IOError Nothing EOF "" "" Nothing) -ioe_notReadable = ioException - (IOError Nothing IllegalOperation "" - "handle is not open for reading" Nothing) -ioe_notWritable = ioException - (IOError Nothing IllegalOperation "" - "handle is not open for writing" Nothing) -ioe_notSeekable = ioException +ioe_notReadable = ioException (IOError Nothing IllegalOperation "" - "handle is not seekable" Nothing) -ioe_notSeekable_notBin = ioException + "handle is not open for reading" Nothing) +ioe_notWritable = ioException (IOError Nothing IllegalOperation "" - "seek operations on text-mode handles are not allowed on this platform" + "handle is not open for writing" Nothing) +ioe_notSeekable = ioException + (IOError Nothing IllegalOperation "" + "handle is not seekable" Nothing) +ioe_notSeekable_notBin = ioException + (IOError Nothing IllegalOperation "" + "seek operations on text-mode handles are not allowed on this platform" Nothing) - + ioe_finalizedHandle fp = throw (IOException - (IOError Nothing IllegalOperation "" - "handle is finalized" (Just fp))) + (IOError Nothing IllegalOperation "" + "handle is finalized" (Just fp))) ioe_bufsiz :: Int -> IO a -ioe_bufsiz n = ioException +ioe_bufsiz n = ioException (IOError Nothing InvalidArgument "hSetBuffering" - ("illegal buffer size " ++ showsPrec 9 n []) Nothing) - -- 9 => should be parens'ified. + ("illegal buffer size " ++ showsPrec 9 n []) Nothing) + -- 9 => should be parens'ified. -- ----------------------------------------------------------------------------- -- Handle Finalizers @@ -343,13 +343,13 @@ stdHandleFinalizer fp m = do handleFinalizer :: FilePath -> MVar Handle__ -> IO () handleFinalizer fp m = do handle_ <- takeMVar m - case haType handle_ of + case haType handle_ of ClosedHandle -> return () _ -> do flushWriteBufferOnly handle_ `catchException` \_ -> return () - -- ignore errors and async exceptions, and close the - -- descriptor anyway... - hClose_handle_ handle_ - return () + -- ignore errors and async exceptions, and close the + -- descriptor anyway... + hClose_handle_ handle_ + return () putMVar m (ioe_finalizedHandle fp) -- --------------------------------------------------------------------------- @@ -357,15 +357,15 @@ handleFinalizer fp m = do #ifdef DEBUG checkBufferInvariants h_ = do - let ref = haBuffer h_ + let ref = haBuffer h_ Buffer{ bufWPtr=w, bufRPtr=r, bufSize=size, bufState=state } <- readIORef ref if not ( - size > 0 - && r <= w - && w <= size - && ( r /= w || (r == 0 && w == 0) ) - && ( state /= WriteBuffer || r == 0 ) - && ( state /= WriteBuffer || w < size ) -- write buffer is never full + size > 0 + && r <= w + && w <= size + && ( r /= w || (r == 0 && w == 0) ) + && ( state /= WriteBuffer || r == 0 ) + && ( state /= WriteBuffer || w < size ) -- write buffer is never full ) then error "buffer invariant violation" else return () @@ -387,12 +387,12 @@ allocateBuffer sz@(I# size) state = IO $ \s -> writeCharIntoBuffer :: RawBuffer -> Int -> Char -> IO Int writeCharIntoBuffer slab (I# off) (C# c) = IO $ \s -> case writeCharArray# slab off c s of - s -> (# s, I# (off +# 1#) #) + s -> (# s, I# (off +# 1#) #) readCharFromBuffer :: RawBuffer -> Int -> IO (Char, Int) readCharFromBuffer slab (I# off) = IO $ \s -> case readCharArray# slab off s of - (# s, c #) -> (# s, (C# c, I# (off +# 1#)) #) + (# s, c #) -> (# s, (C# c, I# (off +# 1#)) #) getBuffer :: FD -> BufferState -> IO (IORef Buffer, BufferMode) getBuffer fd state = do @@ -418,8 +418,8 @@ flushWriteBufferOnly h_ = do ref = haBuffer h_ buf <- readIORef ref new_buf <- if bufferIsWritable buf - then flushWriteBuffer fd (haIsStream h_) buf - else return buf + then flushWriteBuffer fd (haIsStream h_) buf + else return buf writeIORef ref new_buf -- flushBuffer syncs the file with the buffer, including moving the @@ -450,7 +450,7 @@ flushReadBuffer fd buf puts ("flushReadBuffer: new file offset = " ++ show off ++ "\n") # endif throwErrnoIfMinus1Retry "flushReadBuffer" - (c_lseek fd (fromIntegral off) sEEK_CUR) + (c_lseek fd (fromIntegral off) sEEK_CUR) return buf{ bufWPtr=0, bufRPtr=0 } flushWriteBuffer :: FD -> Bool -> Buffer -> IO Buffer @@ -464,7 +464,7 @@ flushWriteBuffer fd is_stream buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w } = then return (buf{ bufRPtr=0, bufWPtr=0 }) else do res <- writeRawBuffer "flushWriteBuffer" fd is_stream b - (fromIntegral r) (fromIntegral bytes) + (fromIntegral r) (fromIntegral bytes) let res' = fromIntegral res if res' < bytes then flushWriteBuffer fd is_stream (buf{ bufRPtr = r + res' }) @@ -492,18 +492,18 @@ fillReadBufferLoop fd is_line is_stream buf b w size = do puts ("fillReadBufferLoop: bytes = " ++ show bytes ++ "\n") #endif res <- readRawBuffer "fillReadBuffer" fd is_stream b - (fromIntegral w) (fromIntegral bytes) + (fromIntegral w) (fromIntegral bytes) let res' = fromIntegral res #ifdef DEBUG_DUMP puts ("fillReadBufferLoop: res' = " ++ show res' ++ "\n") #endif if res' == 0 then if w == 0 - then ioe_EOF - else return buf{ bufRPtr=0, bufWPtr=w } + then ioe_EOF + else return buf{ bufRPtr=0, bufWPtr=w } else if res' < bytes && not is_line - then fillReadBufferLoop fd is_line is_stream buf b (w+res') size - else return buf{ bufRPtr=0, bufWPtr=w+res' } + then fillReadBufferLoop fd is_line is_stream buf b (w+res') size + else return buf{ bufRPtr=0, bufWPtr=w+res' } fillReadBufferWithoutBlocking :: FD -> Bool -> Buffer -> IO Buffer @@ -515,7 +515,7 @@ fillReadBufferWithoutBlocking fd is_stream puts ("fillReadBufferLoopNoBlock: bytes = " ++ show size ++ "\n") #endif res <- readRawBufferNoBlock "fillReadBuffer" fd is_stream b - 0 (fromIntegral size) + 0 (fromIntegral size) let res' = fromIntegral res #ifdef DEBUG_DUMP puts ("fillReadBufferLoopNoBlock: res' = " ++ show res' ++ "\n") @@ -612,7 +612,7 @@ writeRawBuffer loc fd is_nonblock buf off len else do threadWaitWrite (fromIntegral fd); unsafe_write where do_write call = throwErrnoIfMinus1RetryMayBlock loc call - (threadWaitWrite (fromIntegral fd)) + (threadWaitWrite (fromIntegral fd)) unsafe_write = do_write (write_rawBuffer fd buf off len) safe_write = do_write (safe_write_rawBuffer (fromIntegral fd) buf off len) @@ -626,7 +626,7 @@ writeRawBufferPtr loc fd is_nonblock buf off len else do threadWaitWrite (fromIntegral fd); unsafe_write where do_write call = throwErrnoIfMinus1RetryMayBlock loc call - (threadWaitWrite (fromIntegral fd)) + (threadWaitWrite (fromIntegral fd)) unsafe_write = do_write (write_off fd buf off len) safe_write = do_write (safe_write_off (fromIntegral fd) buf off len) @@ -677,15 +677,15 @@ readRawBufferPtrNoBlock = readRawBufferPtr asyncReadRawBuffer loc fd is_stream buf off len = do (l, rc) <- asyncReadBA (fromIntegral fd) (if is_stream then 1 else 0) - (fromIntegral len) off buf + (fromIntegral len) off buf if l == (-1) then - ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing) + ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing) else return (fromIntegral l) asyncReadRawBufferPtr loc fd is_stream buf off len = do (l, rc) <- asyncRead (fromIntegral fd) (if is_stream then 1 else 0) - (fromIntegral len) (buf `plusPtr` off) + (fromIntegral len) (buf `plusPtr` off) if l == (-1) then ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing) @@ -693,7 +693,7 @@ asyncReadRawBufferPtr loc fd is_stream buf off len = do asyncWriteRawBuffer loc fd is_stream buf off len = do (l, rc) <- asyncWriteBA (fromIntegral fd) (if is_stream then 1 else 0) - (fromIntegral len) off buf + (fromIntegral len) off buf if l == (-1) then ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing) @@ -701,7 +701,7 @@ asyncWriteRawBuffer loc fd is_stream buf off len = do asyncWriteRawBufferPtr loc fd is_stream buf off len = do (l, rc) <- asyncWrite (fromIntegral fd) (if is_stream then 1 else 0) - (fromIntegral len) (buf `plusPtr` off) + (fromIntegral len) (buf `plusPtr` off) if l == (-1) then ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing) @@ -868,18 +868,18 @@ openFile' filepath mode binary = let oflags1 = case mode of - ReadMode -> read_flags + ReadMode -> read_flags #ifdef mingw32_HOST_OS - WriteMode -> write_flags .|. o_TRUNC + WriteMode -> write_flags .|. o_TRUNC #else - WriteMode -> write_flags + WriteMode -> write_flags #endif - ReadWriteMode -> rw_flags - AppendMode -> append_flags + ReadWriteMode -> rw_flags + AppendMode -> append_flags binary_flags - | binary = o_BINARY - | otherwise = 0 + | binary = o_BINARY + | otherwise = 0 oflags = oflags1 .|. binary_flags in do @@ -890,22 +890,22 @@ openFile' filepath mode binary = -- always returns EISDIR if the file is a directory and was opened -- for writing, so I think we're ok with a single open() here... fd <- throwErrnoIfMinus1Retry "openFile" - (c_open f (fromIntegral oflags) 0o666) + (c_open f (fromIntegral oflags) 0o666) stat@(fd_type,_,_) <- fdStat fd h <- fdToHandle_stat fd (Just stat) False filepath mode binary `catchException` \e -> do c_close fd; throw e - -- NB. don't forget to close the FD if fdToHandle' fails, otherwise - -- this FD leaks. - -- ASSERT: if we just created the file, then fdToHandle' won't fail - -- (so we don't need to worry about removing the newly created file - -- in the event of an error). + -- NB. don't forget to close the FD if fdToHandle' fails, otherwise + -- this FD leaks. + -- ASSERT: if we just created the file, then fdToHandle' won't fail + -- (so we don't need to worry about removing the newly created file + -- in the event of an error). #ifndef mingw32_HOST_OS - -- we want to truncate() if this is an open in WriteMode, but only - -- if the target is a RegularFile. ftruncate() fails on special files - -- like /dev/null. + -- we want to truncate() if this is an open in WriteMode, but only + -- if the target is a RegularFile. ftruncate() fails on special files + -- like /dev/null. if mode == WriteMode && fd_type == RegularFile then throwErrnoIf (/=0) "openFile" (c_ftruncate fd 0) @@ -945,44 +945,44 @@ fdToHandle_stat fd mb_stat is_socket filepath mode binary = do #endif let (ha_type, write) = - case mode of - ReadMode -> ( ReadHandle, False ) - WriteMode -> ( WriteHandle, True ) - ReadWriteMode -> ( ReadWriteHandle, True ) - AppendMode -> ( AppendHandle, True ) + case mode of + ReadMode -> ( ReadHandle, False ) + WriteMode -> ( WriteHandle, True ) + ReadWriteMode -> ( ReadWriteHandle, True ) + AppendMode -> ( AppendHandle, True ) -- open() won't tell us if it was a directory if we only opened for -- reading, so check again. (fd_type,dev,ino) <- case mb_stat of Just x -> return x - Nothing -> fdStat fd + Nothing -> fdStat fd case fd_type of - Directory -> - ioException (IOError Nothing InappropriateType "openFile" - "is a directory" Nothing) + Directory -> + ioException (IOError Nothing InappropriateType "openFile" + "is a directory" Nothing) - -- regular files need to be locked - RegularFile -> do + -- regular files need to be locked + RegularFile -> do #ifndef mingw32_HOST_OS - r <- lockFile fd dev ino (fromBool write) - when (r == -1) $ - ioException (IOError Nothing ResourceBusy "openFile" - "file is locked" Nothing) + r <- lockFile fd dev ino (fromBool write) + when (r == -1) $ + ioException (IOError Nothing ResourceBusy "openFile" + "file is locked" Nothing) #endif - mkFileHandle fd is_stream filepath ha_type binary + mkFileHandle fd is_stream filepath ha_type binary - Stream - -- only *Streams* can be DuplexHandles. Other read/write - -- Handles must share a buffer. - | ReadWriteHandle <- ha_type -> - mkDuplexHandle fd is_stream filepath binary - | otherwise -> - mkFileHandle fd is_stream filepath ha_type binary + Stream + -- only *Streams* can be DuplexHandles. Other read/write + -- Handles must share a buffer. + | ReadWriteHandle <- ha_type -> + mkDuplexHandle fd is_stream filepath binary + | otherwise -> + mkFileHandle fd is_stream filepath ha_type binary - RawDevice -> - mkFileHandle fd is_stream filepath ha_type binary + RawDevice -> + mkFileHandle fd is_stream filepath ha_type binary -- | Old API kept to avoid breaking clients fdToHandle' :: FD -> Maybe FDType -> Bool -> FilePath -> IOMode -> Bool @@ -1013,19 +1013,19 @@ foreign import ccall unsafe "unlockFile" #endif mkStdHandle :: FD -> FilePath -> HandleType -> IORef Buffer -> BufferMode - -> IO Handle + -> IO Handle mkStdHandle fd filepath ha_type buf bmode = do spares <- newIORef BufferListNil newFileHandle filepath (stdHandleFinalizer filepath) - (Handle__ { haFD = fd, - haType = ha_type, + (Handle__ { haFD = fd, + haType = ha_type, haIsBin = dEFAULT_OPEN_IN_BINARY_MODE, - haIsStream = False, -- means FD is blocking on Unix - haBufferMode = bmode, - haBuffer = buf, - haBuffers = spares, - haOtherSide = Nothing - }) + haIsStream = False, -- means FD is blocking on Unix + haBufferMode = bmode, + haBuffer = buf, + haBuffers = spares, + haOtherSide = Nothing + }) mkFileHandle :: FD -> Bool -> FilePath -> HandleType -> Bool -> IO Handle mkFileHandle fd is_stream filepath ha_type binary = do @@ -1037,50 +1037,50 @@ mkFileHandle fd is_stream filepath ha_type binary = do -- from read mode to write mode on a buffered text-mode handle, see bug -- \#679. bmode <- case ha_type of - ReadWriteHandle | not binary -> return NoBuffering - _other -> return bmode + ReadWriteHandle | not binary -> return NoBuffering + _other -> return bmode #endif spares <- newIORef BufferListNil newFileHandle filepath (handleFinalizer filepath) - (Handle__ { haFD = fd, - haType = ha_type, + (Handle__ { haFD = fd, + haType = ha_type, haIsBin = binary, - haIsStream = is_stream, - haBufferMode = bmode, - haBuffer = buf, - haBuffers = spares, - haOtherSide = Nothing - }) + haIsStream = is_stream, + haBufferMode = bmode, + haBuffer = buf, + haBuffers = spares, + haOtherSide = Nothing + }) mkDuplexHandle :: FD -> Bool -> FilePath -> Bool -> IO Handle mkDuplexHandle fd is_stream filepath binary = do (w_buf, w_bmode) <- getBuffer fd WriteBuffer w_spares <- newIORef BufferListNil let w_handle_ = - Handle__ { haFD = fd, - haType = WriteHandle, + Handle__ { haFD = fd, + haType = WriteHandle, haIsBin = binary, - haIsStream = is_stream, - haBufferMode = w_bmode, - haBuffer = w_buf, - haBuffers = w_spares, - haOtherSide = Nothing - } + haIsStream = is_stream, + haBufferMode = w_bmode, + haBuffer = w_buf, + haBuffers = w_spares, + haOtherSide = Nothing + } write_side <- newMVar w_handle_ (r_buf, r_bmode) <- getBuffer fd ReadBuffer r_spares <- newIORef BufferListNil let r_handle_ = - Handle__ { haFD = fd, - haType = ReadHandle, + Handle__ { haFD = fd, + haType = ReadHandle, haIsBin = binary, - haIsStream = is_stream, - haBufferMode = r_bmode, - haBuffer = r_buf, - haBuffers = r_spares, - haOtherSide = Just write_side - } + haIsStream = is_stream, + haBufferMode = r_bmode, + haBuffer = r_buf, + haBuffers = r_spares, + haOtherSide = Just write_side + } read_side <- newMVar r_handle_ addMVarFinalizer write_side (handleFinalizer filepath write_side) @@ -1088,7 +1088,7 @@ mkDuplexHandle fd is_stream filepath binary = do initBufferState ReadHandle = ReadBuffer -initBufferState _ = WriteBuffer +initBufferState _ = WriteBuffer -- --------------------------------------------------------------------------- -- Closing a handle @@ -1127,7 +1127,7 @@ hClose_help handle_ = case haType handle_ of ClosedHandle -> return (handle_,Nothing) _ -> do flushWriteBufferOnly handle_ -- interruptible - hClose_handle_ handle_ + hClose_handle_ handle_ hClose_handle_ handle_ = do let fd = haFD handle_ @@ -1143,9 +1143,9 @@ hClose_handle_ handle_ = do Nothing -> (do throwErrnoIfMinus1Retry_ "hClose" #ifdef mingw32_HOST_OS - (closeFd (haIsStream handle_) fd) + (closeFd (haIsStream handle_) fd) #else - (c_close fd) + (c_close fd) #endif return Nothing ) @@ -1165,8 +1165,8 @@ hClose_handle_ handle_ = do -- we must set the fd to -1, because the finalizer is going -- to run eventually and try to close/unlock it. return (handle_{ haFD = -1, - haType = ClosedHandle - }, + haType = ClosedHandle + }, maybe_exception) {-# NOINLINE noBuffer #-} @@ -1182,14 +1182,14 @@ hFileSize :: Handle -> IO Integer hFileSize handle = withHandle_ "hFileSize" handle $ \ handle_ -> do case haType handle_ of - ClosedHandle -> ioe_closedHandle - SemiClosedHandle -> ioe_closedHandle + ClosedHandle -> ioe_closedHandle + SemiClosedHandle -> ioe_closedHandle _ -> do flushWriteBufferOnly handle_ - r <- fdFileSize (haFD handle_) - if r /= -1 - then return r - else ioException (IOError Nothing InappropriateType "hFileSize" - "not a regular file" Nothing) + r <- fdFileSize (haFD handle_) + if r /= -1 + then return r + else ioException (IOError Nothing InappropriateType "hFileSize" + "not a regular file" Nothing) -- | 'hSetFileSize' @hdl@ @size@ truncates the physical file with handle @hdl@ to @size@ bytes. @@ -1198,12 +1198,12 @@ hSetFileSize :: Handle -> Integer -> IO () hSetFileSize handle size = withHandle_ "hSetFileSize" handle $ \ handle_ -> do case haType handle_ of - ClosedHandle -> ioe_closedHandle - SemiClosedHandle -> ioe_closedHandle + ClosedHandle -> ioe_closedHandle + SemiClosedHandle -> ioe_closedHandle _ -> do flushWriteBufferOnly handle_ - throwErrnoIf (/=0) "hSetFileSize" - (c_ftruncate (haFD handle_) (fromIntegral size)) - return () + throwErrnoIf (/=0) "hSetFileSize" + (c_ftruncate (haFD handle_) (fromIntegral size)) + return () -- --------------------------------------------------------------------------- -- Detecting the End of Input @@ -1249,8 +1249,8 @@ hLookAhead handle = do -- fill up the read buffer if necessary new_buf <- if bufferEmpty buf - then fillReadBuffer fd True (haIsStream handle_) buf - else return buf + then fillReadBuffer fd True (haIsStream handle_) buf + else return buf writeIORef ref new_buf @@ -1286,49 +1286,49 @@ hSetBuffering handle mode = case haType handle_ of ClosedHandle -> ioe_closedHandle _ -> do - {- Note: - - we flush the old buffer regardless of whether - the new buffer could fit the contents of the old buffer - or not. - - allow a handle's buffering to change even if IO has - occurred (ANSI C spec. does not allow this, nor did - the previous implementation of IO.hSetBuffering). - - a non-standard extension is to allow the buffering - of semi-closed handles to change [sof 6/98] - -} - flushBuffer handle_ - - let state = initBufferState (haType handle_) - new_buf <- - case mode of - -- we always have a 1-character read buffer for - -- unbuffered handles: it's needed to - -- support hLookAhead. - NoBuffering -> allocateBuffer 1 ReadBuffer - LineBuffering -> allocateBuffer dEFAULT_BUFFER_SIZE state - BlockBuffering Nothing -> allocateBuffer dEFAULT_BUFFER_SIZE state - BlockBuffering (Just n) | n <= 0 -> ioe_bufsiz n - | otherwise -> allocateBuffer n state - writeIORef (haBuffer handle_) new_buf - - -- for input terminals we need to put the terminal into - -- cooked or raw mode depending on the type of buffering. - is_tty <- fdIsTTY (haFD handle_) - when (is_tty && isReadableHandleType (haType handle_)) $ - case mode of + {- Note: + - we flush the old buffer regardless of whether + the new buffer could fit the contents of the old buffer + or not. + - allow a handle's buffering to change even if IO has + occurred (ANSI C spec. does not allow this, nor did + the previous implementation of IO.hSetBuffering). + - a non-standard extension is to allow the buffering + of semi-closed handles to change [sof 6/98] + -} + flushBuffer handle_ + + let state = initBufferState (haType handle_) + new_buf <- + case mode of + -- we always have a 1-character read buffer for + -- unbuffered handles: it's needed to + -- support hLookAhead. + NoBuffering -> allocateBuffer 1 ReadBuffer + LineBuffering -> allocateBuffer dEFAULT_BUFFER_SIZE state + BlockBuffering Nothing -> allocateBuffer dEFAULT_BUFFER_SIZE state + BlockBuffering (Just n) | n <= 0 -> ioe_bufsiz n + | otherwise -> allocateBuffer n state + writeIORef (haBuffer handle_) new_buf + + -- for input terminals we need to put the terminal into + -- cooked or raw mode depending on the type of buffering. + is_tty <- fdIsTTY (haFD handle_) + when (is_tty && isReadableHandleType (haType handle_)) $ + case mode of #ifndef mingw32_HOST_OS - -- 'raw' mode under win32 is a bit too specialised (and troublesome - -- for most common uses), so simply disable its use here. - NoBuffering -> setCooked (haFD handle_) False + -- 'raw' mode under win32 is a bit too specialised (and troublesome + -- for most common uses), so simply disable its use here. + NoBuffering -> setCooked (haFD handle_) False #else - NoBuffering -> return () + NoBuffering -> return () #endif - _ -> setCooked (haFD handle_) True + _ -> setCooked (haFD handle_) True - -- throw away spare buffers, they might be the wrong size - writeIORef (haBuffers handle_) BufferListNil + -- throw away spare buffers, they might be the wrong size + writeIORef (haBuffers handle_) BufferListNil - return (handle_{ haBufferMode = mode }) + return (handle_{ haBufferMode = mode }) -- ----------------------------------------------------------------------------- -- hFlush @@ -1349,9 +1349,9 @@ hFlush handle = wantWritableHandle "hFlush" handle $ \ handle_ -> do buf <- readIORef (haBuffer handle_) if bufferIsWritable buf && not (bufferEmpty buf) - then do flushed_buf <- flushWriteBuffer (haFD handle_) (haIsStream handle_) buf - writeIORef (haBuffer handle_) flushed_buf - else return () + then do flushed_buf <- flushWriteBuffer (haFD handle_) (haIsStream handle_) buf + writeIORef (haBuffer handle_) flushed_buf + else return () -- ----------------------------------------------------------------------------- @@ -1364,7 +1364,7 @@ instance Eq HandlePosn where instance Show HandlePosn where showsPrec p (HandlePosn h pos) = - showsPrec p h . showString " at position " . shows pos + showsPrec p h . showString " at position " . shows pos -- HandlePosition is the Haskell equivalent of POSIX' off_t. -- We represent it as an Integer on the Haskell side, but @@ -1396,11 +1396,11 @@ hSetPosn (HandlePosn h i) = hSeek h AbsoluteSeek i -- | A mode that determines the effect of 'hSeek' @hdl mode i@, as follows: data SeekMode - = AbsoluteSeek -- ^ the position of @hdl@ is set to @i@. - | RelativeSeek -- ^ the position of @hdl@ is set to offset @i@ - -- from the current position. - | SeekFromEnd -- ^ the position of @hdl@ is set to offset @i@ - -- from the end of the file. + = AbsoluteSeek -- ^ the position of @hdl@ is set to @i@. + | RelativeSeek -- ^ the position of @hdl@ is set to offset @i@ + -- from the current position. + | SeekFromEnd -- ^ the position of @hdl@ is set to offset @i@ + -- from the end of the file. deriving (Eq, Ord, Ix, Enum, Read, Show) {- Note: @@ -1443,8 +1443,8 @@ hSeek handle mode offset = fd = haFD handle_ let do_seek = - throwErrnoIfMinus1Retry_ "hSeek" - (c_lseek (haFD handle_) (fromIntegral offset) whence) + throwErrnoIfMinus1Retry_ "hSeek" + (c_lseek (haFD handle_) (fromIntegral offset) whence) whence :: CInt whence = case mode of @@ -1453,14 +1453,14 @@ hSeek handle mode offset = SeekFromEnd -> sEEK_END if bufferIsWritable buf - then do new_buf <- flushWriteBuffer fd (haIsStream handle_) buf - writeIORef ref new_buf - do_seek - else do + then do new_buf <- flushWriteBuffer fd (haIsStream handle_) buf + writeIORef ref new_buf + do_seek + else do if mode == RelativeSeek && offset >= 0 && offset < fromIntegral (w - r) - then writeIORef ref buf{ bufRPtr = r + fromIntegral offset } - else do + then writeIORef ref buf{ bufRPtr = r + fromIntegral offset } + else do new_buf <- flushReadBuffer (haFD handle_) buf writeIORef ref new_buf @@ -1472,22 +1472,22 @@ hTell handle = wantSeekableHandle "hGetPosn" handle $ \ handle_ -> do #if defined(mingw32_HOST_OS) - -- urgh, on Windows we have to worry about \n -> \r\n translation, - -- so we can't easily calculate the file position using the - -- current buffer size. Just flush instead. + -- urgh, on Windows we have to worry about \n -> \r\n translation, + -- so we can't easily calculate the file position using the + -- current buffer size. Just flush instead. flushBuffer handle_ #endif let fd = haFD handle_ posn <- fromIntegral `liftM` - throwErrnoIfMinus1Retry "hGetPosn" - (c_lseek fd 0 sEEK_CUR) + throwErrnoIfMinus1Retry "hGetPosn" + (c_lseek fd 0 sEEK_CUR) let ref = haBuffer handle_ buf <- readIORef ref let real_posn - | bufferIsWritable buf = posn + fromIntegral (bufWPtr buf) - | otherwise = posn - fromIntegral (bufWPtr buf - bufRPtr buf) + | bufferIsWritable buf = posn + fromIntegral (bufWPtr buf) + | otherwise = posn - fromIntegral (bufWPtr buf - bufRPtr buf) # ifdef DEBUG_DUMP puts ("\nhGetPosn: (fd, posn, real_posn) = " ++ show (fd, posn, real_posn) ++ "\n") puts (" (bufWPtr, bufRPtr) = " ++ show (bufWPtr buf, bufRPtr buf) ++ "\n") @@ -1507,14 +1507,14 @@ hIsOpen handle = case haType handle_ of ClosedHandle -> return False SemiClosedHandle -> return False - _ -> return True + _ -> return True hIsClosed :: Handle -> IO Bool hIsClosed handle = withHandle_ "hIsClosed" handle $ \ handle_ -> do case haType handle_ of - ClosedHandle -> return True - _ -> return False + ClosedHandle -> return True + _ -> return False {- not defined, nor exported, but mentioned here for documentation purposes: @@ -1531,18 +1531,18 @@ hIsReadable (DuplexHandle _ _ _) = return True hIsReadable handle = withHandle_ "hIsReadable" handle $ \ handle_ -> do case haType handle_ of - ClosedHandle -> ioe_closedHandle - SemiClosedHandle -> ioe_closedHandle - htype -> return (isReadableHandleType htype) + ClosedHandle -> ioe_closedHandle + SemiClosedHandle -> ioe_closedHandle + htype -> return (isReadableHandleType htype) hIsWritable :: Handle -> IO Bool hIsWritable (DuplexHandle _ _ _) = return True hIsWritable handle = withHandle_ "hIsWritable" handle $ \ handle_ -> do case haType handle_ of - ClosedHandle -> ioe_closedHandle - SemiClosedHandle -> ioe_closedHandle - htype -> return (isWritableHandleType htype) + ClosedHandle -> ioe_closedHandle + SemiClosedHandle -> ioe_closedHandle + htype -> return (isWritableHandleType htype) -- | Computation 'hGetBuffering' @hdl@ returns the current buffering mode -- for @hdl@. @@ -1551,19 +1551,19 @@ hGetBuffering :: Handle -> IO BufferMode hGetBuffering handle = withHandle_ "hGetBuffering" handle $ \ handle_ -> do case haType handle_ of - ClosedHandle -> ioe_closedHandle + ClosedHandle -> ioe_closedHandle _ -> - -- We're being non-standard here, and allow the buffering - -- of a semi-closed handle to be queried. -- sof 6/98 - return (haBufferMode handle_) -- could be stricter.. + -- We're being non-standard here, and allow the buffering + -- of a semi-closed handle to be queried. -- sof 6/98 + return (haBufferMode handle_) -- could be stricter.. hIsSeekable :: Handle -> IO Bool hIsSeekable handle = withHandle_ "hIsSeekable" handle $ \ handle_ -> do case haType handle_ of - ClosedHandle -> ioe_closedHandle - SemiClosedHandle -> ioe_closedHandle - AppendHandle -> return False + ClosedHandle -> ioe_closedHandle + SemiClosedHandle -> ioe_closedHandle + AppendHandle -> return False _ -> do t <- fdType (haFD handle_) return ((t == RegularFile || t == RawDevice) && (haIsBin handle_ || tEXT_MODE_SEEK_ALLOWED)) @@ -1656,7 +1656,7 @@ dupHandleTo other_side hto_ h_ = do flushBuffer h_ -- Windows' dup2 does not return the new descriptor, unlike Unix throwErrnoIfMinus1 "dupHandleTo" $ - c_dup2 (haFD h_) (haFD hto_) + c_dup2 (haFD h_) (haFD hto_) dupHandle_ other_side h_ (haFD hto_) dupHandle_ :: Maybe (MVar Handle__) -> Handle__ -> FD @@ -1667,9 +1667,9 @@ dupHandle_ other_side h_ new_fd = do ioref_buffers <- newIORef BufferListNil let new_handle_ = h_{ haFD = new_fd, - haBuffer = ioref, - haBuffers = ioref_buffers, - haOtherSide = other_side } + haBuffer = ioref, + haBuffers = ioref_buffers, + haOtherSide = other_side } return (h_, new_handle_) -- ----------------------------------------------------------------------------- @@ -1699,7 +1699,7 @@ hDuplicateTo h1@(DuplexHandle _ r1 w1) h2@(DuplexHandle _ r2 w2) = do withHandle' "hDuplicateTo" h1 r1 (dupHandleTo (Just w1) r2_) hDuplicateTo h1 _ = ioException (IOError (Just h1) IllegalOperation "hDuplicateTo" - "handles are incompatible" Nothing) + "handles are incompatible" Nothing) -- --------------------------------------------------------------------------- -- showing Handles. @@ -1715,15 +1715,15 @@ showHandle' filepath is_duplex h = withHandle_ "showHandle" h $ \hdl_ -> let showType | is_duplex = showString "duplex (read-write)" - | otherwise = shows (haType hdl_) + | otherwise = shows (haType hdl_) in return (( showChar '{' . showHdl (haType hdl_) - (showString "loc=" . showString filepath . showChar ',' . - showString "type=" . showType . showChar ',' . - showString "binary=" . shows (haIsBin hdl_) . showChar ',' . - showString "buffering=" . showBufMode (unsafePerformIO (readIORef (haBuffer hdl_))) (haBufferMode hdl_) . showString "}" ) + (showString "loc=" . showString filepath . showChar ',' . + showString "type=" . showType . showChar ',' . + showString "binary=" . shows (haIsBin hdl_) . showChar ',' . + showString "buffering=" . showBufMode (unsafePerformIO (readIORef (haBuffer hdl_))) (haBufferMode hdl_) . showString "}" ) ) "") where @@ -1731,15 +1731,15 @@ showHandle' filepath is_duplex h = showHdl ht cont = case ht of ClosedHandle -> shows ht . showString "}" - _ -> cont + _ -> cont showBufMode :: Buffer -> BufferMode -> ShowS showBufMode buf bmo = case bmo of NoBuffering -> showString "none" - LineBuffering -> showString "line" - BlockBuffering (Just n) -> showString "block " . showParen True (shows n) - BlockBuffering Nothing -> showString "block " . showParen True (shows def) + LineBuffering -> showString "line" + BlockBuffering (Just n) -> showString "block " . showParen True (shows n) + BlockBuffering Nothing -> showString "block " . showParen True (shows def) where def :: Int def = bufSize buf @@ -1750,7 +1750,7 @@ showHandle' filepath is_duplex h = #if defined(DEBUG_DUMP) puts :: String -> IO () puts s = do write_rawBuffer 1 (unsafeCoerce# (packCString# s)) 0 (fromIntegral (length s)) - return () + return () #endif -- ----------------------------------------------------------------------------- @@ -1762,11 +1762,11 @@ throwErrnoIfMinus1RetryOnBlock loc f on_block = res <- f if (res :: CInt) == -1 then do - err <- getErrno - if err == eINTR - then throwErrnoIfMinus1RetryOnBlock loc f on_block + err <- getErrno + if err == eINTR + then throwErrnoIfMinus1RetryOnBlock loc f on_block else if err == eWOULDBLOCK || err == eAGAIN - then do on_block + then do on_block else throwErrno loc else return res diff --git a/GHC/IO.hs b/GHC/IO.hs index 151d251..5d88dc1 100644 --- a/GHC/IO.hs +++ b/GHC/IO.hs @@ -20,8 +20,8 @@ -- #hide module GHC.IO ( hWaitForInput, hGetChar, hGetLine, hGetContents, hPutChar, hPutStr, - commitBuffer', -- hack, see below - hGetcBuffered, -- needed by ghc/compiler/utils/StringBuffer.lhs + commitBuffer', -- hack, see below + hGetcBuffered, -- needed by ghc/compiler/utils/StringBuffer.lhs hGetBuf, hGetBufNonBlocking, hPutBuf, hPutBufNonBlocking, slurpFile, memcpy_ba_baoff, memcpy_ptr_baoff, @@ -40,7 +40,7 @@ import System.Posix.Internals import GHC.Enum import GHC.Base import GHC.IOBase -import GHC.Handle -- much of the real stuff is in here +import GHC.Handle -- much of the real stuff is in here import GHC.Real import GHC.Num import GHC.Show @@ -82,19 +82,19 @@ hWaitForInput h msecs = do buf <- readIORef ref if not (bufferEmpty buf) - then return True - else do + then return True + else do if msecs < 0 - then do buf' <- fillReadBuffer (haFD handle_) True - (haIsStream handle_) buf - writeIORef ref buf' - return True - else do r <- throwErrnoIfMinus1Retry "hWaitForInput" $ - fdReady (haFD handle_) 0 {- read -} - (fromIntegral msecs) + then do buf' <- fillReadBuffer (haFD handle_) True + (haIsStream handle_) buf + writeIORef ref buf' + return True + else do r <- throwErrnoIfMinus1Retry "hWaitForInput" $ + fdReady (haFD handle_) 0 {- read -} + (fromIntegral msecs) (fromIntegral $ fromEnum $ haIsStream handle_) - return (r /= 0) + return (r /= 0) foreign import ccall safe "fdReady" fdReady :: CInt -> CInt -> CInt -> CInt -> IO CInt @@ -118,32 +118,32 @@ hGetChar handle = buf <- readIORef ref if not (bufferEmpty buf) - then hGetcBuffered fd ref buf - else do + then hGetcBuffered fd ref buf + else do -- buffer is empty. case haBufferMode handle_ of LineBuffering -> do - new_buf <- fillReadBuffer fd True (haIsStream handle_) buf - hGetcBuffered fd ref new_buf + new_buf <- fillReadBuffer fd True (haIsStream handle_) buf + hGetcBuffered fd ref new_buf BlockBuffering _ -> do - new_buf <- fillReadBuffer fd True (haIsStream handle_) buf - -- ^^^^ - -- don't wait for a completely full buffer. - hGetcBuffered fd ref new_buf + new_buf <- fillReadBuffer fd True (haIsStream handle_) buf + -- ^^^^ + -- don't wait for a completely full buffer. + hGetcBuffered fd ref new_buf NoBuffering -> do - -- make use of the minimal buffer we already have - let raw = bufBuf buf - r <- readRawBuffer "hGetChar" fd (haIsStream handle_) raw 0 1 - if r == 0 - then ioe_EOF - else do (c,_) <- readCharFromBuffer raw 0 - return c + -- make use of the minimal buffer we already have + let raw = bufBuf buf + r <- readRawBuffer "hGetChar" fd (haIsStream handle_) raw 0 1 + if r == 0 + then ioe_EOF + else do (c,_) <- readCharFromBuffer raw 0 + return c hGetcBuffered fd ref buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w } = do (c,r) <- readCharFromBuffer b r let new_buf | r == w = buf{ bufRPtr=0, bufWPtr=0 } - | otherwise = buf{ bufRPtr=r } + | otherwise = buf{ bufRPtr=r } writeIORef ref new_buf return c @@ -168,17 +168,17 @@ hGetcBuffered fd ref buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w } hGetLine :: Handle -> IO String hGetLine h = do m <- wantReadableHandle "hGetLine" h $ \ handle_ -> do - case haBufferMode handle_ of - NoBuffering -> return Nothing - LineBuffering -> do - l <- hGetLineBuffered handle_ - return (Just l) - BlockBuffering _ -> do - l <- hGetLineBuffered handle_ - return (Just l) + case haBufferMode handle_ of + NoBuffering -> return Nothing + LineBuffering -> do + l <- hGetLineBuffered handle_ + return (Just l) + BlockBuffering _ -> do + l <- hGetLineBuffered handle_ + return (Just l) case m of - Nothing -> hGetLineUnBuffered h - Just l -> return l + Nothing -> hGetLineUnBuffered h + Just l -> return l hGetLineBuffered :: Handle__ -> IO String hGetLineBuffered handle_ = do @@ -234,11 +234,11 @@ hGetLineBufferedLoop handle_ ref maybeFillReadBuffer fd is_line is_stream buf = catch (do buf <- fillReadBuffer fd is_line is_stream buf - return (Just buf) + return (Just buf) ) (\e -> do if isEOFError e - then return Nothing - else ioError e) + then return Nothing + else ioError e) unpack :: RawBuffer -> Int -> Int -> IO [Char] @@ -249,7 +249,7 @@ unpack buf (I# r) (I# len) = IO $ \s -> unpack [] (len -# 1#) s | i <# r = (# s, acc #) | otherwise = case readCharArray# buf i s of - (# s, ch #) -> unpack (C# ch : acc) (i -# 1#) s + (# s, ch #) -> unpack (C# ch : acc) (i -# 1#) s hGetLineUnBuffered :: Handle -> IO String @@ -267,9 +267,9 @@ hGetLineUnBuffered h = do (hGetChar h) (\ err -> do if isEOFError err then - return '\n' - else - ioError err) + return '\n' + else + ioError err) if c == '\n' then return "" else do @@ -315,12 +315,12 @@ hGetContents :: Handle -> IO String hGetContents handle = withHandle "hGetContents" handle $ \handle_ -> case haType handle_ of - ClosedHandle -> ioe_closedHandle - SemiClosedHandle -> ioe_closedHandle - AppendHandle -> ioe_notReadable - WriteHandle -> ioe_notReadable + ClosedHandle -> ioe_closedHandle + SemiClosedHandle -> ioe_closedHandle + AppendHandle -> ioe_notReadable + WriteHandle -> ioe_notReadable _ -> do xs <- lazyRead handle - return (handle_{ haType=SemiClosedHandle}, xs ) + return (handle_{ haType=SemiClosedHandle}, xs ) -- Note that someone may close the semi-closed handle (or change its -- buffering), so each time these lazy read functions are pulled on, @@ -329,13 +329,13 @@ hGetContents handle = lazyRead :: Handle -> IO String lazyRead handle = unsafeInterleaveIO $ - withHandle "lazyRead" handle $ \ handle_ -> do - case haType handle_ of - ClosedHandle -> return (handle_, "") - SemiClosedHandle -> lazyRead' handle handle_ - _ -> ioException - (IOError (Just handle) IllegalOperation "lazyRead" - "illegal handle type" Nothing) + withHandle "lazyRead" handle $ \ handle_ -> do + case haType handle_ of + ClosedHandle -> return (handle_, "") + SemiClosedHandle -> lazyRead' handle handle_ + _ -> ioException + (IOError (Just handle) IllegalOperation "lazyRead" + "illegal handle type" Nothing) lazyRead' h handle_ = do let ref = haBuffer handle_ @@ -345,20 +345,20 @@ lazyRead' h handle_ = do -- (see hLookAhead) buf <- readIORef ref if not (bufferEmpty buf) - then lazyReadHaveBuffer h handle_ fd ref buf - else do + then lazyReadHaveBuffer h handle_ fd ref buf + else do case haBufferMode handle_ of NoBuffering -> do - -- make use of the minimal buffer we already have - let raw = bufBuf buf - r <- readRawBuffer "lazyRead" fd (haIsStream handle_) raw 0 1 - if r == 0 - then do (handle_,_) <- hClose_help handle_ - return (handle_, "") - else do (c,_) <- readCharFromBuffer raw 0 - rest <- lazyRead h - return (handle_, c : rest) + -- make use of the minimal buffer we already have + let raw = bufBuf buf + r <- readRawBuffer "lazyRead" fd (haIsStream handle_) raw 0 1 + if r == 0 + then do (handle_,_) <- hClose_help handle_ + return (handle_, "") + else do (c,_) <- readCharFromBuffer raw 0 + rest <- lazyRead h + return (handle_, c : rest) LineBuffering -> lazyReadBuffered h handle_ fd ref buf BlockBuffering _ -> lazyReadBuffered h handle_ fd ref buf @@ -367,13 +367,13 @@ lazyRead' h handle_ = do -- is_line==True, which tells it to "just read what there is". lazyReadBuffered h handle_ fd ref buf = do catch - (do buf <- fillReadBuffer fd True{-is_line-} (haIsStream handle_) buf - lazyReadHaveBuffer h handle_ fd ref buf - ) - -- all I/O errors are discarded. Additionally, we close the handle. - (\e -> do (handle_,_) <- hClose_help handle_ - return (handle_, "") - ) + (do buf <- fillReadBuffer fd True{-is_line-} (haIsStream handle_) buf + lazyReadHaveBuffer h handle_ fd ref buf + ) + -- all I/O errors are discarded. Additionally, we close the handle. + (\e -> do (handle_,_) <- hClose_help handle_ + return (handle_, "") + ) lazyReadHaveBuffer h handle_ fd ref buf = do more <- lazyRead h @@ -390,7 +390,7 @@ unpackAcc buf (I# r) (I# len) acc = IO $ \s -> unpack acc (len -# 1#) s | i <# r = (# s, acc #) | otherwise = case readCharArray# buf i s of - (# s, ch #) -> unpack (C# ch : acc) (i -# 1#) s + (# s, ch #) -> unpack (C# ch : acc) (i -# 1#) s -- --------------------------------------------------------------------------- -- hPutChar @@ -411,12 +411,12 @@ hPutChar handle c = do wantWritableHandle "hPutChar" handle $ \ handle_ -> do let fd = haFD handle_ case haBufferMode handle_ of - LineBuffering -> hPutcBuffered handle_ True c - BlockBuffering _ -> hPutcBuffered handle_ False c - NoBuffering -> - with (castCharToCChar c) $ \buf -> do - writeRawBufferPtr "hPutChar" fd (haIsStream handle_) buf 0 1 - return () + LineBuffering -> hPutcBuffered handle_ True c + BlockBuffering _ -> hPutcBuffered handle_ False c + NoBuffering -> + with (castCharToCChar c) $ \buf -> do + writeRawBufferPtr "hPutChar" fd (haIsStream handle_) buf 0 1 + return () hPutcBuffered handle_ is_line c = do let ref = haBuffer handle_ @@ -426,10 +426,10 @@ hPutcBuffered handle_ is_line c = do let new_buf = buf{ bufWPtr = w' } if bufferFull new_buf || is_line && c == '\n' then do - flushed_buf <- flushWriteBuffer (haFD handle_) (haIsStream handle_) new_buf - writeIORef ref flushed_buf + flushed_buf <- flushWriteBuffer (haFD handle_) (haIsStream handle_) new_buf + writeIORef ref flushed_buf else do - writeIORef ref new_buf + writeIORef ref new_buf hPutChars :: Handle -> [Char] -> IO () @@ -444,12 +444,12 @@ hPutChars handle (c:cs) = hPutChar handle c >> hPutChars handle cs -- I/O operation on the same handle which would lead to deadlock. The classic -- case is -- --- putStr (trace "hello" "world") +-- putStr (trace "hello" "world") -- -- so the basic scheme is this: -- --- * copy the string into a fresh buffer, --- * "commit" the buffer to the handle. +-- * copy the string into a fresh buffer, +-- * "commit" the buffer to the handle. -- -- Committing may involve simply copying the contents of the new -- buffer into the handle's buffer, flushing one or both buffers, or @@ -468,48 +468,48 @@ hPutChars handle (c:cs) = hPutChar handle c >> hPutChars handle cs hPutStr :: Handle -> String -> IO () hPutStr handle str = do buffer_mode <- wantWritableHandle "hPutStr" handle - (\ handle_ -> do getSpareBuffer handle_) + (\ handle_ -> do getSpareBuffer handle_) case buffer_mode of (NoBuffering, _) -> do - hPutChars handle str -- v. slow, but we don't care + hPutChars handle str -- v. slow, but we don't care (LineBuffering, buf) -> do - writeLines handle buf str + writeLines handle buf str (BlockBuffering _, buf) -> do writeBlocks handle buf str getSpareBuffer :: Handle__ -> IO (BufferMode, Buffer) getSpareBuffer Handle__{haBuffer=ref, - haBuffers=spare_ref, - haBufferMode=mode} + haBuffers=spare_ref, + haBufferMode=mode} = do case mode of NoBuffering -> return (mode, error "no buffer!") _ -> do bufs <- readIORef spare_ref - buf <- readIORef ref - case bufs of - BufferListCons b rest -> do - writeIORef spare_ref rest - return ( mode, newEmptyBuffer b WriteBuffer (bufSize buf)) - BufferListNil -> do - new_buf <- allocateBuffer (bufSize buf) WriteBuffer - return (mode, new_buf) + buf <- readIORef ref + case bufs of + BufferListCons b rest -> do + writeIORef spare_ref rest + return ( mode, newEmptyBuffer b WriteBuffer (bufSize buf)) + BufferListNil -> do + new_buf <- allocateBuffer (bufSize buf) WriteBuffer + return (mode, new_buf) writeLines :: Handle -> Buffer -> String -> IO () writeLines hdl Buffer{ bufBuf=raw, bufSize=len } s = let shoveString :: Int -> [Char] -> IO () - -- check n == len first, to ensure that shoveString is strict in n. + -- check n == len first, to ensure that shoveString is strict in n. shoveString n cs | n == len = do - new_buf <- commitBuffer hdl raw len n True{-needs flush-} False - writeLines hdl new_buf cs + new_buf <- commitBuffer hdl raw len n True{-needs flush-} False + writeLines hdl new_buf cs shoveString n [] = do - commitBuffer hdl raw len n False{-no flush-} True{-release-} - return () + commitBuffer hdl raw len n False{-no flush-} True{-release-} + return () shoveString n (c:cs) = do - n' <- writeCharIntoBuffer raw n c + n' <- writeCharIntoBuffer raw n c if (c == '\n') then do new_buf <- commitBuffer hdl raw len n' True{-needs flush-} False @@ -523,16 +523,16 @@ writeBlocks :: Handle -> Buffer -> String -> IO () writeBlocks hdl Buffer{ bufBuf=raw, bufSize=len } s = let shoveString :: Int -> [Char] -> IO () - -- check n == len first, to ensure that shoveString is strict in n. + -- check n == len first, to ensure that shoveString is strict in n. shoveString n cs | n == len = do - new_buf <- commitBuffer hdl raw len n True{-needs flush-} False - writeBlocks hdl new_buf cs + new_buf <- commitBuffer hdl raw len n True{-needs flush-} False + writeBlocks hdl new_buf cs shoveString n [] = do - commitBuffer hdl raw len n False{-no flush-} True{-release-} - return () + commitBuffer hdl raw len n False{-no flush-} True{-release-} + return () shoveString n (c:cs) = do - n' <- writeCharIntoBuffer raw n c - shoveString n' cs + n' <- writeCharIntoBuffer raw n c + shoveString n' cs in shoveString 0 s @@ -545,25 +545,25 @@ writeBlocks hdl Buffer{ bufBuf=raw, bufSize=len } s = -- Implementation: -- -- for block/line buffering, --- 1. If there isn't room in the handle buffer, flush the handle --- buffer. +-- 1. If there isn't room in the handle buffer, flush the handle +-- buffer. -- --- 2. If the handle buffer is empty, --- if flush, --- then write buf directly to the device. --- else swap the handle buffer with buf. +-- 2. If the handle buffer is empty, +-- if flush, +-- then write buf directly to the device. +-- else swap the handle buffer with buf. -- --- 3. If the handle buffer is non-empty, copy buf into the --- handle buffer. Then, if flush != 0, flush --- the buffer. +-- 3. If the handle buffer is non-empty, copy buf into the +-- handle buffer. Then, if flush != 0, flush +-- the buffer. commitBuffer - :: Handle -- handle to commit to - -> RawBuffer -> Int -- address and size (in bytes) of buffer - -> Int -- number of bytes of data in buffer - -> Bool -- True <=> flush the handle afterward - -> Bool -- release the buffer? - -> IO Buffer + :: Handle -- handle to commit to + -> RawBuffer -> Int -- address and size (in bytes) of buffer + -> Int -- number of bytes of data in buffer + -> Bool -- True <=> flush the handle afterward + -> Bool -- release the buffer? + -> IO Buffer commitBuffer hdl raw sz@(I# _) count@(I# _) flush release = do wantWritableHandle "commitAndReleaseBuffer" hdl $ @@ -585,66 +585,66 @@ commitBuffer' raw sz@(I# _) count@(I# _) flush release #ifdef DEBUG_DUMP puts ("commitBuffer: sz=" ++ show sz ++ ", count=" ++ show count - ++ ", flush=" ++ show flush ++ ", release=" ++ show release ++"\n") + ++ ", flush=" ++ show flush ++ ", release=" ++ show release ++"\n") #endif old_buf@Buffer{ bufBuf=old_raw, bufRPtr=r, bufWPtr=w, bufSize=size } - <- readIORef ref + <- readIORef ref buf_ret <- -- enough room in handle buffer? - if (not flush && (size - w > count)) - -- The > is to be sure that we never exactly fill - -- up the buffer, which would require a flush. So - -- if copying the new data into the buffer would - -- make the buffer full, we just flush the existing - -- buffer and the new data immediately, rather than - -- copying before flushing. - - -- not flushing, and there's enough room in the buffer: - -- just copy the data in and update bufWPtr. - then do memcpy_baoff_ba old_raw (fromIntegral w) raw (fromIntegral count) - writeIORef ref old_buf{ bufWPtr = w + count } - return (newEmptyBuffer raw WriteBuffer sz) - - -- else, we have to flush - else do flushed_buf <- flushWriteBuffer fd (haIsStream handle_) old_buf - - let this_buf = - Buffer{ bufBuf=raw, bufState=WriteBuffer, - bufRPtr=0, bufWPtr=count, bufSize=sz } - - -- if: (a) we don't have to flush, and - -- (b) size(new buffer) == size(old buffer), and - -- (c) new buffer is not full, - -- we can just just swap them over... - if (not flush && sz == size && count /= sz) - then do - writeIORef ref this_buf - return flushed_buf - - -- otherwise, we have to flush the new data too, - -- and start with a fresh buffer - else do - flushWriteBuffer fd (haIsStream handle_) this_buf - writeIORef ref flushed_buf - -- if the sizes were different, then allocate - -- a new buffer of the correct size. - if sz == size - then return (newEmptyBuffer raw WriteBuffer sz) - else allocateBuffer size WriteBuffer + if (not flush && (size - w > count)) + -- The > is to be sure that we never exactly fill + -- up the buffer, which would require a flush. So + -- if copying the new data into the buffer would + -- make the buffer full, we just flush the existing + -- buffer and the new data immediately, rather than + -- copying before flushing. + + -- not flushing, and there's enough room in the buffer: + -- just copy the data in and update bufWPtr. + then do memcpy_baoff_ba old_raw (fromIntegral w) raw (fromIntegral count) + writeIORef ref old_buf{ bufWPtr = w + count } + return (newEmptyBuffer raw WriteBuffer sz) + + -- else, we have to flush + else do flushed_buf <- flushWriteBuffer fd (haIsStream handle_) old_buf + + let this_buf = + Buffer{ bufBuf=raw, bufState=WriteBuffer, + bufRPtr=0, bufWPtr=count, bufSize=sz } + + -- if: (a) we don't have to flush, and + -- (b) size(new buffer) == size(old buffer), and + -- (c) new buffer is not full, + -- we can just just swap them over... + if (not flush && sz == size && count /= sz) + then do + writeIORef ref this_buf + return flushed_buf + + -- otherwise, we have to flush the new data too, + -- and start with a fresh buffer + else do + flushWriteBuffer fd (haIsStream handle_) this_buf + writeIORef ref flushed_buf + -- if the sizes were different, then allocate + -- a new buffer of the correct size. + if sz == size + then return (newEmptyBuffer raw WriteBuffer sz) + else allocateBuffer size WriteBuffer -- release the buffer if necessary case buf_ret of Buffer{ bufSize=buf_ret_sz, bufBuf=buf_ret_raw } -> do if release && buf_ret_sz == size - then do - spare_bufs <- readIORef spare_buf_ref - writeIORef spare_buf_ref - (BufferListCons buf_ret_raw spare_bufs) - return buf_ret - else - return buf_ret + then do + spare_bufs <- readIORef spare_buf_ref + writeIORef spare_buf_ref + (BufferListCons buf_ret_raw spare_bufs) + return buf_ret + else + return buf_ret -- --------------------------------------------------------------------------- -- Reading/writing sequences of bytes. @@ -662,31 +662,31 @@ commitBuffer' raw sz@(I# _) count@(I# _) flush release -- has not asked to ignore SIGPIPE, then a SIGPIPE may be delivered -- instead, whose default action is to terminate the program). -hPutBuf :: Handle -- handle to write to - -> Ptr a -- address of buffer - -> Int -- number of bytes of data in buffer - -> IO () +hPutBuf :: Handle -- handle to write to + -> Ptr a -- address of buffer + -> Int -- number of bytes of data in buffer + -> IO () hPutBuf h ptr count = do hPutBuf' h ptr count True; return () hPutBufNonBlocking - :: Handle -- handle to write to - -> Ptr a -- address of buffer - -> Int -- number of bytes of data in buffer - -> IO Int -- returns: number of bytes written + :: Handle -- handle to write to + -> Ptr a -- address of buffer + -> Int -- number of bytes of data in buffer + -> IO Int -- returns: number of bytes written hPutBufNonBlocking h ptr count = hPutBuf' h ptr count False -hPutBuf':: Handle -- handle to write to - -> Ptr a -- address of buffer - -> Int -- number of bytes of data in buffer - -> Bool -- allow blocking? - -> IO Int +hPutBuf':: Handle -- handle to write to + -> Ptr a -- address of buffer + -> Int -- number of bytes of data in buffer + -> Bool -- allow blocking? + -> IO Int hPutBuf' handle ptr count can_block | count == 0 = return 0 | count < 0 = illegalBufferSize handle "hPutBuf" count | otherwise = wantWritableHandle "hPutBuf" handle $ \ handle_@Handle__{ haFD=fd, haBuffer=ref, haIsStream=is_stream } -> - bufWrite fd ref is_stream ptr count can_block + bufWrite fd ref is_stream ptr count can_block bufWrite fd ref is_stream ptr count can_block = seq count $ seq fd $ do -- strictness hack @@ -695,23 +695,23 @@ bufWrite fd ref is_stream ptr count can_block = -- enough room in handle buffer? if (size - w > count) - -- There's enough room in the buffer: - -- just copy the data in and update bufWPtr. - then do memcpy_baoff_ptr old_raw (fromIntegral w) ptr (fromIntegral count) - writeIORef ref old_buf{ bufWPtr = w + count } - return count - - -- else, we have to flush - else do flushed_buf <- flushWriteBuffer fd is_stream old_buf - -- TODO: we should do a non-blocking flush here - writeIORef ref flushed_buf - -- if we can fit in the buffer, then just loop - if count < size - then bufWrite fd ref is_stream ptr count can_block - else if can_block - then do writeChunk fd is_stream (castPtr ptr) count - return count - else writeChunkNonBlocking fd is_stream ptr count + -- There's enough room in the buffer: + -- just copy the data in and update bufWPtr. + then do memcpy_baoff_ptr old_raw (fromIntegral w) ptr (fromIntegral count) + writeIORef ref old_buf{ bufWPtr = w + count } + return count + + -- else, we have to flush + else do flushed_buf <- flushWriteBuffer fd is_stream old_buf + -- TODO: we should do a non-blocking flush here + writeIORef ref flushed_buf + -- if we can fit in the buffer, then just loop + if count < size + then bufWrite fd ref is_stream ptr count can_block + else if can_block + then do writeChunk fd is_stream (castPtr ptr) count + return count + else writeChunkNonBlocking fd is_stream ptr count writeChunk :: FD -> Bool -> Ptr CChar -> Int -> IO () writeChunk fd is_stream ptr bytes = loop 0 bytes @@ -720,8 +720,8 @@ writeChunk fd is_stream ptr bytes = loop 0 bytes loop _ bytes | bytes <= 0 = return () loop off bytes = do r <- fromIntegral `liftM` - writeRawBufferPtr "writeChunk" fd is_stream ptr - off (fromIntegral bytes) + writeRawBufferPtr "writeChunk" fd is_stream ptr + off (fromIntegral bytes) -- write can't return 0 loop (off + r) (bytes - r) @@ -736,15 +736,15 @@ writeChunkNonBlocking fd is_stream ptr bytes = loop 0 bytes let r = fromIntegral ssize :: Int if (r == -1) then do errno <- getErrno - if (errno == eAGAIN || errno == eWOULDBLOCK) - then return off - else throwErrno "writeChunk" + if (errno == eAGAIN || errno == eWOULDBLOCK) + then return off + else throwErrno "writeChunk" else loop (off + r) (bytes - r) #else (ssize, rc) <- asyncWrite (fromIntegral fd) (fromIntegral $ fromEnum is_stream) - (fromIntegral bytes) - (ptr `plusPtr` off) + (fromIntegral bytes) + (ptr `plusPtr` off) let r = fromIntegral ssize :: Int if r == (-1) then ioError (errnoToIOError "hPutBufNonBlocking" (Errno (fromIntegral rc)) Nothing Nothing) @@ -772,8 +772,8 @@ hGetBuf h ptr count | count < 0 = illegalBufferSize h "hGetBuf" count | otherwise = wantReadableHandle "hGetBuf" h $ - \ handle_@Handle__{ haFD=fd, haBuffer=ref, haIsStream=is_stream } -> do - bufRead fd ref is_stream ptr 0 count + \ handle_@Handle__{ haFD=fd, haBuffer=ref, haIsStream=is_stream } -> do + bufRead fd ref is_stream ptr 0 count -- small reads go through the buffer, large reads are satisfied by -- taking data first from the buffer and then direct from the file @@ -783,41 +783,41 @@ bufRead fd ref is_stream ptr so_far count = buf@Buffer{ bufBuf=raw, bufWPtr=w, bufRPtr=r, bufSize=sz } <- readIORef ref if bufferEmpty buf then if count > sz -- small read? - then do rest <- readChunk fd is_stream ptr count - return (so_far + rest) - else do mb_buf <- maybeFillReadBuffer fd True is_stream buf - case mb_buf of - Nothing -> return so_far -- got nothing, we're done - Just buf' -> do - writeIORef ref buf' - bufRead fd ref is_stream ptr so_far count + then do rest <- readChunk fd is_stream ptr count + return (so_far + rest) + else do mb_buf <- maybeFillReadBuffer fd True is_stream buf + case mb_buf of + Nothing -> return so_far -- got nothing, we're done + Just buf' -> do + writeIORef ref buf' + bufRead fd ref is_stream ptr so_far count else do - let avail = w - r - if (count == avail) - then do - memcpy_ptr_baoff ptr raw (fromIntegral r) (fromIntegral count) - writeIORef ref buf{ bufWPtr=0, bufRPtr=0 } - return (so_far + count) - else do - if (count < avail) - then do - memcpy_ptr_baoff ptr raw (fromIntegral r) (fromIntegral count) - writeIORef ref buf{ bufRPtr = r + count } - return (so_far + count) - else do + let avail = w - r + if (count == avail) + then do + memcpy_ptr_baoff ptr raw (fromIntegral r) (fromIntegral count) + writeIORef ref buf{ bufWPtr=0, bufRPtr=0 } + return (so_far + count) + else do + if (count < avail) + then do + memcpy_ptr_baoff ptr raw (fromIntegral r) (fromIntegral count) + writeIORef ref buf{ bufRPtr = r + count } + return (so_far + count) + else do - memcpy_ptr_baoff ptr raw (fromIntegral r) (fromIntegral avail) - writeIORef ref buf{ bufWPtr=0, bufRPtr=0 } - let remaining = count - avail - so_far' = so_far + avail - ptr' = ptr `plusPtr` avail + memcpy_ptr_baoff ptr raw (fromIntegral r) (fromIntegral avail) + writeIORef ref buf{ bufWPtr=0, bufRPtr=0 } + let remaining = count - avail + so_far' = so_far + avail + ptr' = ptr `plusPtr` avail - if remaining < sz - then bufRead fd ref is_stream ptr' so_far' remaining - else do + if remaining < sz + then bufRead fd ref is_stream ptr' so_far' remaining + else do - rest <- readChunk fd is_stream ptr' remaining - return (so_far' + rest) + rest <- readChunk fd is_stream ptr' remaining + return (so_far' + rest) readChunk :: FD -> Bool -> Ptr a -> Int -> IO Int readChunk fd is_stream ptr bytes = loop 0 bytes @@ -827,10 +827,10 @@ readChunk fd is_stream ptr bytes = loop 0 bytes loop off bytes = do r <- fromIntegral `liftM` readRawBufferPtr "readChunk" fd is_stream - (castPtr ptr) off (fromIntegral bytes) + (castPtr ptr) off (fromIntegral bytes) if r == 0 - then return off - else loop (off + r) (bytes - r) + then return off + else loop (off + r) (bytes - r) -- | 'hGetBufNonBlocking' @hdl buf count@ reads data from the handle @hdl@ @@ -852,63 +852,63 @@ hGetBufNonBlocking h ptr count | count < 0 = illegalBufferSize h "hGetBufNonBlocking" count | otherwise = wantReadableHandle "hGetBufNonBlocking" h $ - \ handle_@Handle__{ haFD=fd, haBuffer=ref, haIsStream=is_stream } -> do - bufReadNonBlocking fd ref is_stream ptr 0 count + \ handle_@Handle__{ haFD=fd, haBuffer=ref, haIsStream=is_stream } -> do + bufReadNonBlocking fd ref is_stream ptr 0 count bufReadNonBlocking fd ref is_stream ptr so_far count = seq fd $ seq so_far $ seq count $ do -- strictness hack buf@Buffer{ bufBuf=raw, bufWPtr=w, bufRPtr=r, bufSize=sz } <- readIORef ref if bufferEmpty buf then if count > sz -- large read? - then do rest <- readChunkNonBlocking fd is_stream ptr count - return (so_far + rest) - else do buf' <- fillReadBufferWithoutBlocking fd is_stream buf - case buf' of { Buffer{ bufWPtr=w } -> - if (w == 0) - then return so_far - else do writeIORef ref buf' - bufReadNonBlocking fd ref is_stream ptr - so_far (min count w) - -- NOTE: new count is 'min count w' - -- so we will just copy the contents of the - -- buffer in the recursive call, and not - -- loop again. - } + then do rest <- readChunkNonBlocking fd is_stream ptr count + return (so_far + rest) + else do buf' <- fillReadBufferWithoutBlocking fd is_stream buf + case buf' of { Buffer{ bufWPtr=w } -> + if (w == 0) + then return so_far + else do writeIORef ref buf' + bufReadNonBlocking fd ref is_stream ptr + so_far (min count w) + -- NOTE: new count is 'min count w' + -- so we will just copy the contents of the + -- buffer in the recursive call, and not + -- loop again. + } else do - let avail = w - r - if (count == avail) - then do - memcpy_ptr_baoff ptr raw (fromIntegral r) (fromIntegral count) - writeIORef ref buf{ bufWPtr=0, bufRPtr=0 } - return (so_far + count) - else do - if (count < avail) - then do - memcpy_ptr_baoff ptr raw (fromIntegral r) (fromIntegral count) - writeIORef ref buf{ bufRPtr = r + count } - return (so_far + count) - else do - - memcpy_ptr_baoff ptr raw (fromIntegral r) (fromIntegral avail) - writeIORef ref buf{ bufWPtr=0, bufRPtr=0 } - let remaining = count - avail - so_far' = so_far + avail - ptr' = ptr `plusPtr` avail - - -- we haven't attempted to read anything yet if we get to here. - if remaining < sz - then bufReadNonBlocking fd ref is_stream ptr' so_far' remaining - else do - - rest <- readChunkNonBlocking fd is_stream ptr' remaining - return (so_far' + rest) + let avail = w - r + if (count == avail) + then do + memcpy_ptr_baoff ptr raw (fromIntegral r) (fromIntegral count) + writeIORef ref buf{ bufWPtr=0, bufRPtr=0 } + return (so_far + count) + else do + if (count < avail) + then do + memcpy_ptr_baoff ptr raw (fromIntegral r) (fromIntegral count) + writeIORef ref buf{ bufRPtr = r + count } + return (so_far + count) + else do + + memcpy_ptr_baoff ptr raw (fromIntegral r) (fromIntegral avail) + writeIORef ref buf{ bufWPtr=0, bufRPtr=0 } + let remaining = count - avail + so_far' = so_far + avail + ptr' = ptr `plusPtr` avail + + -- we haven't attempted to read anything yet if we get to here. + if remaining < sz + then bufReadNonBlocking fd ref is_stream ptr' so_far' remaining + else do + + rest <- readChunkNonBlocking fd is_stream ptr' remaining + return (so_far' + rest) readChunkNonBlocking :: FD -> Bool -> Ptr a -> Int -> IO Int readChunkNonBlocking fd is_stream ptr bytes = do fromIntegral `liftM` readRawBufferPtrNoBlock "readChunkNonBlocking" fd is_stream - (castPtr ptr) 0 (fromIntegral bytes) + (castPtr ptr) 0 (fromIntegral bytes) -- we don't have non-blocking read support on Windows, so just invoke -- the ordinary low-level read which will block until data is available, @@ -945,7 +945,7 @@ foreign import ccall unsafe "__hscore_memcpy_dst_off" illegalBufferSize :: Handle -> String -> Int -> IO a illegalBufferSize handle fn (sz :: Int) = - ioException (IOError (Just handle) - InvalidArgument fn - ("illegal buffer size " ++ showsPrec 9 sz []) - Nothing) + ioException (IOError (Just handle) + InvalidArgument fn + ("illegal buffer size " ++ showsPrec 9 sz []) + Nothing) diff --git a/GHC/IOBase.lhs b/GHC/IOBase.lhs index 684497e..5b0c65f 100644 --- a/GHC/IOBase.lhs +++ b/GHC/IOBase.lhs @@ -21,37 +21,37 @@ module GHC.IOBase( unsafePerformIO, unsafeInterleaveIO, unsafeDupablePerformIO, unsafeDupableInterleaveIO, noDuplicate, - - -- To and from from ST + + -- To and from from ST stToIO, ioToST, unsafeIOToST, unsafeSTToIO, - -- References + -- References IORef(..), newIORef, readIORef, writeIORef, IOArray(..), newIOArray, readIOArray, writeIOArray, unsafeReadIOArray, unsafeWriteIOArray, MVar(..), - -- Handles, file descriptors, + -- Handles, file descriptors, FilePath, Handle(..), Handle__(..), HandleType(..), IOMode(..), FD, isReadableHandleType, isWritableHandleType, isReadWriteHandleType, showHandle, - - -- Buffers + + -- Buffers Buffer(..), RawBuffer, BufferState(..), BufferList(..), BufferMode(..), bufferIsWritable, bufferEmpty, bufferFull, - -- Exceptions + -- Exceptions Exception(..), ArithException(..), AsyncException(..), ArrayException(..), stackOverflow, heapOverflow, throw, throwIO, ioException, IOError, IOException(..), IOErrorType(..), ioError, userError, ExitCode(..) ) where - + import GHC.ST -import GHC.Arr -- to derive Ix class +import GHC.Arr -- to derive Ix class import GHC.Enum -- to derive Enum class import GHC.STRef import GHC.Base --- import GHC.Num -- To get fromInteger etc, needed because of -fno-implicit-prelude +-- import GHC.Num -- To get fromInteger etc, needed because of -fno-implicit-prelude import Data.Maybe ( Maybe(..) ) import GHC.Show import GHC.List @@ -59,8 +59,8 @@ import GHC.Read import Foreign.C.Types (CInt) #ifndef __HADDOCK__ -import {-# SOURCE #-} Data.Typeable ( showsTypeRep ) -import {-# SOURCE #-} Data.Dynamic ( Dynamic, dynTypeRep ) +import {-# SOURCE #-} Data.Typeable ( showsTypeRep ) +import {-# SOURCE #-} Data.Dynamic ( Dynamic, dynTypeRep ) #endif -- --------------------------------------------------------------------------- @@ -76,13 +76,13 @@ system. The following list may or may not be exhaustive: Compiler - types of various primitives in PrimOp.lhs -RTS - forceIO (StgMiscClosures.hc) - - catchzh_fast, (un)?blockAsyncExceptionszh_fast, raisezh_fast - (Exceptions.hc) - - raiseAsync (Schedule.c) +RTS - forceIO (StgMiscClosures.hc) + - catchzh_fast, (un)?blockAsyncExceptionszh_fast, raisezh_fast + (Exceptions.hc) + - raiseAsync (Schedule.c) Prelude - GHC.IOBase.lhs, and several other places including - GHC.Exception.lhs. + GHC.Exception.lhs. Libraries - parts of hslibs/lang. @@ -115,10 +115,10 @@ instance Monad IO where {-# INLINE (>>) #-} {-# INLINE (>>=) #-} m >> k = m >>= \ _ -> k - return x = returnIO x + return x = returnIO x m >>= k = bindIO m k - fail s = failIO s + fail s = failIO s failIO :: String -> IO a failIO s = ioError (userError s) @@ -148,10 +148,10 @@ returnIO x = IO (\ s -> (# s, x #)) -- monad. The 'RealWorld' parameter indicates that the internal state -- used by the 'ST' computation is a special one supplied by the 'IO' -- monad, and thus distinct from those used by invocations of 'runST'. -stToIO :: ST RealWorld a -> IO a +stToIO :: ST RealWorld a -> IO a stToIO (ST m) = IO m -ioToST :: IO a -> ST RealWorld a +ioToST :: IO a -> ST RealWorld a ioToST (IO m) = (ST m) -- This relies on IO and ST having the same representation modulo the @@ -179,26 +179,26 @@ effects take place (relative to the main I\/O trunk, or other calls to writing and compiling modules that use 'unsafePerformIO': * Use @{\-\# NOINLINE foo \#-\}@ as a pragma on any function @foo@ - that calls 'unsafePerformIO'. If the call is inlined, - the I\/O may be performed more than once. + that calls 'unsafePerformIO'. If the call is inlined, + the I\/O may be performed more than once. * Use the compiler flag @-fno-cse@ to prevent common sub-expression - elimination being performed on the module, which might combine - two side effects that were meant to be separate. A good example - is using multiple global variables (like @test@ in the example below). + elimination being performed on the module, which might combine + two side effects that were meant to be separate. A good example + is using multiple global variables (like @test@ in the example below). * Make sure that the either you switch off let-floating, or that the - call to 'unsafePerformIO' cannot float outside a lambda. For example, - if you say: - @ - f x = unsafePerformIO (newIORef []) - @ - you may get only one reference cell shared between all calls to @f@. - Better would be - @ - f x = unsafePerformIO (newIORef [x]) - @ - because now it can't float outside the lambda. + call to 'unsafePerformIO' cannot float outside a lambda. For example, + if you say: + @ + f x = unsafePerformIO (newIORef []) + @ + you may get only one reference cell shared between all calls to @f@. + Better would be + @ + f x = unsafePerformIO (newIORef [x]) + @ + because now it can't float outside the lambda. It is less well known that 'unsafePerformIO' is not type safe. For example: @@ -207,9 +207,9 @@ It is less well known that > test = unsafePerformIO $ newIORef [] > > main = do -> writeIORef test [42] -> bang <- readIORef test -> print (bang :: [Char]) +> writeIORef test [42] +> bang <- readIORef test +> print (bang :: [Char]) This program will core dump. This problem with polymorphic references is well known in the ML community, and does not arise with normal @@ -218,7 +218,7 @@ once you use 'unsafePerformIO'. Indeed, it is possible to write @coerce :: a -> b@ with the help of 'unsafePerformIO'. So be careful! -} -unsafePerformIO :: IO a -> a +unsafePerformIO :: IO a -> a unsafePerformIO m = unsafeDupablePerformIO (noDuplicate >> m) {-| @@ -230,7 +230,7 @@ times (on a multiprocessor), and you should therefore ensure that it gives the same results each time. -} {-# NOINLINE unsafeDupablePerformIO #-} -unsafeDupablePerformIO :: IO a -> a +unsafeDupablePerformIO :: IO a -> a unsafeDupablePerformIO (IO m) = lazy (case m realWorld# of (# _, r #) -> r) -- Why do we NOINLINE unsafeDupablePerformIO? See the comment with @@ -243,16 +243,16 @@ unsafeDupablePerformIO (IO m) = lazy (case m realWorld# of (# _, r #) -> r) -- If we don't have it, the demand analyser discovers the following strictness -- for unsafeDupablePerformIO: C(U(AV)) -- But then consider --- unsafeDupablePerformIO (\s -> let r = f x in --- case writeIORef v r s of (# s1, _ #) -> --- (# s1, r #) +-- unsafeDupablePerformIO (\s -> let r = f x in +-- case writeIORef v r s of (# s1, _ #) -> +-- (# s1, r #) -- The strictness analyser will find that the binding for r is strict, -- (becuase of uPIO's strictness sig), and so it'll evaluate it before -- doing the writeIORef. This actually makes tests/lib/should_run/memo002 -- get a deadlock! -- -- Solution: don't expose the strictness of unsafeDupablePerformIO, --- by hiding it with 'lazy' +-- by hiding it with 'lazy' {-| 'unsafeInterleaveIO' allows 'IO' computation to be deferred lazily. @@ -272,9 +272,9 @@ unsafeInterleaveIO m = unsafeDupableInterleaveIO (noDuplicate >> m) unsafeDupableInterleaveIO :: IO a -> IO a unsafeDupableInterleaveIO (IO m) = IO ( \ s -> let - r = case m s of (# _, res #) -> res - in - (# s, r #)) + r = case m s of (# _, res #) -> res + in + (# s, r #)) {-| Ensures that the suspensions under evaluation by the current thread @@ -301,7 +301,7 @@ as a a box, which may be empty or full. -- pull in Eq (Mvar a) too, to avoid GHC.Conc being an orphan-instance module instance Eq (MVar a) where - (MVar mvar1#) == (MVar mvar2#) = sameMVar# mvar1# mvar2# + (MVar mvar1#) == (MVar mvar2#) = sameMVar# mvar1# mvar2# -- A Handle is represented by (a reference to) a record -- containing the state of the I/O port/device. We record @@ -312,7 +312,7 @@ instance Eq (MVar a) where -- * buffering mode -- * buffer, and spare buffers -- * user-friendly name (usually the --- FilePath used when IO.openFile was called) +-- FilePath used when IO.openFile was called) -- Note: when a Handle is garbage collected, we want to flush its buffer -- and close the OS file handle, so as to free up a (precious) resource. @@ -355,15 +355,15 @@ instance Eq (MVar a) where -- ensure that this doesn't happen. data Handle - = FileHandle -- A normal handle to a file - FilePath -- the file (invariant) - !(MVar Handle__) + = FileHandle -- A normal handle to a file + FilePath -- the file (invariant) + !(MVar Handle__) - | DuplexHandle -- A handle to a read/write stream - FilePath -- file for a FIFO, otherwise some - -- descriptive string. - !(MVar Handle__) -- The read side - !(MVar Handle__) -- The write side + | DuplexHandle -- A handle to a read/write stream + FilePath -- file for a FIFO, otherwise some + -- descriptive string. + !(MVar Handle__) -- The read side + !(MVar Handle__) -- The write side -- NOTES: -- * A 'FileHandle' is seekable. A 'DuplexHandle' may or may not be @@ -378,16 +378,16 @@ type FD = CInt data Handle__ = Handle__ { - haFD :: !FD, -- file descriptor - haType :: HandleType, -- type (read/write/append etc.) - haIsBin :: Bool, -- binary mode? - haIsStream :: Bool, -- Windows : is this a socket? + haFD :: !FD, -- file descriptor + haType :: HandleType, -- type (read/write/append etc.) + haIsBin :: Bool, -- binary mode? + haIsStream :: Bool, -- Windows : is this a socket? -- Unix : is O_NONBLOCK set? - haBufferMode :: BufferMode, -- buffer contains read/write data? - haBuffer :: !(IORef Buffer), -- the current buffer + haBufferMode :: BufferMode, -- buffer contains read/write data? + haBuffer :: !(IORef Buffer), -- the current buffer haBuffers :: !(IORef BufferList), -- spare buffers haOtherSide :: Maybe (MVar Handle__) -- ptr to the write side of a - -- duplex handle. + -- duplex handle. } -- --------------------------------------------------------------------------- @@ -427,11 +427,11 @@ type RawBuffer = MutableByteArray# RealWorld data Buffer = Buffer { - bufBuf :: RawBuffer, - bufRPtr :: !Int, - bufWPtr :: !Int, - bufSize :: !Int, - bufState :: BufferState + bufBuf :: RawBuffer, + bufRPtr :: !Int, + bufWPtr :: !Int, + bufSize :: !Int, + bufState :: BufferState } data BufferState = ReadBuffer | WriteBuffer deriving (Eq) @@ -468,12 +468,12 @@ data HandleType isReadableHandleType ReadHandle = True isReadableHandleType ReadWriteHandle = True -isReadableHandleType _ = False +isReadableHandleType _ = False isWritableHandleType AppendHandle = True isWritableHandleType WriteHandle = True isWritableHandleType ReadWriteHandle = True -isWritableHandleType _ = False +isWritableHandleType _ = False isReadWriteHandleType ReadWriteHandle{} = True isReadWriteHandleType _ = False @@ -528,13 +528,13 @@ type FilePath = String -- and terminals will normally be line-buffered. data BufferMode - = NoBuffering -- ^ buffering is disabled if possible. + = NoBuffering -- ^ buffering is disabled if possible. | LineBuffering - -- ^ line-buffering should be enabled if possible. + -- ^ line-buffering should be enabled if possible. | BlockBuffering (Maybe Int) - -- ^ block-buffering should be enabled if possible. - -- The size of the buffer is @n@ items if the argument - -- is 'Just' @n@ and is otherwise implementation-dependent. + -- ^ block-buffering should be enabled if possible. + -- The size of the buffer is @n@ items if the argument + -- is 'Just' @n@ and is otherwise implementation-dependent. deriving (Eq, Ord, Read, Show) -- --------------------------------------------------------------------------- @@ -631,85 +631,85 @@ showHandle file = showString "{handle: " . showString file . showString "}" -- 'Data.Dynamic.Dynamic' (see the section on Dynamic Exceptions: -- "Control.Exception\#DynamicExceptions"). data Exception - = ArithException ArithException - -- ^Exceptions raised by arithmetic - -- operations. (NOTE: GHC currently does not throw - -- 'ArithException's except for 'DivideByZero'). - | ArrayException ArrayException - -- ^Exceptions raised by array-related - -- operations. (NOTE: GHC currently does not throw - -- 'ArrayException's). - | AssertionFailed String - -- ^This exception is thrown by the - -- 'assert' operation when the condition - -- fails. The 'String' argument contains the - -- location of the assertion in the source program. - | AsyncException AsyncException - -- ^Asynchronous exceptions (see section on Asynchronous Exceptions: "Control.Exception\#AsynchronousExceptions"). + = ArithException ArithException + -- ^Exceptions raised by arithmetic + -- operations. (NOTE: GHC currently does not throw + -- 'ArithException's except for 'DivideByZero'). + | ArrayException ArrayException + -- ^Exceptions raised by array-related + -- operations. (NOTE: GHC currently does not throw + -- 'ArrayException's). + | AssertionFailed String + -- ^This exception is thrown by the + -- 'assert' operation when the condition + -- fails. The 'String' argument contains the + -- location of the assertion in the source program. + | AsyncException AsyncException + -- ^Asynchronous exceptions (see section on Asynchronous Exceptions: "Control.Exception\#AsynchronousExceptions"). | BlockedOnDeadMVar - -- ^The current thread was executing a call to - -- 'Control.Concurrent.MVar.takeMVar' that could never return, - -- because there are no other references to this 'MVar'. + -- ^The current thread was executing a call to + -- 'Control.Concurrent.MVar.takeMVar' that could never return, + -- because there are no other references to this 'MVar'. | BlockedIndefinitely - -- ^The current thread was waiting to retry an atomic memory transaction - -- that could never become possible to complete because there are no other - -- threads referring to any of the TVars involved. + -- ^The current thread was waiting to retry an atomic memory transaction + -- that could never become possible to complete because there are no other + -- threads referring to any of the TVars involved. | NestedAtomically - -- ^The runtime detected an attempt to nest one STM transaction - -- inside another one, presumably due to the use of - -- 'unsafePeformIO' with 'atomically'. + -- ^The runtime detected an attempt to nest one STM transaction + -- inside another one, presumably due to the use of + -- 'unsafePeformIO' with 'atomically'. | Deadlock - -- ^There are no runnable threads, so the program is - -- deadlocked. The 'Deadlock' exception is - -- raised in the main thread only (see also: "Control.Concurrent"). - | DynException Dynamic - -- ^Dynamically typed exceptions (see section on Dynamic Exceptions: "Control.Exception\#DynamicExceptions"). - | ErrorCall String - -- ^The 'ErrorCall' exception is thrown by 'error'. The 'String' - -- argument of 'ErrorCall' is the string passed to 'error' when it was - -- called. - | ExitException ExitCode - -- ^The 'ExitException' exception is thrown by 'System.Exit.exitWith' (and - -- 'System.Exit.exitFailure'). The 'ExitCode' argument is the value passed - -- to 'System.Exit.exitWith'. An unhandled 'ExitException' exception in the - -- main thread will cause the program to be terminated with the given - -- exit code. - | IOException IOException - -- ^These are the standard IO exceptions generated by - -- Haskell\'s @IO@ operations. See also "System.IO.Error". + -- ^There are no runnable threads, so the program is + -- deadlocked. The 'Deadlock' exception is + -- raised in the main thread only (see also: "Control.Concurrent"). + | DynException Dynamic + -- ^Dynamically typed exceptions (see section on Dynamic Exceptions: "Control.Exception\#DynamicExceptions"). + | ErrorCall String + -- ^The 'ErrorCall' exception is thrown by 'error'. The 'String' + -- argument of 'ErrorCall' is the string passed to 'error' when it was + -- called. + | ExitException ExitCode + -- ^The 'ExitException' exception is thrown by 'System.Exit.exitWith' (and + -- 'System.Exit.exitFailure'). The 'ExitCode' argument is the value passed + -- to 'System.Exit.exitWith'. An unhandled 'ExitException' exception in the + -- main thread will cause the program to be terminated with the given + -- exit code. + | IOException IOException + -- ^These are the standard IO exceptions generated by + -- Haskell\'s @IO@ operations. See also "System.IO.Error". | NoMethodError String - -- ^An attempt was made to invoke a class method which has - -- no definition in this instance, and there was no default - -- definition given in the class declaration. GHC issues a - -- warning when you compile an instance which has missing - -- methods. + -- ^An attempt was made to invoke a class method which has + -- no definition in this instance, and there was no default + -- definition given in the class declaration. GHC issues a + -- warning when you compile an instance which has missing + -- methods. | NonTermination - -- ^The current thread is stuck in an infinite loop. This - -- exception may or may not be thrown when the program is - -- non-terminating. - | PatternMatchFail String - -- ^A pattern matching failure. The 'String' argument should contain a - -- descriptive message including the function name, source file - -- and line number. - | RecConError String - -- ^An attempt was made to evaluate a field of a record - -- for which no value was given at construction time. The - -- 'String' argument gives the location of the - -- record construction in the source program. - | RecSelError String - -- ^A field selection was attempted on a constructor that - -- doesn\'t have the requested field. This can happen with - -- multi-constructor records when one or more fields are - -- missing from some of the constructors. The - -- 'String' argument gives the location of the - -- record selection in the source program. - | RecUpdError String - -- ^An attempt was made to update a field in a record, - -- where the record doesn\'t have the requested field. This can - -- only occur with multi-constructor records, when one or more - -- fields are missing from some of the constructors. The - -- 'String' argument gives the location of the - -- record update in the source program. + -- ^The current thread is stuck in an infinite loop. This + -- exception may or may not be thrown when the program is + -- non-terminating. + | PatternMatchFail String + -- ^A pattern matching failure. The 'String' argument should contain a + -- descriptive message including the function name, source file + -- and line number. + | RecConError String + -- ^An attempt was made to evaluate a field of a record + -- for which no value was given at construction time. The + -- 'String' argument gives the location of the + -- record construction in the source program. + | RecSelError String + -- ^A field selection was attempted on a constructor that + -- doesn\'t have the requested field. This can happen with + -- multi-constructor records when one or more fields are + -- missing from some of the constructors. The + -- 'String' argument gives the location of the + -- record selection in the source program. + | RecUpdError String + -- ^An attempt was made to update a field in a record, + -- where the record doesn\'t have the requested field. This can + -- only occur with multi-constructor records, when one or more + -- fields are missing from some of the constructors. The + -- 'String' argument gives the location of the + -- record update in the source program. -- |The type of arithmetic exceptions data ArithException @@ -724,34 +724,34 @@ data ArithException -- |Asynchronous exceptions data AsyncException = StackOverflow - -- ^The current thread\'s stack exceeded its limit. - -- Since an exception has been raised, the thread\'s stack - -- will certainly be below its limit again, but the - -- programmer should take remedial action - -- immediately. + -- ^The current thread\'s stack exceeded its limit. + -- Since an exception has been raised, the thread\'s stack + -- will certainly be below its limit again, but the + -- programmer should take remedial action + -- immediately. | HeapOverflow - -- ^The program\'s heap is reaching its limit, and - -- the program should take action to reduce the amount of - -- live data it has. Notes: - -- - -- * It is undefined which thread receives this exception. - -- - -- * GHC currently does not throw 'HeapOverflow' exceptions. + -- ^The program\'s heap is reaching its limit, and + -- the program should take action to reduce the amount of + -- live data it has. Notes: + -- + -- * It is undefined which thread receives this exception. + -- + -- * GHC currently does not throw 'HeapOverflow' exceptions. | ThreadKilled - -- ^This exception is raised by another thread - -- calling 'Control.Concurrent.killThread', or by the system - -- if it needs to terminate the thread for some - -- reason. + -- ^This exception is raised by another thread + -- calling 'Control.Concurrent.killThread', or by the system + -- if it needs to terminate the thread for some + -- reason. deriving (Eq, Ord) -- | Exceptions generated by array operations data ArrayException - = IndexOutOfBounds String - -- ^An attempt was made to index an array outside - -- its declared bounds. - | UndefinedElement String - -- ^An attempt was made to evaluate an element of an - -- array that had not been initialized. + = IndexOutOfBounds String + -- ^An attempt was made to index an array outside + -- its declared bounds. + | UndefinedElement String + -- ^An attempt was made to evaluate an element of an + -- array that had not been initialized. deriving (Eq, Ord) stackOverflow, heapOverflow :: Exception -- for the RTS @@ -772,31 +772,31 @@ instance Show AsyncException where instance Show ArrayException where showsPrec _ (IndexOutOfBounds s) - = showString "array index out of range" - . (if not (null s) then showString ": " . showString s - else id) + = showString "array index out of range" + . (if not (null s) then showString ": " . showString s + else id) showsPrec _ (UndefinedElement s) - = showString "undefined array element" - . (if not (null s) then showString ": " . showString s - else id) + = showString "undefined array element" + . (if not (null s) then showString ": " . showString s + else id) instance Show Exception where - showsPrec _ (IOException err) = shows err + showsPrec _ (IOException err) = shows err showsPrec _ (ArithException err) = shows err showsPrec _ (ArrayException err) = shows err - showsPrec _ (ErrorCall err) = showString err + showsPrec _ (ErrorCall err) = showString err showsPrec _ (ExitException err) = showString "exit: " . shows err showsPrec _ (NoMethodError err) = showString err showsPrec _ (PatternMatchFail err) = showString err - showsPrec _ (RecSelError err) = showString err - showsPrec _ (RecConError err) = showString err - showsPrec _ (RecUpdError err) = showString err + showsPrec _ (RecSelError err) = showString err + showsPrec _ (RecConError err) = showString err + showsPrec _ (RecUpdError err) = showString err showsPrec _ (AssertionFailed err) = showString err showsPrec _ (DynException err) = showString "exception :: " . showsTypeRep (dynTypeRep err) - showsPrec _ (AsyncException e) = shows e - showsPrec _ (BlockedOnDeadMVar) = showString "thread blocked indefinitely" - showsPrec _ (BlockedIndefinitely) = showString "thread blocked indefinitely" - showsPrec _ (NestedAtomically) = showString "Control.Concurrent.STM.atomically was nested" + showsPrec _ (AsyncException e) = shows e + showsPrec _ (BlockedOnDeadMVar) = showString "thread blocked indefinitely" + showsPrec _ (BlockedIndefinitely) = showString "thread blocked indefinitely" + showsPrec _ (NestedAtomically) = showString "Control.Concurrent.STM.atomically was nested" showsPrec _ (NonTermination) = showString "<>" showsPrec _ (Deadlock) = showString "<>" @@ -804,8 +804,8 @@ instance Eq Exception where IOException e1 == IOException e2 = e1 == e2 ArithException e1 == ArithException e2 = e1 == e2 ArrayException e1 == ArrayException e2 = e1 == e2 - ErrorCall e1 == ErrorCall e2 = e1 == e2 - ExitException e1 == ExitException e2 = e1 == e2 + ErrorCall e1 == ErrorCall e2 = e1 == e2 + ExitException e1 == ExitException e2 = e1 == e2 NoMethodError e1 == NoMethodError e2 = e1 == e2 PatternMatchFail e1 == PatternMatchFail e2 = e1 == e2 RecSelError e1 == RecSelError e2 = e1 == e2 @@ -827,12 +827,12 @@ instance Eq Exception where -- Exception datatype (above). data ExitCode - = ExitSuccess -- ^ indicates successful termination; + = ExitSuccess -- ^ indicates successful termination; | ExitFailure Int - -- ^ indicates program failure with an exit code. - -- The exact interpretation of the code is - -- operating-system dependent. In particular, some values - -- may be prohibited (e.g. 0 on a POSIX-compliant system). + -- ^ indicates program failure with an exit code. + -- The exact interpretation of the code is + -- operating-system dependent. In particular, some values + -- may be prohibited (e.g. 0 on a POSIX-compliant system). deriving (Eq, Ord, Read, Show) -- -------------------------------------------------------------------------- @@ -859,14 +859,14 @@ throw exception = raise# exception -- ordering with respect to other 'IO' operations, whereas 'throw' -- does not. throwIO :: Exception -> IO a -throwIO err = IO $ raiseIO# err +throwIO err = IO $ raiseIO# err -ioException :: IOException -> IO a +ioException :: IOException -> IO a ioException err = IO $ raiseIO# (IOException err) -- | Raise an 'IOError' in the 'IO' monad. ioError :: IOError -> IO a -ioError = ioException +ioError = ioException -- --------------------------------------------------------------------------- -- IOError type @@ -886,9 +886,9 @@ type IOError = IOException data IOException = IOError { ioe_handle :: Maybe Handle, -- the handle used by the action flagging - -- the error. + -- the error. ioe_type :: IOErrorType, -- what it was. - ioe_location :: String, -- location. + ioe_location :: String, -- location. ioe_description :: String, -- error type specific information. ioe_filename :: Maybe FilePath -- filename the error is related to. } @@ -932,22 +932,22 @@ instance Show IOErrorType where showsPrec _ e = showString $ case e of - AlreadyExists -> "already exists" + AlreadyExists -> "already exists" NoSuchThing -> "does not exist" ResourceBusy -> "resource busy" ResourceExhausted -> "resource exhausted" - EOF -> "end of file" - IllegalOperation -> "illegal operation" + EOF -> "end of file" + IllegalOperation -> "illegal operation" PermissionDenied -> "permission denied" - UserError -> "user error" - HardwareFault -> "hardware fault" + UserError -> "user error" + HardwareFault -> "hardware fault" InappropriateType -> "inappropriate type" Interrupted -> "interrupted" InvalidArgument -> "invalid argument" OtherError -> "failed" ProtocolError -> "protocol error" ResourceVanished -> "resource vanished" - SystemError -> "system error" + SystemError -> "system error" TimeExpired -> "timeout" UnsatisfiedConstraints -> "unsatisified constraints" -- ultra-precise! UnsupportedOperation -> "unsupported operation" @@ -962,7 +962,7 @@ instance Show IOErrorType where -- > fail s = ioError (userError s) -- userError :: String -> IOError -userError str = IOError Nothing UserError "" str Nothing +userError str = IOError Nothing UserError "" str Nothing -- --------------------------------------------------------------------------- -- Showing IOErrors @@ -970,17 +970,17 @@ userError str = IOError Nothing UserError "" str Nothing instance Show IOException where showsPrec p (IOError hdl iot loc s fn) = (case fn of - Nothing -> case hdl of - Nothing -> id - Just h -> showsPrec p h . showString ": " - Just name -> showString name . showString ": ") . + Nothing -> case hdl of + Nothing -> id + Just h -> showsPrec p h . showString ": " + Just name -> showString name . showString ": ") . (case loc of "" -> id - _ -> showString loc . showString ": ") . + _ -> showString loc . showString ": ") . showsPrec p iot . (case s of - "" -> id - _ -> showString " (" . showString s . showString ")") + "" -> id + _ -> showString " (" . showString s . showString ")") -- ----------------------------------------------------------------------------- -- IOMode type diff --git a/GHC/List.lhs b/GHC/List.lhs index cc2c1a0..a52a1d4 100644 --- a/GHC/List.lhs +++ b/GHC/List.lhs @@ -17,10 +17,10 @@ -- #hide module GHC.List ( - -- [] (..), -- Not Haskell 98; built in syntax + -- [] (..), -- Not Haskell 98; built in syntax map, (++), filter, concat, - head, last, tail, init, null, length, (!!), + head, last, tail, init, null, length, (!!), foldl, scanl, scanl1, foldr, foldr1, scanr, scanr1, iterate, repeat, replicate, cycle, take, drop, splitAt, takeWhile, dropWhile, span, break, @@ -38,7 +38,7 @@ module GHC.List ( ) where -import Data.Tuple() -- Instances +import Data.Tuple() -- Instances import Data.Maybe import GHC.Base @@ -47,9 +47,9 @@ infix 4 `elem`, `notElem` \end{code} %********************************************************* -%* * +%* * \subsection{List-manipulation functions} -%* * +%* * %********************************************************* \begin{code} @@ -61,12 +61,12 @@ head [] = badHead badHead = errorEmptyList "head" -- This rule is useful in cases like --- head [y | (x,y) <- ps, x==t] +-- head [y | (x,y) <- ps, x==t] {-# RULES -"head/build" forall (g::forall b.(a->b->b)->b->b) . - head (build g) = g (\x _ -> x) badHead -"head/augment" forall xs (g::forall b. (a->b->b) -> b -> b) . - head (augment g xs) = g (\x _ -> x) (head xs) +"head/build" forall (g::forall b.(a->b->b)->b->b) . + head (build g) = g (\x _ -> x) badHead +"head/augment" forall xs (g::forall b. (a->b->b) -> b -> b) . + head (augment g xs) = g (\x _ -> x) (head xs) #-} -- | Extract the elements after the head of a list, which must be non-empty. @@ -82,10 +82,10 @@ last (_:xs) = last xs last [] = errorEmptyList "last" #else -- eliminate repeated cases -last [] = errorEmptyList "last" -last (x:xs) = last' x xs +last [] = errorEmptyList "last" +last (x:xs) = last' x xs where last' y [] = y - last' _ (y:ys) = last' y ys + last' _ (y:ys) = last' y ys #endif -- | Return all the elements of a list except the last one. @@ -100,7 +100,7 @@ init [] = errorEmptyList "init" init [] = errorEmptyList "init" init (x:xs) = init' x xs where init' _ [] = [] - init' y (z:zs) = y : init' z zs + init' y (z:zs) = y : init' z zs #endif -- | Test whether a list is empty. @@ -127,16 +127,16 @@ filter :: (a -> Bool) -> [a] -> [a] filter _pred [] = [] filter pred (x:xs) | pred x = x : filter pred xs - | otherwise = filter pred xs + | otherwise = filter pred xs {-# NOINLINE [0] filterFB #-} filterFB c p x r | p x = x `c` r - | otherwise = r + | otherwise = r {-# RULES "filter" [~1] forall p xs. filter p xs = build (\c n -> foldr (filterFB c p) n xs) -"filterList" [1] forall p. foldr (filterFB (:) p) [] = filter p -"filterFB" forall c p q. filterFB (filterFB c p) q = filterFB c (\x -> q x && p x) +"filterList" [1] forall p. foldr (filterFB (:) p) [] = filter p +"filterFB" forall c p q. filterFB (filterFB c p) q = filterFB c (\x -> q x && p x) #-} -- Note the filterFB rule, which has p and q the "wrong way round" in the RHS. @@ -163,9 +163,9 @@ filterFB c p x r | p x = x `c` r foldl :: (a -> b -> a) -> a -> [b] -> a foldl f z xs = lgo z xs - where - lgo z [] = z - lgo z (x:xs) = lgo (f z x) xs + where + lgo z [] = z + lgo z (x:xs) = lgo (f z x) xs -- | 'scanl' is similar to 'foldl', but returns a list of successive -- reduced values from the left: @@ -185,9 +185,9 @@ scanl f q ls = q : (case ls of -- -- > scanl1 f [x1, x2, ...] == [x1, x1 `f` x2, ...] -scanl1 :: (a -> a -> a) -> [a] -> [a] -scanl1 f (x:xs) = scanl f x xs -scanl1 _ [] = [] +scanl1 :: (a -> a -> a) -> [a] -> [a] +scanl1 f (x:xs) = scanl f x xs +scanl1 _ [] = [] -- foldr, foldr1, scanr, and scanr1 are the right-to-left duals of the -- above functions. @@ -213,9 +213,9 @@ scanr f q0 (x:xs) = f x q : qs -- | 'scanr1' is a variant of 'scanr' that has no starting value argument. scanr1 :: (a -> a -> a) -> [a] -> [a] -scanr1 f [] = [] -scanr1 f [x] = [x] -scanr1 f (x:xs) = f x q : qs +scanr1 f [] = [] +scanr1 f [x] = [x] +scanr1 f (x:xs) = f x q : qs where qs@(q:_) = scanr1 f xs -- | 'iterate' @f x@ returns an infinite list of repeated applications @@ -230,8 +230,8 @@ iterateFB c f x = x `c` iterateFB c f (f x) {-# RULES -"iterate" [~1] forall f x. iterate f x = build (\c _n -> iterateFB c f x) -"iterateFB" [1] iterateFB (:) = iterate +"iterate" [~1] forall f x. iterate f x = build (\c _n -> iterateFB c f x) +"iterateFB" [1] iterateFB (:) = iterate #-} @@ -241,13 +241,13 @@ repeat :: a -> [a] -- The pragma just gives the rules more chance to fire repeat x = xs where xs = x : xs -{-# INLINE [0] repeatFB #-} -- ditto +{-# INLINE [0] repeatFB #-} -- ditto repeatFB c x = xs where xs = x `c` xs {-# RULES "repeat" [~1] forall x. repeat x = build (\c _n -> repeatFB c x) -"repeatFB" [1] repeatFB (:) = repeat +"repeatFB" [1] repeatFB (:) = repeat #-} -- | 'replicate' @n x@ is a list of length @n@ with @x@ the value of @@ -263,8 +263,8 @@ replicate n x = take n (repeat x) -- on infinite lists. cycle :: [a] -> [a] -cycle [] = error "Prelude.cycle: empty list" -cycle xs = xs' where xs' = xs ++ xs' +cycle [] = error "Prelude.cycle: empty list" +cycle xs = xs' where xs' = xs ++ xs' -- | 'takeWhile', applied to a predicate @p@ and a list @xs@, returns the -- longest prefix (possibly empty) of @xs@ of elements that satisfy @p@: @@ -350,7 +350,7 @@ splitAt n xs = (take n xs, drop n xs) #else /* hack away */ {-# RULES -"take" [~1] forall n xs . take n xs = takeFoldr n xs +"take" [~1] forall n xs . take n xs = takeFoldr n xs "takeList" [1] forall n xs . foldr (takeFB (:) []) (takeConst []) xs n = takeUInt n xs #-} @@ -369,7 +369,7 @@ takeConst x _ = x {-# NOINLINE [0] takeFB #-} takeFB :: (a -> b -> b) -> b -> a -> (Int# -> b) -> Int# -> b takeFB c n x xs m | m <=# 1# = x `c` n - | otherwise = x `c` xs (m -# 1#) + | otherwise = x `c` xs (m -# 1#) {-# INLINE [0] take #-} take (I# n#) xs = takeUInt n# xs @@ -395,32 +395,32 @@ takeUInt_append n xs rs | n >=# 0# = take_unsafe_UInt_append n xs rs | otherwise = [] -take_unsafe_UInt_append :: Int# -> [b] -> [b] -> [b] -take_unsafe_UInt_append 0# _ rs = rs -take_unsafe_UInt_append m ls rs = +take_unsafe_UInt_append :: Int# -> [b] -> [b] -> [b] +take_unsafe_UInt_append 0# _ rs = rs +take_unsafe_UInt_append m ls rs = case ls of [] -> rs (x:xs) -> x : take_unsafe_UInt_append (m -# 1#) xs rs drop (I# n#) ls - | n# <# 0# = ls - | otherwise = drop# n# ls + | n# <# 0# = ls + | otherwise = drop# n# ls where - drop# :: Int# -> [a] -> [a] - drop# 0# xs = xs - drop# _ xs@[] = xs - drop# m# (_:xs) = drop# (m# -# 1#) xs + drop# :: Int# -> [a] -> [a] + drop# 0# xs = xs + drop# _ xs@[] = xs + drop# m# (_:xs) = drop# (m# -# 1#) xs splitAt (I# n#) ls - | n# <# 0# = ([], ls) - | otherwise = splitAt# n# ls + | n# <# 0# = ([], ls) + | otherwise = splitAt# n# ls where - splitAt# :: Int# -> [a] -> ([a], [a]) - splitAt# 0# xs = ([], xs) - splitAt# _ xs@[] = (xs, xs) - splitAt# m# (x:xs) = (x:xs', xs'') - where - (xs', xs'') = splitAt# (m# -# 1#) xs + splitAt# :: Int# -> [a] -> ([a], [a]) + splitAt# 0# xs = ([], xs) + splitAt# _ xs@[] = (xs, xs) + splitAt# m# (x:xs) = (x:xs', xs'') + where + (xs', xs'') = splitAt# (m# -# 1#) xs #endif /* USE_REPORT_PRELUDE */ @@ -455,10 +455,10 @@ break :: (a -> Bool) -> [a] -> ([a],[a]) break p = span (not . p) #else -- HBC version (stolen) -break _ xs@[] = (xs, xs) +break _ xs@[] = (xs, xs) break p xs@(x:xs') - | p x = ([],xs) - | otherwise = let (ys,zs) = break p xs' in (x:ys,zs) + | p x = ([],xs) + | otherwise = let (ys,zs) = break p xs' in (x:ys,zs) #endif -- | 'reverse' @xs@ returns the elements of @xs@ in reverse order. @@ -486,16 +486,16 @@ or :: [Bool] -> Bool and = foldr (&&) True or = foldr (||) False #else -and [] = True -and (x:xs) = x && and xs -or [] = False -or (x:xs) = x || or xs +and [] = True +and (x:xs) = x && and xs +or [] = False +or (x:xs) = x || or xs {-# RULES -"and/build" forall (g::forall b.(Bool->b->b)->b->b) . - and (build g) = g (&&) True -"or/build" forall (g::forall b.(Bool->b->b)->b->b) . - or (build g) = g (||) False +"and/build" forall (g::forall b.(Bool->b->b)->b->b) . + and (build g) = g (&&) True +"or/build" forall (g::forall b.(Bool->b->b)->b->b) . + or (build g) = g (||) False #-} #endif @@ -510,16 +510,16 @@ all :: (a -> Bool) -> [a] -> Bool any p = or . map p all p = and . map p #else -any _ [] = False -any p (x:xs) = p x || any p xs +any _ [] = False +any p (x:xs) = p x || any p xs -all _ [] = True -all p (x:xs) = p x && all p xs +all _ [] = True +all p (x:xs) = p x && all p xs {-# RULES -"any/build" forall p (g::forall b.(a->b->b)->b->b) . - any p (build g) = g ((||) . p) False -"all/build" forall p (g::forall b.(a->b->b)->b->b) . - all p (build g) = g ((&&) . p) True +"any/build" forall p (g::forall b.(a->b->b)->b->b) . + any p (build g) = g ((||) . p) False +"all/build" forall p (g::forall b.(a->b->b)->b->b) . + all p (build g) = g ((&&) . p) True #-} #endif @@ -533,10 +533,10 @@ notElem :: (Eq a) => a -> [a] -> Bool elem x = any (== x) notElem x = all (/= x) #else -elem _ [] = False -elem x (y:ys) = x==y || elem x ys +elem _ [] = False +elem x (y:ys) = x==y || elem x ys -notElem _ [] = True +notElem _ [] = True notElem x (y:ys)= x /= y && notElem x ys #endif @@ -579,26 +579,26 @@ xs !! n | n < 0 = error "Prelude.!!: negative index" -- in the more efficient version. -- xs !! (I# n) | n <# 0# = error "Prelude.(!!): negative index\n" - | otherwise = sub xs n + | otherwise = sub xs n where - sub :: [a] -> Int# -> a + sub :: [a] -> Int# -> a sub [] _ = error "Prelude.(!!): index too large\n" sub (y:ys) n = if n ==# 0# - then y - else sub ys (n -# 1#) + then y + else sub ys (n -# 1#) #endif \end{code} %********************************************************* -%* * +%* * \subsection{The zip family} -%* * +%* * %********************************************************* \begin{code} -foldr2 _k z [] _ys = z -foldr2 _k z _xs [] = z +foldr2 _k z [] _ys = z +foldr2 _k z _xs [] = z foldr2 k z (x:xs) (y:ys) = k x y (foldr2 k z xs ys) foldr2_left _k z _x _r [] = z @@ -610,11 +610,11 @@ foldr2_right k _z y r (x:xs) = k x y (r xs) -- foldr2 k z xs ys = foldr (foldr2_left k z) (\_ -> z) xs ys -- foldr2 k z xs ys = foldr (foldr2_right k z) (\_ -> z) ys xs {-# RULES -"foldr2/left" forall k z ys (g::forall b.(a->b->b)->b->b) . - foldr2 k z (build g) ys = g (foldr2_left k z) (\_ -> z) ys +"foldr2/left" forall k z ys (g::forall b.(a->b->b)->b->b) . + foldr2 k z (build g) ys = g (foldr2_left k z) (\_ -> z) ys -"foldr2/right" forall k z xs (g::forall b.(a->b->b)->b->b) . - foldr2 k z xs (build g) = g (foldr2_right k z) (\_ -> z) xs +"foldr2/right" forall k z xs (g::forall b.(a->b->b)->b->b) . + foldr2 k z xs (build g) = g (foldr2_right k z) (\_ -> z) xs #-} \end{code} @@ -643,8 +643,8 @@ zip _ _ = [] zipFB c x y r = (x,y) `c` r {-# RULES -"zip" [~1] forall xs ys. zip xs ys = build (\c n -> foldr2 (zipFB c) n xs ys) -"zipList" [1] foldr2 (zipFB (:)) [] = zip +"zip" [~1] forall xs ys. zip xs ys = build (\c n -> foldr2 (zipFB c) n xs ys) +"zipList" [1] foldr2 (zipFB (:)) [] = zip #-} \end{code} @@ -677,8 +677,8 @@ zipWith _ _ _ = [] zipWithFB c f x y r = (x `f` y) `c` r {-# RULES -"zipWith" [~1] forall f xs ys. zipWith f xs ys = build (\c n -> foldr2 (zipWithFB c f) n xs ys) -"zipWithList" [1] forall f. foldr2 (zipWithFB (:) f) [] = zipWith f +"zipWith" [~1] forall f xs ys. zipWith f xs ys = build (\c n -> foldr2 (zipWithFB c f) n xs ys) +"zipWithList" [1] forall f. foldr2 (zipWithFB (:) f) [] = zipWith f #-} \end{code} @@ -707,9 +707,9 @@ unzip3 = foldr (\(a,b,c) ~(as,bs,cs) -> (a:as,b:bs,c:cs)) %********************************************************* -%* * +%* * \subsection{Error code} -%* * +%* * %********************************************************* Common up near identical calls to `error' to reduce the number