From aa36964a8b40526c69d25a93ef7068c6365fed8b Mon Sep 17 00:00:00 2001 From: Bodigrim Date: Fri, 4 Jul 2025 22:56:59 +0100 Subject: [PATCH 1/3] Documentation improvements --- Data/ByteString.hs | 12 +++++++++--- Data/ByteString/Lazy.hs | 14 ++++++++++++-- Data/ByteString/Lazy/Internal.hs | 11 ++++++++--- Data/ByteString/Short/Internal.hs | 7 +++++++ 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/Data/ByteString.hs b/Data/ByteString.hs index 05dff5ed..2f77b402 100644 --- a/Data/ByteString.hs +++ b/Data/ByteString.hs @@ -1558,6 +1558,13 @@ isValidUtf8 (BS ptr len) = accursedUnutterablePerformIO $ unsafeWithForeignPtr p -- | Break a string on a substring, returning a pair of the part of the -- string prior to the match, and the rest of the string. +-- If the substring is not found, return the entire string in the first component +-- and an empty string in the second component. +-- +-- >>> breakSubstring "needle" "hayneedlestraw" +-- ("hay","needlestraw") +-- >>> breakSubstring "needle" "hay" +-- ("hay","") -- -- The following relationships hold: -- @@ -1576,7 +1583,7 @@ isValidUtf8 (BS ptr len) = accursedUnutterablePerformIO $ unsafeWithForeignPtr p -- -- > fst (breakSubstring x y) -- --- Note that calling `breakSubstring x` does some preprocessing work, so +-- Note that calling 'breakSubstring' @x@ does some preprocessing work, so -- you should avoid unnecessarily duplicating breakSubstring calls with the same -- pattern. -- @@ -2017,8 +2024,7 @@ hGetContentsSizeHint hnd = -- we grow the buffer sizes, but not too huge -- we concatenate in the end anyway --- | getContents. Read stdin strictly. Equivalent to hGetContents stdin --- The 'Handle' is closed after the contents have been read. +-- | Equivalent to 'hGetContents' 'stdin', reading it /strictly/. -- getContents :: IO ByteString getContents = hGetContents stdin diff --git a/Data/ByteString/Lazy.hs b/Data/ByteString/Lazy.hs index 5b4d8df2..403e2a68 100644 --- a/Data/ByteString/Lazy.hs +++ b/Data/ByteString/Lazy.hs @@ -1597,11 +1597,21 @@ illegalBufferSize handle fn sz = msg = fn ++ ": illegal ByteString size " ++ showsPrec 9 sz [] -- | Read entire handle contents /lazily/ into a 'ByteString'. Chunks --- are read on demand, using the default chunk size. +-- are read on demand, using the default chunk size ('defaultChunkSize'). -- -- File handles are closed on EOF if all the file is read, or through -- garbage collection otherwise. -- +-- Beware of using this function inside of 'Control.Exception.bracket' \/ +-- 'System.IO.withFile' \/ 'System.IO.withBinaryFile': +-- lazy I/O can easily escape it, causing 'Control.Exception.bracket' to close a handle prematurely: +-- +-- >>> withBinaryFile "foo.txt" ReadMode BL.hGetContents >>= print +-- "*** Exception: foo.txt: hGetBufSome: illegal operation (handle is closed) +-- +-- The expected way of using 'hGetContents' is to open a handle, +-- pass it to 'hGetContents', and leave 'hGetContents' to close the handle when it sees fit. +-- hGetContents :: Handle -> IO ByteString hGetContents = hGetContentsN defaultChunkSize @@ -1644,7 +1654,7 @@ writeFile = modifyFile WriteMode appendFile :: FilePath -> ByteString -> IO () appendFile = modifyFile AppendMode --- | getContents. Equivalent to hGetContents stdin. Will read /lazily/ +-- | Equivalent to 'hGetContents' 'stdin', reading it /lazily/. -- getContents :: IO ByteString getContents = hGetContents stdin diff --git a/Data/ByteString/Lazy/Internal.hs b/Data/ByteString/Lazy/Internal.hs index f93f3d34..b8f42551 100644 --- a/Data/ByteString/Lazy/Internal.hs +++ b/Data/ByteString/Lazy/Internal.hs @@ -78,9 +78,14 @@ import Control.Exception (assert) -- 8-bit characters. -- #ifndef HS_BYTESTRING_ASSERTIONS -data ByteString = Empty | Chunk {-# UNPACK #-} !S.StrictByteString ByteString - -- INVARIANT: The S.StrictByteString field of any Chunk is not empty. - -- (See also the 'invariant' and 'checkInvariant' functions.) +data ByteString + = Empty + | Chunk + {-# UNPACK #-} !S.StrictByteString + -- ^ Must be nonempty. Consider using + -- the smart constructor 'chunk' to ensure this invariant. + -- See also the 'invariant' and 'checkInvariant' functions. + LazyByteString -- To make testing of this invariant convenient, we add an -- assertion to that effect when the HS_BYTESTRING_ASSERTIONS diff --git a/Data/ByteString/Short/Internal.hs b/Data/ByteString/Short/Internal.hs index a3657025..82815554 100644 --- a/Data/ByteString/Short/Internal.hs +++ b/Data/ByteString/Short/Internal.hs @@ -1296,6 +1296,13 @@ isSuffixOf sbs1 = \sbs2 -> do -- | Break a string on a substring, returning a pair of the part of the -- string prior to the match, and the rest of the string. +-- If the substring is not found, return the entire string in the first component +-- and an empty string in the second component. +-- +-- >>> breakSubstring "needle" "hayneedlestraw" +-- ("hay","needlestraw") +-- >>> breakSubstring "needle" "hay" +-- ("hay","") -- -- The following relationships hold: -- From 47388bd556350c2948129d895e7861180b5641b8 Mon Sep 17 00:00:00 2001 From: Bodigrim Date: Fri, 4 Jul 2025 23:23:36 +0100 Subject: [PATCH 2/3] Fix CI --- .github/workflows/ci.yml | 1 + bytestring.cabal | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6a4651ae..335eb3e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,6 +49,7 @@ jobs: cd bytestring-*/ cabal bench --enable-tests --enable-benchmarks --benchmark-option=-l all - name: Haddock + if: matrix.ghc != '8.4' run: | cd bytestring-*/ cabal haddock all diff --git a/bytestring.cabal b/bytestring.cabal index 7079bcbb..c2b4038e 100644 --- a/bytestring.cabal +++ b/bytestring.cabal @@ -232,6 +232,10 @@ test-suite bytestring-tests if !arch(wasm32) ghc-options: -threaded + -- https://github.com/haskellari/splitmix/issues/101 + if os(openbsd) + build-depends: splitmix < 0.1.3 || > 0.1.3.1 + benchmark bytestring-bench import: language main-is: BenchAll.hs From 9bcc5054ff6670516b5813226e43718a5b0b6504 Mon Sep 17 00:00:00 2001 From: Bodigrim Date: Tue, 8 Jul 2025 23:43:30 +0100 Subject: [PATCH 3/3] Drop support of GHC 8.4 --- .github/workflows/ci.yml | 3 +-- README.md | 2 +- bench/BenchReadInt.hs | 3 --- bytestring.cabal | 14 ++++++-------- include/bytestring-cpp-macros.h | 3 +-- 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 335eb3e5..b683dfc4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest] - ghc: ['8.4', '8.6', '8.8', '8.10', '9.0', '9.2', '9.4', '9.6', '9.8', '9.10', '9.12'] + ghc: ['8.6', '8.8', '8.10', '9.0', '9.2', '9.4', '9.6', '9.8', '9.10', '9.12'] include: - os: macOS-latest ghc: 'latest' @@ -49,7 +49,6 @@ jobs: cd bytestring-*/ cabal bench --enable-tests --enable-benchmarks --benchmark-option=-l all - name: Haddock - if: matrix.ghc != '8.4' run: | cd bytestring-*/ cabal haddock all diff --git a/README.md b/README.md index 5ed0a9bf..b8ea9aed 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ of `ByteString` values from smaller pieces during binary serialization. Requirements: * Cabal 2.2 or greater - * GHC 8.4 or greater + * GHC 8.6 or greater ### Authors diff --git a/bench/BenchReadInt.hs b/bench/BenchReadInt.hs index 11524f6c..e1c00d25 100644 --- a/bench/BenchReadInt.hs +++ b/bench/BenchReadInt.hs @@ -18,9 +18,6 @@ import Test.Tasty.Bench import Data.Int import Data.Word import Numeric.Natural -#if !(MIN_VERSION_base(4,11,0)) -import Data.Semigroup (Semigroup((<>))) -#endif import Data.Monoid (mconcat) ------------------------------------------------------------------------------ diff --git a/bytestring.cabal b/bytestring.cabal index c2b4038e..192b49a8 100644 --- a/bytestring.cabal +++ b/bytestring.cabal @@ -57,17 +57,16 @@ Author: Don Stewart, Maintainer: Haskell Bytestring Team , Core Libraries Committee Homepage: https://github.com/haskell/bytestring Bug-reports: https://github.com/haskell/bytestring/issues -Tested-With: GHC==9.12.1, - GHC==9.10.1, +Tested-With: GHC==9.12.2, + GHC==9.10.2, GHC==9.8.4, - GHC==9.6.6, + GHC==9.6.7, GHC==9.4.8, GHC==9.2.8, GHC==9.0.2, GHC==8.10.7, GHC==8.8.4, - GHC==8.6.5, - GHC==8.4.4 + GHC==8.6.5 Build-Type: Simple extra-source-files: README.md Changelog.md include/bytestring-cpp-macros.h @@ -110,7 +109,7 @@ common language library import: language - build-depends: base >= 4.11 && < 5, ghc-prim, deepseq, template-haskell + build-depends: base >= 4.12 && < 5, ghc-prim, deepseq, template-haskell if impl(ghc < 9.4) build-depends: data-array-byte >= 0.1 && < 0.2 @@ -249,8 +248,7 @@ benchmark bytestring-bench hs-source-dirs: bench ghc-options: -O2 "-with-rtsopts=-A32m" - if impl(ghc >= 8.6) - ghc-options: -fproc-alignment=64 + -fproc-alignment=64 build-depends: base, bytestring, deepseq, diff --git a/include/bytestring-cpp-macros.h b/include/bytestring-cpp-macros.h index 350b52e3..7bd9e832 100644 --- a/include/bytestring-cpp-macros.h +++ b/include/bytestring-cpp-macros.h @@ -23,8 +23,7 @@ which are known not to trap (either to the kernel for emulation, or crash). #define HS_UNALIGNED_ByteArray_OPS_OK \ - MIN_VERSION_base(4,12,0) \ - && (MIN_VERSION_base(4,16,1) || HS_UNALIGNED_POKES_OK) + MIN_VERSION_base(4,16,1) || HS_UNALIGNED_POKES_OK /* The unaligned ByteArray# primops became available with base-4.12.0/ghc-8.6, but require an unaligned-friendly host architecture to be safe to use