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