Copy tests from GHC testsuite; part of #1161.
[packages/base.git] / tests / IO / newline001.hs
1 import System.IO
2 import GHC.IO.Handle
3 import Control.Monad
4 import Data.List
5
6 newlines = ["\n","\r","\r\n","\n\r","\n\n","\r\r"]
7
8 -- make sure the file ends in '\r': that's a tricky case for CRLF
9 -- conversion, because the IO library has to check whether there's a
10 -- following \n before returning the \r.
11 content = concat [ show i ++ t | (i,t) <- zip [1..100] (cycle newlines) ]
12
13 filename = "newline001.out"
14
15 fromCRLF [] = []
16 fromCRLF ('\r':'\n':cs) = '\n' : fromCRLF cs
17 fromCRLF (c:cs) = c : fromCRLF cs
18
19 toCRLF [] = []
20 toCRLF ('\n':cs) = '\r':'\n': toCRLF cs
21 toCRLF (c:cs) = c : toCRLF cs
22
23 main = do
24 h <- openBinaryFile filename WriteMode
25 hPutStr h content
26 hClose h
27 testinput NoBuffering
28 testinput LineBuffering
29 testinput (BlockBuffering Nothing)
30 testinput (BlockBuffering (Just 3))
31 testinput (BlockBuffering (Just 7))
32 testinput (BlockBuffering (Just 16))
33 testoutput NoBuffering
34 testoutput LineBuffering
35 testoutput (BlockBuffering Nothing)
36 testoutput (BlockBuffering (Just 3))
37 testoutput (BlockBuffering (Just 7))
38 testoutput (BlockBuffering (Just 16))
39
40 testinput b = do
41 h <- openFile filename ReadMode
42 hSetBuffering h b
43 hSetNewlineMode h noNewlineTranslation
44 str <- hGetContents h
45 check "in1" b str content
46 hClose h
47
48 h <- openFile filename ReadMode
49 hSetBuffering h b
50 hSetNewlineMode h noNewlineTranslation
51 str <- read_chars h
52 check "in2" b str content
53 hClose h
54
55 h <- openFile filename ReadMode
56 hSetBuffering h b
57 hSetNewlineMode h noNewlineTranslation
58 str <- read_lines h
59 check "in3" b str content
60 hClose h
61
62 h <- openFile filename ReadMode
63 hSetBuffering h b
64 hSetNewlineMode h NewlineMode{ inputNL=CRLF, outputNL=LF }
65 str <- hGetContents h
66 check "in4" b str (fromCRLF content)
67 hClose h
68
69 h <- openFile filename ReadMode
70 hSetBuffering h b
71 hSetNewlineMode h NewlineMode{ inputNL=CRLF, outputNL=LF }
72 str <- read_chars h
73 check "in5" b str (fromCRLF content)
74 hClose h
75
76 h <- openFile filename ReadMode
77 hSetBuffering h b
78 hSetNewlineMode h NewlineMode{ inputNL=CRLF, outputNL=LF }
79 str <- read_lines h
80 check "in6" b str (fromCRLF content)
81 hClose h
82
83 testoutput b = do
84 h <- openFile filename WriteMode
85 hSetBuffering h b
86 hSetNewlineMode h NewlineMode{ inputNL=LF, outputNL=CRLF }
87 hPutStr h content
88 hClose h
89 h <- openBinaryFile filename ReadMode
90 str <- hGetContents h
91 check "out1" b (toCRLF content) str
92 hClose h
93
94 h <- openFile filename WriteMode
95 hSetBuffering h b
96 hSetNewlineMode h NewlineMode{ inputNL=LF, outputNL=CRLF }
97 mapM_ (hPutChar h) content
98 hClose h
99 h <- openBinaryFile filename ReadMode
100 str <- hGetContents h
101 check "out2" b (toCRLF content) str
102 hClose h
103
104 check s b str1 str2 = do
105 when (str1 /= str2) $ error ("failed: " ++ s ++ ", " ++ show b ++ '\n':show str1 ++ '\n':show str2)
106
107 read_chars :: Handle -> IO String
108 read_chars h = loop h ""
109 where loop h acc = do
110 b <- hIsEOF h
111 if b then return (reverse acc) else do
112 c <- hGetChar h
113 loop h (c:acc)
114
115 read_lines :: Handle -> IO String
116 read_lines h = loop h []
117 where loop h acc = do
118 b <- hIsEOF h
119 if b then return (intercalate "\n" (reverse acc)) else do
120 l <- hGetLine h
121 loop h (l : acc)