packages feed

attoparsec 0.12.1.1 → 0.12.1.2

raw patch · 8 files changed

+117/−17 lines, 8 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

Data/Attoparsec/ByteString/Buffer.hs view
@@ -65,6 +65,7 @@ import GHC.ForeignPtr (mallocPlainForeignPtrBytes) import Prelude hiding (length) +-- If _cap is zero, this buffer is empty. data Buffer = Buf {       _fp  :: {-# UNPACK #-} !(ForeignPtr Word8)     , _off :: {-# UNPACK #-} !Int@@ -96,7 +97,7 @@     mconcat xs = foldl1' mappend xs  pappend :: Buffer -> ByteString -> Buffer-pappend (Buf _ _ _ 0 _) (PS fp off len) = Buf fp off len 0 0+pappend (Buf _ _ _ 0 _) bs  = buffer bs pappend buf (PS fp off len) = append buf fp off len  append :: Buffer -> ForeignPtr a -> Int -> Int -> Buffer
Data/Attoparsec/Internal.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, BangPatterns, ScopedTypeVariables #-}+{-# LANGUAGE BangPatterns, ScopedTypeVariables #-} -- | -- Module      :  Data.Attoparsec.Internal -- Copyright   :  Bryan O'Sullivan 2007-2014@@ -22,11 +22,9 @@     ) where  import Control.Applicative ((<$>))-#if __GLASGOW_HASKELL__ >= 700+import Data.Attoparsec.Internal.Types import Data.ByteString (ByteString) import Data.Text (Text)-#endif-import Data.Attoparsec.Internal.Types import Prelude hiding (succ)  -- | Compare two 'IResult' values for equality.@@ -53,7 +51,6 @@   if nullChunk s   then lose t pos Complete   else succ (pappendChunk t s) pos Incomplete-#if __GLASGOW_HASKELL__ >= 700 {-# SPECIALIZE prompt :: State ByteString -> Pos -> More                       -> (State ByteString -> Pos -> More                           -> IResult ByteString r)@@ -64,7 +61,6 @@                       -> (State Text -> Pos -> More -> IResult Text r)                       -> (State Text -> Pos -> More -> IResult Text r)                       -> IResult Text r #-}-#endif  -- | Immediately demand more input via a 'Partial' continuation -- result.@@ -75,10 +71,8 @@     _ -> let lose' t' pos' more' = lose t' pos' more' [] "not enough input"              succ' t' pos' more' = succ t' pos' more' ()          in prompt t pos more lose' succ'-#if __GLASGOW_HASKELL__ >= 700 {-# SPECIALIZE demandInput :: Parser ByteString () #-} {-# SPECIALIZE demandInput :: Parser Text () #-}-#endif  -- | This parser always succeeds.  It returns 'True' if any input is -- available either immediately or on demand, and 'False' if the end@@ -103,10 +97,8 @@        let lose' t' pos' more' _ctx _msg = succ t' pos' more' ()            succ' t' pos' more' _a = lose t' pos' more' [] "endOfInput"        in  runParser demandInput t pos more lose' succ'-#if __GLASGOW_HASKELL__ >= 700 {-# SPECIALIZE endOfInput :: Parser ByteString () #-} {-# SPECIALIZE endOfInput :: Parser Text () #-}-#endif  -- | Return an indication of whether the end of input has been -- reached.@@ -127,7 +119,6 @@             Just (e, l) | p e -> succ' t' (pos' + Pos l) more' e                         | otherwise -> lose' t' pos' more' [] "satisfyElem"             Nothing -> runParser (demandInput >> go) t' pos' more' lose' succ'-#if __GLASGOW_HASKELL__ >= 700 {-# SPECIALIZE satisfySuspended :: (ChunkElem ByteString -> Bool)                                 -> State ByteString -> Pos -> More                                 -> Failure ByteString (State ByteString) r@@ -140,7 +131,6 @@                                 -> Success Text (State Text)                                            (ChunkElem Text) r                                 -> IResult Text r #-}-#endif  -- | The parser @satisfyElem p@ succeeds for any chunk element for which the -- predicate @p@ returns 'True'. Returns the element that is
Data/Attoparsec/Text/Buffer.hs view
@@ -51,6 +51,7 @@ import Prelude hiding (length) import qualified Data.Text.Array as A +-- If _cap is zero, this buffer is empty. data Buffer = Buf {       _arr :: {-# UNPACK #-} !A.Array     , _off :: {-# UNPACK #-} !Int@@ -82,8 +83,8 @@     mconcat xs = foldl1' mappend xs  pappend :: Buffer -> Text -> Buffer-pappend (Buf _ _ _ 0 _) (Text arr off len) = Buf arr off len 0 0-pappend buf (Text arr off len)             = append buf arr off len+pappend (Buf _ _ _ 0 _) t      = buffer t+pappend buf (Text arr off len) = append buf arr off len  append :: Buffer -> A.Array -> Int -> Int -> Buffer append (Buf arr0 off0 len0 cap0 gen0) !arr1 !off1 !len1 = runST $ do
attoparsec.cabal view
@@ -1,5 +1,5 @@ name:            attoparsec-version:         0.12.1.1+version:         0.12.1.2 license:         BSD3 license-file:    LICENSE category:        Text, Parsing@@ -84,6 +84,8 @@                   QC.ByteString                   QC.Combinator                   QC.Common+                  QC.Rechunked+                  QC.Simple                   QC.Text    ghc-options:@@ -101,7 +103,8 @@     scientific,     test-framework >= 0.8.0.2,     test-framework-quickcheck2 >= 0.3.0.3,-    text+    text,+    vector  benchmark benchmarks   type: exitcode-stdio-1.0
changelog.md view
@@ -1,3 +1,14 @@+0.12.1.2++* Fixed the incorrect tracking of capacity if the initial buffer was+  empty (https://github.com/bos/attoparsec/issues/75)++0.12.1.1++* Fixed a data corruption bug that occurred under some circumstances+  if a buffer grew after prompting for more input+  (https://github.com/bos/attoparsec/issues/74)+ 0.12.1.0  * Now compatible with GHC 7.9
tests/QC.hs view
@@ -4,6 +4,7 @@ import qualified QC.Buffer as Buffer import qualified QC.ByteString as ByteString import qualified QC.Combinator as Combinator+import qualified QC.Simple as Simple import qualified QC.Text as Text import Test.Framework (defaultMain, testGroup) @@ -13,5 +14,6 @@     testGroup "bs" ByteString.tests   , testGroup "buf" Buffer.tests   , testGroup "combinator" Combinator.tests+  , testGroup "simple" Simple.tests   , testGroup "text" Text.tests   ]
+ tests/QC/Rechunked.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE BangPatterns #-}++module QC.Rechunked (+      rechunkBS+    , rechunkT+    ) where++import Control.Monad (forM, forM_)+import Control.Monad.ST (runST)+import Data.List (unfoldr)+import Test.QuickCheck (Gen, choose)+import qualified Data.ByteString as B+import qualified Data.Text as T+import qualified Data.Vector as V+import qualified Data.Vector.Generic as G+import qualified Data.Vector.Generic.Mutable as M++rechunkBS :: B.ByteString -> Gen [B.ByteString]+rechunkBS = fmap (map B.copy) . rechunk_ B.splitAt B.length++rechunkT :: T.Text -> Gen [T.Text]+rechunkT = fmap (map T.copy) . rechunk_ T.splitAt T.length++rechunk_ :: (Int -> a -> (a,a)) -> (a -> Int) -> a -> Gen [a]+rechunk_ split len xs = (unfoldr go . (,) xs) `fmap` rechunkSizes (len xs)+  where go (b,r:rs)   = Just (h, (t,rs))+          where (h,t) = split r b+        go (_,_)      = Nothing++rechunkSizes :: Int -> Gen [Int]+rechunkSizes n0 = shuffle =<< loop [] (0:repeat 1) n0+  where loop _ [] _ = error "it's 2014, where's my Stream type?"+        loop acc (lb:lbs) n+          | n <= 0 = shuffle (reverse acc)+          | otherwise = do+            !i <- choose (lb,n)+            loop (i:acc) lbs (n-i)++shuffle :: [Int] -> Gen [Int]+shuffle (0:xs) = (0:) `fmap` shuffle xs+shuffle xs = fisherYates xs++fisherYates :: [a] -> Gen [a]+fisherYates xs = (V.toList . V.backpermute v) `fmap` swapIndices (G.length v)+  where+    v = V.fromList xs+    swapIndices n0 = do+        swaps <- forM [0..n] $ \i -> ((,) i) `fmap` choose (i,n)+        return (runST (swapAll swaps))+      where+        n = n0 - 1+        swapAll ijs = do+          mv <- G.unsafeThaw (G.enumFromTo 0 n :: V.Vector Int)+          forM_ ijs $ uncurry (M.swap mv)+          G.unsafeFreeze mv
+ tests/QC/Simple.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE OverloadedStrings #-}+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}++module QC.Simple (+      tests+    ) where++import Control.Applicative ((<|>))+import Data.ByteString (ByteString)+import Data.List (foldl')+import Data.Maybe (fromMaybe)+import QC.Rechunked (rechunkBS)+import Test.Framework (Test)+import Test.Framework.Providers.QuickCheck2 (testProperty)+import Test.QuickCheck (Property, counterexample, forAll)+import qualified Data.Attoparsec.ByteString.Char8 as A++t_issue75 = expect issue75 "ab" (A.Done "" "b")++issue75 :: A.Parser ByteString+issue75 = "a" >> ("b" <|> "")++expect :: (Show r, Eq r) => A.Parser r -> ByteString -> A.Result r -> Property+expect p input wanted =+  forAll (rechunkBS input) $ \in' ->+    let result = parse p in'+    in counterexample (show result ++ " /= " ++ show wanted) $+       fromMaybe False (A.compareResults result wanted)++parse :: A.Parser r -> [ByteString] -> A.Result r+parse p (x:xs) = foldl' A.feed (A.parse p x) xs+parse p []     = A.parse p ""++tests :: [Test]+tests = [+      testProperty "issue75" t_issue75+  ]