    {-# LANGUAGE CPP #-}
    {-# OPTIONS_GHC -cpp #-}
    --  Compiler Toolkit: Compiler I/O
    --
    --  Author : Manuel M T Chakravarty
    --  Created: 2 November 95
    --
    --  Version $Revision: 1.1.1.1 $ from $Date: 2004/11/13 16:42:47 $
    --
    --  Copyright (c) [1995...2003] Manuel M T Chakravarty
    --
    --  This file is free software; you can redistribute it and/or modify
    --  it under the terms of the GNU General Public License as published by
    --  the Free Software Foundation; either version 2 of the License, or
    --  (at your option) any later version.
    --
    --  This file is distributed in the hope that it will be useful,
    --  but WITHOUT ANY WARRANTY; without even the implied warranty of
    --  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    --  GNU General Public License for more details.
    --
    --- DESCRIPTION ---------------------------------------------------------------
    --
    --  This module lifts the Haskell I/O facilities into `STB' and provides some
    --  useful extensions.
    --
    --- DOCU ----------------------------------------------------------------------
    --
    -- language: Haskell 98
    --
    --  * the usage of the `...CIO' functions is exactly as that of the
    --    corresponding `...' functions from the Haskell 98 prelude and library
    --
    --  * error handling can be found in the module `StateTrans' and `State'
    --
    --  * Also reexports constants, such as `stderr', and data types of `IO' to
    --    avoid explicit imports of `IO' in the rest of the compiler.
    --
    --- TODO ----------------------------------------------------------------------
    --

    module CIO (-- (verbatim) re-exports
                --
                Handle, HandlePosn, IOMode(..), BufferMode(..), SeekMode(..),
                stdin, stdout, stderr,
                isAlreadyExistsError, isDoesNotExistError, isAlreadyInUseError,
                isFullError, isEOFError, isIllegalOperation, isPermissionError,
                isUserError,
                ioeGetErrorString, ioeGetHandle, ioeGetFileName,
                --
                -- file handling
                --
                openFileCIO, hCloseCIO,
                --
                -- text I/O
                --
                putCharCIO, putStrCIO, hPutStrCIO, hPutStrLnCIO, writeFileCIO,
                readFileCIO, printCIO, getCharCIO, hFlushCIO,  hPutCharCIO,
                hGetContentsCIO, hSetBufferingCIO, hGetBufferingCIO,
                newlineCIO,
                --
                -- `Directory'
                --
                doesFileExistCIO, removeFileCIO,
                --
                -- `System'
                --
                ExitCode(..), exitWithCIO, getArgsCIO, getProgNameCIO,
                --
                -- CTK general stuff
                --
                fileFindInCIO, mktempCIO)
    where

    import System.IO
    import System.IO.Error
    import System.Cmd
    import System.Directory
    import System.Exit
    import System.Environment
    #if __GLASGOW_HASKELL__ >= 612
    import System.IO (hSetEncoding, latin1)
    #endif

    import FileOps   (fileFindIn, mktemp)
    import StateBase (PreCST, liftIO)

    -- file handling
    -- -------------

    openFileCIO     :: FilePath -> IOMode -> PreCST e s Handle
    openFileCIO :: FilePath -> IOMode -> PreCST e s Handle
    openFileCIO p :: FilePath
    p m :: IOMode
    m  = IO Handle -> PreCST e s Handle
    forall a e s. IO a -> PreCST e s a
    liftIO (IO Handle -> PreCST e s Handle) -> IO Handle -> PreCST e s Handle
    forall a b. (a -> b) -> a -> b
    $ do
      Handle
    hnd <- FilePath -> IOMode -> IO Handle
    openFile FilePath
    p IOMode
    m
    #if __GLASGOW_HASKELL__ >= 612
      Handle -> TextEncoding -> IO ()
    hSetEncoding Handle
    hnd TextEncoding
    latin1
    #endif
      Handle -> IO Handle
    forall (m :: * -> *) a. Monad m => a -> m a
    return Handle
    hnd

    hCloseCIO   :: Handle -> PreCST e s ()
    hCloseCIO :: Handle -> PreCST e s ()
    hCloseCIO h :: Handle
    h  = IO () -> PreCST e s ()
    forall a e s. IO a -> PreCST e s a
    liftIO (Handle -> IO ()
    hClose Handle
    h)

    -- text I/O
    -- --------

    putCharCIO   :: Char -> PreCST e s ()
    putCharCIO :: Char -> PreCST e s ()
    putCharCIO c :: Char
    c  = IO () -> PreCST e s ()
    forall a e s. IO a -> PreCST e s a
    liftIO (Char -> IO ()
    putChar Char
    c)

    putStrCIO   :: String -> PreCST e s ()
    putStrCIO :: FilePath -> PreCST e s ()
    putStrCIO s :: FilePath
    s  = IO () -> PreCST e s ()
    forall a e s. IO a -> PreCST e s a
    liftIO (FilePath -> IO ()
    putStr FilePath
    s)

    hPutStrCIO     :: Handle -> String -> PreCST e s ()
    hPutStrCIO :: Handle -> FilePath -> PreCST e s ()
    hPutStrCIO h :: Handle
    h s :: FilePath
    s  = IO () -> PreCST e s ()
    forall a e s. IO a -> PreCST e s a
    liftIO (Handle -> FilePath -> IO ()
    hPutStr Handle
    h FilePath
    s)

    hPutStrLnCIO     :: Handle -> String -> PreCST e s ()
    hPutStrLnCIO :: Handle -> FilePath -> PreCST e s ()
    hPutStrLnCIO h :: Handle
    h s :: FilePath
    s  = IO () -> PreCST e s ()
    forall a e s. IO a -> PreCST e s a
    liftIO (Handle -> FilePath -> IO ()
    hPutStrLn Handle
    h FilePath
    s)

    writeFileCIO                :: FilePath -> String -> PreCST e s ()
    writeFileCIO :: FilePath -> FilePath -> PreCST e s ()
    writeFileCIO fname :: FilePath
    fname contents :: FilePath
    contents  = do
      Handle
    hnd <- FilePath -> IOMode -> PreCST e s Handle
    forall e s. FilePath -> IOMode -> PreCST e s Handle
    openFileCIO FilePath
    fname IOMode
    WriteMode
      Handle -> FilePath -> PreCST e s ()
    forall e s. Handle -> FilePath -> PreCST e s ()
    hPutStrCIO Handle
    hnd FilePath
    contents
      Handle -> PreCST e s ()
    forall e s. Handle -> PreCST e s ()
    hCloseCIO Handle
    hnd

    readFileCIO       :: FilePath -> PreCST e s String
    readFileCIO :: FilePath -> PreCST e s FilePath
    readFileCIO fname :: FilePath
    fname  = do
      Handle
    hnd <- FilePath -> IOMode -> PreCST e s Handle
    forall e s. FilePath -> IOMode -> PreCST e s Handle
    openFileCIO FilePath
    fname IOMode
    ReadMode
      IO FilePath -> PreCST e s FilePath
    forall a e s. IO a -> PreCST e s a
    liftIO (Handle -> IO FilePath
    hGetContents Handle
    hnd)

    hGetContentsCIO :: Handle -> PreCST e s String
    hGetContentsCIO :: Handle -> PreCST e s FilePath
    hGetContentsCIO hnd :: Handle
    hnd = IO FilePath -> PreCST e s FilePath
    forall a e s. IO a -> PreCST e s a
    liftIO (Handle -> IO FilePath
    hGetContents Handle
    hnd)

    printCIO   :: Show a => a -> PreCST e s ()
    printCIO :: a -> PreCST e s ()
    printCIO a :: a
    a  = IO () -> PreCST e s ()
    forall a e s. IO a -> PreCST e s a
    liftIO (a -> IO ()
    forall a. Show a => a -> IO ()
    print a
    a)

    getCharCIO :: PreCST e s Char
    getCharCIO :: PreCST e s Char
    getCharCIO  = IO Char -> PreCST e s Char
    forall a e s. IO a -> PreCST e s a
    liftIO IO Char
    getChar

    hFlushCIO   :: Handle -> PreCST e s ()
    hFlushCIO :: Handle -> PreCST e s ()
    hFlushCIO h :: Handle
    h  = IO () -> PreCST e s ()
    forall a e s. IO a -> PreCST e s a
    liftIO (Handle -> IO ()
    hFlush Handle
    h)

    hPutCharCIO      :: Handle -> Char -> PreCST e s ()
    hPutCharCIO :: Handle -> Char -> PreCST e s ()
    hPutCharCIO h :: Handle
    h ch :: Char
    ch  = IO () -> PreCST e s ()
    forall a e s. IO a -> PreCST e s a
    liftIO (Handle -> Char -> IO ()
    hPutChar Handle
    h Char
    ch)

    hSetBufferingCIO     :: Handle  -> BufferMode -> PreCST e s ()
    hSetBufferingCIO :: Handle -> BufferMode -> PreCST e s ()
    hSetBufferingCIO h :: Handle
    h m :: BufferMode
    m  = IO () -> PreCST e s ()
    forall a e s. IO a -> PreCST e s a
    liftIO (Handle -> BufferMode -> IO ()
    hSetBuffering Handle
    h BufferMode
    m)

    hGetBufferingCIO   :: Handle  -> PreCST e s BufferMode
    hGetBufferingCIO :: Handle -> PreCST e s BufferMode
    hGetBufferingCIO h :: Handle
    h  = IO BufferMode -> PreCST e s BufferMode
    forall a e s. IO a -> PreCST e s a
    liftIO (Handle -> IO BufferMode
    hGetBuffering Handle
    h)

    -- derived functions
    --

    newlineCIO :: PreCST e s ()
    newlineCIO :: PreCST e s ()
    newlineCIO  = Char -> PreCST e s ()
    forall e s. Char -> PreCST e s ()
    putCharCIO '\n'

    -- `Directory'
    -- -----------

    doesFileExistCIO :: FilePath -> PreCST e s Bool
    doesFileExistCIO :: FilePath -> PreCST e s Bool
    doesFileExistCIO  = IO Bool -> PreCST e s Bool
    forall a e s. IO a -> PreCST e s a
    liftIO (IO Bool -> PreCST e s Bool)
    -> (FilePath -> IO Bool) -> FilePath -> PreCST e s Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FilePath -> IO Bool
    doesFileExist

    removeFileCIO :: FilePath -> PreCST e s ()
    removeFileCIO :: FilePath -> PreCST e s ()
    removeFileCIO  = IO () -> PreCST e s ()
    forall a e s. IO a -> PreCST e s a
    liftIO (IO () -> PreCST e s ())
    -> (FilePath -> IO ()) -> FilePath -> PreCST e s ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FilePath -> IO ()
    removeFile

    -- `System'
    -- --------

    exitWithCIO :: ExitCode -> PreCST e s a
    exitWithCIO :: ExitCode -> PreCST e s a
    exitWithCIO  = IO a -> PreCST e s a
    forall a e s. IO a -> PreCST e s a
    liftIO (IO a -> PreCST e s a)
    -> (ExitCode -> IO a) -> ExitCode -> PreCST e s a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ExitCode -> IO a
    forall a. ExitCode -> IO a
    exitWith

    getArgsCIO :: PreCST e s [String]
    getArgsCIO :: PreCST e s [FilePath]
    getArgsCIO  = IO [FilePath] -> PreCST e s [FilePath]
    forall a e s. IO a -> PreCST e s a
    liftIO IO [FilePath]
    getArgs

    getProgNameCIO :: PreCST e s String
    getProgNameCIO :: PreCST e s FilePath
    getProgNameCIO  = IO FilePath -> PreCST e s FilePath
    forall a e s. IO a -> PreCST e s a
    liftIO IO FilePath
    getProgName

    -- general IO routines defined in CTK
    -- ----------------------------------

    fileFindInCIO            :: FilePath -> [FilePath] -> PreCST e s FilePath
    fileFindInCIO :: FilePath -> [FilePath] -> PreCST e s FilePath
    fileFindInCIO file :: FilePath
    file paths :: [FilePath]
    paths  = IO FilePath -> PreCST e s FilePath
    forall a e s. IO a -> PreCST e s a
    liftIO (IO FilePath -> PreCST e s FilePath)
    -> IO FilePath -> PreCST e s FilePath
    forall a b. (a -> b) -> a -> b
    $ FilePath
    file FilePath -> [FilePath] -> IO FilePath
    `fileFindIn` [FilePath]
    paths

    mktempCIO :: FilePath -> FilePath -> PreCST e s (Handle, FilePath)
    mktempCIO :: FilePath -> FilePath -> PreCST e s (Handle, FilePath)
    mktempCIO pre :: FilePath
    pre post :: FilePath
    post = IO (Handle, FilePath) -> PreCST e s (Handle, FilePath)
    forall a e s. IO a -> PreCST e s a
    liftIO (IO (Handle, FilePath) -> PreCST e s (Handle, FilePath))
    -> IO (Handle, FilePath) -> PreCST e s (Handle, FilePath)
    forall a b. (a -> b) -> a -> b
    $ FilePath -> FilePath -> IO (Handle, FilePath)
    mktemp FilePath
    pre FilePath
    post