Hello community,

here is the log from the commit of package ghc-attoparsec for openSUSE:Factory 
checked in at 2016-01-08 15:22:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-attoparsec (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-attoparsec.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-attoparsec"

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-attoparsec/ghc-attoparsec.changes    
2015-05-21 08:12:45.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.ghc-attoparsec.new/ghc-attoparsec.changes       
2016-01-08 15:22:39.000000000 +0100
@@ -1,0 +2,7 @@
+Mon Sep 28 18:29:13 UTC 2015 - mimi...@gmail.com
+
+- update to 0.13.0.1
+* Fixed a bug in the implementations of inClass and notInClass for Text
+* Made the parser type in the Zepto module a monad transformer.
+
+-------------------------------------------------------------------

Old:
----
  attoparsec-0.12.1.6.tar.gz

New:
----
  attoparsec-0.13.0.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-attoparsec.spec ++++++
--- /var/tmp/diff_new_pack.ukkIEd/_old  2016-01-08 15:22:40.000000000 +0100
+++ /var/tmp/diff_new_pack.ukkIEd/_new  2016-01-08 15:22:40.000000000 +0100
@@ -21,7 +21,7 @@
 %bcond_with tests
 
 Name:           ghc-%{pkg_name}
-Version:        0.12.1.6
+Version:        0.13.0.1
 Release:        0
 Summary:        Fast combinator parsing for bytestrings and text
 License:        BSD-3-Clause
@@ -40,6 +40,7 @@
 BuildRequires:  ghc-deepseq-devel
 BuildRequires:  ghc-scientific-devel
 BuildRequires:  ghc-text-devel
+BuildRequires:  ghc-transformers-devel
 %if %{with tests}
 BuildRequires:  ghc-QuickCheck-devel
 BuildRequires:  ghc-quickcheck-unicode-devel

++++++ attoparsec-0.12.1.6.tar.gz -> attoparsec-0.13.0.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/attoparsec-0.12.1.6/Data/Attoparsec/ByteString/Char8.hs 
new/attoparsec-0.13.0.1/Data/Attoparsec/ByteString/Char8.hs
--- old/attoparsec-0.12.1.6/Data/Attoparsec/ByteString/Char8.hs 2015-04-05 
21:51:22.000000000 +0200
+++ new/attoparsec-0.13.0.1/Data/Attoparsec/ByteString/Char8.hs 2015-07-09 
02:08:52.000000000 +0200
@@ -444,9 +444,8 @@
 
 -- | Parse and decode an unsigned decimal number.
 decimal :: Integral a => Parser a
-decimal = B8.foldl' step 0 `fmap` I.takeWhile1 isDig
-  where isDig w  = w >= 48 && w <= 57
-        step a w = a * 10 + fromIntegral (w - 48)
+decimal = B8.foldl' step 0 `fmap` I.takeWhile1 isDigit_w8
+  where step a w = a * 10 + fromIntegral (w - 48)
 {-# SPECIALISE decimal :: Parser Int #-}
 {-# SPECIALISE decimal :: Parser Int8 #-}
 {-# SPECIALISE decimal :: Parser Int16 #-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/attoparsec-0.12.1.6/Data/Attoparsec/ByteString.hs 
new/attoparsec-0.13.0.1/Data/Attoparsec/ByteString.hs
--- old/attoparsec-0.12.1.6/Data/Attoparsec/ByteString.hs       2015-04-05 
21:51:22.000000000 +0200
+++ new/attoparsec-0.13.0.1/Data/Attoparsec/ByteString.hs       2015-07-09 
02:08:52.000000000 +0200
@@ -63,6 +63,7 @@
     , I.skipWhile
     , I.take
     , I.scan
+    , I.runScanner
     , I.takeWhile
     , I.takeWhile1
     , I.takeTill
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/attoparsec-0.12.1.6/Data/Attoparsec/Text/FastSet.hs 
new/attoparsec-0.13.0.1/Data/Attoparsec/Text/FastSet.hs
--- old/attoparsec-0.12.1.6/Data/Attoparsec/Text/FastSet.hs     2015-04-05 
21:51:22.000000000 +0200
+++ new/attoparsec-0.13.0.1/Data/Attoparsec/Text/FastSet.hs     2015-07-09 
02:08:52.000000000 +0200
@@ -1,116 +1,38 @@
-{-# LANGUAGE BangPatterns #-}
-
-------------------------------------------------------------------------------
 -- |
--- Module      :  Data.Attoparsec.FastSet
--- Copyright   :  Felipe Lessa 2010, Bryan O'Sullivan 2007-2015
+-- Module      :  Data.Attoparsec.Text.FastSet
+-- Copyright   :  Bryan O'Sullivan 2015
 -- License     :  BSD3
 --
--- Maintainer  :  felipe.le...@gmail.com
+-- Maintainer  :  b...@serpentine.com
 -- Stability   :  experimental
 -- Portability :  unknown
 --
--- Fast set membership tests for 'Char' values. We test for
--- membership using a hashtable implemented with Robin Hood
--- collision resolution. The set representation is unboxed,
--- and the characters and hashes interleaved, for efficiency.
---
---
------------------------------------------------------------------------------
+-- Fast set membership tests for 'Char' values.
+
 module Data.Attoparsec.Text.FastSet
     (
     -- * Data type
       FastSet
     -- * Construction
     , fromList
-    , set
     -- * Lookup
     , member
     -- * Handy interface
     , charClass
     ) where
 
-import Data.Bits ((.|.), (.&.), shiftR)
-import Data.Function (on)
-import Data.List (sort, sortBy)
-import qualified Data.Array.Base as AB
-import qualified Data.Array.Unboxed as A
-import qualified Data.Text as T
-
-data FastSet = FastSet {
-    table :: {-# UNPACK #-} !(A.UArray Int Int)
-  , mask  :: {-# UNPACK #-} !Int
-  }
-
-data Entry = Entry {
-    key          :: {-# UNPACK #-} !Char
-  , initialIndex :: {-# UNPACK #-} !Int
-  , index        :: {-# UNPACK #-} !Int
-  }
-
-offset :: Entry -> Int
-offset e = index e - initialIndex e
-
-resolveCollisions :: [Entry] -> [Entry]
-resolveCollisions [] = []
-resolveCollisions [e] = [e]
-resolveCollisions (a:b:entries) = a' : resolveCollisions (b' : entries)
-  where (a', b')
-          | index a < index b   = (a, b)
-          | offset a < offset b = (b { index=index a }, a { index=index a + 1 
})
-          | otherwise           = (a, b { index=index a + 1 })
-
-pad :: Int -> [Entry] -> [Entry]
-pad = go 0
-  where go !_ !m []          = replicate (max 1 m) empty
-        go  k  m (e:entries) = map (const empty) [k..i - 1] ++ e :
-                               go (i + 1) (m + i - k - 1) entries
-          where i            = index e
-        empty                = Entry '\0' maxBound 0
-
-nextPowerOf2 :: Int -> Int
-nextPowerOf2 0  = 1
-nextPowerOf2 x  = go (x - 1) 1
-  where go y 32 = y + 1
-        go y k  = go (y .|. (y `shiftR` k)) $ k * 2
+import qualified Data.IntSet as I
+import Data.Char (ord)
 
-fastHash :: Char -> Int
-fastHash = fromEnum
+newtype FastSet = FastSet I.IntSet
 
 fromList :: String -> FastSet
-fromList s = FastSet (AB.listArray (0, length interleaved - 1) interleaved)
-             mask'
-  where s'      = ordNub (sort s)
-        l       = length s'
-        mask'   = nextPowerOf2 ((5 * l) `div` 4) - 1
-        entries = pad mask' .
-                  resolveCollisions .
-                  sortBy (compare `on` initialIndex) .
-                  zipWith (\c i -> Entry c i i) s' .
-                  map ((.&. mask') . fastHash) $ s'
-        interleaved = concatMap (\e -> [fromEnum $ key e, initialIndex e])
-                      entries
-
-ordNub :: Eq a => [a] -> [a]
-ordNub []     = []
-ordNub (y:ys) = go y ys
-  where go x (z:zs)
-          | x == z    = go x zs
-          | otherwise = x : go z zs
-        go x []       = [x]
-
-set :: T.Text -> FastSet
-set = fromList . T.unpack
+fromList = FastSet . I.fromList . map ord
 
 -- | Check the set for membership.
 member :: Char -> FastSet -> Bool
-member c a           = go (2 * i)
-  where i            = fastHash c .&. mask a
-        lookupAt j b = (i' <= i) && (c == c' || b)
-            where c' = toEnum $ AB.unsafeAt (table a) j
-                  i' = AB.unsafeAt (table a) $ j + 1
-        go j         = lookupAt j . lookupAt (j + 2) . lookupAt (j + 4) .
-                       lookupAt (j + 6) . go $ j + 8
+member c (FastSet s) = I.member (ord c) s
+{-# INLINE member #-}
 
 charClass :: String -> FastSet
 charClass = fromList . go
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/attoparsec-0.12.1.6/Data/Attoparsec/Text.hs 
new/attoparsec-0.13.0.1/Data/Attoparsec/Text.hs
--- old/attoparsec-0.12.1.6/Data/Attoparsec/Text.hs     2015-04-05 
21:51:22.000000000 +0200
+++ new/attoparsec-0.13.0.1/Data/Attoparsec/Text.hs     2015-07-09 
02:08:52.000000000 +0200
@@ -72,6 +72,7 @@
     , skipSpace
     , I.skipWhile
     , I.scan
+    , I.runScanner
     , I.take
     , I.takeWhile
     , I.takeWhile1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/attoparsec-0.12.1.6/Data/Attoparsec/Zepto.hs 
new/attoparsec-0.13.0.1/Data/Attoparsec/Zepto.hs
--- old/attoparsec-0.12.1.6/Data/Attoparsec/Zepto.hs    2015-04-05 
21:51:22.000000000 +0200
+++ new/attoparsec-0.13.0.1/Data/Attoparsec/Zepto.hs    2015-07-09 
02:08:52.000000000 +0200
@@ -2,7 +2,7 @@
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Trustworthy #-} -- Data.ByteString.Unsafe
 #endif
-{-# LANGUAGE BangPatterns, MagicHash, UnboxedTuples #-}
+{-# LANGUAGE BangPatterns #-}
 
 -- |
 -- Module      :  Data.Attoparsec.Zepto
@@ -27,101 +27,130 @@
 module Data.Attoparsec.Zepto
     (
       Parser
+    , ZeptoT
     , parse
+    , parseT
     , atEnd
     , string
     , take
     , takeWhile
     ) where
 
-import Data.Word (Word8)
 import Control.Applicative
-import Control.Monad
-import Data.Monoid
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Unsafe as B
+import Control.Monad (MonadPlus(..), ap)
+import Control.Monad.IO.Class (MonadIO(..))
 import Data.ByteString (ByteString)
+import Data.Functor.Identity (Identity(runIdentity))
+import Data.Word (Word8)
 import Prelude hiding (take, takeWhile)
+import qualified Data.ByteString as B
+import qualified Data.ByteString.Unsafe as B
+
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (Monoid(..))
+#endif
 
 newtype S = S {
       input :: ByteString
     }
 
 data Result a = Fail String
-              | OK !a
+              | OK !a S
 
 -- | A simple parser.
 --
 -- This monad is strict in its state, and the monadic bind operator
 -- ('>>=') evaluates each result to weak head normal form before
 -- passing it along.
-newtype Parser a = Parser {
-      runParser :: S -> (# Result a, S #)
+newtype ZeptoT m a = Parser {
+      runParser :: S -> m (Result a)
     }
 
-instance Functor Parser where
-    fmap f m = Parser $ \s -> case runParser m s of
-                                (# OK a, s' #)     -> (# OK (f a), s' #)
-                                (# Fail err, s' #) -> (# Fail err, s' #)
+type Parser a = ZeptoT Identity a
+
+instance Monad m => Functor (ZeptoT m) where
+    fmap f m = Parser $ \s -> do
+      result <- runParser m s
+      case result of
+        OK a s'  -> return (OK (f a) s')
+        Fail err -> return (Fail err)
     {-# INLINE fmap #-}
 
-instance Monad Parser where
-    return a = Parser $ \s -> (# OK a, s #)
+instance MonadIO m => MonadIO (ZeptoT m) where
+  liftIO act = Parser $ \s -> do
+    result <- liftIO act
+    return (OK result s)
+  {-# INLINE liftIO #-}
+
+instance Monad m => Monad (ZeptoT m) where
+    return a = Parser $ \s -> return (OK a s)
     {-# INLINE return #-}
 
-    m >>= k   = Parser $ \s -> case runParser m s of
-                                 (# OK a, s' #) -> runParser (k a) s'
-                                 (# Fail err, s' #) -> (# Fail err, s' #)
+    m >>= k   = Parser $ \s -> do
+      result <- runParser m s
+      case result of
+        OK a s'  -> runParser (k a) s'
+        Fail err -> return (Fail err)
     {-# INLINE (>>=) #-}
 
-    fail msg = Parser $ \s -> (# Fail msg, s #)
+    fail msg = Parser $ \_ -> return (Fail msg)
+    {-# INLINE fail #-}
 
-instance MonadPlus Parser where
+instance Monad m => MonadPlus (ZeptoT m) where
     mzero = fail "mzero"
     {-# INLINE mzero #-}
 
-    mplus a b = Parser $ \s ->
-                case runParser a s of
-                  (# ok@(OK _), s' #) -> (# ok, s' #)
-                  (# _, _ #) -> case runParser b s of
-                                   (# ok@(OK _), s'' #) -> (# ok, s'' #)
-                                   (# err, s'' #) -> (# err, s'' #)
+    mplus a b = Parser $ \s -> do
+      result <- runParser a s
+      case result of
+        ok@(OK _ _) -> return ok
+        _           -> runParser b s
     {-# INLINE mplus #-}
 
-instance Applicative Parser where
+instance (Monad m) => Applicative (ZeptoT m) where
     pure   = return
     {-# INLINE pure #-}
     (<*>)  = ap
     {-# INLINE (<*>) #-}
 
-gets :: (S -> a) -> Parser a
-gets f = Parser $ \s -> (# OK (f s), s #)
+gets :: Monad m => (S -> a) -> ZeptoT m a
+gets f = Parser $ \s -> return (OK (f s) s)
 {-# INLINE gets #-}
 
-put :: S -> Parser ()
-put s = Parser $ \_ -> (# OK (), s #)
+put :: Monad m => S -> ZeptoT m ()
+put s = Parser $ \_ -> return (OK () s)
 {-# INLINE put #-}
 
 -- | Run a parser.
 parse :: Parser a -> ByteString -> Either String a
-parse p bs = case runParser p (S bs) of
-               (# OK a, _ #) -> Right a
-               (# Fail err, _ #) -> Left err
+parse p bs = case runIdentity (runParser p (S bs)) of
+               (OK a _)   -> Right a
+               (Fail err) -> Left err
+{-# INLINE parse #-}
+
+-- | Run a parser on top of the given base monad.
+parseT :: Monad m => ZeptoT m a -> ByteString -> m (Either String a)
+parseT p bs = do
+  result <- runParser p (S bs)
+  case result of
+    OK a _   -> return (Right a)
+    Fail err -> return (Left err)
+{-# INLINE parseT #-}
 
-instance Monoid (Parser a) where
+instance Monad m => Monoid (ZeptoT m a) where
     mempty  = fail "mempty"
     {-# INLINE mempty #-}
     mappend = mplus
     {-# INLINE mappend #-}
 
-instance Alternative Parser where
+instance Monad m => Alternative (ZeptoT m) where
     empty = fail "empty"
     {-# INLINE empty #-}
     (<|>) = mplus
     {-# INLINE (<|>) #-}
 
 -- | Consume input while the predicate returns 'True'.
-takeWhile :: (Word8 -> Bool) -> Parser ByteString
+takeWhile :: Monad m => (Word8 -> Bool) -> ZeptoT m ByteString
 takeWhile p = do
   (h,t) <- gets (B.span p . input)
   put (S t)
@@ -129,7 +158,7 @@
 {-# INLINE takeWhile #-}
 
 -- | Consume @n@ bytes of input.
-take :: Int -> Parser ByteString
+take :: Monad m => Int -> ZeptoT m ByteString
 take !n = do
   s <- gets input
   if B.length s >= n
@@ -138,7 +167,7 @@
 {-# INLINE take #-}
 
 -- | Match a string exactly.
-string :: ByteString -> Parser ()
+string :: Monad m => ByteString -> ZeptoT m ()
 string s = do
   i <- gets input
   if s `B.isPrefixOf` i
@@ -147,7 +176,7 @@
 {-# INLINE string #-}
 
 -- | Indicate whether the end of the input has been reached.
-atEnd :: Parser Bool
+atEnd :: Monad m => ZeptoT m Bool
 atEnd = do
   i <- gets input
   return $! B.null i
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/attoparsec-0.12.1.6/attoparsec.cabal 
new/attoparsec-0.13.0.1/attoparsec.cabal
--- old/attoparsec-0.12.1.6/attoparsec.cabal    2015-04-05 21:51:22.000000000 
+0200
+++ new/attoparsec-0.13.0.1/attoparsec.cabal    2015-07-09 02:08:52.000000000 
+0200
@@ -1,5 +1,5 @@
 name:            attoparsec
-version:         0.12.1.6
+version:         0.13.0.1
 license:         BSD3
 license-file:    LICENSE
 category:        Text, Parsing
@@ -43,6 +43,7 @@
                  containers,
                  deepseq,
                  scientific >= 0.3.1 && < 0.4,
+                 transformers,
                  text >= 1.1.1.3
   if impl(ghc < 7.4)
     build-depends:
@@ -99,6 +100,7 @@
     array,
     base >= 4 && < 5,
     bytestring,
+    containers,
     deepseq >= 1.1,
     QuickCheck >= 2.7,
     quickcheck-unicode,
@@ -106,6 +108,7 @@
     test-framework >= 0.8.0.2,
     test-framework-quickcheck2 >= 0.3.0.3,
     text,
+    transformers,
     vector
 
 benchmark benchmarks
@@ -120,6 +123,8 @@
     HeadersText
     Links
     Numbers
+    Sets
+    TextFastSet
     Warp
   ghc-options: -O2 -Wall
 
@@ -131,6 +136,7 @@
     base == 4.*,
     bytestring >= 0.10.4.0,
     case-insensitive,
+    containers,
     criterion >= 1.0,
     deepseq >= 1.1,
     directory,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/attoparsec-0.12.1.6/benchmarks/Benchmarks.hs 
new/attoparsec-0.13.0.1/benchmarks/Benchmarks.hs
--- old/attoparsec-0.12.1.6/benchmarks/Benchmarks.hs    2015-04-05 
21:51:22.000000000 +0200
+++ new/attoparsec-0.13.0.1/benchmarks/Benchmarks.hs    2015-07-09 
02:08:52.000000000 +0200
@@ -28,6 +28,7 @@
 import qualified HeadersText
 import qualified Links
 import qualified Text.Parsec as P
+import qualified Sets
 
 main :: IO ()
 main = do
@@ -86,6 +87,7 @@
    , headersT
    , Links.links
    , numbers
+   , Sets.benchmarks
    , Warp.benchmarks
    ]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/attoparsec-0.12.1.6/benchmarks/Sets.hs 
new/attoparsec-0.13.0.1/benchmarks/Sets.hs
--- old/attoparsec-0.12.1.6/benchmarks/Sets.hs  1970-01-01 01:00:00.000000000 
+0100
+++ new/attoparsec-0.13.0.1/benchmarks/Sets.hs  2015-07-09 02:08:52.000000000 
+0200
@@ -0,0 +1,21 @@
+module Sets (benchmarks) where
+
+import Criterion
+import Data.Char (ord)
+import qualified Data.Attoparsec.Text.FastSet as FastSet
+import qualified TextFastSet
+import qualified Data.HashSet as HashSet
+import qualified Data.IntSet as IntSet
+
+smallSet :: String
+smallSet = ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9']
+
+benchmarks :: Benchmark
+benchmarks = bgroup "sets" [
+    bench "Fast" $ whnf (FastSet.member '*') (FastSet.fromList smallSet)
+  , bench "Hash" $ whnf (HashSet.member '*') (HashSet.fromList smallSet)
+  , bench "Int" $ whnf (IntSet.member (ord '*'))
+                  (IntSet.fromList (map ord smallSet))
+  , bench "TextFast" $ whnf (TextFastSet.member '*')
+                       (TextFastSet.fromList smallSet)
+  ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/attoparsec-0.12.1.6/benchmarks/TextFastSet.hs 
new/attoparsec-0.13.0.1/benchmarks/TextFastSet.hs
--- old/attoparsec-0.12.1.6/benchmarks/TextFastSet.hs   1970-01-01 
01:00:00.000000000 +0100
+++ new/attoparsec-0.13.0.1/benchmarks/TextFastSet.hs   2015-07-09 
02:08:52.000000000 +0200
@@ -0,0 +1,119 @@
+{-# LANGUAGE BangPatterns #-}
+
+------------------------------------------------------------------------------
+-- |
+-- Module      :  Data.Attoparsec.FastSet
+-- Copyright   :  Felipe Lessa 2010, Bryan O'Sullivan 2007-2015
+-- License     :  BSD3
+--
+-- Maintainer  :  felipe.le...@gmail.com
+-- Stability   :  experimental
+-- Portability :  unknown
+--
+-- Fast set membership tests for 'Char' values. We test for
+-- membership using a hashtable implemented with Robin Hood
+-- collision resolution. The set representation is unboxed,
+-- and the characters and hashes interleaved, for efficiency.
+--
+--
+-----------------------------------------------------------------------------
+module TextFastSet
+    (
+    -- * Data type
+      FastSet
+    -- * Construction
+    , fromList
+    , set
+    -- * Lookup
+    , member
+    -- * Handy interface
+    , charClass
+    ) where
+
+import Data.Bits ((.|.), (.&.), shiftR)
+import Data.Function (on)
+import Data.List (sort, sortBy)
+import qualified Data.Array.Base as AB
+import qualified Data.Array.Unboxed as A
+import qualified Data.Text as T
+
+data FastSet = FastSet {
+    table :: {-# UNPACK #-} !(A.UArray Int Int)
+  , mask  :: {-# UNPACK #-} !Int
+  }
+
+data Entry = Entry {
+    key          :: {-# UNPACK #-} !Char
+  , initialIndex :: {-# UNPACK #-} !Int
+  , index        :: {-# UNPACK #-} !Int
+  }
+
+offset :: Entry -> Int
+offset e = index e - initialIndex e
+
+resolveCollisions :: [Entry] -> [Entry]
+resolveCollisions [] = []
+resolveCollisions [e] = [e]
+resolveCollisions (a:b:entries) = a' : resolveCollisions (b' : entries)
+  where (a', b')
+          | index a < index b   = (a, b)
+          | offset a < offset b = (b { index=index a }, a { index=index a + 1 
})
+          | otherwise           = (a, b { index=index a + 1 })
+
+pad :: Int -> [Entry] -> [Entry]
+pad = go 0
+  where go !_ !m []          = replicate (max 1 m) empty
+        go  k  m (e:entries) = map (const empty) [k..i - 1] ++ e :
+                               go (i + 1) (m + i - k - 1) entries
+          where i            = index e
+        empty                = Entry '\0' maxBound 0
+
+nextPowerOf2 :: Int -> Int
+nextPowerOf2 0  = 1
+nextPowerOf2 x  = go (x - 1) 1
+  where go y 32 = y + 1
+        go y k  = go (y .|. (y `shiftR` k)) $ k * 2
+
+fastHash :: Char -> Int
+fastHash = fromEnum
+
+fromList :: String -> FastSet
+fromList s = FastSet (AB.listArray (0, length interleaved - 1) interleaved)
+             mask'
+  where s'      = ordNub (sort s)
+        l       = length s'
+        mask'   = nextPowerOf2 ((5 * l) `div` 4) - 1
+        entries = pad mask' .
+                  resolveCollisions .
+                  sortBy (compare `on` initialIndex) .
+                  zipWith (\c i -> Entry c i i) s' .
+                  map ((.&. mask') . fastHash) $ s'
+        interleaved = concatMap (\e -> [fromEnum $ key e, initialIndex e])
+                      entries
+
+ordNub :: Eq a => [a] -> [a]
+ordNub []     = []
+ordNub (y:ys) = go y ys
+  where go x (z:zs)
+          | x == z    = go x zs
+          | otherwise = x : go z zs
+        go x []       = [x]
+
+set :: T.Text -> FastSet
+set = fromList . T.unpack
+
+-- | Check the set for membership.
+member :: Char -> FastSet -> Bool
+member c a           = go (2 * i)
+  where i            = fastHash c .&. mask a
+        lookupAt j b = (i' <= i) && (c == c' || b)
+            where c' = toEnum $ AB.unsafeAt (table a) j
+                  i' = AB.unsafeAt (table a) $ j + 1
+        go j         = lookupAt j . lookupAt (j + 2) . lookupAt (j + 4) .
+                       lookupAt (j + 6) . go $ j + 8
+
+charClass :: String -> FastSet
+charClass = fromList . go
+  where go (a:'-':b:xs) = [a..b] ++ go xs
+        go (x:xs)       = x : go xs
+        go _            = ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/attoparsec-0.12.1.6/benchmarks/attoparsec-benchmarks.cabal 
new/attoparsec-0.13.0.1/benchmarks/attoparsec-benchmarks.cabal
--- old/attoparsec-0.12.1.6/benchmarks/attoparsec-benchmarks.cabal      
2015-04-05 21:51:22.000000000 +0200
+++ new/attoparsec-0.13.0.1/benchmarks/attoparsec-benchmarks.cabal      
2015-07-09 02:08:52.000000000 +0200
@@ -16,6 +16,7 @@
     Links
     Numbers
     Network.Wai.Handler.Warp.ReadInt
+    Sets
     Warp
   hs-source-dirs: .. . warp-3.0.1.1
   ghc-options: -O2 -Wall -rtsopts
@@ -24,6 +25,7 @@
     base == 4.*,
     bytestring >= 0.10.4.0,
     case-insensitive,
+    containers,
     criterion >= 1.0,
     deepseq >= 1.1,
     directory,
@@ -33,5 +35,6 @@
     parsec >= 3.1.2,
     scientific >= 0.3.1,
     text >= 1.1.1.0,
+    transformers,
     unordered-containers,
     vector
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/attoparsec-0.12.1.6/changelog.md 
new/attoparsec-0.13.0.1/changelog.md
--- old/attoparsec-0.12.1.6/changelog.md        2015-04-05 21:51:22.000000000 
+0200
+++ new/attoparsec-0.13.0.1/changelog.md        2015-07-09 02:08:52.000000000 
+0200
@@ -1,3 +1,13 @@
+0.13.0.1
+
+* Fixed a bug in the implementations of inClass and notInClass for
+  Text (https://github.com/bos/attoparsec/issues/103)
+
+0.13.0.0
+
+* Made the parser type in the Zepto module a monad transformer
+  (needed by aeson's string unescaping parser).
+
 0.12.1.6
 
 * Fixed a case folding bug in the ByteString version of stringCI.


Reply via email to