{-# LANGUAGE CPP #-}
{- |
Module      :  ./Common/IO.hs
Description :  wrapper module for changed IO handling since ghc-6.12.1
Copyright   :  (c) Christian Maeder DFKI GmbH 2010
License     :  GPLv2 or higher, see LICENSE.txt

Maintainer  :  Christian.Maeder@dfki.de
Stability   :  provisional
Portability :  portable

reading and writing files changed between ghc-6.10.4 and ghc-6.12.1 from
latin1 to utf8.

This module allows to continue reading and writing latin1 (DOL) files.
However, this module does not support to write utf8 files with ghc-6.10.4 or
earlier versions.

The encoding only effects the contents. The encoding of file names is always
utf8.
-}

module Common.IO
  ( Enc (..)
  , readEncFile
  , writeEncFile
  , setStdEnc
  , catchIOException
  ) where

import System.IO
import Control.Exception as Exception

catchIOException :: a -> IO a -> IO a
catchIOException :: a -> IO a -> IO a
catchIOException d :: a
d a :: IO a
a = (SomeException -> Maybe IOException)
-> IO a -> (IOException -> IO a) -> IO a
forall e b a.
Exception e =>
(e -> Maybe b) -> IO a -> (b -> IO a) -> IO a
catchJust (\ e :: SomeException
e ->
  SomeException -> Maybe IOException
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
e :: Maybe IOException) IO a
a ((IOException -> IO a) -> IO a)
-> (IO a -> IOException -> IO a) -> IO a -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> IOException -> IO a
forall a b. a -> b -> a
const (IO a -> IO a) -> IO a -> IO a
forall a b. (a -> b) -> a -> b
$ a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
d

data Enc = Latin1 | Utf8 deriving Int -> Enc -> ShowS
[Enc] -> ShowS
Enc -> String
(Int -> Enc -> ShowS)
-> (Enc -> String) -> ([Enc] -> ShowS) -> Show Enc
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Enc] -> ShowS
$cshowList :: [Enc] -> ShowS
show :: Enc -> String
$cshow :: Enc -> String
showsPrec :: Int -> Enc -> ShowS
$cshowsPrec :: Int -> Enc -> ShowS
Show

readEncFile :: Enc -> String -> IO String
writeEncFile :: Enc -> String -> String -> IO ()

-- | set encoding of stdin and stdout
setStdEnc :: Enc -> IO ()

#if __GLASGOW_HASKELL__ < 612
readEncFile _ = readFile
writeEncFile _ = writeFile
setStdEnc _ = return ()
#else
readEncFile :: Enc -> String -> IO String
readEncFile c :: Enc
c f :: String
f = do
  Handle
hdl <- String -> IOMode -> IO Handle
openFile String
f IOMode
ReadMode
  Handle -> TextEncoding -> IO ()
hSetEncoding Handle
hdl (TextEncoding -> IO ()) -> TextEncoding -> IO ()
forall a b. (a -> b) -> a -> b
$ case Enc
c of
    Utf8 -> TextEncoding
utf8
    Latin1 -> TextEncoding
latin1
  Handle -> IO String
hGetContents Handle
hdl

writeEncFile :: Enc -> String -> String -> IO ()
writeEncFile c :: Enc
c f :: String
f txt :: String
txt = String -> IOMode -> (Handle -> IO ()) -> IO ()
forall r. String -> IOMode -> (Handle -> IO r) -> IO r
withFile String
f IOMode
WriteMode ((Handle -> IO ()) -> IO ()) -> (Handle -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ hdl :: Handle
hdl -> do
    Handle -> TextEncoding -> IO ()
hSetEncoding Handle
hdl (TextEncoding -> IO ()) -> TextEncoding -> IO ()
forall a b. (a -> b) -> a -> b
$ case Enc
c of
      Utf8 -> TextEncoding
utf8
      Latin1 -> TextEncoding
latin1
    Handle -> String -> IO ()
hPutStr Handle
hdl String
txt

setStdEnc :: Enc -> IO ()
setStdEnc c :: Enc
c = do
  Handle -> TextEncoding -> IO ()
hSetEncoding Handle
stdin (TextEncoding -> IO ()) -> TextEncoding -> IO ()
forall a b. (a -> b) -> a -> b
$ case Enc
c of
    Utf8 -> TextEncoding
utf8
    Latin1 -> TextEncoding
latin1
  Handle -> TextEncoding -> IO ()
hSetEncoding Handle
stdout (TextEncoding -> IO ()) -> TextEncoding -> IO ()
forall a b. (a -> b) -> a -> b
$ case Enc
c of
    Utf8 -> TextEncoding
utf8
    Latin1 -> TextEncoding
latin1
#endif