[project @ 2001-05-22 15:06:47 by simonmar]
[ghc-hetmet.git] / ghc / lib / std / PrelIO.hsc
1 {-# OPTIONS -fno-implicit-prelude #-}
2
3 #undef DEBUG_DUMP
4
5 -- -----------------------------------------------------------------------------
6 -- $Id: PrelIO.hsc,v 1.3 2001/05/22 15:06:47 simonmar Exp $
7 --
8 -- (c) The University of Glasgow, 1992-2001
9 --
10 -- Module PrelIO
11
12 -- This module defines all basic IO operations.
13 -- These are needed for the IO operations exported by Prelude,
14 -- but as it happens they also do everything required by library
15 -- module IO.
16
17 module PrelIO where
18
19 #include "HsStd.h"
20 #include "PrelHandle_hsc.h"
21
22 import PrelBase
23
24 import PrelPosix
25 import PrelMarshalAlloc
26 import PrelMarshalUtils
27 import PrelStorable
28 import PrelCError
29 import PrelCString
30 import PrelCTypes
31 import PrelCTypesISO
32
33 import PrelIOBase
34 import PrelHandle       -- much of the real stuff is in here
35
36 import PrelMaybe
37 import PrelReal
38 import PrelNum
39 import PrelRead
40 import PrelShow
41 import PrelMaybe        ( Maybe(..) )
42 import PrelPtr
43 import PrelList
44 import PrelException    ( ioError, catch, throw )
45 import PrelConc
46
47 -- -----------------------------------------------------------------------------
48 -- Standard IO
49
50 putChar         :: Char -> IO ()
51 putChar c       =  hPutChar stdout c
52
53 putStr          :: String -> IO ()
54 putStr s        =  hPutStr stdout s
55
56 putStrLn        :: String -> IO ()
57 putStrLn s      =  do putStr s
58                       putChar '\n'
59
60 print           :: Show a => a -> IO ()
61 print x         =  putStrLn (show x)
62
63 getChar         :: IO Char
64 getChar         =  hGetChar stdin
65
66 getLine         :: IO String
67 getLine         =  hGetLine stdin
68
69 getContents     :: IO String
70 getContents     =  hGetContents stdin
71
72 interact        ::  (String -> String) -> IO ()
73 interact f      =   do s <- getContents
74                        putStr (f s)
75
76 readFile        :: FilePath -> IO String
77 readFile name   =  openFile name ReadMode >>= hGetContents
78
79 writeFile       :: FilePath -> String -> IO ()
80 writeFile name str = do
81     hdl <- openFile name WriteMode
82     hPutStr hdl str
83     hClose hdl
84
85 appendFile      :: FilePath -> String -> IO ()
86 appendFile name str = do
87     hdl <- openFile name AppendMode
88     hPutStr hdl str
89     hClose hdl
90
91 readLn          :: Read a => IO a
92 readLn          =  do l <- getLine
93                       r <- readIO l
94                       return r
95
96   -- raises an exception instead of an error
97 readIO          :: Read a => String -> IO a
98 readIO s        =  case (do { (x,t) <- reads s ;
99                               ("","") <- lex t ;
100                               return x }) of
101 #ifndef NEW_READS_REP
102                         [x]    -> return x
103                         []     -> ioError (userError "Prelude.readIO: no parse")
104                         _      -> ioError (userError "Prelude.readIO: ambiguous parse")
105 #else
106                         Just x -> return x
107                         Nothing  -> ioError (userError "Prelude.readIO: no parse")
108 #endif
109
110 -- ---------------------------------------------------------------------------
111 -- Simple input operations
112
113 -- Computation "hReady hdl" indicates whether at least
114 -- one item is available for input from handle "hdl".
115
116 -- If hWaitForInput finds anything in the Handle's buffer, it
117 -- immediately returns.  If not, it tries to read from the underlying
118 -- OS handle. Notice that for buffered Handles connected to terminals
119 -- this means waiting until a complete line is available.
120
121 hReady :: Handle -> IO Bool
122 hReady h = hWaitForInput h 0
123
124 hWaitForInput :: Handle -> Int -> IO Bool
125 hWaitForInput h msecs = do
126   wantReadableHandle "hReady" h $ \ handle_ -> do
127   let ref = haBuffer handle_
128   buf <- readIORef ref
129
130   if not (bufferEmpty buf)
131         then return True
132         else do
133
134   r <- throwErrnoIfMinus1Retry "hReady"
135           (inputReady (fromIntegral (haFD handle_)) (fromIntegral msecs))
136   return (r /= 0)
137
138 foreign import "inputReady" 
139   inputReady :: CInt -> CInt -> IO CInt
140
141 -- ---------------------------------------------------------------------------
142 -- hGetChar
143
144 -- hGetChar reads the next character from a handle,
145 -- blocking until a character is available.
146
147 hGetChar :: Handle -> IO Char
148 hGetChar handle =
149   wantReadableHandle "hGetChar" handle $ \handle_ -> do
150
151   let fd = haFD handle_
152       ref = haBuffer handle_
153
154   buf <- readIORef ref
155   if not (bufferEmpty buf)
156         then hGetcBuffered fd ref buf
157         else do
158
159   -- buffer is empty.
160   case haBufferMode handle_ of
161     LineBuffering    -> do
162         new_buf <- fillReadBuffer fd True buf
163         hGetcBuffered fd ref new_buf
164     BlockBuffering _ -> do
165         new_buf <- fillReadBuffer fd False buf
166         hGetcBuffered fd ref new_buf
167     NoBuffering -> do
168         -- make use of the minimal buffer we already have
169         let raw = bufBuf buf
170         r <- throwErrnoIfMinus1RetryMayBlock "hGetChar"
171                 (read_off (fromIntegral fd) raw 0 1)
172                 (threadWaitRead fd)
173         if r == 0
174            then ioe_EOF
175            else do (c,_) <- readCharFromBuffer raw 0
176                    return c
177
178 hGetcBuffered fd ref buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w }
179  = do (c,r) <- readCharFromBuffer b r
180       let new_buf | r == w    = buf{ bufRPtr=0, bufWPtr=0 }
181                   | otherwise = buf{ bufRPtr=r }
182       writeIORef ref new_buf
183       return c
184
185 -- ---------------------------------------------------------------------------
186 -- hGetLine
187
188 -- If EOF is reached before EOL is encountered, ignore the EOF and
189 -- return the partial line. Next attempt at calling hGetLine on the
190 -- handle will yield an EOF IO exception though.
191
192 -- ToDo: the unbuffered case is wrong: it doesn't lock the handle for
193 -- the duration.
194 hGetLine :: Handle -> IO String
195 hGetLine h = do
196   m <- wantReadableHandle "hGetLine" h $ \ handle_ -> do
197         case haBufferMode handle_ of
198            NoBuffering      -> return Nothing
199            LineBuffering    -> do
200               l <- hGetLineBuffered handle_
201               return (Just l)
202            BlockBuffering _ -> do 
203               l <- hGetLineBuffered handle_
204               return (Just l)
205   case m of
206         Nothing -> hGetLineUnBuffered h
207         Just l  -> return l
208
209
210 hGetLineBuffered handle_ = do
211   let ref = haBuffer handle_
212   buf <- readIORef ref
213   hGetLineBufferedLoop handle_ ref buf []
214
215
216 hGetLineBufferedLoop handle_ ref 
217         buf@Buffer{ bufRPtr=r, bufWPtr=w, bufBuf=raw } xss =
218   let 
219         -- find the end-of-line character, if there is one
220         loop raw r
221            | r == w = return (False, w)
222            | otherwise =  do
223                 (c,r') <- readCharFromBuffer raw r
224                 if c == '\n' 
225                    then return (True, r) -- NB. not r': don't include the '\n'
226                    else loop raw r'
227   in do
228   (eol, off) <- loop raw r
229
230 #ifdef DEBUG_DUMP
231   puts ("hGetLineBufferedLoop: r=" ++ show r ++ ", w=" ++ show w ++ ", off=" ++ show off ++ "\n")
232 #endif
233
234   xs <- unpack raw r off
235   if eol
236         then do if w == off + 1
237                    then writeIORef ref buf{ bufRPtr=0, bufWPtr=0 }
238                    else writeIORef ref buf{ bufRPtr = off + 1 }
239                 return (concat (reverse (xs:xss)))
240         else do
241              maybe_buf <- maybeFillReadBuffer (haFD handle_) True 
242                                 buf{ bufWPtr=0, bufRPtr=0 }
243              case maybe_buf of
244                 -- Nothing indicates we caught an EOF, and we may have a
245                 -- partial line to return.
246                 Nothing -> let str = concat (reverse (xs:xss)) in
247                            if not (null str)
248                               then return str
249                               else ioe_EOF
250                 Just new_buf -> 
251                      hGetLineBufferedLoop handle_ ref new_buf (xs:xss)
252
253
254 unpack :: RawBuffer -> Int -> Int -> IO [Char]
255 unpack buf r 0   = return ""
256 unpack buf (I## r) (I## len) = IO $ \s -> unpack [] (len -## 1##) s
257    where
258     unpack acc i s
259      | i <## r  = (## s, acc ##)
260      | otherwise = 
261           case readCharArray## buf i s of
262             (## s, ch ##) -> unpack (C## ch : acc) (i -## 1##) s
263
264
265 hGetLineUnBuffered :: Handle -> IO String
266 hGetLineUnBuffered h = do
267   c <- hGetChar h
268   if c == '\n' then
269      return ""
270    else do
271     l <- getRest
272     return (c:l)
273  where
274   getRest = do
275     c <- 
276       catch 
277         (hGetChar h)
278         (\ err -> do
279           if isEOFError err then
280              return '\n'
281            else
282              ioError err)
283     if c == '\n' then
284        return ""
285      else do
286        s <- getRest
287        return (c:s)
288
289 -- -----------------------------------------------------------------------------
290 -- hGetContents
291
292 -- hGetContents returns the list of characters corresponding to the
293 -- unread portion of the channel or file managed by the handle, which
294 -- is made semi-closed.
295
296 hGetContents :: Handle -> IO String
297 hGetContents handle = 
298         -- can't use wantReadableHandle here, because we want to side effect
299         -- the handle.
300     withHandle "hGetContents" handle $ \ handle_ -> do
301     case haType handle_ of 
302       ClosedHandle         -> ioe_closedHandle
303       SemiClosedHandle     -> ioe_closedHandle
304       AppendHandle         -> ioException not_readable_error
305       WriteHandle          -> ioException not_readable_error
306       _ -> do xs <- lazyRead handle
307               return (handle_{ haType=SemiClosedHandle}, xs )
308   where
309    not_readable_error = 
310         IOError (Just handle) IllegalOperation "hGetContents"
311                 "handle is not open for reading" Nothing
312
313 -- Note that someone may close the semi-closed handle (or change its
314 -- buffering), so each these lazy read functions are pulled on, they
315 -- have to check whether the handle has indeed been closed.
316
317 lazyRead :: Handle -> IO String
318 lazyRead handle = 
319    unsafeInterleaveIO $
320         withHandle_ "lazyRead" handle $ \ handle_ -> do
321         case haType handle_ of
322           ClosedHandle     -> return ""
323           SemiClosedHandle -> lazyRead' handle handle_
324           _ -> ioException 
325                   (IOError (Just handle) IllegalOperation "lazyRead"
326                         "illegal handle type" Nothing)
327
328 lazyRead' h handle_ = do
329   let ref = haBuffer handle_
330       fd  = haFD handle_
331
332   -- even a NoBuffering handle can have a char in the buffer... 
333   -- (see hLookAhead)
334   buf <- readIORef ref
335   if not (bufferEmpty buf)
336         then lazyReadBuffered h fd ref buf
337         else do
338
339   case haBufferMode handle_ of
340      NoBuffering      -> do
341         -- make use of the minimal buffer we already have
342         let raw = bufBuf buf
343             fd  = haFD handle_
344         r <- throwErrnoIfMinus1RetryMayBlock "hGetChar"
345                 (read_off (fromIntegral fd) raw 0 1)
346                 (threadWaitRead fd)
347         if r == 0
348            then return ""
349            else do (c,_) <- readCharFromBuffer raw 0
350                    rest <- lazyRead h
351                    return (c : rest)
352
353      LineBuffering    -> lazyReadBuffered h fd ref buf
354      BlockBuffering _ -> lazyReadBuffered h fd ref buf
355
356 -- we never want to block during the read, so we call fillReadBuffer with
357 -- is_line==True, which tells it to "just read what there is".
358 lazyReadBuffered h fd ref buf = do
359    maybe_new_buf <- 
360         if bufferEmpty buf 
361            then maybeFillReadBuffer fd True buf
362            else return (Just buf)
363    case maybe_new_buf of
364         Nothing  -> return ""
365         Just buf -> do
366            more <- lazyRead h
367            writeIORef ref buf{ bufRPtr=0, bufWPtr=0 }
368            unpackAcc (bufBuf buf) (bufRPtr buf) (bufWPtr buf) more
369
370
371 maybeFillReadBuffer fd is_line buf
372   = catch 
373      (do buf <- fillReadBuffer fd is_line buf
374          return (Just buf)
375      )
376      (\e -> if isEOFError e 
377                 then return Nothing 
378                 else throw e)
379
380
381 unpackAcc :: RawBuffer -> Int -> Int -> [Char] -> IO [Char]
382 unpackAcc buf r 0 acc  = return ""
383 unpackAcc buf (I## r) (I## len) acc = IO $ \s -> unpack acc (len -## 1##) s
384    where
385     unpack acc i s
386      | i <## r  = (## s, acc ##)
387      | otherwise = 
388           case readCharArray## buf i s of
389             (## s, ch ##) -> unpack (C## ch : acc) (i -## 1##) s
390
391 -- ---------------------------------------------------------------------------
392 -- hPutChar
393
394 -- `hPutChar hdl ch' writes the character `ch' to the file or channel
395 -- managed by `hdl'.  Characters may be buffered if buffering is
396 -- enabled for `hdl'.
397
398 hPutChar :: Handle -> Char -> IO ()
399 hPutChar handle c = 
400     c `seq` do   -- must evaluate c before grabbing the handle lock
401     wantWritableHandle "hPutChar" handle $ \ handle_  -> do
402     let fd = haFD handle_
403     case haBufferMode handle_ of
404         LineBuffering    -> hPutcBuffered handle_ True  c
405         BlockBuffering _ -> hPutcBuffered handle_ False c
406         NoBuffering      ->
407                 withObject (castCharToCChar c) $ \buf ->
408                 throwErrnoIfMinus1RetryMayBlock_ "hPutChar"
409                    (c_write (fromIntegral fd) buf 1)
410                    (threadWaitWrite fd)
411
412
413 hPutcBuffered handle_ is_line c = do
414   let ref = haBuffer handle_
415   buf <- readIORef ref
416   let w = bufWPtr buf
417   w'  <- writeCharIntoBuffer (bufBuf buf) w c
418   let new_buf = buf{ bufWPtr = w' }
419   if bufferFull new_buf || is_line && c == '\n'
420      then do 
421         flushed_buf <- flushWriteBuffer (haFD handle_) new_buf
422         writeIORef ref flushed_buf
423      else do 
424         writeIORef ref new_buf
425
426
427 hPutChars :: Handle -> [Char] -> IO ()
428 hPutChars handle [] = return ()
429 hPutChars handle (c:cs) = hPutChar handle c >> hPutChars handle cs
430
431 -- ---------------------------------------------------------------------------
432 -- hPutStr
433
434 -- `hPutStr hdl s' writes the string `s' to the file or
435 -- hannel managed by `hdl', buffering the output if needs be.
436
437 -- We go to some trouble to avoid keeping the handle locked while we're
438 -- evaluating the string argument to hPutStr, in case doing so triggers another
439 -- I/O operation on the same handle which would lead to deadlock.  The classic
440 -- case is
441 --
442 --              putStr (trace "hello" "world")
443 --
444 -- so the basic scheme is this:
445 --
446 --      * copy the string into a fresh buffer,
447 --      * "commit" the buffer to the handle.
448 --
449 -- Committing may involve simply copying the contents of the new
450 -- buffer into the handle's buffer, flushing one or both buffers, or
451 -- maybe just swapping the buffers over (if the handle's buffer was
452 -- empty).  See commitBuffer below.
453
454 hPutStr :: Handle -> String -> IO ()
455 hPutStr handle str = do
456     buffer_mode <- wantWritableHandle "hPutStr" handle 
457                         (\ handle_ -> do getSpareBuffer handle_)
458     case buffer_mode of
459        (NoBuffering, _) -> do
460             hPutChars handle str        -- v. slow, but we don't care
461        (LineBuffering, buf) -> do
462             writeLines handle buf str
463        (BlockBuffering _, buf) -> do
464             writeBlocks handle buf str
465
466
467 getSpareBuffer :: Handle__ -> IO (BufferMode, Buffer)
468 getSpareBuffer Handle__{haBuffer=ref, 
469                         haBuffers=spare_ref,
470                         haBufferMode=mode}
471  = do
472    case mode of
473      NoBuffering -> return (mode, error "no buffer!")
474      _ -> do
475           bufs <- readIORef spare_ref
476           buf  <- readIORef ref
477           case bufs of
478             BufferListCons b rest -> do
479                 writeIORef spare_ref rest
480                 return ( mode, newEmptyBuffer b WriteBuffer (bufSize buf))
481             BufferListNil -> do
482                 new_buf <- allocateBuffer (bufSize buf) WriteBuffer
483                 return (mode, new_buf)
484
485
486 writeLines :: Handle -> Buffer -> String -> IO ()
487 writeLines hdl Buffer{ bufBuf=raw, bufSize=len } s =
488   let
489    shoveString :: Int -> [Char] -> IO ()
490         -- check n == len first, to ensure that shoveString is strict in n.
491    shoveString n cs | n == len = do
492         new_buf <- commitBuffer hdl raw len n True{-needs flush-} False
493         writeBlocks hdl new_buf cs
494    shoveString n [] = do
495         commitBuffer hdl raw len n False{-no flush-} True{-release-}
496         return ()
497    shoveString n (c:cs) = do
498         n' <- writeCharIntoBuffer raw n c
499         shoveString n' cs
500   in
501   shoveString 0 s
502
503 writeBlocks :: Handle -> Buffer -> String -> IO ()
504 writeBlocks hdl Buffer{ bufBuf=raw, bufSize=len } s =
505   let
506    shoveString :: Int -> [Char] -> IO ()
507         -- check n == len first, to ensure that shoveString is strict in n.
508    shoveString n cs | n == len = do
509         new_buf <- commitBuffer hdl raw len n True{-needs flush-} False
510         writeBlocks hdl new_buf cs
511    shoveString n [] = do
512         commitBuffer hdl raw len n False{-no flush-} True{-release-}
513         return ()
514    shoveString n (c:cs) = do
515         n' <- writeCharIntoBuffer raw n c
516         shoveString n' cs
517   in
518   shoveString 0 s
519
520 -- -----------------------------------------------------------------------------
521 -- commitBuffer handle buf sz count flush release
522 -- 
523 -- Write the contents of the buffer 'buf' ('sz' bytes long, containing
524 -- 'count' bytes of data) to handle (handle must be block or line buffered).
525 -- 
526 -- Implementation:
527 -- 
528 --    for block/line buffering,
529 --       1. If there isn't room in the handle buffer, flush the handle
530 --          buffer.
531 -- 
532 --       2. If the handle buffer is empty,
533 --               if flush, 
534 --                   then write buf directly to the device.
535 --                   else swap the handle buffer with buf.
536 -- 
537 --       3. If the handle buffer is non-empty, copy buf into the
538 --          handle buffer.  Then, if flush != 0, flush
539 --          the buffer.
540
541 commitBuffer
542         :: Handle                       -- handle to commit to
543         -> RawBuffer -> Int             -- address and size (in bytes) of buffer
544         -> Int                          -- number of bytes of data in buffer
545         -> Bool                         -- flush the handle afterward?
546         -> Bool                         -- release the buffer?
547         -> IO Buffer
548
549 commitBuffer hdl raw sz count flush release = do
550   wantWritableHandle "commitAndReleaseBuffer" hdl $ 
551     \ handle_@Handle__{ haFD=fd, haBuffer=ref, haBuffers=spare_buf_ref } -> do
552
553 #ifdef DEBUG_DUMP
554       puts ("commitBuffer: sz=" ++ show sz ++ ", count=" ++ show count
555             ++ ", flush=" ++ show flush ++ ", release=" ++ show release ++"\n")
556 #endif
557
558       old_buf@Buffer{ bufBuf=old_raw, bufRPtr=r, bufWPtr=w, bufSize=size }
559           <- readIORef ref
560
561       buf_ret <-
562         -- enough room in handle buffer?
563          if (not flush && (size - w > count))
564                 -- The > is to be sure that we never exactly fill
565                 -- up the buffer, which would require a flush.  So
566                 -- if copying the new data into the buffer would
567                 -- make the buffer full, we just flush the existing
568                 -- buffer and the new data immediately, rather than
569                 -- copying before flushing.
570
571                 -- not flushing, and there's enough room in the buffer:
572                 -- just copy the data in and update bufWPtr.
573             then do memcpy_off old_raw w raw (fromIntegral count)
574                     writeIORef ref old_buf{ bufWPtr = w + count }
575                     return (newEmptyBuffer raw WriteBuffer sz)
576
577                 -- else, we have to flush
578             else do flushed_buf <- flushWriteBuffer fd old_buf
579
580                     let this_buf = 
581                             Buffer{ bufBuf=raw, bufState=WriteBuffer, 
582                                     bufRPtr=0, bufWPtr=count, bufSize=sz }
583
584                         -- if:  (a) we don't have to flush, and
585                         --      (b) size(new buffer) == size(old buffer), and
586                         --      (c) new buffer is not full,
587                         -- we can just just swap them over...
588                     if (not flush && sz == size && count /= sz)
589                         then do 
590                           writeIORef ref this_buf
591                           return flushed_buf                         
592
593                         -- otherwise, we have to flush the new data too,
594                         -- and start with a fresh buffer
595                         else do 
596                           flushWriteBuffer fd this_buf
597                           writeIORef ref flushed_buf
598                             -- if the sizes were different, then allocate
599                             -- a new buffer of the correct size.
600                           if sz == size
601                              then return (newEmptyBuffer raw WriteBuffer sz)
602                              else allocateBuffer size WriteBuffer
603
604       -- release the buffer if necessary
605       if release && bufSize buf_ret == size
606          then do
607               spare_bufs <- readIORef spare_buf_ref
608               writeIORef spare_buf_ref 
609                 (BufferListCons (bufBuf buf_ret) spare_bufs)
610               return buf_ret
611          else
612               return buf_ret
613
614
615 foreign import "memcpy_wrap" unsafe 
616    memcpy_off :: RawBuffer -> Int -> RawBuffer -> CSize -> IO (Ptr ())
617 #def inline \
618 void *memcpy_wrap(char *dst, int dst_off, char *src, size_t sz) \
619 { return memcpy(dst+dst_off, src, sz); }
620
621 -- ---------------------------------------------------------------------------
622 -- hPutStrLn
623
624 -- Derived action `hPutStrLn hdl str' writes the string `str' to
625 -- the handle `hdl', adding a newline at the end.
626
627 hPutStrLn :: Handle -> String -> IO ()
628 hPutStrLn hndl str = do
629  hPutStr  hndl str
630  hPutChar hndl '\n'
631
632 -- ---------------------------------------------------------------------------
633 -- hPrint
634
635 -- Computation `hPrint hdl t' writes the string representation of `t'
636 -- given by the `shows' function to the file or channel managed by `hdl'.
637
638 hPrint :: Show a => Handle -> a -> IO ()
639 hPrint hdl = hPutStrLn hdl . show