on master help sign in
Data/Text.hs+10−7
since splitsnapshots
unifiedsplit
@@ -238,6 +238,7 @@ import Data.ByteString (ByteString)
238import qualified Data.Text.Lazy as L
238import qualified Data.Text.Lazy as L
239import Data.Int (Int64)
239import Data.Int (Int64)
240#endif
240#endif
241+import GHC.Base (eqInt, neInt, gtInt, geInt, ltInt, leInt)
241#if __GLASGOW_HASKELL__ >= 708
242#if __GLASGOW_HASKELL__ >= 708
242import qualified GHC.Exts as Exts
243import qualified GHC.Exts as Exts
243#endif
244#endif
@@ -571,7 +572,9 @@ isSingleton = S.isSingleton . stream
571-- Subject to fusion.
572-- Subject to fusion.
572length :: Text -> Int
573length :: Text -> Int
573length t = S.length (stream t)
574length t = S.length (stream t)
574−{-# INLINE length #-}
575+{-# INLINE [0] length #-}
576+-- length needs to be phased after the compareN/length rules otherwise
577+-- it may inline before the rules have an opportunity to fire.
575
578
576-- | /O(n)/ Compare the count of characters in a 'Text' to a number.
579-- | /O(n)/ Compare the count of characters in a 'Text' to a number.
577-- Subject to fusion.
580-- Subject to fusion.
@@ -590,32 +593,32 @@ compareLength t n = S.compareLengthI (stream t) n
590
593
591{-# RULES
594{-# RULES
592"TEXT ==N/length -> compareLength/==EQ" [~1] forall t n.
595"TEXT ==N/length -> compareLength/==EQ" [~1] forall t n.
593− (==) (length t) n = compareLength t n == EQ
596+ eqInt (length t) n = compareLength t n == EQ
594 #-}
597 #-}
595
598
596{-# RULES
599{-# RULES
597"TEXT /=N/length -> compareLength//=EQ" [~1] forall t n.
600"TEXT /=N/length -> compareLength//=EQ" [~1] forall t n.
598− (/=) (length t) n = compareLength t n /= EQ
601+ neInt (length t) n = compareLength t n /= EQ
599 #-}
602 #-}
600
603
601{-# RULES
604{-# RULES
602"TEXT <N/length -> compareLength/==LT" [~1] forall t n.
605"TEXT <N/length -> compareLength/==LT" [~1] forall t n.
603− (<) (length t) n = compareLength t n == LT
606+ ltInt (length t) n = compareLength t n == LT
604 #-}
607 #-}
605
608
606{-# RULES
609{-# RULES
607"TEXT <=N/length -> compareLength//=GT" [~1] forall t n.
610"TEXT <=N/length -> compareLength//=GT" [~1] forall t n.
608− (<=) (length t) n = compareLength t n /= GT
611+ leInt (length t) n = compareLength t n /= GT
609 #-}
612 #-}
610
613
611{-# RULES
614{-# RULES
612"TEXT >N/length -> compareLength/==GT" [~1] forall t n.
615"TEXT >N/length -> compareLength/==GT" [~1] forall t n.
613− (>) (length t) n = compareLength t n == GT
616+ gtInt (length t) n = compareLength t n == GT
614 #-}
617 #-}
615
618
616{-# RULES
619{-# RULES
617"TEXT >=N/length -> compareLength//=LT" [~1] forall t n.
620"TEXT >=N/length -> compareLength//=LT" [~1] forall t n.
618− (>=) (length t) n = compareLength t n /= LT
621+ geInt (length t) n = compareLength t n /= LT
619 #-}
622 #-}
620
623
621-- -----------------------------------------------------------------------------
624-- -----------------------------------------------------------------------------
Data/Text/Array.hs+1−1
@@ -20,7 +20,7 @@
20-- > import qualified Data.Text.Array as A
20-- > import qualified Data.Text.Array as A
21--
21--
22-- The names in this module resemble those in the 'Data.Array' family
22-- The names in this module resemble those in the 'Data.Array' family
23−-- of modules, but are shorter due to the assumption of qualifid
23+-- of modules, but are shorter due to the assumption of qualified
24-- naming.
24-- naming.
25module Data.Text.Array
25module Data.Text.Array
26 (
26 (
Data/Text/Encoding.hs+7−18
@@ -55,13 +55,9 @@ module Data.Text.Encoding
55 , encodeUtf32LE
55 , encodeUtf32LE
56 , encodeUtf32BE
56 , encodeUtf32BE
57
57
58−#if MIN_VERSION_bytestring(0,10,4)
59 -- * Encoding Text using ByteString Builders
58 -- * Encoding Text using ByteString Builders
60− -- | /Note/ that these functions are only available if built against
61− -- @bytestring >= 0.10.4.0@.
62 , encodeUtf8Builder
59 , encodeUtf8Builder
63 , encodeUtf8BuilderEscaped
60 , encodeUtf8BuilderEscaped
64−#endif
65 ) where
61 ) where
66
62
67#if __GLASGOW_HASKELL__ >= 702
63#if __GLASGOW_HASKELL__ >= 702
@@ -70,24 +66,15 @@ import Control.Monad.ST.Unsafe (unsafeIOToST, unsafeSTToIO)
70import Control.Monad.ST (unsafeIOToST, unsafeSTToIO)
66import Control.Monad.ST (unsafeIOToST, unsafeSTToIO)
71#endif
67#endif
72
68
73−#if MIN_VERSION_bytestring(0,10,4)
74−import Data.Bits ((.&.))
75−import Data.Text.Internal.Unsafe.Char (ord)
76−import qualified Data.ByteString.Builder as B
77−import qualified Data.ByteString.Builder.Internal as B hiding (empty, append)
78−import qualified Data.ByteString.Builder.Prim as BP
79−import qualified Data.ByteString.Builder.Prim.Internal as BP
80−import qualified Data.Text.Internal.Encoding.Utf16 as U16
81−#endif
82−
83import Control.Exception (evaluate, try)
69import Control.Exception (evaluate, try)
84import Control.Monad.ST (runST)
70import Control.Monad.ST (runST)
71+import Data.Bits ((.&.))
85import Data.ByteString as B
72import Data.ByteString as B
86import Data.ByteString.Internal as B hiding (c2w)
73import Data.ByteString.Internal as B hiding (c2w)
87import Data.Text.Encoding.Error (OnDecodeError, UnicodeException, strictDecode)
74import Data.Text.Encoding.Error (OnDecodeError, UnicodeException, strictDecode)
88import Data.Text.Internal (Text(..), safe, text)
75import Data.Text.Internal (Text(..), safe, text)
89import Data.Text.Internal.Private (runText)
76import Data.Text.Internal.Private (runText)
90−import Data.Text.Internal.Unsafe.Char (unsafeWrite)
77+import Data.Text.Internal.Unsafe.Char (ord, unsafeWrite)
91import Data.Text.Internal.Unsafe.Shift (shiftR)
78import Data.Text.Internal.Unsafe.Shift (shiftR)
92import Data.Text.Show ()
79import Data.Text.Show ()
93import Data.Text.Unsafe (unsafeDupablePerformIO)
80import Data.Text.Unsafe (unsafeDupablePerformIO)
@@ -98,8 +85,13 @@ import Foreign.Marshal.Utils (with)
98import Foreign.Ptr (Ptr, minusPtr, nullPtr, plusPtr)
85import Foreign.Ptr (Ptr, minusPtr, nullPtr, plusPtr)
99import Foreign.Storable (Storable, peek, poke)
86import Foreign.Storable (Storable, peek, poke)
100import GHC.Base (ByteArray#, MutableByteArray#)
87import GHC.Base (ByteArray#, MutableByteArray#)
88+import qualified Data.ByteString.Builder as B
89+import qualified Data.ByteString.Builder.Internal as B hiding (empty, append)
90+import qualified Data.ByteString.Builder.Prim as BP
91+import qualified Data.ByteString.Builder.Prim.Internal as BP
101import qualified Data.Text.Array as A
92import qualified Data.Text.Array as A
102import qualified Data.Text.Internal.Encoding.Fusion as E
93import qualified Data.Text.Internal.Encoding.Fusion as E
94+import qualified Data.Text.Internal.Encoding.Utf16 as U16
103import qualified Data.Text.Internal.Fusion as F
95import qualified Data.Text.Internal.Fusion as F
104
96
105#include "text_cbits.h"
97#include "text_cbits.h"
@@ -315,8 +307,6 @@ decodeUtf8' :: ByteString -> Either UnicodeException Text
315decodeUtf8' = unsafeDupablePerformIO . try . evaluate . decodeUtf8With strictDecode
307decodeUtf8' = unsafeDupablePerformIO . try . evaluate . decodeUtf8With strictDecode
316{-# INLINE decodeUtf8' #-}
308{-# INLINE decodeUtf8' #-}
317
309
318−#if MIN_VERSION_bytestring(0,10,4)
319−
320-- | Encode text to a ByteString 'B.Builder' using UTF-8 encoding.
310-- | Encode text to a ByteString 'B.Builder' using UTF-8 encoding.
321encodeUtf8Builder :: Text -> B.Builder
311encodeUtf8Builder :: Text -> B.Builder
322encodeUtf8Builder = encodeUtf8BuilderEscaped (BP.liftFixedToBounded BP.word8)
312encodeUtf8Builder = encodeUtf8BuilderEscaped (BP.liftFixedToBounded BP.word8)
@@ -377,7 +367,6 @@ encodeUtf8BuilderEscaped be =
377 outerLoop i (B.BufferRange op ope)
367 outerLoop i (B.BufferRange op ope)
378 where
368 where
379 poke8 j v = poke (op `plusPtr` j) (fromIntegral v :: Word8)
369 poke8 j v = poke (op `plusPtr` j) (fromIntegral v :: Word8)
380−#endif
381
370
382-- | Encode text using UTF-8 encoding.
371-- | Encode text using UTF-8 encoding.
383encodeUtf8 :: Text -> ByteString
372encodeUtf8 :: Text -> ByteString
Data/Text/Internal/Builder.hs+2
@@ -242,6 +242,8 @@ flush = Builder $ \ k buf@(Buffer p o u l) ->
242 !t = Text arr o u
242 !t = Text arr o u
243 ts <- inlineInterleaveST (k b)
243 ts <- inlineInterleaveST (k b)
244 return $! t : ts
244 return $! t : ts
245+{-# INLINE [1] flush #-}
246+-- defer inlining so that flush/flush rule may fire.
245
247
246------------------------------------------------------------------------
248------------------------------------------------------------------------
247
249
Data/Text/Internal/Fusion.hs+27−17
@@ -98,25 +98,35 @@ reverseStream (Text arr off len) = Stream next (off+len-1) (betweenSize (len `sh
98-- | /O(n)/ Convert a 'Stream Char' into a 'Text'.
98-- | /O(n)/ Convert a 'Stream Char' into a 'Text'.
99unstream :: Stream Char -> Text
99unstream :: Stream Char -> Text
100unstream (Stream next0 s0 len) = runText $ \done -> do
100unstream (Stream next0 s0 len) = runText $ \done -> do
101+ -- Before encoding each char we perform a buffer realloc check assuming
102+ -- worst case encoding size of two 16-bit units for the char. Just add an
103+ -- extra space to the buffer so that we do not end up reallocating even when
104+ -- all the chars are encoded as single unit.
101− let mlen = upperBound 4 len
105+ let mlen = upperBound 4 len + 1
102 arr0 <- A.new mlen
106 arr0 <- A.new mlen
103− let outer arr top = loop
107+ let outer !arr !maxi = encode
104 where
108 where
105− loop !s !i =
109+ -- keep the common case loop as small as possible
110+ encode !si !di =
106− case next0 s of
111+ case next0 si of
107− Done -> done arr i
112+ Done -> done arr di
108− Skip s' -> loop s' i
113+ Skip si' -> encode si' di
109− Yield x s'
114+ Yield c si'
110− | j >= top -> {-# SCC "unstream/resize" #-} do
115+ -- simply check for the worst case
111− let top' = (top + 1) `shiftL` 1
116+ | maxi < di + 1 -> realloc si di
117+ | otherwise -> do
118+ n <- unsafeWrite arr di c
119+ encode si' (di + n)
120+
121+ -- keep uncommon case separate from the common case code
122+ {-# NOINLINE realloc #-}
123+ realloc !si !di = do
124+ let newlen = (maxi + 1) * 2
112− arr' <- A.new top'
125+ arr' <- A.new newlen
113− A.copyM arr' 0 arr 0 top
126+ A.copyM arr' 0 arr 0 di
114− outer arr' top' s i
127+ outer arr' (newlen - 1) si di
115− | otherwise -> do d <- unsafeWrite arr i x
128+
116− loop s' (i+d)
117− where j | ord x < 0x10000 = i
118− | otherwise = i + 1
119− outer arr0 mlen s0 0
129+ outer arr0 (mlen - 1) s0 0
120{-# INLINE [0] unstream #-}
130{-# INLINE [0] unstream #-}
121{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}
131{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}
122
132
Data/Text/Internal/Fusion/Common.hs+3−3
@@ -669,12 +669,12 @@ scanl f z0 (Stream next0 s0 len) = Stream next (Scan1 z0 s0) (len+1) -- HINT may
669-- ** Generating and unfolding streams
669-- ** Generating and unfolding streams
670
670
671replicateCharI :: Integral a => a -> Char -> Stream Char
671replicateCharI :: Integral a => a -> Char -> Stream Char
672−replicateCharI n c
672+replicateCharI !n !c
673 | n < 0 = empty
673 | n < 0 = empty
674 | otherwise = Stream next 0 (fromIntegral n) -- HINT maybe too low
674 | otherwise = Stream next 0 (fromIntegral n) -- HINT maybe too low
675 where
675 where
676− next i | i >= n = Done
676+ next !i | i >= n = Done
677− | otherwise = Yield c (i + 1)
677+ | otherwise = Yield c (i + 1)
678{-# INLINE [0] replicateCharI #-}
678{-# INLINE [0] replicateCharI #-}
679
679
680data RI s = RI !s {-# UNPACK #-} !Int64
680data RI s = RI !s {-# UNPACK #-} !Int64
Data/Text/Lazy.hs+2−2
@@ -545,7 +545,7 @@ tail Empty = emptyError "tail"
545 unstream (S.tail (stream t)) = tail t
545 unstream (S.tail (stream t)) = tail t
546 #-}
546 #-}
547
547
548−-- | /O(1)/ Returns all but the last character of a 'Text', which must
548+-- | /O(n\/c)/ Returns all but the last character of a 'Text', which must
549-- be non-empty. Subject to fusion.
549-- be non-empty. Subject to fusion.
550init :: Text -> Text
550init :: Text -> Text
551init (Chunk t0 ts0) = go t0 ts0
551init (Chunk t0 ts0) = go t0 ts0
@@ -581,7 +581,7 @@ isSingleton :: Text -> Bool
581isSingleton = S.isSingleton . stream
581isSingleton = S.isSingleton . stream
582{-# INLINE isSingleton #-}
582{-# INLINE isSingleton #-}
583
583
584−-- | /O(1)/ Returns the last character of a 'Text', which must be
584+-- | /O(n\/c)/ Returns the last character of a 'Text', which must be
585-- non-empty. Subject to fusion.
585-- non-empty. Subject to fusion.
586last :: Text -> Char
586last :: Text -> Char
587last Empty = emptyError "last"
587last Empty = emptyError "last"
Data/Text/Lazy/Encoding.hs+5−15
@@ -46,27 +46,23 @@ module Data.Text.Lazy.Encoding
46 , encodeUtf32LE
46 , encodeUtf32LE
47 , encodeUtf32BE
47 , encodeUtf32BE
48
48
49−#if MIN_VERSION_bytestring(0,10,4)
50 -- * Encoding Text using ByteString Builders
49 -- * Encoding Text using ByteString Builders
51 , encodeUtf8Builder
50 , encodeUtf8Builder
52 , encodeUtf8BuilderEscaped
51 , encodeUtf8BuilderEscaped
53−#endif
54 ) where
52 ) where
55
53
56import Control.Exception (evaluate, try)
54import Control.Exception (evaluate, try)
55+import Data.Monoid (Monoid(..))
57import Data.Text.Encoding.Error (OnDecodeError, UnicodeException, strictDecode)
56import Data.Text.Encoding.Error (OnDecodeError, UnicodeException, strictDecode)
58import Data.Text.Internal.Lazy (Text(..), chunk, empty, foldrChunks)
57import Data.Text.Internal.Lazy (Text(..), chunk, empty, foldrChunks)
59−import qualified Data.ByteString as S
60−import qualified Data.ByteString.Lazy as B
61−import qualified Data.ByteString.Lazy.Internal as B
62−import qualified Data.ByteString.Unsafe as B
63−#if MIN_VERSION_bytestring(0,10,4)
64import Data.Word (Word8)
58import Data.Word (Word8)
65−import Data.Monoid (Monoid(..))
59+import qualified Data.ByteString as S
66import qualified Data.ByteString.Builder as B
60import qualified Data.ByteString.Builder as B
67import qualified Data.ByteString.Builder.Extra as B (safeStrategy, toLazyByteStringWith)
61import qualified Data.ByteString.Builder.Extra as B (safeStrategy, toLazyByteStringWith)
68import qualified Data.ByteString.Builder.Prim as BP
62import qualified Data.ByteString.Builder.Prim as BP
69−#endif
63+import qualified Data.ByteString.Lazy as B
64+import qualified Data.ByteString.Lazy.Internal as B
65+import qualified Data.ByteString.Unsafe as B
70import qualified Data.Text as T
66import qualified Data.Text as T
71import qualified Data.Text.Encoding as TE
67import qualified Data.Text.Encoding as TE
72import qualified Data.Text.Internal.Lazy.Encoding.Fusion as E
68import qualified Data.Text.Internal.Lazy.Encoding.Fusion as E
@@ -146,7 +142,6 @@ decodeUtf8' bs = unsafeDupablePerformIO $ do
146{-# INLINE decodeUtf8' #-}
142{-# INLINE decodeUtf8' #-}
147
143
148encodeUtf8 :: Text -> B.ByteString
144encodeUtf8 :: Text -> B.ByteString
149−#if MIN_VERSION_bytestring(0,10,4)
150encodeUtf8 Empty = B.empty
145encodeUtf8 Empty = B.empty
151encodeUtf8 lt@(Chunk t _) =
146encodeUtf8 lt@(Chunk t _) =
152 B.toLazyByteStringWith strategy B.empty $ encodeUtf8Builder lt
147 B.toLazyByteStringWith strategy B.empty $ encodeUtf8Builder lt
@@ -168,11 +163,6 @@ encodeUtf8BuilderEscaped :: BP.BoundedPrim Word8 -> Text -> B.Builder
168encodeUtf8BuilderEscaped prim =
163encodeUtf8BuilderEscaped prim =
169 foldrChunks (\c b -> TE.encodeUtf8BuilderEscaped prim c `mappend` b) mempty
164 foldrChunks (\c b -> TE.encodeUtf8BuilderEscaped prim c `mappend` b) mempty
170
165
171−#else
172−encodeUtf8 (Chunk c cs) = B.Chunk (TE.encodeUtf8 c) (encodeUtf8 cs)
173−encodeUtf8 Empty = B.Empty
174−#endif
175−
176-- | Decode text from little endian UTF-16 encoding.
166-- | Decode text from little endian UTF-16 encoding.
177decodeUtf16LEWith :: OnDecodeError -> B.ByteString -> Text
167decodeUtf16LEWith :: OnDecodeError -> B.ByteString -> Text
178decodeUtf16LEWith onErr bs = F.unstream (E.streamUtf16LE onErr bs)
168decodeUtf16LEWith onErr bs = F.unstream (E.streamUtf16LE onErr bs)
benchmarks/haskell/Benchmarks.hs+1−1
@@ -53,7 +53,7 @@ benchmarks = do
53 , Mul.benchmark
53 , Mul.benchmark
54 , Pure.benchmark "tiny" (tf "tiny.txt")
54 , Pure.benchmark "tiny" (tf "tiny.txt")
55 , Pure.benchmark "ascii" (tf "ascii-small.txt")
55 , Pure.benchmark "ascii" (tf "ascii-small.txt")
56− , Pure.benchmark "france" (tf "france.html")
56+ -- , Pure.benchmark "france" (tf "france.html")
57 , Pure.benchmark "russian" (tf "russian-small.txt")
57 , Pure.benchmark "russian" (tf "russian-small.txt")
58 , Pure.benchmark "japanese" (tf "japanese.txt")
58 , Pure.benchmark "japanese" (tf "japanese.txt")
59 , ReadNumbers.benchmark (tf "numbers.txt")
59 , ReadNumbers.benchmark (tf "numbers.txt")
benchmarks/haskell/Benchmarks/Stream.hs+16−5
@@ -18,11 +18,11 @@ import qualified Data.Text.Encoding as T
18import qualified Data.Text.Encoding.Error as E
18import qualified Data.Text.Encoding.Error as E
19import qualified Data.Text.Internal.Encoding.Fusion as T
19import qualified Data.Text.Internal.Encoding.Fusion as T
20import qualified Data.Text.Internal.Encoding.Fusion.Common as F
20import qualified Data.Text.Internal.Encoding.Fusion.Common as F
21−import qualified Data.Text.Internal.Fusion as T
21+import qualified Data.Text.Internal.Fusion as F
22import qualified Data.Text.IO as T
22import qualified Data.Text.IO as T
23import qualified Data.Text.Lazy.Encoding as TL
23import qualified Data.Text.Lazy.Encoding as TL
24import qualified Data.Text.Internal.Lazy.Encoding.Fusion as TL
24import qualified Data.Text.Internal.Lazy.Encoding.Fusion as TL
25−import qualified Data.Text.Internal.Lazy.Fusion as TL
25+import qualified Data.Text.Internal.Lazy.Fusion as FL
26import qualified Data.Text.Lazy.IO as TL
26import qualified Data.Text.Lazy.IO as TL
27
27
28instance NFData a => NFData (Stream a) where
28instance NFData a => NFData (Stream a) where
@@ -53,14 +53,25 @@ benchmark fp = do
53 !utf32beL = TL.encodeUtf32BE tl
53 !utf32beL = TL.encodeUtf32BE tl
54
54
55 -- For the functions which operate on streams
55 -- For the functions which operate on streams
56− let !s = T.stream t
56+ let !s = F.stream t
57
57
58 return $ bgroup "Stream"
58 return $ bgroup "Stream"
59
59
60 -- Fusion
60 -- Fusion
61 [ bgroup "stream" $
61 [ bgroup "stream" $
62− [ bench "Text" $ nf T.stream t
62+ [ bench "Text" $ nf F.stream t
63+ , bench "LazyText" $ nf FL.stream tl
64+ ]
65+ -- must perform exactly the same as stream above due to
66+ -- stream/unstream (i.e. stream after unstream) fusion
67+ , bgroup "stream-fusion" $
68+ [ bench "Text" $ nf (F.stream . F.unstream . F.stream) t
63− , bench "LazyText" $ nf TL.stream tl
69+ , bench "LazyText" $ nf (FL.stream . FL.unstream . FL.stream) tl
70+ ]
71+ -- measure the overhead of unstream after stream
72+ , bgroup "stream-unstream" $
73+ [ bench "Text" $ nf (F.unstream . F.stream) t
74+ , bench "LazyText" $ nf (FL.unstream . FL.stream) tl
64 ]
75 ]
65
76
66 -- Encoding.Fusion
77 -- Encoding.Fusion
benchmarks/text-benchmarks.cabal+11−1
@@ -15,6 +15,11 @@ build-type: Simple
15
15
16cabal-version: >=1.2
16cabal-version: >=1.2
17
17
18+flag bytestring-builder
19+ description: Depend on the bytestring-builder package for backwards compatibility.
20+ default: False
21+ manual: False
22+
18flag llvm
23flag llvm
19 description: use LLVM
24 description: use LLVM
20 default: False
25 default: False
@@ -33,7 +38,6 @@ executable text-benchmarks
33 build-depends: base == 4.*,
38 build-depends: base == 4.*,
34 binary,
39 binary,
35 blaze-builder,
40 blaze-builder,
36− bytestring,
37 bytestring-lexing >= 0.5.0,
41 bytestring-lexing >= 0.5.0,
38 containers,
42 containers,
39 criterion >= 0.10.0.0,
43 criterion >= 0.10.0.0,
@@ -46,6 +50,12 @@ executable text-benchmarks
46 utf8-string,
50 utf8-string,
47 vector
51 vector
48
52
53+ if flag(bytestring-builder)
54+ build-depends: bytestring >= 0.9 && < 0.10.4,
55+ bytestring-builder >= 0.10.4
56+ else
57+ build-depends: bytestring >= 0.10.4
58+
49executable text-multilang
59executable text-multilang
50 hs-source-dirs: haskell
60 hs-source-dirs: haskell
51 main-is: Multilang.hs
61 main-is: Multilang.hs
tests/literal-rule-test.sh+1−1
@@ -6,7 +6,7 @@ function check_firings() {
6 rule=$1
6 rule=$1
7 expected=$2
7 expected=$2
8 build="ghc -O -ddump-rule-firings LiteralRuleTest.hs"
8 build="ghc -O -ddump-rule-firings LiteralRuleTest.hs"
9− build="$build -i.. -I../include -DMIN_VERSION_bytestring(a,b,c)=1"
9+ build="$build -i.. -I../include"
10 touch LiteralRuleTest.hs
10 touch LiteralRuleTest.hs
11 echo -n "Want to see $expected firings of rule $rule... " >&2
11 echo -n "Want to see $expected firings of rule $rule... " >&2
12 firings=$($build 2>&1 | grep "Rule fired: $rule\$" | wc -l)
12 firings=$($build 2>&1 | grep "Rule fired: $rule\$" | wc -l)
text.cabal+15−4
@@ -64,6 +64,11 @@ extra-source-files:
64 tests/scripts/*.sh
64 tests/scripts/*.sh
65 tests/text-tests.cabal
65 tests/text-tests.cabal
66
66
67+flag bytestring-builder
68+ description: Depend on the bytestring-builder package for backwards compatibility.
69+ default: False
70+ manual: False
71+
67flag developer
72flag developer
68 description: operate in developer mode
73 description: operate in developer mode
69 default: False
74 default: False
@@ -133,10 +138,11 @@ library
133 deepseq >= 1.1.0.0,
138 deepseq >= 1.1.0.0,
134 ghc-prim >= 0.2
139 ghc-prim >= 0.2
135
140
136− if impl(ghc >= 7.7)
141+ if flag(bytestring-builder)
137− build-depends: bytestring >= 0.10.4.0
142+ build-depends: bytestring >= 0.9 && < 0.10.4,
143+ bytestring-builder >= 0.10.4
138 else
144 else
139− build-depends: bytestring >= 0.9
145+ build-depends: bytestring >= 0.10.4
140
146
141 cpp-options: -DHAVE_DEEPSEQ
147 cpp-options: -DHAVE_DEEPSEQ
142 ghc-options: -Wall -fwarn-tabs -funbox-strict-fields -O2
148 ghc-options: -Wall -fwarn-tabs -funbox-strict-fields -O2
@@ -171,7 +177,6 @@ test-suite tests
171 array,
177 array,
172 base,
178 base,
173 binary,
179 binary,
174− bytestring,
175 deepseq,
180 deepseq,
176 directory,
181 directory,
177 ghc-prim,
182 ghc-prim,
@@ -181,6 +186,12 @@ test-suite tests
181 test-framework-hunit >= 0.2,
186 test-framework-hunit >= 0.2,
182 test-framework-quickcheck2 >= 0.2
187 test-framework-quickcheck2 >= 0.2
183
188
189+ if flag(bytestring-builder)
190+ build-depends: bytestring >= 0.9 && < 0.10.4,
191+ bytestring-builder >= 0.10.4
192+ else
193+ build-depends: bytestring >= 0.10.4
194+
184 if flag(integer-simple)
195 if flag(integer-simple)
185 cpp-options: -DINTEGER_SIMPLE
196 cpp-options: -DINTEGER_SIMPLE
186 build-depends: integer-simple >= 0.1 && < 0.5
197 build-depends: integer-simple >= 0.1 && < 0.5