base 4.9.0.0 → 4.9.1.0
raw patch · 13 files changed
+324/−125 lines, 13 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Data.Either: instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.Either.Either a b)
- Data.Either: instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Data.Either.Either a b)
- Data.Either: instance (GHC.Read.Read a, GHC.Read.Read b) => GHC.Read.Read (Data.Either.Either a b)
- Data.Either: instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Data.Either.Either a b)
- Data.Functor.Compose: instance forall k (f :: k -> *) k1 (g :: k1 -> k) (a :: k1). (Data.Data.Data (f (g a)), Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable k, Data.Typeable.Internal.Typeable k1, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable g) => Data.Data.Data (Data.Functor.Compose.Compose f g a)
- Data.Functor.Product: instance forall k (f :: k -> *) (g :: k -> *) (a :: k). (Data.Data.Data (f a), Data.Data.Data (g a), Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable k, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable g) => Data.Data.Data (Data.Functor.Product.Product f g a)
- Data.Functor.Sum: instance forall k (f :: k -> *) (g :: k -> *) (a :: k). (Data.Data.Data (f a), Data.Data.Data (g a), Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable k, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable g) => Data.Data.Data (Data.Functor.Sum.Sum f g a)
- Data.Semigroup: instance (Data.Data.Data a, Data.Data.Data b) => Data.Data.Data (Data.Semigroup.Arg a b)
- Data.Semigroup: instance (GHC.Read.Read a, GHC.Read.Read b) => GHC.Read.Read (Data.Semigroup.Arg a b)
- Data.Semigroup: instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Data.Semigroup.Arg a b)
- GHC.Generics: instance (GHC.Base.Functor f, GHC.Base.Functor g) => GHC.Base.Functor (f GHC.Generics.:*: g)
- GHC.Generics: instance (GHC.Base.Functor f, GHC.Base.Functor g) => GHC.Base.Functor (f GHC.Generics.:+: g)
- GHC.Generics: instance (GHC.Base.Functor f, GHC.Base.Functor g) => GHC.Base.Functor (f GHC.Generics.:.: g)
- GHC.Generics: instance (GHC.Classes.Eq (f p), GHC.Classes.Eq (g p)) => GHC.Classes.Eq ((GHC.Generics.:*:) f g p)
- GHC.Generics: instance (GHC.Classes.Eq (f p), GHC.Classes.Eq (g p)) => GHC.Classes.Eq ((GHC.Generics.:+:) f g p)
- GHC.Generics: instance (GHC.Classes.Ord (f p), GHC.Classes.Ord (g p)) => GHC.Classes.Ord ((GHC.Generics.:*:) f g p)
- GHC.Generics: instance (GHC.Classes.Ord (f p), GHC.Classes.Ord (g p)) => GHC.Classes.Ord ((GHC.Generics.:+:) f g p)
- GHC.Generics: instance (GHC.Read.Read (f p), GHC.Read.Read (g p)) => GHC.Read.Read ((GHC.Generics.:*:) f g p)
- GHC.Generics: instance (GHC.Read.Read (f p), GHC.Read.Read (g p)) => GHC.Read.Read ((GHC.Generics.:+:) f g p)
- GHC.Generics: instance (GHC.Show.Show (f p), GHC.Show.Show (g p)) => GHC.Show.Show ((GHC.Generics.:*:) f g p)
- GHC.Generics: instance (GHC.Show.Show (f p), GHC.Show.Show (g p)) => GHC.Show.Show ((GHC.Generics.:+:) f g p)
+ Data.Either: instance (GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.Either.Either a b)
+ Data.Either: instance (GHC.Classes.Ord b, GHC.Classes.Ord a) => GHC.Classes.Ord (Data.Either.Either a b)
+ Data.Either: instance (GHC.Read.Read b, GHC.Read.Read a) => GHC.Read.Read (Data.Either.Either a b)
+ Data.Either: instance (GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Data.Either.Either a b)
+ Data.Functor.Compose: instance forall k (f :: k -> *) k1 (g :: k1 -> k) (a :: k1). (Data.Data.Data (f (g a)), Data.Typeable.Internal.Typeable k, Data.Typeable.Internal.Typeable k1, Data.Typeable.Internal.Typeable g, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable a) => Data.Data.Data (Data.Functor.Compose.Compose f g a)
+ Data.Functor.Product: instance forall k (f :: k -> *) (g :: k -> *) (a :: k). (Data.Data.Data (g a), Data.Data.Data (f a), Data.Typeable.Internal.Typeable k, Data.Typeable.Internal.Typeable g, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable a) => Data.Data.Data (Data.Functor.Product.Product f g a)
+ Data.Functor.Sum: instance forall k (f :: k -> *) (g :: k -> *) (a :: k). (Data.Data.Data (g a), Data.Data.Data (f a), Data.Typeable.Internal.Typeable k, Data.Typeable.Internal.Typeable g, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable a) => Data.Data.Data (Data.Functor.Sum.Sum f g a)
+ Data.Semigroup: instance (Data.Data.Data b, Data.Data.Data a) => Data.Data.Data (Data.Semigroup.Arg a b)
+ Data.Semigroup: instance (GHC.Read.Read b, GHC.Read.Read a) => GHC.Read.Read (Data.Semigroup.Arg a b)
+ Data.Semigroup: instance (GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Data.Semigroup.Arg a b)
+ GHC.Foreign: withCStringsLen :: TextEncoding -> [String] -> (Int -> Ptr CString -> IO a) -> IO a
+ GHC.Generics: instance (GHC.Base.Functor g, GHC.Base.Functor f) => GHC.Base.Functor (f GHC.Generics.:*: g)
+ GHC.Generics: instance (GHC.Base.Functor g, GHC.Base.Functor f) => GHC.Base.Functor (f GHC.Generics.:+: g)
+ GHC.Generics: instance (GHC.Base.Functor g, GHC.Base.Functor f) => GHC.Base.Functor (f GHC.Generics.:.: g)
+ GHC.Generics: instance (GHC.Classes.Eq (g p), GHC.Classes.Eq (f p)) => GHC.Classes.Eq ((GHC.Generics.:*:) f g p)
+ GHC.Generics: instance (GHC.Classes.Eq (g p), GHC.Classes.Eq (f p)) => GHC.Classes.Eq ((GHC.Generics.:+:) f g p)
+ GHC.Generics: instance (GHC.Classes.Ord (g p), GHC.Classes.Ord (f p)) => GHC.Classes.Ord ((GHC.Generics.:*:) f g p)
+ GHC.Generics: instance (GHC.Classes.Ord (g p), GHC.Classes.Ord (f p)) => GHC.Classes.Ord ((GHC.Generics.:+:) f g p)
+ GHC.Generics: instance (GHC.Read.Read (g p), GHC.Read.Read (f p)) => GHC.Read.Read ((GHC.Generics.:*:) f g p)
+ GHC.Generics: instance (GHC.Read.Read (g p), GHC.Read.Read (f p)) => GHC.Read.Read ((GHC.Generics.:+:) f g p)
+ GHC.Generics: instance (GHC.Show.Show (g p), GHC.Show.Show (f p)) => GHC.Show.Show ((GHC.Generics.:*:) f g p)
+ GHC.Generics: instance (GHC.Show.Show (g p), GHC.Show.Show (f p)) => GHC.Show.Show ((GHC.Generics.:+:) f g p)
- Data.Eq: (/=) :: a -> a -> Bool
+ Data.Eq: (/=) :: Eq a => a -> a -> Bool
- Data.Eq: (==) :: a -> a -> Bool
+ Data.Eq: (==) :: Eq a => a -> a -> Bool
- Data.Ord: (<) :: a -> a -> Bool
+ Data.Ord: (<) :: Ord a => a -> a -> Bool
- Data.Ord: (<=) :: a -> a -> Bool
+ Data.Ord: (<=) :: Ord a => a -> a -> Bool
- Data.Ord: (>) :: a -> a -> Bool
+ Data.Ord: (>) :: Ord a => a -> a -> Bool
- Data.Ord: (>=) :: a -> a -> Bool
+ Data.Ord: (>=) :: Ord a => a -> a -> Bool
- Data.Ord: compare :: a -> a -> Ordering
+ Data.Ord: compare :: Ord a => a -> a -> Ordering
- Data.Ord: max :: a -> a -> a
+ Data.Ord: max :: Ord a => a -> a -> a
- Data.Ord: min :: a -> a -> a
+ Data.Ord: min :: Ord a => a -> a -> a
- Prelude: (/=) :: a -> a -> Bool
+ Prelude: (/=) :: Eq a => a -> a -> Bool
- Prelude: (<) :: a -> a -> Bool
+ Prelude: (<) :: Ord a => a -> a -> Bool
- Prelude: (<=) :: a -> a -> Bool
+ Prelude: (<=) :: Ord a => a -> a -> Bool
- Prelude: (==) :: a -> a -> Bool
+ Prelude: (==) :: Eq a => a -> a -> Bool
- Prelude: (>) :: a -> a -> Bool
+ Prelude: (>) :: Ord a => a -> a -> Bool
- Prelude: (>=) :: a -> a -> Bool
+ Prelude: (>=) :: Ord a => a -> a -> Bool
- Prelude: compare :: a -> a -> Ordering
+ Prelude: compare :: Ord a => a -> a -> Ordering
- Prelude: max :: a -> a -> a
+ Prelude: max :: Ord a => a -> a -> a
- Prelude: min :: a -> a -> a
+ Prelude: min :: Ord a => a -> a -> a
Files
- Foreign/C/Types.hs +6/−0
- GHC/Base.hs +1/−1
- GHC/Enum.hs +138/−14
- GHC/Foreign.hs +18/−0
- GHC/IO/FD.hs +8/−8
- GHC/Read.hs +47/−5
- System/Environment.hs +11/−17
- System/Posix/Internals.hs +36/−66
- System/Posix/Types.hs +6/−0
- Text/Read/Lex.hs +10/−1
- base.cabal +2/−4
- cbits/inputReady.c +33/−9
- changelog.md +8/−0
Foreign/C/Types.hs view
@@ -23,6 +23,12 @@ ( -- * Representations of C types -- $ctypes + -- ** Platform differences+ -- | This module contains platform specific information about types.+ -- __/As such the types presented on this page reflect the platform+ -- on which the documentation was generated and may not coincide with+ -- the types on your platform./__+ -- ** Integral types -- | These types are represented as @newtype@s of -- types in "Data.Int" and "Data.Word", and are instances of
GHC/Base.hs view
@@ -456,7 +456,7 @@ * @'return' a '>>=' k = k a@ * @m '>>=' 'return' = m@-* @m '>>=' (\x -> k x '>>=' h) = (m '>>=' k) '>>=' h@+* @m '>>=' (\\x -> k x '>>=' h) = (m '>>=' k) '>>=' h@ Furthermore, the 'Monad' and 'Applicative' operations should relate as follows:
GHC/Enum.hs view
@@ -636,26 +636,150 @@ | x <= maxIntWord = I# (word2Int# x#) | otherwise = fromEnumError "Word" x - enumFrom n = map integerToWordX [wordToIntegerX n .. wordToIntegerX (maxBound :: Word)]- enumFromTo n1 n2 = map integerToWordX [wordToIntegerX n1 .. wordToIntegerX n2]- enumFromThenTo n1 n2 m = map integerToWordX [wordToIntegerX n1, wordToIntegerX n2 .. wordToIntegerX m]- enumFromThen n1 n2 = map integerToWordX [wordToIntegerX n1, wordToIntegerX n2 .. wordToIntegerX limit]- where- limit :: Word- limit | n2 >= n1 = maxBound- | otherwise = minBound+ {-# INLINE enumFrom #-}+ enumFrom (W# x#) = eftWord x# maxWord#+ where !(W# maxWord#) = maxBound+ -- Blarg: technically I guess enumFrom isn't strict! + {-# INLINE enumFromTo #-}+ enumFromTo (W# x) (W# y) = eftWord x y++ {-# INLINE enumFromThen #-}+ enumFromThen (W# x1) (W# x2) = efdWord x1 x2++ {-# INLINE enumFromThenTo #-}+ enumFromThenTo (W# x1) (W# x2) (W# y) = efdtWord x1 x2 y+ maxIntWord :: Word -- The biggest word representable as an Int maxIntWord = W# (case maxInt of I# i -> int2Word# i) --- For some reason integerToWord and wordToInteger (GHC.Integer.Type)--- work over Word#-integerToWordX :: Integer -> Word-integerToWordX i = W# (integerToWord i)+-----------------------------------------------------+-- eftWord and eftWordFB deal with [a..b], which is the+-- most common form, so we take a lot of care+-- In particular, we have rules for deforestation -wordToIntegerX :: Word -> Integer-wordToIntegerX (W# x#) = wordToInteger x#+{-# RULES+"eftWord" [~1] forall x y. eftWord x y = build (\ c n -> eftWordFB c n x y)+"eftWordList" [1] eftWordFB (:) [] = eftWord+ #-}++-- The Enum rules for Word work much the same way that they do for Int.+-- See Note [How the Enum rules work].++{-# NOINLINE [1] eftWord #-}+eftWord :: Word# -> Word# -> [Word]+-- [x1..x2]+eftWord x0 y | isTrue# (x0 `gtWord#` y) = []+ | otherwise = go x0+ where+ go x = W# x : if isTrue# (x `eqWord#` y)+ then []+ else go (x `plusWord#` 1##)++{-# INLINE [0] eftWordFB #-}+eftWordFB :: (Word -> r -> r) -> r -> Word# -> Word# -> r+eftWordFB c n x0 y | isTrue# (x0 `gtWord#` y) = n+ | otherwise = go x0+ where+ go x = W# x `c` if isTrue# (x `eqWord#` y)+ then n+ else go (x `plusWord#` 1##)+ -- Watch out for y=maxBound; hence ==, not >+ -- Be very careful not to have more than one "c"+ -- so that when eftInfFB is inlined we can inline+ -- whatever is bound to "c"+++-----------------------------------------------------+-- efdWord and efdtWord deal with [a,b..] and [a,b..c].+-- The code is more complicated because of worries about Word overflow.++-- See Note [How the Enum rules work]+{-# RULES+"efdtWord" [~1] forall x1 x2 y.+ efdtWord x1 x2 y = build (\ c n -> efdtWordFB c n x1 x2 y)+"efdtWordUpList" [1] efdtWordFB (:) [] = efdtWord+ #-}++efdWord :: Word# -> Word# -> [Word]+-- [x1,x2..maxWord]+efdWord x1 x2+ | isTrue# (x2 `geWord#` x1) = case maxBound of W# y -> efdtWordUp x1 x2 y+ | otherwise = case minBound of W# y -> efdtWordDn x1 x2 y++{-# NOINLINE [1] efdtWord #-}+efdtWord :: Word# -> Word# -> Word# -> [Word]+-- [x1,x2..y]+efdtWord x1 x2 y+ | isTrue# (x2 `geWord#` x1) = efdtWordUp x1 x2 y+ | otherwise = efdtWordDn x1 x2 y++{-# INLINE [0] efdtWordFB #-}+efdtWordFB :: (Word -> r -> r) -> r -> Word# -> Word# -> Word# -> r+efdtWordFB c n x1 x2 y+ | isTrue# (x2 `geWord#` x1) = efdtWordUpFB c n x1 x2 y+ | otherwise = efdtWordDnFB c n x1 x2 y++-- Requires x2 >= x1+efdtWordUp :: Word# -> Word# -> Word# -> [Word]+efdtWordUp x1 x2 y -- Be careful about overflow!+ | isTrue# (y `ltWord#` x2) = if isTrue# (y `ltWord#` x1) then [] else [W# x1]+ | otherwise = -- Common case: x1 <= x2 <= y+ let !delta = x2 `minusWord#` x1 -- >= 0+ !y' = y `minusWord#` delta -- x1 <= y' <= y; hence y' is representable++ -- Invariant: x <= y+ -- Note that: z <= y' => z + delta won't overflow+ -- so we are guaranteed not to overflow if/when we recurse+ go_up x | isTrue# (x `gtWord#` y') = [W# x]+ | otherwise = W# x : go_up (x `plusWord#` delta)+ in W# x1 : go_up x2++-- Requires x2 >= x1+efdtWordUpFB :: (Word -> r -> r) -> r -> Word# -> Word# -> Word# -> r+efdtWordUpFB c n x1 x2 y -- Be careful about overflow!+ | isTrue# (y `ltWord#` x2) = if isTrue# (y `ltWord#` x1) then n else W# x1 `c` n+ | otherwise = -- Common case: x1 <= x2 <= y+ let !delta = x2 `minusWord#` x1 -- >= 0+ !y' = y `minusWord#` delta -- x1 <= y' <= y; hence y' is representable++ -- Invariant: x <= y+ -- Note that: z <= y' => z + delta won't overflow+ -- so we are guaranteed not to overflow if/when we recurse+ go_up x | isTrue# (x `gtWord#` y') = W# x `c` n+ | otherwise = W# x `c` go_up (x `plusWord#` delta)+ in W# x1 `c` go_up x2++-- Requires x2 <= x1+efdtWordDn :: Word# -> Word# -> Word# -> [Word]+efdtWordDn x1 x2 y -- Be careful about underflow!+ | isTrue# (y `gtWord#` x2) = if isTrue# (y `gtWord#` x1) then [] else [W# x1]+ | otherwise = -- Common case: x1 >= x2 >= y+ let !delta = x2 `minusWord#` x1 -- <= 0+ !y' = y `minusWord#` delta -- y <= y' <= x1; hence y' is representable++ -- Invariant: x >= y+ -- Note that: z >= y' => z + delta won't underflow+ -- so we are guaranteed not to underflow if/when we recurse+ go_dn x | isTrue# (x `ltWord#` y') = [W# x]+ | otherwise = W# x : go_dn (x `plusWord#` delta)+ in W# x1 : go_dn x2++-- Requires x2 <= x1+efdtWordDnFB :: (Word -> r -> r) -> r -> Word# -> Word# -> Word# -> r+efdtWordDnFB c n x1 x2 y -- Be careful about underflow!+ | isTrue# (y `gtWord#` x2) = if isTrue# (y `gtWord#` x1) then n else W# x1 `c` n+ | otherwise = -- Common case: x1 >= x2 >= y+ let !delta = x2 `minusWord#` x1 -- <= 0+ !y' = y `minusWord#` delta -- y <= y' <= x1; hence y' is representable++ -- Invariant: x >= y+ -- Note that: z >= y' => z + delta won't underflow+ -- so we are guaranteed not to underflow if/when we recurse+ go_dn x | isTrue# (x `ltWord#` y') = W# x `c` n+ | otherwise = W# x `c` go_dn (x `plusWord#` delta)+ in W# x1 `c` go_dn x2 ------------------------------------------------------------------------ -- Integer
GHC/Foreign.hs view
@@ -32,6 +32,7 @@ -- withCString, withCStringLen,+ withCStringsLen, charIsRepresentable, ) where@@ -134,6 +135,23 @@ withCStringLen :: TextEncoding -> String -> (CStringLen -> IO a) -> IO a withCStringLen enc = withEncodedCString enc False +-- | Marshal a list of Haskell strings into an array of NUL terminated C strings+-- using temporary storage.+--+-- * the Haskell strings may /not/ contain any NUL characters+--+-- * the memory is freed when the subcomputation terminates (either+-- normally or via an exception), so the pointer to the temporary+-- storage must /not/ be used after this.+--+withCStringsLen :: TextEncoding+ -> [String]+ -> (Int -> Ptr CString -> IO a)+ -> IO a+withCStringsLen enc strs f = go [] strs+ where+ go cs (s:ss) = withCString enc s $ \c -> go (c:cs) ss+ go cs [] = withArrayLen (reverse cs) f -- | Determines whether a character can be accurately encoded in a 'CString'. --
GHC/IO/FD.hs view
@@ -606,18 +606,18 @@ blockingReadRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt blockingReadRawBufferPtr loc fd buf off len- = fmap fromIntegral $ throwErrnoIfMinus1Retry loc $+ = throwErrnoIfMinus1Retry loc $ if fdIsSocket fd- then c_safe_recv (fdFD fd) (buf `plusPtr` off) len 0- else c_safe_read (fdFD fd) (buf `plusPtr` off) len+ then c_safe_recv (fdFD fd) (buf `plusPtr` off) (fromIntegral len) 0+ else c_safe_read (fdFD fd) (buf `plusPtr` off) (fromIntegral len) blockingWriteRawBufferPtr :: String -> FD -> Ptr Word8-> Int -> CSize -> IO CInt blockingWriteRawBufferPtr loc fd buf off len- = fmap fromIntegral $ throwErrnoIfMinus1Retry loc $+ = throwErrnoIfMinus1Retry loc $ if fdIsSocket fd- then c_safe_send (fdFD fd) (buf `plusPtr` off) len 0+ then c_safe_send (fdFD fd) (buf `plusPtr` off) (fromIntegral len) 0 else do- r <- c_safe_write (fdFD fd) (buf `plusPtr` off) len+ r <- c_safe_write (fdFD fd) (buf `plusPtr` off) (fromIntegral len) when (r == -1) c_maperrno return r -- we don't trust write() to give us the correct errno, and@@ -631,10 +631,10 @@ -- These calls may block, but that's ok. foreign import WINDOWS_CCONV safe "recv"- c_safe_recv :: CInt -> Ptr Word8 -> CSize -> CInt{-flags-} -> IO CSsize+ c_safe_recv :: CInt -> Ptr Word8 -> CInt -> CInt{-flags-} -> IO CInt foreign import WINDOWS_CCONV safe "send"- c_safe_send :: CInt -> Ptr Word8 -> CSize -> CInt{-flags-} -> IO CSsize+ c_safe_send :: CInt -> Ptr Word8 -> CInt -> CInt{-flags-} -> IO CInt #endif
GHC/Read.hs view
@@ -229,7 +229,13 @@ -- lexLitChar :: ReadS String -- As defined by H2010 lexLitChar = readP_to_S (do { (s, _) <- P.gather L.lexChar ;- return s })+ let s' = removeNulls s in+ return s' })+ where+ -- remove nulls from end of the character if they exist+ removeNulls [] = []+ removeNulls ('\\':'&':xs) = removeNulls xs+ removeNulls (first:rest) = first : removeNulls rest -- There was a skipSpaces before the P.gather L.lexChar, -- but that seems inconsistent with readLitChar @@ -256,13 +262,49 @@ expectP :: L.Lexeme -> ReadPrec () expectP lexeme = lift (L.expect lexeme) +expectCharP :: Char -> ReadPrec a -> ReadPrec a+expectCharP c a = do+ q <- get+ if q == c+ then a+ else pfail+{-# INLINE expectCharP #-}++-- A version of skipSpaces that takes the next+-- parser as an argument. That is,+--+-- skipSpacesThenP m = lift skipSpaces >> m+--+-- Since skipSpaces is recursive, it appears that we get+-- cleaner code by providing the continuation explicitly.+-- In particular, we avoid passing an extra continuation+-- of the form+--+-- \ () -> ...+skipSpacesThenP :: ReadPrec a -> ReadPrec a+skipSpacesThenP m =+ do s <- look+ skip s+ where+ skip (c:s) | isSpace c = get *> skip s+ skip _ = m+ paren :: ReadPrec a -> ReadPrec a -- ^ @(paren p)@ parses \"(P0)\" -- where @p@ parses \"P0\" in precedence context zero-paren p = do expectP (L.Punc "(")- x <- reset p- expectP (L.Punc ")")- return x+paren p = skipSpacesThenP (paren' p)++-- We try very hard to make paren' efficient, because parens is ubiquitous.+-- Earlier code used `expectP` to look for the parentheses. The problem is that+-- this lexes a (potentially long) token just to check if it's a parenthesis or+-- not. So the first token of pretty much every value would be fully lexed+-- twice. Now, we look for the '(' by hand instead. Since there's no reason not+-- to, and it allows for faster failure, we do the same for ')'. This strategy+-- works particularly well here because neither '(' nor ')' can begin any other+-- lexeme.+paren' :: ReadPrec a -> ReadPrec a+paren' p = expectCharP '(' $ reset p >>= \x ->+ skipSpacesThenP (expectCharP ')' (pure x)) parens :: ReadPrec a -> ReadPrec a -- ^ @(parens p)@ parses \"P\", \"(P0)\", \"((P0))\", etc,
System/Environment.hs view
@@ -32,12 +32,14 @@ import Foreign import Foreign.C import System.IO.Error (mkIOError)-import Control.Exception.Base (bracket, throwIO)+import Control.Exception.Base (bracket_, throwIO)+#ifdef mingw32_HOST_OS+import Control.Exception.Base (bracket)+#endif -- import GHC.IO import GHC.IO.Exception import GHC.IO.Encoding (getFileSystemEncoding) import qualified GHC.Foreign as GHC-import Data.List import Control.Monad #ifdef mingw32_HOST_OS import GHC.Environment@@ -369,25 +371,17 @@ withProgArgv new_args act = do pName <- System.Environment.getProgName existing_args <- System.Environment.getArgs- bracket (setProgArgv new_args)- (\argv -> do _ <- setProgArgv (pName:existing_args)- freeProgArgv argv)- (const act)--freeProgArgv :: Ptr CString -> IO ()-freeProgArgv argv = do- size <- lengthArray0 nullPtr argv- sequence_ [ peek (argv `advancePtr` i) >>= free- | i <- [size - 1, size - 2 .. 0]]- free argv+ bracket_ (setProgArgv new_args)+ (setProgArgv (pName:existing_args))+ act -setProgArgv :: [String] -> IO (Ptr CString)+setProgArgv :: [String] -> IO () setProgArgv argv = do enc <- getFileSystemEncoding- vs <- mapM (GHC.newCString enc) argv >>= newArray0 nullPtr- c_setProgArgv (genericLength argv) vs- return vs+ GHC.withCStringsLen enc argv $ \len css ->+ c_setProgArgv (fromIntegral len) css +-- setProgArgv copies the arguments foreign import ccall unsafe "setProgArgv" c_setProgArgv :: CInt -> Ptr CString -> IO ()
System/Posix/Internals.hs view
@@ -378,121 +378,92 @@ See https://msdn.microsoft.com/en-us/library/ms235384.aspx for more.++However since we can't hope to get people to support Windows+packages we should support the deprecated names. See #12497 -}-#if defined(mingw32_HOST_OS)-foreign import ccall unsafe "io.h _lseeki64"- c_lseek :: CInt -> Int64 -> CInt -> IO Int64+foreign import capi unsafe "unistd.h lseek"+ c_lseek :: CInt -> COff -> CInt -> IO COff -foreign import ccall unsafe "HsBase.h _access"+foreign import ccall unsafe "HsBase.h access" c_access :: CString -> CInt -> IO CInt -foreign import ccall unsafe "HsBase.h _chmod"+foreign import ccall unsafe "HsBase.h chmod" c_chmod :: CString -> CMode -> IO CInt -foreign import ccall unsafe "HsBase.h _close"+foreign import ccall unsafe "HsBase.h close" c_close :: CInt -> IO CInt -foreign import ccall unsafe "HsBase.h _creat"+foreign import ccall unsafe "HsBase.h creat" c_creat :: CString -> CMode -> IO CInt -foreign import ccall unsafe "HsBase.h _dup"+foreign import ccall unsafe "HsBase.h dup" c_dup :: CInt -> IO CInt -foreign import ccall unsafe "HsBase.h _dup2"+foreign import ccall unsafe "HsBase.h dup2" c_dup2 :: CInt -> CInt -> IO CInt -foreign import ccall unsafe "HsBase.h _isatty"+foreign import ccall unsafe "HsBase.h isatty" c_isatty :: CInt -> IO CInt --- See Note: CSsize+#if defined(mingw32_HOST_OS)+-- See Note: Windows types foreign import capi unsafe "HsBase.h _read"- c_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize+ c_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt --- See Note: CSsize+-- See Note: Windows types foreign import capi safe "HsBase.h _read"- c_safe_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize+ c_safe_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt foreign import ccall unsafe "HsBase.h _umask" c_umask :: CMode -> IO CMode --- See Note: CSsize+-- See Note: Windows types foreign import capi unsafe "HsBase.h _write"- c_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize+ c_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt --- See Note: CSsize+-- See Note: Windows types foreign import capi safe "HsBase.h _write"- c_safe_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize--foreign import ccall unsafe "HsBase.h _unlink"- c_unlink :: CString -> IO CInt+ c_safe_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt foreign import ccall unsafe "HsBase.h _pipe" c_pipe :: Ptr CInt -> IO CInt--foreign import capi unsafe "HsBase.h _utime"- c_utime :: CString -> Ptr CUtimbuf -> IO CInt--foreign import ccall unsafe "HsBase.h _getpid"- c_getpid :: IO CPid #else -- We use CAPI as on some OSs (eg. Linux) this is wrapped by a macro -- which redirects to the 64-bit-off_t versions when large file -- support is enabled.-foreign import capi unsafe "unistd.h lseek"- c_lseek :: CInt -> COff -> CInt -> IO COff -foreign import ccall unsafe "HsBase.h access"- c_access :: CString -> CInt -> IO CInt--foreign import ccall unsafe "HsBase.h chmod"- c_chmod :: CString -> CMode -> IO CInt--foreign import ccall unsafe "HsBase.h close"- c_close :: CInt -> IO CInt--foreign import ccall unsafe "HsBase.h creat"- c_creat :: CString -> CMode -> IO CInt--foreign import ccall unsafe "HsBase.h dup"- c_dup :: CInt -> IO CInt--foreign import ccall unsafe "HsBase.h dup2"- c_dup2 :: CInt -> CInt -> IO CInt--foreign import ccall unsafe "HsBase.h isatty"- c_isatty :: CInt -> IO CInt---- See Note: CSsize+-- See Note: Windows types foreign import capi unsafe "HsBase.h read" c_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize --- See Note: CSsize+-- See Note: Windows types foreign import capi safe "HsBase.h read" c_safe_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize foreign import ccall unsafe "HsBase.h umask" c_umask :: CMode -> IO CMode --- See Note: CSsize+-- See Note: Windows types foreign import capi unsafe "HsBase.h write" c_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize --- See Note: CSsize+-- See Note: Windows types foreign import capi safe "HsBase.h write" c_safe_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize -foreign import ccall unsafe "HsBase.h unlink"- c_unlink :: CString -> IO CInt- foreign import ccall unsafe "HsBase.h pipe" c_pipe :: Ptr CInt -> IO CInt+#endif +foreign import ccall unsafe "HsBase.h unlink"+ c_unlink :: CString -> IO CInt+ foreign import capi unsafe "HsBase.h utime" c_utime :: CString -> Ptr CUtimbuf -> IO CInt foreign import ccall unsafe "HsBase.h getpid" c_getpid :: IO CPid-#endif foreign import ccall unsafe "HsBase.h __hscore_stat" c_stat :: CFilePath -> Ptr CStat -> IO CInt@@ -619,14 +590,13 @@ foreign import capi unsafe "stdio.h value SEEK_END" sEEK_END :: CInt {--Note: CSsize--On Win64, ssize_t is 64 bit, but functions like read return 32 bit-ints. The CAPI wrapper means the C compiler takes care of doing all-the necessary casting.+Note: Windows types -When using ccall instead, when the functions failed with -1, we thought-they were returning with 4294967295, and so didn't throw an exception.-This lead to a segfault in echo001(ghci).+Windows' _read and _write have types that differ from POSIX. They take an+unsigned int for lengh and return a signed int where POSIX uses size_t and+ssize_t. Those are different on x86_64 and equivalent on x86. We import them+with the types in Microsoft's documentation which means that c_read,+c_safe_read, c_write and c_safe_write have different Haskell types depending on+the OS. -}
System/Posix/Types.hs view
@@ -25,6 +25,12 @@ module System.Posix.Types ( -- * POSIX data types++ -- ** Platform differences+ -- | This module contains platform specific information about types.+ -- __/As such the types presented on this page reflect the platform+ -- on which the documentation was generated and may not coincide with+ -- the types on your platform./__ #if defined(HTYPE_DEV_T) CDev(..), #endif
Text/Read/Lex.hs view
@@ -253,7 +253,16 @@ return (Char c) lexChar :: ReadP Char-lexChar = do { (c,_) <- lexCharE; return c }+lexChar = do { (c,_) <- lexCharE; consumeEmpties; return c }+ where+ -- Consumes the string "\&" repeatedly and greedily (will only produce one match)+ consumeEmpties :: ReadP ()+ consumeEmpties = do+ rest <- look+ case rest of+ ('\\':'&':_) -> string "\\&" >> consumeEmpties+ _ -> return ()+ lexCharE :: ReadP (Char, Bool) -- "escaped or not"? lexCharE =
base.cabal view
@@ -1,5 +1,5 @@ name: base-version: 4.9.0.0+version: 4.9.1.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 license-file: LICENSE@@ -44,13 +44,11 @@ Flag integer-simple Description: Use integer-simple- Manual: True Default: False Flag integer-gmp Description: Use integer-gmp- Manual: True- Default: False+ Default: True Library default-language: Haskell2010
cbits/inputReady.c view
@@ -7,6 +7,9 @@ /* select and supporting types is not Posix */ /* #include "PosixSource.h" */ #include "HsBase.h"+#if !defined(_WIN32)+#include <poll.h>+#endif /* * inputReady(fd) checks to see whether input is available on the file@@ -16,19 +19,41 @@ int fdReady(int fd, int write, int msecs, int isSock) {- if -#if defined(_WIN32)- ( isSock ) {++#if !defined(_WIN32)++ // We only handle msecs == 0 on non-Windows, because this is the+ // only case we need. Non-zero waiting is handled by the IO manager.+ if (msecs != 0) {+ fprintf(stderr, "fdReady: msecs != 0, this shouldn't happen");+ abort();+ }++ struct pollfd fds[1];++ fds[0].fd = fd;+ fds[0].events = write ? POLLOUT : POLLIN;+ fds[0].revents = 0;++ int res;+ while ((res = poll(fds, 1, 0)) < 0) {+ if (errno != EINTR) {+ return (-1);+ }+ }++ // res is the number of FDs with events+ return (res > 0);+ #else- ( 1 ) {-#endif++ if (isSock) { int maxfd, ready; fd_set rfd, wfd; struct timeval tv; if ((fd >= (int)FD_SETSIZE) || (fd < 0)) {- /* avoid memory corruption on too large FDs */- errno = EINVAL;- return -1;+ fprintf(stderr, "fdReady: fd is too big");+ abort(); } FD_ZERO(&rfd); FD_ZERO(&wfd);@@ -54,7 +79,6 @@ /* 1 => Input ready, 0 => not ready, -1 => error */ return (ready); }-#if defined(_WIN32) else { DWORD rc; HANDLE hFile = (HANDLE)_get_osfhandle(fd);
changelog.md view
@@ -1,5 +1,13 @@ # Changelog for [`base` package](http://hackage.haskell.org/package/base) +## 4.9.1.0 *Jan 2017*++ * Bundled with GHC 8.0.2++ * Performance improvements in `Read` implementation++ * Teach event manager to use poll instead of select (#12912)+ ## 4.9.0.0 *May 2016* * Bundled with GHC 8.0