summaryrefslogtreecommitdiff
path: root/ghc/lib/prelude/PreludeWriteTextIO.lhs
diff options
context:
space:
mode:
Diffstat (limited to 'ghc/lib/prelude/PreludeWriteTextIO.lhs')
-rw-r--r--ghc/lib/prelude/PreludeWriteTextIO.lhs190
1 files changed, 190 insertions, 0 deletions
diff --git a/ghc/lib/prelude/PreludeWriteTextIO.lhs b/ghc/lib/prelude/PreludeWriteTextIO.lhs
new file mode 100644
index 0000000000..000c343637
--- /dev/null
+++ b/ghc/lib/prelude/PreludeWriteTextIO.lhs
@@ -0,0 +1,190 @@
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1994
+%
+\section[PrelWriteTextIO]{Haskell 1.3 Text Output}
+
+This module defines the standard set of output operations for writing
+characters and strings to text files, using
+$handles$
+
+\begin{code}
+module PreludeWriteTextIO (
+ hPutChar,
+ putChar,
+ hPutStr,
+ putStr,
+ hPutText,
+ putText,
+ print13,
+ writeFile13,
+ appendFile13
+ ) where
+
+import Cls
+import Core
+import IChar
+import IInt
+import IList
+import List ( splitAt, (++) )
+import Prel ( ord, (.), otherwise )
+import Text
+import TyArray -- instance _CCallable (_ByteArray a)
+
+import PreludeIOError
+import PreludeMonadicIO
+import PreludePrimIO
+import PreludeGlaST
+import PreludeStdIO
+import PS
+
+hPutChar :: Handle -> Char -> IO ()
+hPutChar handle c =
+ takeMVar handle >>= \ htype ->
+ case htype of
+ _ErrorHandle ioError ->
+ putMVar handle htype >>
+ failWith ioError
+ _ClosedHandle ->
+ putMVar handle htype >>
+ failWith (IllegalOperation "handle is closed")
+ _SemiClosedHandle _ _ ->
+ putMVar handle htype >>
+ failWith (IllegalOperation "handle is closed")
+ _ReadHandle _ _ _ ->
+ putMVar handle htype >>
+ failWith (IllegalOperation "handle is not open for writing")
+ other ->
+ _ccall_ filePutc (_filePtr other) (ord c) `thenPrimIO` \ rc ->
+ putMVar handle (_markHandle htype) >>
+ if rc == 0 then
+ return ()
+ else
+ _constructError `thenPrimIO` \ ioError ->
+ failWith ioError
+
+putChar :: Char -> IO ()
+putChar = hPutChar stdout13
+
+\end{code}
+
+Computation $hPutChar hdl c$ writes the character {\em c} to the file
+or channel managed by {\em hdl}. Characters may be buffered if
+buffering is enabled for {\em hdl}.
+
+\begin{code}
+hPutStr :: Handle -> String -> IO ()
+hPutStr handle str =
+ takeMVar handle >>= \ htype ->
+ case htype of
+ _ErrorHandle ioError ->
+ putMVar handle htype >>
+ failWith ioError
+ _ClosedHandle ->
+ putMVar handle htype >>
+ failWith (IllegalOperation "handle is closed")
+ _SemiClosedHandle _ _ ->
+ putMVar handle htype >>
+ failWith (IllegalOperation "handle is closed")
+ _ReadHandle _ _ _ ->
+ putMVar handle htype >>
+ failWith (IllegalOperation "handle is not open for writing")
+ other ->
+ _getBufferMode other `thenPrimIO` \ other ->
+ (case _bufferMode other of
+ Just LineBuffering ->
+ writeLines (_filePtr other) str
+ Just (BlockBuffering (Just size)) ->
+ writeBlocks (_filePtr other) size str
+ Just (BlockBuffering Nothing) ->
+ writeBlocks (_filePtr other) ``BUFSIZ'' str
+ _ -> -- Nothing is treated pessimistically as NoBuffering
+ writeChars (_filePtr other) str
+ ) `thenPrimIO` \ success ->
+ putMVar handle (_markHandle other) `seqPrimIO`
+ if success then
+ return ()
+ else
+ _constructError `thenPrimIO` \ ioError ->
+ failWith ioError
+
+ where
+
+ writeBlocks :: _Addr -> Int -> String -> PrimIO Bool
+ writeBlocks fp size "" = returnPrimIO True
+ writeBlocks fp size s =
+ let
+ (some, more) = splitAt size s
+ in
+ _packBytesForCST some `thenPrimIO`
+ \ bytes@(_ByteArray (0, count) _) ->
+ _ccall_ writeFile bytes fp (count+1) `thenPrimIO` \ rc ->
+ if rc == 0 then
+ writeBlocks fp size more
+ else
+ returnPrimIO False
+
+ writeLines :: _Addr -> String -> PrimIO Bool
+ writeLines fp "" = returnPrimIO True
+ writeLines fp s =
+ let
+ (some, more) = breakLine s
+ in
+ _packBytesForCST some `thenPrimIO`
+ \ bytes@(_ByteArray (0, count) _) ->
+ _ccall_ writeFile bytes fp (count+1) `thenPrimIO` \ rc ->
+ if rc == 0 then
+ writeLines fp more
+ else
+ returnPrimIO False
+ where
+ breakLine "" = ("","")
+ breakLine (x:xs)
+ | x == '\n' = ([x],xs)
+ | otherwise = let (ys,zs) = breakLine xs in (x:ys,zs)
+
+ writeChars :: _Addr -> String -> PrimIO Bool
+ writeChars fp "" = returnPrimIO True
+ writeChars fp (c:cs) =
+ _ccall_ filePutc fp (ord c) `thenPrimIO` \ rc ->
+ if rc == 0 then
+ writeChars fp cs
+ else
+ returnPrimIO False
+
+putStr :: String -> IO ()
+putStr = hPutStr stdout13
+
+hPutText :: Text a => Handle -> a -> IO ()
+hPutText hdl = hPutStr hdl . show
+
+putText :: Text a => a -> IO ()
+putText = hPutText stdout13
+
+print13 :: Text a => a -> IO ()
+print13 x = putText x >> putChar '\n'
+
+\end{code}
+
+Computation $hPutStr hdl s$ writes the string {\em s} to the file or
+channel managed by {\em hdl}.
+
+Computation $putStr s$ writes the string {\em s} to $stdout$.
+
+Computation $hPutText hdl t$ writes the string representation of {\em
+t} given by the $shows$ function to the file or channel managed by
+{\em hdl}.
+
+\begin{code}
+
+writeFile13 :: FilePath -> String -> IO ()
+writeFile13 name str =
+ openFile name WriteMode >>= \hdl -> hPutStr hdl str >> hClose hdl
+
+appendFile13 :: FilePath -> String -> IO ()
+appendFile13 name str =
+ openFile name AppendMode >>= \hdl -> hPutStr hdl str >> hClose hdl
+
+\end{code}
+
+$writeFile file s$ replaces the contents of {\em file} by the string
+{\em s}. $appendFile file s$ appends string {\em s} to {\em file}.