-{-# OPTIONS_GHC -fno-implicit-prelude #-}
+{-# OPTIONS_GHC -XNoImplicitPrelude #-}
-----------------------------------------------------------------------------
-- |
-- Module : System.IO
openTempFile,
openBinaryTempFile,
+
+#if !defined(__NHC__) && !defined(__HUGS__)
+ -- * Unicode encoding\/decoding
+
+ -- | A text-mode 'Handle' has an associated 'TextEncoding', which
+ -- is used to decode bytes into Unicode characters when reading,
+ -- and encode Unicode characters into bytes when writing.
+ --
+ -- The default 'TextEncoding' is the same as the default encoding
+ -- on your system, which is also available as 'localeEncoding'.
+ -- (GHC note: on Windows, currently 'localeEncoding' is always
+ -- 'latin1'; there is no support for encoding and decoding using
+ -- the ANSI code page).
+ --
+ -- Encoding and decoding errors are always detected and reported,
+ -- except during lazy I/O ('hGetContents', 'getContents', and
+ -- 'readFile'), where a decoding error merely results in
+ -- termination of the character stream, as with other I/O errors.
+
+ hSetEncoding,
+
+ -- ** Unicode encodings
+ TextEncoding,
+ latin1,
+ utf8,
+ utf16, utf16le, utf16be,
+ utf32, utf32le, utf32be,
+ localeEncoding,
+ mkTextEncoding,
+#endif
+
+#if !defined(__NHC__) && !defined(__HUGS__)
+ -- * Newline conversion
+
+ -- | In Haskell, a newline is always represented by the character
+ -- '\n'. However, in files and external character streams, a
+ -- newline may be represented by another character sequence, such
+ -- as '\r\n'.
+ --
+ -- A text-mode 'Handle' has an associated 'NewlineMode' that
+ -- specifies how to transate newline characters. The
+ -- 'NewlineMode' specifies the input and output translation
+ -- separately, so that for instance you can translate '\r\n'
+ -- to '\n' on input, but leave newlines as '\n' on output.
+ --
+ -- The default 'NewlineMode' for a 'Handle' is
+ -- 'nativeNewlineMode', which does no translation on Unix systems,
+ -- but translates '\r\n' to '\n' and back on Windows.
+ --
+ -- Binary-mode 'Handle's do no newline translation at all.
+ --
+ hSetNewlineMode,
+ Newline(..), nativeNewline,
+ NewlineMode(..),
+ noNewlineTranslation, universalNewlineMode, nativeNewlineMode,
+#endif
) where
+import Control.Exception.Base
+
#ifndef __NHC__
import Data.Bits
import Data.List
import Data.Maybe
import Foreign.C.Error
-import Foreign.C.String
+import Foreign.C.Types
import System.Posix.Internals
#endif
#ifdef __GLASGOW_HASKELL__
-import GHC.Exception as ExceptionBase hiding (catch)
-#endif
-#ifdef __HUGS__
-import Hugs.Exception as ExceptionBase
-#endif
-
-#ifdef __GLASGOW_HASKELL__
import GHC.Base
-import GHC.IOBase -- Together these four Prelude modules define
-import GHC.Handle -- all the stuff exported by IO for the GHC version
-import GHC.IO
+import GHC.IO hiding ( onException )
+import GHC.IO.IOMode
+import GHC.IO.Handle.FD
+import GHC.IO.Handle
+import GHC.IORef
+import GHC.IO.Exception ( userError )
+import GHC.IO.Encoding
import GHC.Exception
import GHC.Num
-import GHC.Read
+import Text.Read
import GHC.Show
#endif
import Hugs.IO
import Hugs.IOExts
import Hugs.IORef
-import Hugs.Prelude ( throw, Exception(NonTermination) )
-import Control.Exception ( bracket )
import System.IO.Unsafe ( unsafeInterleaveIO )
#endif
return (filepath, h)
#else
findTempName x = do
- fd <- withCString filepath $ \ f ->
+ fd <- withFilePath filepath $ \ f ->
c_open f oflags 0o600
if fd < 0
then do
-- XXX We want to tell fdToHandle what the filepath is,
-- as any exceptions etc will only be able to report the
-- fd currently
- h <- fdToHandle fd
- `ExceptionBase.catchException` \e -> do c_close fd; throw e
+ h <- fdToHandle fd `onException` c_close fd
return (filepath, h)
#endif
where
#ifndef __NHC__
-- XXX Copied from GHC.Handle
+std_flags, output_flags, rw_flags :: CInt
std_flags = o_NONBLOCK .|. o_NOCTTY
output_flags = std_flags .|. o_CREAT
-read_flags = std_flags .|. o_RDONLY
-write_flags = output_flags .|. o_WRONLY
rw_flags = output_flags .|. o_RDWR
-append_flags = write_flags .|. o_APPEND
#endif
#ifdef __NHC__
-- It follows that an attempt to write to a file (using 'writeFile', for
-- example) that was earlier opened by 'readFile' will usually result in
-- failure with 'System.IO.Error.isAlreadyInUseError'.
-
--- -----------------------------------------------------------------------------
--- Utils
-
-#ifdef __GLASGOW_HASKELL__
--- Copied here to avoid recursive dependency with Control.Exception
-bracket
- :: IO a -- ^ computation to run first (\"acquire resource\")
- -> (a -> IO b) -- ^ computation to run last (\"release resource\")
- -> (a -> IO c) -- ^ computation to run in-between
- -> IO c -- returns the value from the in-between computation
-bracket before after thing =
- block (do
- a <- before
- r <- catchException
- (unblock (thing a))
- (\e -> do { after a; throw e })
- after a
- return r
- )
-#endif