Sat Jul 25 22:19:26 BST 2009 Ian Lynagh <igloo@earth.li>
* Make the code compatible with the stricter labelled-field parsing rules
diff -rN -u old-base/Data/HashTable.hs new-base/Data/HashTable.hs
|
old
|
new
|
|
| 137 | 137 | |
| 138 | 138 | recordNew :: IO () |
| 139 | 139 | recordNew = instrument rec |
| 140 | | where rec hd@HD{ tables=t, totBuckets=b } = |
| 141 | | hd{ tables=t+1, totBuckets=b+fromIntegral tABLE_MIN } |
| | 140 | where rec hd@(HD{ tables=t, totBuckets=b }) = |
| | 141 | hd{ tables=t+1, totBuckets=b+fromIntegral tABLE_MIN } |
| 142 | 142 | |
| 143 | 143 | recordIns :: Int32 -> Int32 -> [a] -> IO () |
| 144 | 144 | recordIns i sz bkt = instrument rec |
| 145 | | where rec hd@HD{ insertions=ins, maxEntries=mx, maxChain=mc } = |
| 146 | | hd{ insertions=ins+fromIntegral i, maxEntries=mx `max` sz, |
| 147 | | maxChain=mc `max` length bkt } |
| | 145 | where rec hd@(HD{ insertions=ins, maxEntries=mx, maxChain=mc }) = |
| | 146 | hd{ insertions=ins+fromIntegral i, maxEntries=mx `max` sz, |
| | 147 | maxChain=mc `max` length bkt } |
| 148 | 148 | |
| 149 | 149 | recordResize :: Int32 -> Int32 -> IO () |
| 150 | 150 | recordResize older newer = instrument rec |
| 151 | | where rec hd@HD{ totBuckets=b, maxBuckets=mx } = |
| 152 | | hd{ totBuckets=b+fromIntegral (newer-older), |
| 153 | | maxBuckets=mx `max` newer } |
| | 151 | where rec hd@(HD{ totBuckets=b, maxBuckets=mx }) = |
| | 152 | hd{ totBuckets=b+fromIntegral (newer-older), |
| | 153 | maxBuckets=mx `max` newer } |
| 154 | 154 | |
| 155 | 155 | recordLookup :: IO () |
| 156 | 156 | recordLookup = instrument lkup |
| 157 | | where lkup hd@HD{ lookups=l } = hd{ lookups=l+1 } |
| | 157 | where lkup hd@(HD{ lookups=l }) = hd{ lookups=l+1 } |
| 158 | 158 | |
| 159 | 159 | -- stats :: IO String |
| 160 | 160 | -- stats = fmap show $ readIORef hashData |
| … |
… |
|
| 323 | 323 | -- from scratch. |
| 324 | 324 | {-# INLINE findBucket #-} |
| 325 | 325 | findBucket :: HashTable key val -> key -> IO (HT key val, Int32, [(key,val)]) |
| 326 | | findBucket HashTable{ tab=ref, hash_fn=hash} key = do |
| 327 | | table@HT{ buckets=bkts, bmask=b } <- readIORef ref |
| | 326 | findBucket (HashTable{ tab=ref, hash_fn=hash}) key = do |
| | 327 | table@(HT{ buckets=bkts, bmask=b }) <- readIORef ref |
| 328 | 328 | let indx = bucketIndex b (hash key) |
| 329 | 329 | bucket <- readHTArray bkts indx |
| 330 | 330 | return (table, indx, bucket) |
| … |
… |
|
| 351 | 351 | HashTable key val -> key -> |
| 352 | 352 | IO a |
| 353 | 353 | updatingBucket canEnlarge bucketFn |
| 354 | | ht@HashTable{ tab=ref, hash_fn=hash } key = do |
| 355 | | (table@HT{ kcount=k, buckets=bkts, bmask=b }, |
| | 354 | ht@(HashTable{ tab=ref, hash_fn=hash }) key = do |
| | 355 | (table@(HT{ kcount=k, buckets=bkts, bmask=b }), |
| 356 | 356 | indx, bckt) <- findBucket ht key |
| 357 | 357 | (bckt', inserts, result) <- return $ bucketFn bckt |
| 358 | 358 | let k' = k + inserts |
| … |
… |
|
| 368 | 368 | return result |
| 369 | 369 | |
| 370 | 370 | expandHashTable :: (key -> Int32) -> HT key val -> IO (HT key val) |
| 371 | | expandHashTable hash table@HT{ buckets=bkts, bmask=mask } = do |
| | 371 | expandHashTable hash table@(HT{ buckets=bkts, bmask=mask }) = do |
| 372 | 372 | let |
| 373 | 373 | oldsize = mask + 1 |
| 374 | 374 | newmask = mask + mask + 1 |
| … |
… |
|
| 406 | 406 | -- | Remove an entry from the hash table. |
| 407 | 407 | delete :: HashTable key val -> key -> IO () |
| 408 | 408 | |
| 409 | | delete ht@HashTable{ cmp=eq } key = |
| | 409 | delete ht@(HashTable{ cmp=eq }) key = |
| 410 | 410 | updatingBucket Can'tInsert (deleteBucket (eq key)) ht key |
| 411 | 411 | |
| 412 | 412 | -- ----------------------------------------------------------------------------- |
| … |
… |
|
| 422 | 422 | -- by 'insert'. |
| 423 | 423 | update :: HashTable key val -> key -> val -> IO Bool |
| 424 | 424 | |
| 425 | | update ht@HashTable{ cmp=eq } key val = |
| | 425 | update ht@(HashTable{ cmp=eq }) key val = |
| 426 | 426 | updatingBucket CanInsert |
| 427 | 427 | (\bucket -> let (bucket', dels, _) = deleteBucket (eq key) bucket |
| 428 | 428 | in ((key,val):bucket', 1+dels, dels/=0)) |
| … |
… |
|
| 434 | 434 | -- | Looks up the value of a key in the hash table. |
| 435 | 435 | lookup :: HashTable key val -> key -> IO (Maybe val) |
| 436 | 436 | |
| 437 | | lookup ht@HashTable{ cmp=eq } key = do |
| | 437 | lookup ht@(HashTable{ cmp=eq }) key = do |
| 438 | 438 | recordLookup |
| 439 | 439 | (_, _, bucket) <- findBucket ht key |
| 440 | 440 | let firstHit (k,v) r | eq key k = Just v |
| … |
… |
|
| 460 | 460 | |
| 461 | 461 | {-# INLINE mapReduce #-} |
| 462 | 462 | mapReduce :: ([(key,val)] -> r) -> ([r] -> r) -> HashTable key val -> IO r |
| 463 | | mapReduce m r HashTable{ tab=ref } = do |
| 464 | | HT{ buckets=bckts, bmask=b } <- readIORef ref |
| | 463 | mapReduce m r (HashTable{ tab=ref }) = do |
| | 464 | (HT{ buckets=bckts, bmask=b }) <- readIORef ref |
| 465 | 465 | fmap r (mapM (fmap m . readHTArray bckts) [0..b]) |
| 466 | 466 | |
| 467 | 467 | -- ----------------------------------------------------------------------------- |
diff -rN -u old-base/Data/Version.hs new-base/Data/Version.hs
|
old
|
new
|
|
| 141 | 141 | #endif |
| 142 | 142 | parseVersion = do branch <- sepBy1 (liftM read $ munch1 isDigit) (char '.') |
| 143 | 143 | tags <- many (char '-' >> munch1 isAlphaNum) |
| 144 | | return Version{versionBranch=branch, versionTags=tags} |
| | 144 | return $ Version{versionBranch=branch, versionTags=tags} |
diff -rN -u old-base/GHC/IO/Buffer.hs new-base/GHC/IO/Buffer.hs
|
old
|
new
|
|
| 191 | 191 | data BufferState = ReadBuffer | WriteBuffer deriving (Eq) |
| 192 | 192 | |
| 193 | 193 | withBuffer :: Buffer e -> (Ptr e -> IO a) -> IO a |
| 194 | | withBuffer Buffer{ bufRaw=raw } f = withForeignPtr (castForeignPtr raw) f |
| | 194 | withBuffer (Buffer{ bufRaw=raw }) f = withForeignPtr (castForeignPtr raw) f |
| 195 | 195 | |
| 196 | 196 | withRawBuffer :: RawBuffer e -> (Ptr e -> IO a) -> IO a |
| 197 | 197 | withRawBuffer raw f = withForeignPtr (castForeignPtr raw) f |
| 198 | 198 | |
| 199 | 199 | isEmptyBuffer :: Buffer e -> Bool |
| 200 | | isEmptyBuffer Buffer{ bufR=w } = w == 0 |
| | 200 | isEmptyBuffer (Buffer{ bufR=w }) = w == 0 |
| 201 | 201 | |
| 202 | 202 | isFullBuffer :: Buffer e -> Bool |
| 203 | | isFullBuffer Buffer{ bufR=w, bufSize=s } = s == w |
| | 203 | isFullBuffer (Buffer{ bufR=w, bufSize=s }) = s == w |
| 204 | 204 | |
| 205 | 205 | -- if a Char buffer does not have room for a surrogate pair, it is "full" |
| 206 | 206 | isFullCharBuffer :: Buffer e -> Bool |
| … |
… |
|
| 216 | 216 | ReadBuffer -> False |
| 217 | 217 | |
| 218 | 218 | bufferElems :: Buffer e -> Int |
| 219 | | bufferElems Buffer{ bufR=w, bufL=r } = w - r |
| | 219 | bufferElems (Buffer{ bufR=w, bufL=r }) = w - r |
| 220 | 220 | |
| 221 | 221 | bufferAvailable :: Buffer e -> Int |
| 222 | | bufferAvailable Buffer{ bufR=w, bufSize=s } = s - w |
| | 222 | bufferAvailable (Buffer{ bufR=w, bufSize=s }) = s - w |
| 223 | 223 | |
| 224 | 224 | bufferRemove :: Int -> Buffer e -> Buffer e |
| 225 | | bufferRemove i buf@Buffer{ bufL=r } = bufferAdjustL (r+i) buf |
| | 225 | bufferRemove i buf@(Buffer{ bufL=r }) = bufferAdjustL (r+i) buf |
| 226 | 226 | |
| 227 | 227 | bufferAdjustL :: Int -> Buffer e -> Buffer e |
| 228 | | bufferAdjustL l buf@Buffer{ bufR=w } |
| | 228 | bufferAdjustL l buf@(Buffer{ bufR=w }) |
| 229 | 229 | | l == w = buf{ bufL=0, bufR=0 } |
| 230 | 230 | | otherwise = buf{ bufL=l, bufR=w } |
| 231 | 231 | |
| 232 | 232 | bufferAdd :: Int -> Buffer e -> Buffer e |
| 233 | | bufferAdd i buf@Buffer{ bufR=w } = buf{ bufR=w+i } |
| | 233 | bufferAdd i buf@(Buffer{ bufR=w }) = buf{ bufR=w+i } |
| 234 | 234 | |
| 235 | 235 | emptyBuffer :: RawBuffer e -> Int -> BufferState -> Buffer e |
| 236 | 236 | emptyBuffer raw sz state = |
| … |
… |
|
| 249 | 249 | |
| 250 | 250 | -- | slides the contents of the buffer to the beginning |
| 251 | 251 | slideContents :: Buffer Word8 -> IO (Buffer Word8) |
| 252 | | slideContents buf@Buffer{ bufL=l, bufR=r, bufRaw=raw } = do |
| | 252 | slideContents buf@(Buffer{ bufL=l, bufR=r, bufRaw=raw }) = do |
| 253 | 253 | let elems = r - l |
| 254 | 254 | withRawBuffer raw $ \p -> |
| 255 | 255 | do _ <- memcpy p (p `plusPtr` l) (fromIntegral elems) |
| 256 | 256 | return () |
| 257 | | return buf{ bufL=0, bufR=elems } |
| | 257 | return $ buf{ bufL=0, bufR=elems } |
| 258 | 258 | |
| 259 | 259 | foreign import ccall unsafe "memcpy" |
| 260 | 260 | memcpy :: Ptr a -> Ptr a -> CSize -> IO (Ptr ()) |
| … |
… |
|
| 273 | 273 | -- operation, a read buffer always has at least one character of space. |
| 274 | 274 | |
| 275 | 275 | checkBuffer :: Buffer a -> IO () |
| 276 | | checkBuffer buf@Buffer{ bufState = state, bufL=r, bufR=w, bufSize=size } = do |
| | 276 | checkBuffer buf@(Buffer{ bufState = state, bufL=r, bufR=w, bufSize=size }) = do |
| 277 | 277 | check buf ( |
| 278 | 278 | size > 0 |
| 279 | 279 | && r <= w |
diff -rN -u old-base/GHC/IO/Encoding/Iconv.hs new-base/GHC/IO/Encoding/Iconv.hs
|
old
|
new
|
|
| 152 | 152 | withCString to $ \ to_str -> do |
| 153 | 153 | iconvt <- throwErrnoIfMinus1 "mkTextEncoding" $ hs_iconv_open to_str from_str |
| 154 | 154 | let iclose = throwErrnoIfMinus1_ "Iconv.close" $ hs_iconv_close iconvt |
| 155 | | return BufferCodec{ |
| | 155 | return $ BufferCodec{ |
| 156 | 156 | encode = fn iconvt, |
| 157 | 157 | close = iclose, |
| 158 | 158 | -- iconv doesn't supply a way to save/restore the state |
| … |
… |
|
| 171 | 171 | iconvRecode :: IConv -> Buffer a -> Int -> Buffer b -> Int |
| 172 | 172 | -> IO (Buffer a, Buffer b) |
| 173 | 173 | iconvRecode iconv_t |
| 174 | | input@Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } iscale |
| 175 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } oscale |
| | 174 | input@(Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ }) iscale |
| | 175 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os }) oscale |
| 176 | 176 | = do |
| 177 | 177 | iconv_trace ("iconvRecode before, input=" ++ show (summaryBuffer input)) |
| 178 | 178 | iconv_trace ("iconvRecode before, output=" ++ show (summaryBuffer output)) |
diff -rN -u old-base/GHC/IO/Encoding/Latin1.hs new-base/GHC/IO/Encoding/Latin1.hs
|
old
|
new
|
|
| 76 | 76 | |
| 77 | 77 | latin1_decode :: DecodeBuffer |
| 78 | 78 | latin1_decode |
| 79 | | input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } |
| 80 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } |
| | 79 | input@(Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }) |
| | 80 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }) |
| 81 | 81 | = let |
| 82 | 82 | loop !ir !ow |
| 83 | 83 | | ow >= os || ir >= iw = done ir ow |
| … |
… |
|
| 95 | 95 | |
| 96 | 96 | latin1_encode :: EncodeBuffer |
| 97 | 97 | latin1_encode |
| 98 | | input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } |
| 99 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } |
| | 98 | input@(Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }) |
| | 99 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }) |
| 100 | 100 | = let |
| 101 | 101 | done !ir !ow = return (if ir == iw then input{ bufL=0, bufR=0 } |
| 102 | 102 | else input{ bufL=ir }, |
| … |
… |
|
| 112 | 112 | |
| 113 | 113 | latin1_checked_encode :: EncodeBuffer |
| 114 | 114 | latin1_checked_encode |
| 115 | | input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } |
| 116 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } |
| | 115 | input@(Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }) |
| | 116 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }) |
| 117 | 117 | = let |
| 118 | 118 | done !ir !ow = return (if ir == iw then input{ bufL=0, bufR=0 } |
| 119 | 119 | else input{ bufL=ir }, |
diff -rN -u old-base/GHC/IO/Encoding/UTF16.hs new-base/GHC/IO/Encoding/UTF16.hs
|
old
|
new
|
|
| 84 | 84 | |
| 85 | 85 | utf16_encode :: IORef Bool -> EncodeBuffer |
| 86 | 86 | utf16_encode done_bom input |
| 87 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } |
| | 87 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os }) |
| 88 | 88 | = do |
| 89 | 89 | b <- readIORef done_bom |
| 90 | 90 | if b then utf16_native_encode input output |
| … |
… |
|
| 94 | 94 | writeIORef done_bom True |
| 95 | 95 | writeWord8Buf oraw ow bom1 |
| 96 | 96 | writeWord8Buf oraw (ow+1) bom2 |
| 97 | | utf16_native_encode input output{ bufR = ow+2 } |
| | 97 | utf16_native_encode input (output{ bufR = ow+2 }) |
| 98 | 98 | |
| 99 | 99 | utf16_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer |
| 100 | 100 | utf16_decode seen_bom |
| 101 | | input@Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } |
| | 101 | input@(Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ }) |
| 102 | 102 | output |
| 103 | 103 | = do |
| 104 | 104 | mb <- readIORef seen_bom |
| … |
… |
|
| 111 | 111 | case () of |
| 112 | 112 | _ | c0 == bomB && c1 == bomL -> do |
| 113 | 113 | writeIORef seen_bom (Just utf16be_decode) |
| 114 | | utf16be_decode input{ bufL= ir+2 } output |
| | 114 | utf16be_decode (input{ bufL= ir+2 }) output |
| 115 | 115 | | c0 == bomL && c1 == bomB -> do |
| 116 | 116 | writeIORef seen_bom (Just utf16le_decode) |
| 117 | | utf16le_decode input{ bufL= ir+2 } output |
| | 117 | utf16le_decode (input{ bufL= ir+2 }) output |
| 118 | 118 | | otherwise -> do |
| 119 | 119 | writeIORef seen_bom (Just utf16_native_decode) |
| 120 | 120 | utf16_native_decode input output |
| … |
… |
|
| 184 | 184 | |
| 185 | 185 | utf16be_decode :: DecodeBuffer |
| 186 | 186 | utf16be_decode |
| 187 | | input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } |
| 188 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } |
| | 187 | input@(Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }) |
| | 188 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }) |
| 189 | 189 | = let |
| 190 | 190 | loop !ir !ow |
| 191 | 191 | | ow >= os || ir >= iw = done ir ow |
| … |
… |
|
| 216 | 216 | |
| 217 | 217 | utf16le_decode :: DecodeBuffer |
| 218 | 218 | utf16le_decode |
| 219 | | input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } |
| 220 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } |
| | 219 | input@(Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }) |
| | 220 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }) |
| 221 | 221 | = let |
| 222 | 222 | loop !ir !ow |
| 223 | 223 | | ow >= os || ir >= iw = done ir ow |
| … |
… |
|
| 253 | 253 | |
| 254 | 254 | utf16be_encode :: EncodeBuffer |
| 255 | 255 | utf16be_encode |
| 256 | | input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } |
| 257 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } |
| | 256 | input@(Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }) |
| | 257 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }) |
| 258 | 258 | = let |
| 259 | 259 | done !ir !ow = return (if ir == iw then input{ bufL=0, bufR=0 } |
| 260 | 260 | else input{ bufL=ir }, |
| … |
… |
|
| 289 | 289 | |
| 290 | 290 | utf16le_encode :: EncodeBuffer |
| 291 | 291 | utf16le_encode |
| 292 | | input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } |
| 293 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } |
| | 292 | input@(Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }) |
| | 293 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }) |
| 294 | 294 | = let |
| 295 | 295 | done !ir !ow = return (if ir == iw then input{ bufL=0, bufR=0 } |
| 296 | 296 | else input{ bufL=ir }, |
diff -rN -u old-base/GHC/IO/Encoding/UTF32.hs new-base/GHC/IO/Encoding/UTF32.hs
|
old
|
new
|
|
| 73 | 73 | |
| 74 | 74 | utf32_encode :: IORef Bool -> EncodeBuffer |
| 75 | 75 | utf32_encode done_bom input |
| 76 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } |
| | 76 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os }) |
| 77 | 77 | = do |
| 78 | 78 | b <- readIORef done_bom |
| 79 | 79 | if b then utf32_native_encode input output |
| … |
… |
|
| 85 | 85 | writeWord8Buf oraw (ow+1) bom1 |
| 86 | 86 | writeWord8Buf oraw (ow+2) bom2 |
| 87 | 87 | writeWord8Buf oraw (ow+3) bom3 |
| 88 | | utf32_native_encode input output{ bufR = ow+4 } |
| | 88 | utf32_native_encode input (output{ bufR = ow+4 }) |
| 89 | 89 | |
| 90 | 90 | utf32_decode :: IORef (Maybe DecodeBuffer) -> DecodeBuffer |
| 91 | 91 | utf32_decode seen_bom |
| 92 | | input@Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } |
| | 92 | input@(Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ }) |
| 93 | 93 | output |
| 94 | 94 | = do |
| 95 | 95 | mb <- readIORef seen_bom |
| … |
… |
|
| 104 | 104 | case () of |
| 105 | 105 | _ | c0 == bom0 && c1 == bom1 && c2 == bom2 && c3 == bom3 -> do |
| 106 | 106 | writeIORef seen_bom (Just utf32be_decode) |
| 107 | | utf32be_decode input{ bufL= ir+4 } output |
| | 107 | utf32be_decode (input{ bufL= ir+4 }) output |
| 108 | 108 | _ | c0 == bom3 && c1 == bom2 && c2 == bom1 && c3 == bom0 -> do |
| 109 | 109 | writeIORef seen_bom (Just utf32le_decode) |
| 110 | | utf32le_decode input{ bufL= ir+4 } output |
| | 110 | utf32le_decode (input{ bufL= ir+4 }) output |
| 111 | 111 | | otherwise -> do |
| 112 | 112 | writeIORef seen_bom (Just utf32_native_decode) |
| 113 | 113 | utf32_native_decode input output |
| … |
… |
|
| 177 | 177 | |
| 178 | 178 | utf32be_decode :: DecodeBuffer |
| 179 | 179 | utf32be_decode |
| 180 | | input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } |
| 181 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } |
| | 180 | input@(Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }) |
| | 181 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }) |
| 182 | 182 | = let |
| 183 | 183 | loop !ir !ow |
| 184 | 184 | | ow >= os || iw - ir < 4 = done ir ow |
| … |
… |
|
| 203 | 203 | |
| 204 | 204 | utf32le_decode :: DecodeBuffer |
| 205 | 205 | utf32le_decode |
| 206 | | input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } |
| 207 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } |
| | 206 | input@(Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }) |
| | 207 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }) |
| 208 | 208 | = let |
| 209 | 209 | loop !ir !ow |
| 210 | 210 | | ow >= os || iw - ir < 4 = done ir ow |
| … |
… |
|
| 234 | 234 | |
| 235 | 235 | utf32be_encode :: EncodeBuffer |
| 236 | 236 | utf32be_encode |
| 237 | | input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } |
| 238 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } |
| | 237 | input@(Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }) |
| | 238 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }) |
| 239 | 239 | = let |
| 240 | 240 | done !ir !ow = return (if ir == iw then input{ bufL=0, bufR=0 } |
| 241 | 241 | else input{ bufL=ir }, |
| … |
… |
|
| 256 | 256 | |
| 257 | 257 | utf32le_encode :: EncodeBuffer |
| 258 | 258 | utf32le_encode |
| 259 | | input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } |
| 260 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } |
| | 259 | input@(Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }) |
| | 260 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }) |
| 261 | 261 | = let |
| 262 | 262 | done !ir !ow = return (if ir == iw then input{ bufL=0, bufR=0 } |
| 263 | 263 | else input{ bufL=ir }, |
diff -rN -u old-base/GHC/IO/Encoding/UTF8.hs new-base/GHC/IO/Encoding/UTF8.hs
|
old
|
new
|
|
| 83 | 83 | |
| 84 | 84 | utf8_bom_decode :: IORef Bool -> DecodeBuffer |
| 85 | 85 | utf8_bom_decode ref |
| 86 | | input@Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } |
| | 86 | input@(Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ }) |
| 87 | 87 | output |
| 88 | 88 | = do |
| 89 | 89 | first <- readIORef ref |
| … |
… |
|
| 102 | 102 | if (c2 /= bom2) then no_bom else do |
| 103 | 103 | -- found a BOM, ignore it and carry on |
| 104 | 104 | writeIORef ref False |
| 105 | | utf8_decode input{ bufL = ir + 3 } output |
| | 105 | utf8_decode (input{ bufL = ir + 3 }) output |
| 106 | 106 | |
| 107 | 107 | utf8_bom_encode :: IORef Bool -> EncodeBuffer |
| 108 | 108 | utf8_bom_encode ref input |
| 109 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } |
| | 109 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os }) |
| 110 | 110 | = do |
| 111 | 111 | b <- readIORef ref |
| 112 | 112 | if not b then utf8_encode input output |
| … |
… |
|
| 117 | 117 | writeWord8Buf oraw ow bom0 |
| 118 | 118 | writeWord8Buf oraw (ow+1) bom1 |
| 119 | 119 | writeWord8Buf oraw (ow+2) bom2 |
| 120 | | utf8_encode input output{ bufR = ow+3 } |
| | 120 | utf8_encode input (output{ bufR = ow+3 }) |
| 121 | 121 | |
| 122 | 122 | bom0, bom1, bom2 :: Word8 |
| 123 | 123 | bom0 = 0xef |
| … |
… |
|
| 126 | 126 | |
| 127 | 127 | utf8_decode :: DecodeBuffer |
| 128 | 128 | utf8_decode |
| 129 | | input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } |
| 130 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } |
| | 129 | input@(Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }) |
| | 130 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }) |
| 131 | 131 | = let |
| 132 | 132 | loop !ir !ow |
| 133 | 133 | | ow >= os || ir >= iw = done ir ow |
| … |
… |
|
| 177 | 177 | |
| 178 | 178 | utf8_encode :: EncodeBuffer |
| 179 | 179 | utf8_encode |
| 180 | | input@Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ } |
| 181 | | output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os } |
| | 180 | input@(Buffer{ bufRaw=iraw, bufL=ir0, bufR=iw, bufSize=_ }) |
| | 181 | output@(Buffer{ bufRaw=oraw, bufL=_, bufR=ow0, bufSize=os }) |
| 182 | 182 | = let |
| 183 | 183 | done !ir !ow = return (if ir == iw then input{ bufL=0, bufR=0 } |
| 184 | 184 | else input{ bufL=ir }, |
diff -rN -u old-base/GHC/IO/FD.hs new-base/GHC/IO/FD.hs
|
old
|
new
|
|
| 341 | 341 | dup :: FD -> IO FD |
| 342 | 342 | dup fd = do |
| 343 | 343 | newfd <- throwErrnoIfMinus1 "GHC.IO.FD.dup" $ c_dup (fdFD fd) |
| 344 | | return fd{ fdFD = newfd } |
| | 344 | return $ fd{ fdFD = newfd } |
| 345 | 345 | |
| 346 | 346 | dup2 :: FD -> FD -> IO FD |
| 347 | 347 | dup2 fd fdto = do |
| 348 | 348 | -- Windows' dup2 does not return the new descriptor, unlike Unix |
| 349 | 349 | throwErrnoIfMinus1_ "GHC.IO.FD.dup2" $ |
| 350 | 350 | c_dup2 (fdFD fd) (fdFD fdto) |
| 351 | | return fd{ fdFD = fdFD fdto } -- original FD, with the new fdFD |
| | 351 | return $ fd{ fdFD = fdFD fdto } -- original FD, with the new fdFD |
| 352 | 352 | |
| 353 | 353 | setNonBlockingMode :: FD -> Bool -> IO FD |
| 354 | 354 | setNonBlockingMode fd set = do |
| … |
… |
|
| 356 | 356 | #if defined(mingw32_HOST_OS) |
| 357 | 357 | return fd |
| 358 | 358 | #else |
| 359 | | return fd{ fdIsNonBlocking = fromEnum set } |
| | 359 | return $ fd{ fdIsNonBlocking = fromEnum set } |
| 360 | 360 | #endif |
| 361 | 361 | |
| 362 | 362 | ready :: FD -> Bool -> Int -> IO Bool |
diff -rN -u old-base/GHC/IO/Handle/Internals.hs new-base/GHC/IO/Handle/Internals.hs
|
old
|
new
|
|
| 168 | 168 | return () |
| 169 | 169 | |
| 170 | 170 | augmentIOError :: IOException -> String -> Handle -> IOException |
| 171 | | augmentIOError ioe@IOError{ ioe_filename = fp } fun h |
| | 171 | augmentIOError ioe@(IOError{ ioe_filename = fp }) fun h |
| 172 | 172 | = ioe { ioe_handle = Just h, ioe_location = fun, ioe_filename = filepath } |
| 173 | 173 | where filepath |
| 174 | 174 | | Just _ <- fp = fp |
| … |
… |
|
| 192 | 192 | = withHandle_' fun h m (checkWritableHandle act) |
| 193 | 193 | |
| 194 | 194 | checkWritableHandle :: (Handle__ -> IO a) -> Handle__ -> IO a |
| 195 | | checkWritableHandle act h_@Handle__{..} |
| | 195 | checkWritableHandle act h_@(Handle__{..}) |
| 196 | 196 | = case haType of |
| 197 | 197 | ClosedHandle -> ioe_closedHandle |
| 198 | 198 | SemiClosedHandle -> ioe_closedHandle |
| … |
… |
|
| 203 | 203 | flushCharReadBuffer h_ |
| 204 | 204 | flushByteReadBuffer h_ |
| 205 | 205 | buf <- readIORef haCharBuffer |
| 206 | | writeIORef haCharBuffer buf{ bufState = WriteBuffer } |
| | 206 | writeIORef haCharBuffer (buf{ bufState = WriteBuffer }) |
| 207 | 207 | buf <- readIORef haByteBuffer |
| 208 | | writeIORef haByteBuffer buf{ bufState = WriteBuffer } |
| | 208 | writeIORef haByteBuffer (buf{ bufState = WriteBuffer }) |
| 209 | 209 | act h_ |
| 210 | 210 | _other -> act h_ |
| 211 | 211 | |
| … |
… |
|
| 228 | 228 | = withHandle_' fun h m (checkReadableHandle act) |
| 229 | 229 | |
| 230 | 230 | checkReadableHandle :: (Handle__ -> IO a) -> Handle__ -> IO a |
| 231 | | checkReadableHandle act h_@Handle__{..} = |
| | 231 | checkReadableHandle act h_@(Handle__{..}) = |
| 232 | 232 | case haType of |
| 233 | 233 | ClosedHandle -> ioe_closedHandle |
| 234 | 234 | SemiClosedHandle -> ioe_closedHandle |
| … |
… |
|
| 240 | 240 | cbuf <- readIORef haCharBuffer |
| 241 | 241 | when (isWriteBuffer cbuf) $ do |
| 242 | 242 | cbuf' <- flushWriteBuffer_ h_ cbuf |
| 243 | | writeIORef haCharBuffer cbuf'{ bufState = ReadBuffer } |
| | 243 | writeIORef haCharBuffer (cbuf'{ bufState = ReadBuffer }) |
| 244 | 244 | bbuf <- readIORef haByteBuffer |
| 245 | | writeIORef haByteBuffer bbuf{ bufState = ReadBuffer } |
| | 245 | writeIORef haByteBuffer (bbuf{ bufState = ReadBuffer }) |
| 246 | 246 | act h_ |
| 247 | 247 | _other -> act h_ |
| 248 | 248 | |
| … |
… |
|
| 257 | 257 | withHandle_' fun h m (checkSeekableHandle act) |
| 258 | 258 | |
| 259 | 259 | checkSeekableHandle :: (Handle__ -> IO a) -> Handle__ -> IO a |
| 260 | | checkSeekableHandle act handle_@Handle__{haDevice=dev} = |
| | 260 | checkSeekableHandle act handle_@(Handle__{haDevice=dev}) = |
| 261 | 261 | case haType handle_ of |
| 262 | 262 | ClosedHandle -> ioe_closedHandle |
| 263 | 263 | SemiClosedHandle -> ioe_closedHandle |
| … |
… |
|
| 374 | 374 | -- file pointer backwards in the case of a read buffer. This can fail |
| 375 | 375 | -- on a non-seekable read Handle. |
| 376 | 376 | flushBuffer :: Handle__ -> IO () |
| 377 | | flushBuffer h_@Handle__{..} = do |
| | 377 | flushBuffer h_@(Handle__{..}) = do |
| 378 | 378 | buf <- readIORef haCharBuffer |
| 379 | 379 | case bufState buf of |
| 380 | 380 | ReadBuffer -> do |
| … |
… |
|
| 387 | 387 | -- | flushes at least the Char buffer, and the byte buffer for a write |
| 388 | 388 | -- Handle. Works on all Handles. |
| 389 | 389 | flushCharBuffer :: Handle__ -> IO () |
| 390 | | flushCharBuffer h_@Handle__{..} = do |
| | 390 | flushCharBuffer h_@(Handle__{..}) = do |
| 391 | 391 | buf <- readIORef haCharBuffer |
| 392 | 392 | case bufState buf of |
| 393 | 393 | ReadBuffer -> do |
| … |
… |
|
| 403 | 403 | -- data. Flushes both the Char and the byte buffer, leaving both |
| 404 | 404 | -- empty. |
| 405 | 405 | flushWriteBuffer :: Handle__ -> IO () |
| 406 | | flushWriteBuffer h_@Handle__{..} = do |
| | 406 | flushWriteBuffer h_@(Handle__{..}) = do |
| 407 | 407 | buf <- readIORef haCharBuffer |
| 408 | 408 | if isWriteBuffer buf |
| 409 | 409 | then do buf' <- flushWriteBuffer_ h_ buf |
| … |
… |
|
| 411 | 411 | else return () |
| 412 | 412 | |
| 413 | 413 | flushWriteBuffer_ :: Handle__ -> CharBuffer -> IO CharBuffer |
| 414 | | flushWriteBuffer_ h_@Handle__{..} cbuf = do |
| | 414 | flushWriteBuffer_ h_@(Handle__{..}) cbuf = do |
| 415 | 415 | bbuf <- readIORef haByteBuffer |
| 416 | 416 | if not (isEmptyBuffer cbuf) || not (isEmptyBuffer bbuf) |
| 417 | 417 | then do writeTextDevice h_ cbuf |
| 418 | | return cbuf{ bufL=0, bufR=0 } |
| | 418 | return $ cbuf{ bufL=0, bufR=0 } |
| 419 | 419 | else return cbuf |
| 420 | 420 | |
| 421 | 421 | -- ----------------------------------------------------------------------------- |
| … |
… |
|
| 423 | 423 | |
| 424 | 424 | -- It is always possible to flush the Char buffer back to the byte buffer. |
| 425 | 425 | flushCharReadBuffer :: Handle__ -> IO () |
| 426 | | flushCharReadBuffer Handle__{..} = do |
| | 426 | flushCharReadBuffer (Handle__{..}) = do |
| 427 | 427 | cbuf <- readIORef haCharBuffer |
| 428 | 428 | if isWriteBuffer cbuf || isEmptyBuffer cbuf then return () else do |
| 429 | 429 | |
| … |
… |
|
| 433 | 433 | (codec_state, bbuf0) <- readIORef haLastDecode |
| 434 | 434 | |
| 435 | 435 | cbuf0 <- readIORef haCharBuffer |
| 436 | | writeIORef haCharBuffer cbuf0{ bufL=0, bufR=0 } |
| | 436 | writeIORef haCharBuffer (cbuf0{ bufL=0, bufR=0 }) |
| 437 | 437 | |
| 438 | 438 | -- if we haven't used any characters from the char buffer, then just |
| 439 | 439 | -- re-install the old byte buffer. |
| … |
… |
|
| 444 | 444 | |
| 445 | 445 | case haDecoder of |
| 446 | 446 | Nothing -> do |
| 447 | | writeIORef haByteBuffer bbuf0 { bufL = bufL bbuf0 + bufL cbuf0 } |
| | 447 | writeIORef haByteBuffer (bbuf0 { bufL = bufL bbuf0 + bufL cbuf0 }) |
| 448 | 448 | -- no decoder: the number of bytes to decode is the same as the |
| 449 | 449 | -- number of chars we have used up. |
| 450 | 450 | |
| … |
… |
|
| 456 | 456 | setState decoder codec_state |
| 457 | 457 | |
| 458 | 458 | (bbuf1,cbuf1) <- (encode decoder) bbuf0 |
| 459 | | cbuf0{ bufL=0, bufR=0, bufSize = bufL cbuf0 } |
| | 459 | (cbuf0{ bufL=0, bufR=0, bufSize = bufL cbuf0 }) |
| 460 | 460 | |
| 461 | 461 | debugIO ("finished, bbuf=" ++ summaryBuffer bbuf1 ++ |
| 462 | 462 | " cbuf=" ++ summaryBuffer cbuf1) |
| … |
… |
|
| 470 | 470 | -- handle is not allowed. |
| 471 | 471 | |
| 472 | 472 | flushByteReadBuffer :: Handle__ -> IO () |
| 473 | | flushByteReadBuffer h_@Handle__{..} = do |
| | 473 | flushByteReadBuffer h_@(Handle__{..}) = do |
| 474 | 474 | bbuf <- readIORef haByteBuffer |
| 475 | 475 | |
| 476 | 476 | if isEmptyBuffer bbuf then return () else do |
| … |
… |
|
| 483 | 483 | debugIO ("flushByteReadBuffer: new file offset = " ++ show seek) |
| 484 | 484 | IODevice.seek haDevice RelativeSeek (fromIntegral seek) |
| 485 | 485 | |
| 486 | | writeIORef haByteBuffer bbuf{ bufL=0, bufR=0 } |
| | 486 | writeIORef haByteBuffer (bbuf{ bufL=0, bufR=0 }) |
| 487 | 487 | |
| 488 | 488 | -- ---------------------------------------------------------------------------- |
| 489 | 489 | -- Making Handles |
| … |
… |
|
| 584 | 584 | -> IO a |
| 585 | 585 | |
| 586 | 586 | openTextEncoding Nothing ha_type cont = cont Nothing Nothing |
| 587 | | openTextEncoding (Just TextEncoding{..}) ha_type cont = do |
| | 587 | openTextEncoding (Just (TextEncoding{..})) ha_type cont = do |
| 588 | 588 | mb_decoder <- if isReadableHandleType ha_type then do |
| 589 | 589 | decoder <- mkTextDecoder |
| 590 | 590 | return (Just decoder) |
| … |
… |
|
| 622 | 622 | trymaybe io = (do io; return Nothing) `catchException` \e -> return (Just e) |
| 623 | 623 | |
| 624 | 624 | hClose_handle_ :: Handle__ -> IO (Handle__, Maybe SomeException) |
| 625 | | hClose_handle_ Handle__{..} = do |
| | 625 | hClose_handle_ (Handle__{..}) = do |
| 626 | 626 | |
| 627 | 627 | -- close the file descriptor, but not when this is the read |
| 628 | 628 | -- side of a duplex handle. |
| … |
… |
|
| 662 | 662 | -- Looking ahead |
| 663 | 663 | |
| 664 | 664 | hLookAhead_ :: Handle__ -> IO Char |
| 665 | | hLookAhead_ handle_@Handle__{..} = do |
| | 665 | hLookAhead_ handle_@(Handle__{..}) = do |
| 666 | 666 | buf <- readIORef haCharBuffer |
| 667 | 667 | |
| 668 | 668 | -- fill up the read buffer if necessary |
| … |
… |
|
| 691 | 691 | -- Write the contents of the supplied Char buffer to the device, return |
| 692 | 692 | -- only when all the data has been written. |
| 693 | 693 | writeTextDevice :: Handle__ -> CharBuffer -> IO () |
| 694 | | writeTextDevice h_@Handle__{..} cbuf = do |
| | 694 | writeTextDevice h_@(Handle__{..}) cbuf = do |
| 695 | 695 | -- |
| 696 | 696 | bbuf <- readIORef haByteBuffer |
| 697 | 697 | |
| … |
… |
|
| 706 | 706 | " bbuf=" ++ summaryBuffer bbuf') |
| 707 | 707 | |
| 708 | 708 | Buffered.flushWriteBuffer haDevice bbuf' |
| 709 | | writeIORef haByteBuffer bbuf{bufL=0,bufR=0} |
| | 709 | writeIORef haByteBuffer (bbuf{bufL=0,bufR=0}) |
| 710 | 710 | if not (isEmptyBuffer cbuf') |
| 711 | 711 | then writeTextDevice h_ cbuf' |
| 712 | 712 | else return () |
| … |
… |
|
| 715 | 715 | -- characters are available; raise an exception if the end of |
| 716 | 716 | -- file is reached. |
| 717 | 717 | readTextDevice :: Handle__ -> CharBuffer -> IO CharBuffer |
| 718 | | readTextDevice h_@Handle__{..} cbuf = do |
| | 718 | readTextDevice h_@(Handle__{..}) cbuf = do |
| 719 | 719 | -- |
| 720 | 720 | bbuf0 <- readIORef haByteBuffer |
| 721 | 721 | |
| … |
… |
|
| 752 | 752 | -- we have an incomplete byte sequence at the end of the buffer: try to |
| 753 | 753 | -- read more bytes. |
| 754 | 754 | readTextDevice' :: Handle__ -> Buffer Word8 -> CharBuffer -> IO CharBuffer |
| 755 | | readTextDevice' h_@Handle__{..} bbuf0 cbuf = do |
| | 755 | readTextDevice' h_@(Handle__{..}) bbuf0 cbuf = do |
| 756 | 756 | -- |
| 757 | 757 | -- copy the partial sequence to the beginning of the buffer, so we have |
| 758 | 758 | -- room to read more bytes. |
| … |
… |
|
| 786 | 786 | -- Read characters into the provided buffer. Do not block; |
| 787 | 787 | -- return zero characters instead. Raises an exception on end-of-file. |
| 788 | 788 | readTextDeviceNonBlocking :: Handle__ -> CharBuffer -> IO CharBuffer |
| 789 | | readTextDeviceNonBlocking h_@Handle__{..} cbuf = do |
| | 789 | readTextDeviceNonBlocking h_@(Handle__{..}) cbuf = do |
| 790 | 790 | -- |
| 791 | 791 | bbuf0 <- readIORef haByteBuffer |
| 792 | 792 | bbuf1 <- if not (isEmptyBuffer bbuf0) |
diff -rN -u old-base/GHC/IO/Handle/Text.hs new-base/GHC/IO/Handle/Text.hs
|
old
|
new
|
|
| 77 | 77 | |
| 78 | 78 | hWaitForInput :: Handle -> Int -> IO Bool |
| 79 | 79 | hWaitForInput h msecs = do |
| 80 | | wantReadableHandle_ "hWaitForInput" h $ \ handle_@Handle__{..} -> do |
| | 80 | wantReadableHandle_ "hWaitForInput" h $ \ handle_@(Handle__{..}) -> do |
| 81 | 81 | buf <- readIORef haCharBuffer |
| 82 | 82 | |
| 83 | 83 | if not (isEmptyBuffer buf) |
| … |
… |
|
| 107 | 107 | |
| 108 | 108 | hGetChar :: Handle -> IO Char |
| 109 | 109 | hGetChar handle = |
| 110 | | wantReadableHandle_ "hGetChar" handle $ \handle_@Handle__{..} -> do |
| | 110 | wantReadableHandle_ "hGetChar" handle $ \handle_@(Handle__{..}) -> do |
| 111 | 111 | |
| 112 | 112 | -- buffering mode makes no difference: we just read whatever is available |
| 113 | 113 | -- from the device (blocking only if there is nothing available), and then |
| … |
… |
|
| 171 | 171 | hGetLineBuffered handle_ |
| 172 | 172 | |
| 173 | 173 | hGetLineBuffered :: Handle__ -> IO String |
| 174 | | hGetLineBuffered handle_@Handle__{..} = do |
| | 174 | hGetLineBuffered handle_@(Handle__{..}) = do |
| 175 | 175 | buf <- readIORef haCharBuffer |
| 176 | 176 | hGetLineBufferedLoop handle_ buf [] |
| 177 | 177 | |
| 178 | 178 | hGetLineBufferedLoop :: Handle__ |
| 179 | 179 | -> CharBuffer -> [String] |
| 180 | 180 | -> IO String |
| 181 | | hGetLineBufferedLoop handle_@Handle__{..} |
| 182 | | buf@Buffer{ bufL=r0, bufR=w, bufRaw=raw0 } xss = |
| | 181 | hGetLineBufferedLoop handle_@(Handle__{..}) |
| | 182 | buf@(Buffer{ bufL=r0, bufR=w, bufRaw=raw0 }) xss = |
| 183 | 183 | let |
| 184 | 184 | -- find the end-of-line character, if there is one |
| 185 | 185 | loop raw r |
| … |
… |
|
| 216 | 216 | -- append it to the line if necessary. |
| 217 | 217 | -- |
| 218 | 218 | let pre = if not (isEmptyBuffer buf1) then "\r" else "" |
| 219 | | writeIORef haCharBuffer buf1{ bufL=0, bufR=0 } |
| | 219 | writeIORef haCharBuffer (buf1{ bufL=0, bufR=0 }) |
| 220 | 220 | let str = concat (reverse (pre:xs:xss)) |
| 221 | 221 | if not (null str) |
| 222 | 222 | then return str |
| … |
… |
|
| 354 | 354 | "illegal handle type" Nothing Nothing) |
| 355 | 355 | |
| 356 | 356 | lazyReadBuffered :: Handle -> Handle__ -> IO (Handle__, [Char]) |
| 357 | | lazyReadBuffered h handle_@Handle__{..} = do |
| | 357 | lazyReadBuffered h handle_@(Handle__{..}) = do |
| 358 | 358 | buf <- readIORef haCharBuffer |
| 359 | 359 | catch |
| 360 | 360 | (do |
| 361 | | buf'@Buffer{..} <- getSomeCharacters handle_ buf |
| | 361 | buf'@(Buffer{..}) <- getSomeCharacters handle_ buf |
| 362 | 362 | lazy_rest <- lazyRead h |
| 363 | 363 | (s,r) <- if haInputNL == CRLF |
| 364 | 364 | then unpack_nl bufRaw bufL bufR lazy_rest |
| … |
… |
|
| 379 | 379 | |
| 380 | 380 | -- ensure we have some characters in the buffer |
| 381 | 381 | getSomeCharacters :: Handle__ -> CharBuffer -> IO CharBuffer |
| 382 | | getSomeCharacters handle_@Handle__{..} buf@Buffer{..} = |
| | 382 | getSomeCharacters handle_@(Handle__{..}) buf@(Buffer{..}) = |
| 383 | 383 | case bufferElems buf of |
| 384 | 384 | |
| 385 | 385 | -- buffer empty: read some more |
| … |
… |
|
| 426 | 426 | _other -> hPutcBuffered handle_ False c |
| 427 | 427 | |
| 428 | 428 | hPutcBuffered :: Handle__ -> Bool -> Char -> IO () |
| 429 | | hPutcBuffered handle_@Handle__{..} is_line c = do |
| | 429 | hPutcBuffered handle_@(Handle__{..}) is_line c = do |
| 430 | 430 | buf <- readIORef haCharBuffer |
| 431 | 431 | if c == '\n' |
| 432 | 432 | then do buf1 <- if haOutputNL == CRLF |
| … |
… |
|
| 445 | 445 | buf1 <- putc buf c |
| 446 | 446 | writeIORef haCharBuffer buf1 |
| 447 | 447 | where |
| 448 | | putc buf@Buffer{ bufRaw=raw, bufR=w } c = do |
| | 448 | putc buf@(Buffer{ bufRaw=raw, bufR=w }) c = do |
| 449 | 449 | debugIO ("putc: " ++ summaryBuffer buf) |
| 450 | 450 | w' <- writeCharBuf raw w c |
| 451 | 451 | let buf' = buf{ bufR = w' } |
| … |
… |
|
| 502 | 502 | hPutChars handle (c:cs) = hPutChar handle c >> hPutChars handle cs |
| 503 | 503 | |
| 504 | 504 | getSpareBuffer :: Handle__ -> IO (BufferMode, CharBuffer) |
| 505 | | getSpareBuffer Handle__{haCharBuffer=ref, |
| 506 | | haBuffers=spare_ref, |
| 507 | | haBufferMode=mode} |
| | 505 | getSpareBuffer (Handle__{haCharBuffer=ref, |
| | 506 | haBuffers=spare_ref, |
| | 507 | haBufferMode=mode}) |
| 508 | 508 | = do |
| 509 | 509 | case mode of |
| 510 | 510 | NoBuffering -> return (mode, error "no buffer!") |
| … |
… |
|
| 523 | 523 | -- NB. performance-critical code: eyeball the Core. |
| 524 | 524 | writeBlocks :: Handle -> Bool -> Newline -> Buffer CharBufElem -> String -> IO () |
| 525 | 525 | writeBlocks hdl line_buffered nl |
| 526 | | buf@Buffer{ bufRaw=raw, bufSize=len } s = |
| | 526 | buf@(Buffer{ bufRaw=raw, bufSize=len }) s = |
| 527 | 527 | let |
| 528 | 528 | shoveString :: Int -> [Char] -> IO () |
| 529 | 529 | shoveString !n [] = do |
| … |
… |
|
| 601 | 601 | commitBuffer' :: RawCharBuffer -> Int -> Int -> Bool -> Bool -> Handle__ |
| 602 | 602 | -> IO CharBuffer |
| 603 | 603 | commitBuffer' raw sz@(I# _) count@(I# _) flush release |
| 604 | | handle_@Handle__{ haCharBuffer=ref, haBuffers=spare_buf_ref } = do |
| | 604 | handle_@(Handle__{ haCharBuffer=ref, haBuffers=spare_buf_ref }) = do |
| 605 | 605 | |
| 606 | 606 | debugIO ("commitBuffer: sz=" ++ show sz ++ ", count=" ++ show count |
| 607 | 607 | ++ ", flush=" ++ show flush ++ ", release=" ++ show release) |
| 608 | 608 | |
| 609 | | old_buf@Buffer{ bufRaw=old_raw, bufR=w, bufSize=size } |
| | 609 | old_buf@(Buffer{ bufRaw=old_raw, bufR=w, bufSize=size }) |
| 610 | 610 | <- readIORef ref |
| 611 | 611 | |
| 612 | 612 | buf_ret <- |
| … |
… |
|
| 624 | 624 | then do withRawBuffer raw $ \praw -> |
| 625 | 625 | copyToRawBuffer old_raw (w*charSize) |
| 626 | 626 | praw (fromIntegral (count*charSize)) |
| 627 | | writeIORef ref old_buf{ bufR = w + count } |
| | 627 | writeIORef ref (old_buf{ bufR = w + count }) |
| 628 | 628 | return (emptyBuffer raw sz WriteBuffer) |
| 629 | 629 | |
| 630 | 630 | -- else, we have to flush |
| … |
… |
|
| 714 | 714 | | count < 0 = illegalBufferSize handle "hPutBuf" count |
| 715 | 715 | | otherwise = |
| 716 | 716 | wantWritableHandle "hPutBuf" handle $ |
| 717 | | \ h_@Handle__{..} -> do |
| | 717 | \ h_@(Handle__{..}) -> do |
| 718 | 718 | debugIO ("hPutBuf count=" ++ show count) |
| 719 | 719 | -- first flush the Char buffer if it is non-empty, then we |
| 720 | 720 | -- can work directly with the byte buffer |
| … |
… |
|
| 732 | 732 | return r |
| 733 | 733 | |
| 734 | 734 | bufWrite :: Handle__-> Ptr Word8 -> Int -> Bool -> IO Int |
| 735 | | bufWrite h_@Handle__{..} ptr count can_block = |
| | 735 | bufWrite h_@(Handle__{..}) ptr count can_block = |
| 736 | 736 | seq count $ do -- strictness hack |
| 737 | | old_buf@Buffer{ bufRaw=old_raw, bufR=w, bufSize=size } |
| | 737 | old_buf@(Buffer{ bufRaw=old_raw, bufR=w, bufSize=size }) |
| 738 | 738 | <- readIORef haByteBuffer |
| 739 | 739 | |
| 740 | 740 | -- enough room in handle buffer? |
| … |
… |
|
| 743 | 743 | -- just copy the data in and update bufR. |
| 744 | 744 | then do debugIO ("hPutBuf: copying to buffer, w=" ++ show w) |
| 745 | 745 | copyToRawBuffer old_raw w ptr (fromIntegral count) |
| 746 | | writeIORef haByteBuffer old_buf{ bufR = w + count } |
| | 746 | writeIORef haByteBuffer (old_buf{ bufR = w + count }) |
| 747 | 747 | return count |
| 748 | 748 | |
| 749 | 749 | -- else, we have to flush |
| 750 | 750 | else do debugIO "hPutBuf: flushing first" |
| 751 | 751 | Buffered.flushWriteBuffer haDevice old_buf |
| 752 | 752 | -- TODO: we should do a non-blocking flush here |
| 753 | | writeIORef haByteBuffer old_buf{bufL=0,bufR=0} |
| | 753 | writeIORef haByteBuffer (old_buf{bufL=0,bufR=0}) |
| 754 | 754 | -- if we can fit in the buffer, then just loop |
| 755 | 755 | if count < size |
| 756 | 756 | then bufWrite h_ ptr count can_block |
| … |
… |
|
| 760 | 760 | else writeChunkNonBlocking h_ (castPtr ptr) count |
| 761 | 761 | |
| 762 | 762 | writeChunk :: Handle__ -> Ptr Word8 -> Int -> IO () |
| 763 | | writeChunk h_@Handle__{..} ptr bytes |
| | 763 | writeChunk h_@(Handle__{..}) ptr bytes |
| 764 | 764 | | Just fd <- cast haDevice = RawIO.write (fd::FD) ptr bytes |
| 765 | 765 | | otherwise = error "Todo: hPutBuf" |
| 766 | 766 | |
| 767 | 767 | writeChunkNonBlocking :: Handle__ -> Ptr Word8 -> Int -> IO Int |
| 768 | | writeChunkNonBlocking h_@Handle__{..} ptr bytes |
| | 768 | writeChunkNonBlocking h_@(Handle__{..}) ptr bytes |
| 769 | 769 | | Just fd <- cast haDevice = RawIO.writeNonBlocking (fd::FD) ptr bytes |
| 770 | 770 | | otherwise = error "Todo: hPutBuf" |
| 771 | 771 | |
| … |
… |
|
| 803 | 803 | -- taking data first from the buffer and then direct from the file |
| 804 | 804 | -- descriptor. |
| 805 | 805 | bufRead :: Handle__ -> Ptr Word8 -> Int -> Int -> IO Int |
| 806 | | bufRead h_@Handle__{..} ptr so_far count = |
| | 806 | bufRead h_@(Handle__{..}) ptr so_far count = |
| 807 | 807 | seq so_far $ seq count $ do -- strictness hack |
| 808 | | buf@Buffer{ bufRaw=raw, bufR=w, bufL=r, bufSize=sz } <- readIORef haByteBuffer |
| | 808 | buf@(Buffer{ bufRaw=raw, bufR=w, bufL=r, bufSize=sz }) <- readIORef haByteBuffer |
| 809 | 809 | if isEmptyBuffer buf |
| 810 | 810 | then if count > sz -- small read? |
| 811 | 811 | then do rest <- readChunk h_ ptr count |
| … |
… |
|
| 820 | 820 | if (count == avail) |
| 821 | 821 | then do |
| 822 | 822 | copyFromRawBuffer ptr raw r count |
| 823 | | writeIORef haByteBuffer buf{ bufR=0, bufL=0 } |
| | 823 | writeIORef haByteBuffer (buf{ bufR=0, bufL=0 }) |
| 824 | 824 | return (so_far + count) |
| 825 | 825 | else do |
| 826 | 826 | if (count < avail) |
| 827 | 827 | then do |
| 828 | 828 | copyFromRawBuffer ptr raw r count |
| 829 | | writeIORef haByteBuffer buf{ bufL = r + count } |
| | 829 | writeIORef haByteBuffer (buf{ bufL = r + count }) |
| 830 | 830 | return (so_far + count) |
| 831 | 831 | else do |
| 832 | 832 | |
| 833 | 833 | copyFromRawBuffer ptr raw (fromIntegral r) (fromIntegral avail) |
| 834 | | writeIORef haByteBuffer buf{ bufR=0, bufL=0 } |
| | 834 | writeIORef haByteBuffer (buf{ bufR=0, bufL=0 }) |
| 835 | 835 | let remaining = count - avail |
| 836 | 836 | so_far' = so_far + avail |
| 837 | 837 | ptr' = ptr `plusPtr` avail |
| … |
… |
|
| 844 | 844 | return (so_far' + rest) |
| 845 | 845 | |
| 846 | 846 | readChunk :: Handle__ -> Ptr a -> Int -> IO Int |
| 847 | | readChunk h_@Handle__{..} ptr bytes |
| | 847 | readChunk h_@(Handle__{..}) ptr bytes |
| 848 | 848 | | Just fd <- cast haDevice = loop fd 0 bytes |
| 849 | 849 | | otherwise = error "ToDo: hGetBuf" |
| 850 | 850 | where |
| … |
… |
|
| 886 | 886 | bufReadNonBlocking h_ (castPtr ptr) 0 count |
| 887 | 887 | |
| 888 | 888 | bufReadNonBlocking :: Handle__ -> Ptr Word8 -> Int -> Int -> IO Int |
| 889 | | bufReadNonBlocking h_@Handle__{..} ptr so_far count = |
| | 889 | bufReadNonBlocking h_@(Handle__{..}) ptr so_far count = |
| 890 | 890 | seq so_far $ seq count $ do -- strictness hack |
| 891 | | buf@Buffer{ bufRaw=raw, bufR=w, bufL=r, bufSize=sz } <- readIORef haByteBuffer |
| | 891 | buf@(Buffer{ bufRaw=raw, bufR=w, bufL=r, bufSize=sz }) <- readIORef haByteBuffer |
| 892 | 892 | if isEmptyBuffer buf |
| 893 | 893 | then if count > sz -- large read? |
| 894 | 894 | then do rest <- readChunkNonBlocking h_ ptr count |
| … |
… |
|
| 909 | 909 | if (count == avail) |
| 910 | 910 | then do |
| 911 | 911 | copyFromRawBuffer ptr raw r count |
| 912 | | writeIORef haByteBuffer buf{ bufR=0, bufL=0 } |
| | 912 | writeIORef haByteBuffer (buf{ bufR=0, bufL=0 }) |
| 913 | 913 | return (so_far + count) |
| 914 | 914 | else do |
| 915 | 915 | if (count < avail) |
| 916 | 916 | then do |
| 917 | 917 | copyFromRawBuffer ptr raw r count |
| 918 | | writeIORef haByteBuffer buf{ bufL = r + count } |
| | 918 | writeIORef haByteBuffer (buf{ bufL = r + count }) |
| 919 | 919 | return (so_far + count) |
| 920 | 920 | else do |
| 921 | 921 | |
| 922 | 922 | copyFromRawBuffer ptr raw (fromIntegral r) (fromIntegral avail) |
| 923 | | writeIORef haByteBuffer buf{ bufR=0, bufL=0 } |
| | 923 | writeIORef haByteBuffer (buf{ bufR=0, bufL=0 }) |
| 924 | 924 | let remaining = count - avail |
| 925 | 925 | so_far' = so_far + avail |
| 926 | 926 | ptr' = ptr `plusPtr` avail |
| … |
… |
|
| 935 | 935 | |
| 936 | 936 | |
| 937 | 937 | readChunkNonBlocking :: Handle__ -> Ptr Word8 -> Int -> IO Int |
| 938 | | readChunkNonBlocking h_@Handle__{..} ptr bytes |
| | 938 | readChunkNonBlocking h_@(Handle__{..}) ptr bytes |
| 939 | 939 | | Just fd <- cast haDevice = do |
| 940 | 940 | m <- RawIO.readNonBlocking (fd::FD) ptr bytes |
| 941 | 941 | case m of |
diff -rN -u old-base/GHC/IO/Handle/Types.hs new-base/GHC/IO/Handle/Types.hs
|
old
|
new
|
|
| 170 | 170 | isWritableHandleType _ = False |
| 171 | 171 | |
| 172 | 172 | isReadWriteHandleType :: HandleType -> Bool |
| 173 | | isReadWriteHandleType ReadWriteHandle{} = True |
| 174 | | isReadWriteHandleType _ = False |
| | 173 | isReadWriteHandleType (ReadWriteHandle{}) = True |
| | 174 | isReadWriteHandleType _ = False |
| 175 | 175 | |
| 176 | 176 | -- INVARIANTS on Handles: |
| 177 | 177 | -- |
diff -rN -u old-base/GHC/IO/Handle.hs new-base/GHC/IO/Handle.hs
|
old
|
new
|
|
| 108 | 108 | |
| 109 | 109 | hFileSize :: Handle -> IO Integer |
| 110 | 110 | hFileSize handle = |
| 111 | | withHandle_ "hFileSize" handle $ \ handle_@Handle__{haDevice=dev} -> do |
| | 111 | withHandle_ "hFileSize" handle $ \ handle_@(Handle__{haDevice=dev}) -> do |
| 112 | 112 | case haType handle_ of |
| 113 | 113 | ClosedHandle -> ioe_closedHandle |
| 114 | 114 | SemiClosedHandle -> ioe_closedHandle |
| … |
… |
|
| 124 | 124 | |
| 125 | 125 | hSetFileSize :: Handle -> Integer -> IO () |
| 126 | 126 | hSetFileSize handle size = |
| 127 | | withHandle_ "hSetFileSize" handle $ \ handle_@Handle__{haDevice=dev} -> do |
| | 127 | withHandle_ "hSetFileSize" handle $ \ handle_@(Handle__{haDevice=dev}) -> do |
| 128 | 128 | case haType handle_ of |
| 129 | 129 | ClosedHandle -> ioe_closedHandle |
| 130 | 130 | SemiClosedHandle -> ioe_closedHandle |
| … |
… |
|
| 189 | 189 | |
| 190 | 190 | hSetBuffering :: Handle -> BufferMode -> IO () |
| 191 | 191 | hSetBuffering handle mode = |
| 192 | | withAllHandles__ "hSetBuffering" handle $ \ handle_@Handle__{..} -> do |
| | 192 | withAllHandles__ "hSetBuffering" handle $ \ handle_@(Handle__{..}) -> do |
| 193 | 193 | case haType of |
| 194 | 194 | ClosedHandle -> ioe_closedHandle |
| 195 | 195 | _ -> do |
| … |
… |
|
| 239 | 239 | -- throw away spare buffers, they might be the wrong size |
| 240 | 240 | writeIORef haBuffers BufferListNil |
| 241 | 241 | |
| 242 | | return Handle__{ haBufferMode = mode,.. } |
| | 242 | return $ Handle__{ haBufferMode = mode,.. } |
| 243 | 243 | |
| 244 | 244 | -- ----------------------------------------------------------------------------- |
| 245 | 245 | -- hSetEncoding |
| … |
… |
|
| 258 | 258 | -- |
| 259 | 259 | hSetEncoding :: Handle -> TextEncoding -> IO () |
| 260 | 260 | hSetEncoding hdl encoding = do |
| 261 | | withHandle "hSetEncoding" hdl $ \h_@Handle__{..} -> do |
| | 261 | withHandle "hSetEncoding" hdl $ \h_@(Handle__{..}) -> do |
| 262 | 262 | flushCharBuffer h_ |
| 263 | 263 | openTextEncoding (Just encoding) haType $ \ mb_encoder mb_decoder -> do |
| 264 | 264 | bbuf <- readIORef haByteBuffer |
| … |
… |
|
| 280 | 280 | -- |
| 281 | 281 | hGetEncoding :: Handle -> IO (Maybe TextEncoding) |
| 282 | 282 | hGetEncoding hdl = |
| 283 | | withHandle_ "hGetEncoding" hdl $ \h_@Handle__{..} -> return haCodec |
| | 283 | withHandle_ "hGetEncoding" hdl $ \h_@(Handle__{..}) -> return haCodec |
| 284 | 284 | |
| 285 | 285 | -- ----------------------------------------------------------------------------- |
| 286 | 286 | -- hFlush |
| … |
… |
|
| 388 | 388 | |
| 389 | 389 | hSeek :: Handle -> SeekMode -> Integer -> IO () |
| 390 | 390 | hSeek handle mode offset = |
| 391 | | wantSeekableHandle "hSeek" handle $ \ handle_@Handle__{..} -> do |
| | 391 | wantSeekableHandle "hSeek" handle $ \ handle_@(Handle__{..}) -> do |
| 392 | 392 | debugIO ("hSeek " ++ show (mode,offset)) |
| 393 | 393 | buf <- readIORef haCharBuffer |
| 394 | 394 | |
| … |
… |
|
| 400 | 400 | let r = bufL buf; w = bufR buf |
| 401 | 401 | if mode == RelativeSeek && isNothing haDecoder && |
| 402 | 402 | offset >= 0 && offset < fromIntegral (w - r) |
| 403 | | then writeIORef haCharBuffer buf{ bufL = r + fromIntegral offset } |
| | 403 | then writeIORef haCharBuffer (buf{ bufL = r + fromIntegral offset }) |
| 404 | 404 | else do |
| 405 | 405 | |
| 406 | 406 | flushCharReadBuffer handle_ |
| … |
… |
|
| 410 | 410 | |
| 411 | 411 | hTell :: Handle -> IO Integer |
| 412 | 412 | hTell handle = |
| 413 | | wantSeekableHandle "hGetPosn" handle $ \ handle_@Handle__{..} -> do |
| | 413 | wantSeekableHandle "hGetPosn" handle $ \ handle_@(Handle__{..}) -> do |
| 414 | 414 | |
| 415 | 415 | posn <- IODevice.tell haDevice |
| 416 | 416 | |
| … |
… |
|
| 493 | 493 | |
| 494 | 494 | hIsSeekable :: Handle -> IO Bool |
| 495 | 495 | hIsSeekable handle = |
| 496 | | withHandle_ "hIsSeekable" handle $ \ handle_@Handle__{..} -> do |
| | 496 | withHandle_ "hIsSeekable" handle $ \ handle_@(Handle__{..}) -> do |
| 497 | 497 | case haType of |
| 498 | 498 | ClosedHandle -> ioe_closedHandle |
| 499 | 499 | SemiClosedHandle -> ioe_closedHandle |
| … |
… |
|
| 511 | 511 | if not isT |
| 512 | 512 | then return () |
| 513 | 513 | else |
| 514 | | withHandle_ "hSetEcho" handle $ \ Handle__{..} -> do |
| | 514 | withHandle_ "hSetEcho" handle $ \(Handle__{..}) -> do |
| 515 | 515 | case haType of |
| 516 | 516 | ClosedHandle -> ioe_closedHandle |
| 517 | 517 | _ -> IODevice.setEcho haDevice on |
| … |
… |
|
| 524 | 524 | if not isT |
| 525 | 525 | then return False |
| 526 | 526 | else |
| 527 | | withHandle_ "hGetEcho" handle $ \ Handle__{..} -> do |
| | 527 | withHandle_ "hGetEcho" handle $ \(Handle__{..}) -> do |
| 528 | 528 | case haType of |
| 529 | 529 | ClosedHandle -> ioe_closedHandle |
| 530 | 530 | _ -> IODevice.getEcho haDevice |
| … |
… |
|
| 533 | 533 | |
| 534 | 534 | hIsTerminalDevice :: Handle -> IO Bool |
| 535 | 535 | hIsTerminalDevice handle = do |
| 536 | | withHandle_ "hIsTerminalDevice" handle $ \ Handle__{..} -> do |
| | 536 | withHandle_ "hIsTerminalDevice" handle $ \(Handle__{..}) -> do |
| 537 | 537 | case haType of |
| 538 | 538 | ClosedHandle -> ioe_closedHandle |
| 539 | 539 | _ -> IODevice.isTerminal haDevice |
| … |
… |
|
| 549 | 549 | -- |
| 550 | 550 | hSetBinaryMode :: Handle -> Bool -> IO () |
| 551 | 551 | hSetBinaryMode handle bin = |
| 552 | | withAllHandles__ "hSetBinaryMode" handle $ \ h_@Handle__{..} -> |
| | 552 | withAllHandles__ "hSetBinaryMode" handle $ \h_@(Handle__{..}) -> |
| 553 | 553 | do |
| 554 | 554 | flushBuffer h_ |
| 555 | 555 | |
| … |
… |
|
| 565 | 565 | bbuf <- readIORef haByteBuffer |
| 566 | 566 | ref <- newIORef (error "codec_state", bbuf) |
| 567 | 567 | |
| 568 | | return Handle__{ haLastDecode = ref, |
| 569 | | haEncoder = mb_encoder, |
| 570 | | haDecoder = mb_decoder, |
| 571 | | haCodec = mb_te, |
| 572 | | haInputNL = inputNL nl, |
| 573 | | haOutputNL = outputNL nl, .. } |
| | 568 | return $ Handle__{ haLastDecode = ref, |
| | 569 | haEncoder = mb_encoder, |
| | 570 | haDecoder = mb_decoder, |
| | 571 | haCodec = mb_te, |
| | 572 | haInputNL = inputNL nl, |
| | 573 | haOutputNL = outputNL nl, .. } |
| 574 | 574 | |
| 575 | 575 | -- ----------------------------------------------------------------------------- |
| 576 | 576 | -- hSetNewlineMode |
| … |
… |
|
| 578 | 578 | -- | Set the 'NewlineMode' on the specified 'Handle'. All buffered |
| 579 | 579 | -- data is flushed first. |
| 580 | 580 | hSetNewlineMode :: Handle -> NewlineMode -> IO () |
| 581 | | hSetNewlineMode handle NewlineMode{ inputNL=i, outputNL=o } = |
| 582 | | withAllHandles__ "hSetNewlineMode" handle $ \h_@Handle__{..} -> |
| | 581 | hSetNewlineMode handle (NewlineMode{ inputNL=i, outputNL=o }) = |
| | 582 | withAllHandles__ "hSetNewlineMode" handle $ \h_@(Handle__{..}) -> |
| 583 | 583 | do |
| 584 | 584 | flushBuffer h_ |
| 585 | | return h_{ haInputNL=i, haOutputNL=o } |
| | 585 | return $ h_{ haInputNL=i, haOutputNL=o } |
| 586 | 586 | |
| 587 | 587 | -- ----------------------------------------------------------------------------- |
| 588 | 588 | -- Duplicating a Handle |
| … |
… |
|
| 611 | 611 | -> Handle__ |
| 612 | 612 | -> Maybe HandleFinalizer |
| 613 | 613 | -> IO Handle |
| 614 | | dupHandle filepath h other_side h_@Handle__{..} mb_finalizer = do |
| | 614 | dupHandle filepath h other_side h_@(Handle__{..}) mb_finalizer = do |
| 615 | 615 | -- flush the buffer first, so we don't have to copy its contents |
| 616 | 616 | flushBuffer h_ |
| 617 | 617 | case other_side of |
| … |
… |
|
| 619 | 619 | new_dev <- IODevice.dup haDevice |
| 620 | 620 | dupHandle_ new_dev filepath other_side h_ mb_finalizer |
| 621 | 621 | Just r -> |
| 622 | | withHandle_' "dupHandle" h r $ \Handle__{haDevice=dev} -> do |
| | 622 | withHandle_' "dupHandle" h r $ \(Handle__{haDevice=dev}) -> do |
| 623 | 623 | dupHandle_ dev filepath other_side h_ mb_finalizer |
| 624 | 624 | |
| 625 | 625 | dupHandle_ :: (IODevice dev, BufferedIO dev, Typeable dev) => dev |
| … |
… |
|
| 628 | 628 | -> Handle__ |
| 629 | 629 | -> Maybe HandleFinalizer |
| 630 | 630 | -> IO Handle |
| 631 | | dupHandle_ new_dev filepath other_side h_@Handle__{..} mb_finalizer = do |
| | 631 | dupHandle_ new_dev filepath other_side h_@(Handle__{..}) mb_finalizer = do |
| 632 | 632 | -- XXX wrong! |
| 633 | 633 | let mb_codec = if isJust haEncoder then Just localeEncoding else Nothing |
| 634 | 634 | mkHandle new_dev filepath haType True{-buffered-} mb_codec |
| 635 | | NewlineMode { inputNL = haInputNL, outputNL = haOutputNL } |
| | 635 | (NewlineMode { inputNL = haInputNL, outputNL = haOutputNL }) |
| 636 | 636 | mb_finalizer other_side |
| 637 | 637 | |
| 638 | 638 | -- ----------------------------------------------------------------------------- |
| … |
… |
|
| 680 | 680 | -> Maybe HandleFinalizer |
| 681 | 681 | -> IO Handle__ |
| 682 | 682 | dupHandleTo filepath h other_side |
| 683 | | hto_@Handle__{haDevice=devTo,..} |
| 684 | | h_@Handle__{haDevice=dev} mb_finalizer = do |
| | 683 | hto_@(Handle__{haDevice=devTo,..}) |
| | 684 | h_@(Handle__{haDevice=dev}) mb_finalizer = do |
| 685 | 685 | flushBuffer h_ |
| 686 | 686 | case cast devTo of |
| 687 | 687 | Nothing -> ioe_dupHandlesNotCompatible h |
diff -rN -u old-base/GHC/TopHandler.lhs new-base/GHC/TopHandler.lhs
|
old
|
new
|
|
| 165 | 165 | |
| 166 | 166 | -- EPIPE errors received for stdout are ignored (#2699) |
| 167 | 167 | _ -> case cast exn of |
| 168 | | Just IOError{ ioe_type = ResourceVanished, |
| 169 | | ioe_errno = Just ioe, |
| 170 | | ioe_handle = Just hdl } |
| | 168 | Just (IOError{ ioe_type = ResourceVanished, |
| | 169 | ioe_errno = Just ioe, |
| | 170 | ioe_handle = Just hdl }) |
| 171 | 171 | | Errno ioe == ePIPE, hdl == stdout -> exit 0 |
| 172 | 172 | _ -> do reportError se |
| 173 | 173 | exit 1 |