File: IO.hs

package info (click to toggle)
bali-phy 4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 15,392 kB
  • sloc: cpp: 120,442; xml: 13,966; haskell: 9,975; python: 2,936; yacc: 1,328; perl: 1,169; lex: 912; sh: 343; makefile: 26
file content (311 lines) | stat: -rw-r--r-- 7,656 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
{-# LANGUAGE NoImplicitPrelude #-}
module System.IO (module System.IO,
                  module Compiler.IO,
                  FilePath)
    where

import System.FilePath (FilePath)
import Compiler.Base -- for String
import Compiler.IO -- for String
import Data.Bool
import Data.Maybe
import Foreign.String
import Text.Show -- for Show
import Text.Read -- for Read
import Control.Monad -- for >>
import Data.Functor -- for fmap
import Data.Function -- for $
import Compiler.Enum

import Data.Exception

data Handle
{-
-- input, output, or both
-- open, closed, or semi-closed
-- seekable or not
-- buffering is enabled, disabled, enabled by line, enabled by block (with block size)
-- a buffer
-}


data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
-- deriving Eq, Show, Read, Ord, Enum

intFromIOMode ReadMode = 0
intFromIOMode WriteMode = 1
intFromIOMode AppendMode = 2
intFromIOMode ReadWriteMode = 3

foreign import bpcall "File:" getStdin :: () -> Handle

foreign import bpcall "File:" getStdout :: () -> Handle

foreign import bpcall "File:" getStderr :: () -> Handle

stdin :: Handle
stdin = getStdin ()

stdout :: Handle
stdout = getStdout ()

stderr :: Handle
stderr = getStderr ()

withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r
withFile path mode action = do
  handle <- openFile path mode
  action handle

foreign import bpcall "File:" openFileRaw :: CPPString -> Int -> IO Handle
openFile :: FilePath -> IOMode -> IO Handle
openFile path mode = openFileRaw (list_to_string path) (intFromIOMode mode)


foreign import bpcall "File:" hClose :: Handle -> IO ()

readFile :: FilePath -> IO String
readFile path = do handle <- openFile path ReadMode
                   text <- hGetContents handle
                   return text

-- strict
readFile' :: FilePath -> IO String
readFile' path = do handle <- openFile path ReadMode
                    text <- hGetContents' handle
                    return text

writeFile :: FilePath -> String -> IO ()
writeFile path text = do handle <- openFile path WriteMode
                         putStr text
                         hClose handle

appendFile :: FilePath -> String -> IO ()
appendFile path text = do handle <- openFile path AppendMode
                          putStr text
                          hClose handle

-- These are apparently for when we know the file that the handle is attached to.
-- But what if the file has been unliked from the filesystem?
-- Then we'd have to own the dentry or something...
foreign import bpcall "File:" hFileSize :: Handle -> IO Integer

{-
hSetFileSize :: Handle -> Integer -> IO ()
-}

foreign import bpcall "File:" hIsEOF :: Handle -> IO Bool

isEOF :: IO Bool
isEOF = hIsEOF stdin

data BufferMode = NoBuffering | LineBuffering | BlockBuffering (Maybe Int)

{-
hSetBuffering :: Handle -> BufferMode -> IO ()
-}

foreign import bpcall "File:" hFlush :: Handle -> IO ()

{-
hGetPosn :: Handle -> IO HandlePosn

hSetPosn :: HandlePsn -> IO ()
-}

data HandlePosn

data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
intFromSeekMode AbsoluteSeek = 0
intFromSeekMode RelativeSeek = 1
intFromSeekMode SeekFromEnd  = 2

foreign import bpcall "File:" hSeekRaw :: Handle -> Int -> Integer -> IO ()
hSeek :: Handle -> SeekMode -> Integer -> IO ()
hSeek h mode pos = hSeekRaw h (intFromSeekMode mode) pos

{-
C++ streams can have different read and write positions: tellg() vs tellp()
Not sure what to do here.

hTell :: Handle -> IO Integer
-}

foreign import bpcall "File:" hIsOpen :: Handle -> IO Bool

hIsClosed :: Handle -> IO Bool
hIsClosed h = fmap not $ hIsOpen h

{-
hIsReadable :: Handle -> IO Bool

hIsWriteable :: Handle -> IO Bool

hIsSeekable :: Handle -> IO Bool

-- Not portable
               
hIsTerminalDevice :: Handle -> IO Bool

hSetEcho :: Handle -> Bool -> IO ()

hGetEcho :: Handle -> IO Bool

hShow :: Handle -> IO String

hWaitForInput :: Handle -> Int -> IO Bool

hReady :: Handle -> IO Bool
-}

foreign import bpcall "File:" hGetChar :: Handle -> IO Char

foreign import bpcall "File:" hGetLineRaw :: Handle -> IO CPPString
hGetLine :: Handle -> IO String
hGetLine h = fmap unpack_cpp_string $ hGetLineRaw h

foreign import bpcall "File:" hLookAhead :: Handle -> IO Char

foreign import bpcall "File:" hGetContentsRaw :: Handle -> IO CPPString
hGetContents :: Handle -> IO String
hGetContents h = unsafeInterleaveIO $ hGetContents' h

-- strict
hGetContents' :: Handle -> IO String
hGetContents' h = fmap unpack_cpp_string $ hGetContentsRaw h

foreign import bpcall "File:" hPutChar :: Handle -> Char -> IO ()

foreign import bpcall "File:" hPutStrRaw :: Handle -> CPPString -> IO ()
hPutStr :: Handle -> String -> IO ()
hPutStr h s = hPutStrRaw h $ list_to_string s

hPutStrLn :: Handle -> String -> IO ()
hPutStrLn h s = hPutStr h s >> hPutChar h '\n'

hPrint :: Show a => Handle -> a -> IO ()
hPrint h x = hPutStr h (show x)


interact :: (String -> String) -> IO ()
interact f = do contents <- getContents
                putStr (f contents)

putChar :: Char -> IO ()
putChar c = hPutChar stdout c

putStr :: String -> IO ()
putStr s = hPutStr stdout s

putStrLn :: String -> IO ()
putStrLn s = hPutStrLn stdout s

print :: Show a => a -> IO ()
print x = putStrLn (show x)

getChar :: IO Char
getChar = hGetChar stdin

getLine :: IO String
getLine = hGetLine stdin

getContents :: IO String
getContents = hGetContents stdin

getContents' :: IO String -- strict
getContents' = hGetContents' stdin

readIO :: Read a => String -> IO a
readIO s = catch (return $ read s) (\e -> fail "readIO failed")
-- catches exceptions and calls fail in the IO monad

readLn :: Read a => IO a
readLn = getLine >>= readIO


withBinaryFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile path mode action = do
  handle <- openBinaryFile path mode
  action handle

foreign import bpcall "File:" openBinaryFileRaw :: CPPString -> Int -> IO Handle
openBinaryFile :: FilePath -> IOMode -> IO Handle
openBinaryFile path mode = openBinaryFileRaw (list_to_string path) (intFromIOMode mode)

{-
hSetBinaryMode :: Handle -> Bool -> IO ()

data Ptr a

hPutBuf :: Handle -> Ptr a -> Int -> IO ()

hGetBuf :: Handle -> Ptr a -> Int -> IO Int

hGetBufSome :: Handle -> Ptr a -> Int -> IO Int

hPutBufNonBlocking :: Handle -> Ptr a -> Int -> IO ()

hGetBufNonBlocking :: Handle -> Ptr a -> Int -> IO Int

openTempFile :: FilePath -> String -> IO (FilePath, Handle)

openBinaryTempFile :: FilePath -> String -> IO (FilePath, Handle)

openTempFileWithDefaultPermissions :: FilePath -> String -> IO (FilePath, Handle)

openBinaryTempFileWithDefaultPermissions :: FilePath -> String -> IO (FilePath, Handle)

hSetEncoding :: Handle -> TextEncoding -> IO ()

hGetEncoding :: Handle -> IO (Maybe TextEncoding)

-}

data TextEncoding

{-

latin1 :: TextEncoding

utf8 :: TextEncoding

utf8_bom :: TextEncoding

utf16 :: TextEncoding

utf16le :: TextEncoding         

utf16be :: TextEncoding         

utf32 :: TextEncoding

utf32le :: TextEncoding

utf32be :: TextEncoding

char8 :: TextEncoding

mkTextEncoding :: String -> IO TextEncoding

hSetNewlineMode :: Handle -> NewlineMode -> IO ()

-}

data Newline = LF | CRLF

{-
nativeNewline :: Newline -- LF on Unix, CRLF on Windows
-}

data NewlineMode = NewlineMode { inputNL, outputNL :: Newline }

{-
noNewlineTranslation :: NewlineMode
noNewlineTranslation = NewlineMode { inputNL = LF, outputNL = LF }
                        
universalNewlineMode :: NewlineMode
universalNewlineMode  = NewlineMode { inputNL = CRLF, outputNL = nativeNewLine }

nativeNewlineMode :: NewlineMode
nativeNewlineMode = NewlineMode { inputNL = nativeNewline, outputNL = nativeNewline }
-}