    {-# LINE 1 "src/Text/Regex/Posix/Wrap.hsc" #-}
    {-# LANGUAGE CPP #-}
    {-# OPTIONS_GHC -Wno-unused-imports #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Text.Regex.Posix.Wrap
    -- Copyright   :  (c) Chris Kuklewicz 2006,2007,2008 derived from (c) The University of Glasgow 2002
    -- Identifier  :  BSD-3-Clause
    --
    -- Maintainer  :  Andreas Abel
    -- Stability   :  stable
    -- Portability :  non-portable (regex-base needs MPTC+FD)
    --
    -- WrapPosix.hsc exports a wrapped version of the ffi imports.  To
    -- increase type safety, the flags are newtype'd.  The other important
    -- export is a 'Regex' type that is specific to the Posix library
    -- backend.  The flags are documented in "Text.Regex.Posix".  The
    -- 'defaultCompOpt' is @(compExtended .|. compNewline)@.
    --
    -- The 'Regex', 'CompOption', and 'ExecOption' types and their 'RegexOptions'
    -- instance is declared.  The '=~' and '=~~' convenience functions are
    -- defined.
    --
    -- This module will fail or error only if allocation fails or a nullPtr
    -- is passed in.
    --
    -- 2009-January : 'wrapMatchAll' and 'wrapCount' now adjust the execution
    -- option 'execNotBOL' after the first result to take into account '\n'
    -- in the text immediately before the next matches. (version 0.93.3)
    --
    -- 2009-January : 'wrapMatchAll' and 'wrapCount' have been changed to
    -- return all non-overlapping matches, including empty matches even if
    -- they coincide with the end of the previous non-empty match.  The
    -- change is that the first non-empty match no longer terminates the
    -- search.  One can filter the results to obtain the old behavior or
    -- to obtain the behavior of "sed", where "sed" eliminates the empty
    -- matches which coincide with the end of non-empty matches. (version
    -- 0.94.0)
    -----------------------------------------------------------------------------

    module Text.Regex.Posix.Wrap(
      -- ** High-level API
      Regex,
      RegOffset,
      RegOffsetT,
      (=~),
      (=~~),

      -- ** Low-level API
      WrapError,
      wrapCompile,
      wrapTest,
      wrapMatch,
      wrapMatchAll,
      wrapCount,

      -- ** Miscellaneous
      unusedRegOffset,

      -- ** Compilation options
      CompOption(CompOption),
      compBlank,
      compExtended,   -- use extended regex syntax
      compIgnoreCase, -- ignore case when matching
      compNoSub,      -- no substring matching needed
      compNewline,    -- '.' doesn't match newline

      -- ** Execution options
      ExecOption(ExecOption),
      execBlank,
      execNotBOL,     -- not at begining of line
      execNotEOL,     -- not at end of line

      -- ** Return codes
      ReturnCode(ReturnCode),
      retBadbr,
      retBadpat,
      retBadrpt,
      retEcollate,
      retEctype,
      retEescape,
      retEsubreg,
      retEbrack,
      retEparen,
      retEbrace,
      retErange,
      retEspace
      ) where

    {-# LINE 96 "src/Text/Regex/Posix/Wrap.hsc" #-}

    import Prelude
      ( Bool(True, False), otherwise
      , Either(Left, Right)
      , Eq, (==), (/=), (>=)
      , IO, return, mapM
      , Int, Num, (+), (*), (-), fromIntegral, pred, succ, toEnum
      , Maybe(Nothing, Just)
      , Show(show)
      , String
      , ($), (.), seq, undefined
      , (++), iterate, length, map, take
      )
    import Control.Monad.Fail (MonadFail)

    import Control.Monad(liftM)
    import Data.Array(Array,listArray)
    import Data.Bits(Bits(..))
    import Data.Int(Int32,Int64)   -- need whatever RegeOffset or #regoff_t type will be
    import Data.Word(Word32,Word64) -- need whatever RegeOffset or #regoff_t type will be
    import Foreign(Ptr, FunPtr, nullPtr, newForeignPtr,
                   Storable(peekByteOff), allocaArray,
                   allocaBytes, withForeignPtr,ForeignPtr,plusPtr,peekElemOff)
    import Foreign.Marshal.Alloc(mallocBytes)
    import Foreign.C(CChar)
    import Foreign.C(CSize(CSize),CInt(CInt))
    import Foreign.C.String(peekCAString, CString)
    import Text.Regex.Base.RegexLike(RegexOptions(..),RegexMaker(..),RegexContext(..),MatchArray)
    -- deprecated: import qualified System.IO.Error as IOERROR(try)
    import qualified Control.Exception(try,IOException)

    try :: IO a -> IO (Either Control.Exception.IOException a)
    try :: forall a. IO a -> IO (Either IOException a)
    try = IO a -> IO (Either IOException a)
    forall e a. Exception e => IO a -> IO (Either e a)
    Control.Exception.try

    data CRegex   -- pointer tag for regex_t C type

    -- | 'RegOffset' is @typedef int regoff_t@ on Linux and ultimately @typedef
    -- long long __int64_t@ on Max OS X.  So rather than saying
    -- 2,147,483,647 is all the length you need, I'll take the larger:
    -- 9,223,372,036,854,775,807 should be enough bytes for anyone, no
    -- need for Integer. The alternative is to compile to different sizes
    -- in a platform dependent manner with @type RegOffset = (#type
    -- regoff_t)@, which I do not want to do.
    --
    -- There is also a special value @'unusedRegOffset' :: 'RegOffset'@ which is
    -- (-1) and as a starting index means that the subgroup capture was
    -- unused.  Otherwise the 'RegOffset' indicates a character boundary that
    -- is before the character at that index offset, with the first
    -- character at index offset 0. So starting at 1 and ending at 2 means
    -- to take only the second character.
    type RegOffset = Int64
    --debugging 64-bit ubuntu
    type RegOffsetT = (Int32)
    {-# LINE 153 "src/Text/Regex/Posix/Wrap.hsc" #-}

    -- | A bitmapped 'CInt' containing options for compilation of regular
    -- expressions.  Option values (and their man 3 regcomp names) are
    --
    --  * 'compBlank' which is a completely zero value for all the flags.
    --    This is also the 'blankCompOpt' value.
    --
    --  * 'compExtended' (REG_EXTENDED) which can be set to use extended instead
    --    of basic regular expressions.
    --    This is set in the 'defaultCompOpt' value.
    --
    --  * 'compNewline' (REG_NEWLINE) turns on newline sensitivity: The dot (.)
    --    and inverted set @[^ ]@ never match newline, and ^ and $ anchors do
    --    match after and before newlines.
    --    This is set in the 'defaultCompOpt' value.
    --
    --  * 'compIgnoreCase' (REG_ICASE) which can be set to match ignoring upper
    --    and lower distinctions.
    --
    --  * 'compNoSub' (REG_NOSUB) which turns off all information from matching
    --    except whether a match exists.

    newtype CompOption = CompOption CInt deriving (CompOption -> CompOption -> Bool
    (CompOption -> CompOption -> Bool)
    -> (CompOption -> CompOption -> Bool) -> Eq CompOption
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: CompOption -> CompOption -> Bool
    == :: CompOption -> CompOption -> Bool
    $c/= :: CompOption -> CompOption -> Bool
    /= :: CompOption -> CompOption -> Bool
    Eq,Int -> CompOption -> ShowS
    [CompOption] -> ShowS
    CompOption -> String
    (Int -> CompOption -> ShowS)
    -> (CompOption -> String)
    -> ([CompOption] -> ShowS)
    -> Show CompOption
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> CompOption -> ShowS
    showsPrec :: Int -> CompOption -> ShowS
    $cshow :: CompOption -> String
    show :: CompOption -> String
    $cshowList :: [CompOption] -> ShowS
    showList :: [CompOption] -> ShowS
    Show,Integer -> CompOption
    CompOption -> CompOption
    CompOption -> CompOption -> CompOption
    (CompOption -> CompOption -> CompOption)
    -> (CompOption -> CompOption -> CompOption)
    -> (CompOption -> CompOption -> CompOption)
    -> (CompOption -> CompOption)
    -> (CompOption -> CompOption)
    -> (CompOption -> CompOption)
    -> (Integer -> CompOption)
    -> Num CompOption
    forall a.
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (Integer -> a)
    -> Num a
    $c+ :: CompOption -> CompOption -> CompOption
    + :: CompOption -> CompOption -> CompOption
    $c- :: CompOption -> CompOption -> CompOption
    - :: CompOption -> CompOption -> CompOption
    $c* :: CompOption -> CompOption -> CompOption
    * :: CompOption -> CompOption -> CompOption
    $cnegate :: CompOption -> CompOption
    negate :: CompOption -> CompOption
    $cabs :: CompOption -> CompOption
    abs :: CompOption -> CompOption
    $csignum :: CompOption -> CompOption
    signum :: CompOption -> CompOption
    $cfromInteger :: Integer -> CompOption
    fromInteger :: Integer -> CompOption
    Num,Eq CompOption
    CompOption
    Eq CompOption =>
    (CompOption -> CompOption -> CompOption)
    -> (CompOption -> CompOption -> CompOption)
    -> (CompOption -> CompOption -> CompOption)
    -> (CompOption -> CompOption)
    -> (CompOption -> Int -> CompOption)
    -> (CompOption -> Int -> CompOption)
    -> CompOption
    -> (Int -> CompOption)
    -> (CompOption -> Int -> CompOption)
    -> (CompOption -> Int -> CompOption)
    -> (CompOption -> Int -> CompOption)
    -> (CompOption -> Int -> Bool)
    -> (CompOption -> Maybe Int)
    -> (CompOption -> Int)
    -> (CompOption -> Bool)
    -> (CompOption -> Int -> CompOption)
    -> (CompOption -> Int -> CompOption)
    -> (CompOption -> Int -> CompOption)
    -> (CompOption -> Int -> CompOption)
    -> (CompOption -> Int -> CompOption)
    -> (CompOption -> Int -> CompOption)
    -> (CompOption -> Int)
    -> Bits CompOption
    Int -> CompOption
    CompOption -> Bool
    CompOption -> Int
    CompOption -> Maybe Int
    CompOption -> CompOption
    CompOption -> Int -> Bool
    CompOption -> Int -> CompOption
    CompOption -> CompOption -> CompOption
    forall a.
    Eq a =>
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> a
    -> (Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> Bool)
    -> (a -> Maybe Int)
    -> (a -> Int)
    -> (a -> Bool)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int)
    -> Bits a
    $c.&. :: CompOption -> CompOption -> CompOption
    .&. :: CompOption -> CompOption -> CompOption
    $c.|. :: CompOption -> CompOption -> CompOption
    .|. :: CompOption -> CompOption -> CompOption
    $cxor :: CompOption -> CompOption -> CompOption
    xor :: CompOption -> CompOption -> CompOption
    $ccomplement :: CompOption -> CompOption
    complement :: CompOption -> CompOption
    $cshift :: CompOption -> Int -> CompOption
    shift :: CompOption -> Int -> CompOption
    $crotate :: CompOption -> Int -> CompOption
    rotate :: CompOption -> Int -> CompOption
    $czeroBits :: CompOption
    zeroBits :: CompOption
    $cbit :: Int -> CompOption
    bit :: Int -> CompOption
    $csetBit :: CompOption -> Int -> CompOption
    setBit :: CompOption -> Int -> CompOption
    $cclearBit :: CompOption -> Int -> CompOption
    clearBit :: CompOption -> Int -> CompOption
    $ccomplementBit :: CompOption -> Int -> CompOption
    complementBit :: CompOption -> Int -> CompOption
    $ctestBit :: CompOption -> Int -> Bool
    testBit :: CompOption -> Int -> Bool
    $cbitSizeMaybe :: CompOption -> Maybe Int
    bitSizeMaybe :: CompOption -> Maybe Int
    $cbitSize :: CompOption -> Int
    bitSize :: CompOption -> Int
    $cisSigned :: CompOption -> Bool
    isSigned :: CompOption -> Bool
    $cshiftL :: CompOption -> Int -> CompOption
    shiftL :: CompOption -> Int -> CompOption
    $cunsafeShiftL :: CompOption -> Int -> CompOption
    unsafeShiftL :: CompOption -> Int -> CompOption
    $cshiftR :: CompOption -> Int -> CompOption
    shiftR :: CompOption -> Int -> CompOption
    $cunsafeShiftR :: CompOption -> Int -> CompOption
    unsafeShiftR :: CompOption -> Int -> CompOption
    $crotateL :: CompOption -> Int -> CompOption
    rotateL :: CompOption -> Int -> CompOption
    $crotateR :: CompOption -> Int -> CompOption
    rotateR :: CompOption -> Int -> CompOption
    $cpopCount :: CompOption -> Int
    popCount :: CompOption -> Int
    Bits)

    -- | A bitmapped 'CInt' containing options for execution of compiled
    -- regular expressions.  Option values (and their man 3 regexec names) are
    --
    --  * 'execBlank' which is a complete zero value for all the flags.  This is
    --    the @blankExecOpt@ value.
    --
    --  * 'execNotBOL' (REG_NOTBOL) can be set to prevent ^ from matching at the
    --    start of the input.
    --
    --  * 'execNotEOL' (REG_NOTEOL) can be set to prevent $ from matching at the
    --    end of the input (before the terminating NUL).
    newtype ExecOption = ExecOption CInt deriving (ExecOption -> ExecOption -> Bool
    (ExecOption -> ExecOption -> Bool)
    -> (ExecOption -> ExecOption -> Bool) -> Eq ExecOption
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ExecOption -> ExecOption -> Bool
    == :: ExecOption -> ExecOption -> Bool
    $c/= :: ExecOption -> ExecOption -> Bool
    /= :: ExecOption -> ExecOption -> Bool
    Eq,Int -> ExecOption -> ShowS
    [ExecOption] -> ShowS
    ExecOption -> String
    (Int -> ExecOption -> ShowS)
    -> (ExecOption -> String)
    -> ([ExecOption] -> ShowS)
    -> Show ExecOption
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ExecOption -> ShowS
    showsPrec :: Int -> ExecOption -> ShowS
    $cshow :: ExecOption -> String
    show :: ExecOption -> String
    $cshowList :: [ExecOption] -> ShowS
    showList :: [ExecOption] -> ShowS
    Show,Integer -> ExecOption
    ExecOption -> ExecOption
    ExecOption -> ExecOption -> ExecOption
    (ExecOption -> ExecOption -> ExecOption)
    -> (ExecOption -> ExecOption -> ExecOption)
    -> (ExecOption -> ExecOption -> ExecOption)
    -> (ExecOption -> ExecOption)
    -> (ExecOption -> ExecOption)
    -> (ExecOption -> ExecOption)
    -> (Integer -> ExecOption)
    -> Num ExecOption
    forall a.
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (a -> a)
    -> (Integer -> a)
    -> Num a
    $c+ :: ExecOption -> ExecOption -> ExecOption
    + :: ExecOption -> ExecOption -> ExecOption
    $c- :: ExecOption -> ExecOption -> ExecOption
    - :: ExecOption -> ExecOption -> ExecOption
    $c* :: ExecOption -> ExecOption -> ExecOption
    * :: ExecOption -> ExecOption -> ExecOption
    $cnegate :: ExecOption -> ExecOption
    negate :: ExecOption -> ExecOption
    $cabs :: ExecOption -> ExecOption
    abs :: ExecOption -> ExecOption
    $csignum :: ExecOption -> ExecOption
    signum :: ExecOption -> ExecOption
    $cfromInteger :: Integer -> ExecOption
    fromInteger :: Integer -> ExecOption
    Num,Eq ExecOption
    ExecOption
    Eq ExecOption =>
    (ExecOption -> ExecOption -> ExecOption)
    -> (ExecOption -> ExecOption -> ExecOption)
    -> (ExecOption -> ExecOption -> ExecOption)
    -> (ExecOption -> ExecOption)
    -> (ExecOption -> Int -> ExecOption)
    -> (ExecOption -> Int -> ExecOption)
    -> ExecOption
    -> (Int -> ExecOption)
    -> (ExecOption -> Int -> ExecOption)
    -> (ExecOption -> Int -> ExecOption)
    -> (ExecOption -> Int -> ExecOption)
    -> (ExecOption -> Int -> Bool)
    -> (ExecOption -> Maybe Int)
    -> (ExecOption -> Int)
    -> (ExecOption -> Bool)
    -> (ExecOption -> Int -> ExecOption)
    -> (ExecOption -> Int -> ExecOption)
    -> (ExecOption -> Int -> ExecOption)
    -> (ExecOption -> Int -> ExecOption)
    -> (ExecOption -> Int -> ExecOption)
    -> (ExecOption -> Int -> ExecOption)
    -> (ExecOption -> Int)
    -> Bits ExecOption
    Int -> ExecOption
    ExecOption -> Bool
    ExecOption -> Int
    ExecOption -> Maybe Int
    ExecOption -> ExecOption
    ExecOption -> Int -> Bool
    ExecOption -> Int -> ExecOption
    ExecOption -> ExecOption -> ExecOption
    forall a.
    Eq a =>
    (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> (a -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> a
    -> (Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> Bool)
    -> (a -> Maybe Int)
    -> (a -> Int)
    -> (a -> Bool)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int -> a)
    -> (a -> Int)
    -> Bits a
    $c.&. :: ExecOption -> ExecOption -> ExecOption
    .&. :: ExecOption -> ExecOption -> ExecOption
    $c.|. :: ExecOption -> ExecOption -> ExecOption
    .|. :: ExecOption -> ExecOption -> ExecOption
    $cxor :: ExecOption -> ExecOption -> ExecOption
    xor :: ExecOption -> ExecOption -> ExecOption
    $ccomplement :: ExecOption -> ExecOption
    complement :: ExecOption -> ExecOption
    $cshift :: ExecOption -> Int -> ExecOption
    shift :: ExecOption -> Int -> ExecOption
    $crotate :: ExecOption -> Int -> ExecOption
    rotate :: ExecOption -> Int -> ExecOption
    $czeroBits :: ExecOption
    zeroBits :: ExecOption
    $cbit :: Int -> ExecOption
    bit :: Int -> ExecOption
    $csetBit :: ExecOption -> Int -> ExecOption
    setBit :: ExecOption -> Int -> ExecOption
    $cclearBit :: ExecOption -> Int -> ExecOption
    clearBit :: ExecOption -> Int -> ExecOption
    $ccomplementBit :: ExecOption -> Int -> ExecOption
    complementBit :: ExecOption -> Int -> ExecOption
    $ctestBit :: ExecOption -> Int -> Bool
    testBit :: ExecOption -> Int -> Bool
    $cbitSizeMaybe :: ExecOption -> Maybe Int
    bitSizeMaybe :: ExecOption -> Maybe Int
    $cbitSize :: ExecOption -> Int
    bitSize :: ExecOption -> Int
    $cisSigned :: ExecOption -> Bool
    isSigned :: ExecOption -> Bool
    $cshiftL :: ExecOption -> Int -> ExecOption
    shiftL :: ExecOption -> Int -> ExecOption
    $cunsafeShiftL :: ExecOption -> Int -> ExecOption
    unsafeShiftL :: ExecOption -> Int -> ExecOption
    $cshiftR :: ExecOption -> Int -> ExecOption
    shiftR :: ExecOption -> Int -> ExecOption
    $cunsafeShiftR :: ExecOption -> Int -> ExecOption
    unsafeShiftR :: ExecOption -> Int -> ExecOption
    $crotateL :: ExecOption -> Int -> ExecOption
    rotateL :: ExecOption -> Int -> ExecOption
    $crotateR :: ExecOption -> Int -> ExecOption
    rotateR :: ExecOption -> Int -> ExecOption
    $cpopCount :: ExecOption -> Int
    popCount :: ExecOption -> Int
    Bits)

    -- | ReturnCode is an enumerated 'CInt', corresponding to the error codes
    -- from @man 3 regex@:
    --
    -- * 'retBadbr' (@REG_BADBR@) invalid repetition count(s) in @{ }@
    --
    -- * 'retBadpat' (@REG_BADPAT@) invalid regular expression
    --
    -- * 'retBadrpt' (@REG_BADRPT@) @?@, @*@, or @+@ operand invalid
    --
    -- * 'retEcollate' (@REG_ECOLLATE@) invalid collating element
    --
    -- * 'retEctype' (@REG_ECTYPE@) invalid character class
    --
    -- * 'retEescape' (@REG_EESCAPE@) @\\@ applied to unescapable character
    --
    -- * 'retEsubreg' (@REG_ESUBREG@) invalid backreference number
    --
    -- * 'retEbrack' (@REG_EBRACK@) brackets @[ ]@ not balanced
    --
    -- * 'retEparen' (@REG_EPAREN@) parentheses @( )@ not balanced
    --
    -- * 'retEbrace' (@REG_EBRACE@) braces @{ }@ not balanced
    --
    -- * 'retErange' (@REG_ERANGE@) invalid character range in @[ ]@
    --
    -- * 'retEspace' (@REG_ESPACE@) ran out of memory
    --
    -- * 'retNoMatch' (@REG_NOMATCH@) The regexec() function failed to match
    --
    newtype ReturnCode = ReturnCode CInt deriving (ReturnCode -> ReturnCode -> Bool
    (ReturnCode -> ReturnCode -> Bool)
    -> (ReturnCode -> ReturnCode -> Bool) -> Eq ReturnCode
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ReturnCode -> ReturnCode -> Bool
    == :: ReturnCode -> ReturnCode -> Bool
    $c/= :: ReturnCode -> ReturnCode -> Bool
    /= :: ReturnCode -> ReturnCode -> Bool
    Eq,Int -> ReturnCode -> ShowS
    [ReturnCode] -> ShowS
    ReturnCode -> String
    (Int -> ReturnCode -> ShowS)
    -> (ReturnCode -> String)
    -> ([ReturnCode] -> ShowS)
    -> Show ReturnCode
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ReturnCode -> ShowS
    showsPrec :: Int -> ReturnCode -> ShowS
    $cshow :: ReturnCode -> String
    show :: ReturnCode -> String
    $cshowList :: [ReturnCode] -> ShowS
    showList :: [ReturnCode] -> ShowS
    Show)

    -- | A compiled regular expression.
    data Regex = Regex (ForeignPtr CRegex) CompOption ExecOption

    -- | A completely zero value for all the flags.
    -- This is also the 'blankCompOpt' value.
    compBlank :: CompOption
    compBlank :: CompOption
    compBlank = CInt -> CompOption
    CompOption CInt
    0

    -- | A completely zero value for all the flags.
    -- This is also the 'blankExecOpt' value.
    execBlank :: ExecOption
    execBlank :: ExecOption
    execBlank = CInt -> ExecOption
    ExecOption CInt
    0

    unusedRegOffset :: RegOffset
    unusedRegOffset :: RegOffset
    unusedRegOffset = (-RegOffset
    1)

    -- | The return code will be @retOk@ when it is the Haskell wrapper and
    -- not the underlying library generating the error message.
    type WrapError = (ReturnCode,String)

    wrapCompile :: CompOption -- ^ Flags (bitmapped)
                -> ExecOption -- ^ Flags (bitmapped)
                -> CString -- ^ The regular expression to compile (ASCII only, no null bytes)
                -> IO (Either WrapError Regex) -- ^ Returns: the compiled regular expression

    wrapTest :: Regex -> CString
             -> IO (Either WrapError Bool)

    -- | 'wrapMatch' returns offsets for the begin and end of each capture.
    -- Unused captures have offsets of 'unusedRegOffset' which is (-1).
    wrapMatch :: Regex -> CString
              -> IO (Either WrapError (Maybe [(RegOffset,RegOffset)]))

    -- | 'wrapMatchAll' returns the offset and length of each capture.
    -- Unused captures have an offset of 'unusedRegOffset' which is (-1) and
    -- length of 0.
    wrapMatchAll :: Regex -> CString
                 -> IO (Either WrapError [MatchArray])

    wrapCount :: Regex -> CString
              -> IO (Either WrapError Int)

    (=~)  :: (RegexMaker Regex CompOption ExecOption source,RegexContext Regex source1 target)
          => source1 -> source -> target
    (=~~) :: (RegexMaker Regex CompOption ExecOption source,RegexContext Regex source1 target,MonadFail m)
          => source1 -> source -> m target

    instance RegexOptions Regex CompOption ExecOption where
      blankCompOpt :: CompOption
    blankCompOpt = CompOption
    compBlank
      blankExecOpt :: ExecOption
    blankExecOpt = ExecOption
    execBlank
      defaultCompOpt :: CompOption
    defaultCompOpt = CompOption
    compExtended CompOption -> CompOption -> CompOption
    forall a. Bits a => a -> a -> a
    .|. CompOption
    compNewline
      defaultExecOpt :: ExecOption
    defaultExecOpt = ExecOption
    execBlank
      setExecOpts :: ExecOption -> Regex -> Regex
    setExecOpts ExecOption
    e' (Regex ForeignPtr CRegex
    r CompOption
    c ExecOption
    _) = ForeignPtr CRegex -> CompOption -> ExecOption -> Regex
    Regex ForeignPtr CRegex
    r CompOption
    c ExecOption
    e'
      getExecOpts :: Regex -> ExecOption
    getExecOpts (Regex ForeignPtr CRegex
    _ CompOption
    _ ExecOption
    e) = ExecOption
    e

    -- (=~) ::(RegexMaker Regex CompOption ExecOption source,RegexContext Regex source1 target) => source1 -> source -> target
    =~ :: forall source source1 target.
    (RegexMaker Regex CompOption ExecOption source,
     RegexContext Regex source1 target) =>
    source1 -> source -> target
    (=~) source1
    x source
    r = let make :: RegexMaker Regex CompOption ExecOption a => a -> Regex
                   make :: forall a. RegexMaker Regex CompOption ExecOption a => a -> Regex
    make = a -> Regex
    forall regex compOpt execOpt source.
    RegexMaker regex compOpt execOpt source =>
    source -> regex
    makeRegex
               in Regex -> source1 -> target
    forall regex source target.
    RegexContext regex source target =>
    regex -> source -> target
    match (source -> Regex
    forall a. RegexMaker Regex CompOption ExecOption a => a -> Regex
    make source
    r) source1
    x

    -- (=~~) ::(RegexMaker Regex CompOption ExecOption source,RegexContext Regex source1 target,MonadFail m) => source1 -> source -> m target
    =~~ :: forall source source1 target (m :: * -> *).
    (RegexMaker Regex CompOption ExecOption source,
     RegexContext Regex source1 target, MonadFail m) =>
    source1 -> source -> m target
    (=~~) source1
    x source
    r = let make :: RegexMaker Regex CompOption ExecOption a => a -> Regex
                    make :: forall a. RegexMaker Regex CompOption ExecOption a => a -> Regex
    make = a -> Regex
    forall regex compOpt execOpt source.
    RegexMaker regex compOpt execOpt source =>
    source -> regex
    makeRegex
                in Regex -> source1 -> m target
    forall regex source target (m :: * -> *).
    (RegexContext regex source target, MonadFail m) =>
    regex -> source -> m target
    forall (m :: * -> *). MonadFail m => Regex -> source1 -> m target
    matchM (source -> Regex
    forall a. RegexMaker Regex CompOption ExecOption a => a -> Regex
    make source
    r) source1
    x

    type CRegMatch = () -- dummy regmatch_t used below to read out so and eo values

    -- -----------------------------------------------------------------------------
    -- The POSIX regex C interface

    -- string.h
    foreign import ccall unsafe "memset"
      c_memset :: Ptr CRegex -> CInt -> CSize -> IO (Ptr CRegex)

    -- cbits/myfree.h and cbits/myfree.c
    foreign import ccall unsafe "&hs_regex_regfree"
      c_myregfree :: FunPtr (Ptr CRegex -> IO ())

    foreign import ccall unsafe "regex.h regcomp"
      c_regcomp :: Ptr CRegex -> CString -> CompOption -> IO ReturnCode

    {- currently unused
    foreign import ccall unsafe "regex.h &regfree"
      c_regfree :: FunPtr (Ptr CRegex -> IO ())
    -}

    foreign import ccall unsafe "regex.h regexec"
      c_regexec :: Ptr CRegex -> CString -> CSize
                -> Ptr CRegMatch -> ExecOption -> IO ReturnCode

    foreign import ccall unsafe "regex.h regerror"
      c_regerror :: ReturnCode -> Ptr CRegex
                 -> CString -> CSize -> IO CSize

    retOk :: ReturnCode
    retOk :: ReturnCode
    retOk = CInt -> ReturnCode
    ReturnCode CInt
    0

    -- Flags for regexec
    execNotBOL  :: ExecOption
    execNotBOL :: ExecOption
    execNotBOL  = CInt -> ExecOption
    ExecOption CInt
    1
    execNotEOL  :: ExecOption
    execNotEOL :: ExecOption
    execNotEOL  = CInt -> ExecOption
    ExecOption CInt
    2

    {-# LINE 322 "src/Text/Regex/Posix/Wrap.hsc" #-}

    -- Flags for regcomp
    compExtended  :: CompOption
    compExtended :: CompOption
    compExtended  = CInt -> CompOption
    CompOption CInt
    1
    compIgnoreCase  :: CompOption
    compIgnoreCase :: CompOption
    compIgnoreCase  = CInt -> CompOption
    CompOption CInt
    2
    compNoSub  :: CompOption
    compNoSub :: CompOption
    compNoSub  = CInt -> CompOption
    CompOption CInt
    8
    compNewline  :: CompOption
    compNewline :: CompOption
    compNewline  = CInt -> CompOption
    CompOption CInt
    4

    {-# LINE 329 "src/Text/Regex/Posix/Wrap.hsc" #-}

    -- Return values from regexec (REG_NOMATCH, REG_ESPACE,...)
    -- Error codes from regcomp (not REG_NOMATCH)
    -- Though calling retNoMatch an error is rather missing the point...
    retNoMatch  :: ReturnCode
    retNoMatch :: ReturnCode
    retNoMatch  = CInt -> ReturnCode
    ReturnCode CInt
    1
    retBadbr  :: ReturnCode
    retBadbr :: ReturnCode
    retBadbr  = CInt -> ReturnCode
    ReturnCode CInt
    10
    retBadpat  :: ReturnCode
    retBadpat :: ReturnCode
    retBadpat  = CInt -> ReturnCode
    ReturnCode CInt
    2
    retBadrpt  :: ReturnCode
    retBadrpt :: ReturnCode
    retBadrpt  = CInt -> ReturnCode
    ReturnCode CInt
    13
    retEcollate  :: ReturnCode
    retEcollate :: ReturnCode
    retEcollate  = CInt -> ReturnCode
    ReturnCode CInt
    3
    retEctype  :: ReturnCode
    retEctype :: ReturnCode
    retEctype  = CInt -> ReturnCode
    ReturnCode CInt
    4
    retEescape  :: ReturnCode
    retEescape :: ReturnCode
    retEescape  = CInt -> ReturnCode
    ReturnCode CInt
    5
    retEsubreg  :: ReturnCode
    retEsubreg :: ReturnCode
    retEsubreg  = CInt -> ReturnCode
    ReturnCode CInt
    6
    retEbrack  :: ReturnCode
    retEbrack :: ReturnCode
    retEbrack  = CInt -> ReturnCode
    ReturnCode CInt
    7
    retEparen  :: ReturnCode
    retEparen :: ReturnCode
    retEparen  = CInt -> ReturnCode
    ReturnCode CInt
    8
    retEbrace  :: ReturnCode
    retEbrace :: ReturnCode
    retEbrace  = CInt -> ReturnCode
    ReturnCode CInt
    9
    retErange  :: ReturnCode
    retErange :: ReturnCode
    retErange  = CInt -> ReturnCode
    ReturnCode CInt
    11
    retEspace  :: ReturnCode
    retEspace :: ReturnCode
    isNewline :: Ptr CChar -> Int -> IO Bool
    retEspace  = CInt -> ReturnCode
    ReturnCode CInt
    12

    {-# LINE 347 "src/Text/Regex/Posix/Wrap.hsc" #-}
    ----
    -- error helpers

    nullTest :: Ptr a -> String -> IO (Either WrapError b) -> IO (Either WrapError b)
    {-# INLINE nullTest #-}
    nullTest ptr msg io = do
      if nullPtr == ptr
        then return (Left (retOk,"Ptr parameter was nullPtr in Text.Regex.TRE.Wrap."++msg))
        else io

    isNewline,isNull :: Ptr CChar -> Int -> IO Bool
    isNewline cstr pos = liftM (newline ==) (peekElemOff cstr pos)
      where newline = toEnum 10
    isNull cstr pos = liftM (nullChar ==) (peekElemOff cstr pos)
      where nullChar = toEnum 0

    {-
    wrapRC :: ReturnCode -> IO (Either WrapError b)
    {-# INLINE wrapRC #-}
    wrapRC r = return (Left (r,"Error in Text.Regex.Posix.Wrap: "++show r))
    -}
    wrapError :: ReturnCode -> Ptr CRegex -> IO (Either WrapError b)
    wrapError :: forall b. ReturnCode -> Ptr CRegex -> IO (Either WrapError b)
    wrapError ReturnCode
    errCode Ptr CRegex
    regex_ptr = do
      -- Call once to compute the error message buffer size
      errBufSize <- ReturnCode -> Ptr CRegex -> Ptr CChar -> CSize -> IO CSize
    c_regerror ReturnCode
    errCode Ptr CRegex
    regex_ptr Ptr CChar
    forall a. Ptr a
    nullPtr CSize
    0
      -- Allocate a temporary buffer to hold the error message
      allocaArray (fromIntegral errBufSize) $ \Ptr CChar
    errBuf -> do
       Ptr CChar
    -> String -> IO (Either WrapError b) -> IO (Either WrapError b)
    forall a b.
    Ptr a
    -> String -> IO (Either WrapError b) -> IO (Either WrapError b)
    nullTest Ptr CChar
    errBuf String
    "wrapError errBuf" (IO (Either WrapError b) -> IO (Either WrapError b))
    -> IO (Either WrapError b) -> IO (Either WrapError b)
    forall a b. (a -> b) -> a -> b
    $ do
        _ <- ReturnCode -> Ptr CRegex -> Ptr CChar -> CSize -> IO CSize
    c_regerror ReturnCode
    errCode Ptr CRegex
    regex_ptr Ptr CChar
    errBuf CSize
    errBufSize
        msg <- peekCAString errBuf :: IO String
        return (Left (errCode, msg))

    ----------
    wrapCompile :: CompOption
    -> ExecOption -> Ptr CChar -> IO (Either WrapError Regex)
    wrapCompile CompOption
    flags ExecOption
    e Ptr CChar
    pattern = do
     Ptr CChar
    -> String
    -> IO (Either WrapError Regex)
    -> IO (Either WrapError Regex)
    forall a b.
    Ptr a
    -> String -> IO (Either WrapError b) -> IO (Either WrapError b)
    nullTest Ptr CChar
    pattern String
    "wrapCompile pattern" (IO (Either WrapError Regex) -> IO (Either WrapError Regex))
    -> IO (Either WrapError Regex) -> IO (Either WrapError Regex)
    forall a b. (a -> b) -> a -> b
    $ do
      e_regex_ptr <- IO (Ptr CRegex) -> IO (Either IOException (Ptr CRegex))
    forall a. IO a -> IO (Either IOException a)
    try (IO (Ptr CRegex) -> IO (Either IOException (Ptr CRegex)))
    -> IO (Ptr CRegex) -> IO (Either IOException (Ptr CRegex))
    forall a b. (a -> b) -> a -> b
    $ Int -> IO (Ptr CRegex)
    forall a. Int -> IO (Ptr a)
    mallocBytes (Int
    64) -- ioError called if nullPtr
    {-# LINE 383 "src/Text/Regex/Posix/Wrap.hsc" #-}
      case e_regex_ptr of
        Left ioerror -> return (Left (retOk,"Text.Regex.Posix.Wrap.wrapCompile: IOError from mallocBytes(regex_t) : "++show ioerror))
        Right raw_regex_ptr -> do
          zero_regex_ptr <- c_memset raw_regex_ptr 0 (64) -- no calloc, so clear the new area to zero
    {-# LINE 387 "src/Text/Regex/Posix/Wrap.hsc" #-}
          regex_fptr <- newForeignPtr c_myregfree zero_regex_ptr -- once pointed-to area is clear it should be safe to add finalizer
          withForeignPtr regex_fptr $ \regex_ptr -> do  -- withForeignPtr is best hygiene here
            errCode <- c_regcomp regex_ptr pattern flags
            if (errCode == retOk)
              then return . Right $ Regex regex_fptr flags e
              else wrapError errCode regex_ptr

    ---------
    wrapTest :: Regex -> Ptr CChar -> IO (Either WrapError Bool)
    wrapTest (Regex ForeignPtr CRegex
    regex_fptr CompOption
    _ ExecOption
    flags) Ptr CChar
    cstr = do
     Ptr CChar
    -> String
    -> IO (Either WrapError Bool)
    -> IO (Either WrapError Bool)
    forall a b.
    Ptr a
    -> String -> IO (Either WrapError b) -> IO (Either WrapError b)
    nullTest Ptr CChar
    cstr String
    "wrapTest" (IO (Either WrapError Bool) -> IO (Either WrapError Bool))
    -> IO (Either WrapError Bool) -> IO (Either WrapError Bool)
    forall a b. (a -> b) -> a -> b
    $ do
      ForeignPtr CRegex
    -> (Ptr CRegex -> IO (Either WrapError Bool))
    -> IO (Either WrapError Bool)
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr CRegex
    regex_fptr ((Ptr CRegex -> IO (Either WrapError Bool))
     -> IO (Either WrapError Bool))
    -> (Ptr CRegex -> IO (Either WrapError Bool))
    -> IO (Either WrapError Bool)
    forall a b. (a -> b) -> a -> b
    $ \Ptr CRegex
    regex_ptr -> do
        r <- Ptr CRegex
    -> Ptr CChar
    -> CSize
    -> Ptr CRegMatch
    -> ExecOption
    -> IO ReturnCode
    c_regexec Ptr CRegex
    regex_ptr Ptr CChar
    cstr CSize
    0 Ptr CRegMatch
    forall a. Ptr a
    nullPtr ExecOption
    flags
        if r == retOk
          then return (Right True)
          else if r == retNoMatch
                  then return (Right False)
                  else wrapError r regex_ptr

    ---------
    wrapMatch :: Regex
    -> Ptr CChar
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    wrapMatch regex :: Regex
    regex@(Regex ForeignPtr CRegex
    regex_fptr CompOption
    compileOptions ExecOption
    flags) Ptr CChar
    cstr = do
     Ptr CChar
    -> String
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    forall a b.
    Ptr a
    -> String -> IO (Either WrapError b) -> IO (Either WrapError b)
    nullTest Ptr CChar
    cstr String
    "wrapMatch cstr" (IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
     -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)])))
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    forall a b. (a -> b) -> a -> b
    $ do
      if (CompOption
    0 CompOption -> CompOption -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CompOption
    compNoSub CompOption -> CompOption -> CompOption
    forall a. Bits a => a -> a -> a
    .&. CompOption
    compileOptions)
        then do
          r <- Regex -> Ptr CChar -> IO (Either WrapError Bool)
    wrapTest Regex
    regex Ptr CChar
    cstr
          case r of
            Right Bool
    True -> Either WrapError (Maybe [(RegOffset, RegOffset)])
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe [(RegOffset, RegOffset)]
    -> Either WrapError (Maybe [(RegOffset, RegOffset)])
    forall a b. b -> Either a b
    Right ([(RegOffset, RegOffset)] -> Maybe [(RegOffset, RegOffset)]
    forall a. a -> Maybe a
    Just [])) -- Source of much "wtf?" crap
            Right Bool
    False -> Either WrapError (Maybe [(RegOffset, RegOffset)])
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe [(RegOffset, RegOffset)]
    -> Either WrapError (Maybe [(RegOffset, RegOffset)])
    forall a b. b -> Either a b
    Right Maybe [(RegOffset, RegOffset)]
    forall a. Maybe a
    Nothing)
            Left WrapError
    err -> Either WrapError (Maybe [(RegOffset, RegOffset)])
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (WrapError -> Either WrapError (Maybe [(RegOffset, RegOffset)])
    forall a b. a -> Either a b
    Left WrapError
    err)
        else do
          ForeignPtr CRegex
    -> (Ptr CRegex
        -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)])))
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr CRegex
    regex_fptr ((Ptr CRegex
      -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)])))
     -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)])))
    -> (Ptr CRegex
        -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)])))
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    forall a b. (a -> b) -> a -> b
    $ \Ptr CRegex
    regex_ptr -> do
            nsub <- ((\Ptr CRegex
    hsc_ptr -> Ptr CRegex -> Int -> IO CSize
    forall b. Ptr b -> Int -> IO CSize
    forall a b. Storable a => Ptr b -> Int -> IO a
    peekByteOff Ptr CRegex
    hsc_ptr Int
    48)) Ptr CRegex
    regex_ptr :: IO CSize
    {-# LINE 418 "src/Text/Regex/Posix/Wrap.hsc" #-}
            let nsub_int,nsub_bytes :: Int
                nsub_int = CSize -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral CSize
    nsub
                nsub_bytes = ((Int
    1 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    nsub_int) Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * (Int
    8))
    {-# LINE 421 "src/Text/Regex/Posix/Wrap.hsc" #-}
            -- add one because index zero covers the whole match
            allocaBytes nsub_bytes $ \Ptr CRegMatch
    p_match -> do
             Ptr CRegMatch
    -> String
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    forall a b.
    Ptr a
    -> String -> IO (Either WrapError b) -> IO (Either WrapError b)
    nullTest Ptr CRegMatch
    p_match String
    "wrapMatch allocaBytes" (IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
     -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)])))
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    forall a b. (a -> b) -> a -> b
    $ do
              Ptr CRegex
    -> Ptr CChar
    -> CSize
    -> Ptr CRegMatch
    -> ExecOption
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    doMatch Ptr CRegex
    regex_ptr Ptr CChar
    cstr CSize
    nsub Ptr CRegMatch
    p_match ExecOption
    flags

    -- Very very thin wrapper
    -- Requires, but does not check, that nsub>=0
    -- Cannot return (Right (Just []))
    doMatch :: Ptr CRegex -> CString -> CSize -> Ptr CRegMatch -> ExecOption
            -> IO (Either WrapError (Maybe [(RegOffset,RegOffset)]))
    {-# INLINE doMatch #-}
    doMatch :: Ptr CRegex
    -> Ptr CChar
    -> CSize
    -> Ptr CRegMatch
    -> ExecOption
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    doMatch Ptr CRegex
    regex_ptr Ptr CChar
    cstr CSize
    nsub Ptr CRegMatch
    p_match ExecOption
    flags = do
      r <- Ptr CRegex
    -> Ptr CChar
    -> CSize
    -> Ptr CRegMatch
    -> ExecOption
    -> IO ReturnCode
    c_regexec Ptr CRegex
    regex_ptr Ptr CChar
    cstr (CSize
    1 CSize -> CSize -> CSize
    forall a. Num a => a -> a -> a
    + CSize
    nsub) Ptr CRegMatch
    p_match ExecOption
    flags
      if r == retOk
        then do
           regions <- mapM getOffsets . take (1+fromIntegral nsub)
                      . iterate (`plusPtr` (8)) $ p_match
    {-# LINE 438 "src/Text/Regex/Posix/Wrap.hsc" #-}
           return (Right (Just regions)) -- regions will not be []
        else if r == retNoMatch
           then return (Right Nothing)
           else wrapError r regex_ptr
      where
        getOffsets :: Ptr CRegMatch -> IO (RegOffset,RegOffset)
        {-# INLINE getOffsets #-}
        getOffsets :: Ptr CRegMatch -> IO (RegOffset, RegOffset)
    getOffsets Ptr CRegMatch
    pmatch' = do
          start <- ((\Ptr CRegMatch
    hsc_ptr -> Ptr CRegMatch -> Int -> IO Int32
    forall b. Ptr b -> Int -> IO Int32
    forall a b. Storable a => Ptr b -> Int -> IO a
    peekByteOff Ptr CRegMatch
    hsc_ptr Int
    0)) Ptr CRegMatch
    pmatch' :: IO (Int32)
    {-# LINE 447 "src/Text/Regex/Posix/Wrap.hsc" #-}
          end   <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) pmatch' :: IO (Int32)
    {-# LINE 448 "src/Text/Regex/Posix/Wrap.hsc" #-}
          return (fromIntegral start,fromIntegral end)

    wrapMatchAll :: Regex -> Ptr CChar -> IO (Either WrapError [MatchArray])
    wrapMatchAll regex :: Regex
    regex@(Regex ForeignPtr CRegex
    regex_fptr CompOption
    compileOptions ExecOption
    flags) Ptr CChar
    cstr = do
     Ptr CChar
    -> String
    -> IO (Either WrapError [MatchArray])
    -> IO (Either WrapError [MatchArray])
    forall a b.
    Ptr a
    -> String -> IO (Either WrapError b) -> IO (Either WrapError b)
    nullTest Ptr CChar
    cstr String
    "wrapMatchAll cstr" (IO (Either WrapError [MatchArray])
     -> IO (Either WrapError [MatchArray]))
    -> IO (Either WrapError [MatchArray])
    -> IO (Either WrapError [MatchArray])
    forall a b. (a -> b) -> a -> b
    $ do
      if (CompOption
    0 CompOption -> CompOption -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CompOption
    compNoSub CompOption -> CompOption -> CompOption
    forall a. Bits a => a -> a -> a
    .&. CompOption
    compileOptions)
        then do
          r <- Regex -> Ptr CChar -> IO (Either WrapError Bool)
    wrapTest Regex
    regex Ptr CChar
    cstr
          case r of
            Right Bool
    True -> Either WrapError [MatchArray] -> IO (Either WrapError [MatchArray])
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([MatchArray] -> Either WrapError [MatchArray]
    forall a b. b -> Either a b
    Right [(Int -> [(RegOffset, RegOffset)] -> MatchArray
    toMA Int
    0 [])]) -- Source of much "wtf?" crap
            Right Bool
    False -> Either WrapError [MatchArray] -> IO (Either WrapError [MatchArray])
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([MatchArray] -> Either WrapError [MatchArray]
    forall a b. b -> Either a b
    Right [])
            Left WrapError
    err -> Either WrapError [MatchArray] -> IO (Either WrapError [MatchArray])
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (WrapError -> Either WrapError [MatchArray]
    forall a b. a -> Either a b
    Left WrapError
    err)
        else do
          ForeignPtr CRegex
    -> (Ptr CRegex -> IO (Either WrapError [MatchArray]))
    -> IO (Either WrapError [MatchArray])
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr CRegex
    regex_fptr ((Ptr CRegex -> IO (Either WrapError [MatchArray]))
     -> IO (Either WrapError [MatchArray]))
    -> (Ptr CRegex -> IO (Either WrapError [MatchArray]))
    -> IO (Either WrapError [MatchArray])
    forall a b. (a -> b) -> a -> b
    $ \Ptr CRegex
    regex_ptr -> do
            nsub <- ((\Ptr CRegex
    hsc_ptr -> Ptr CRegex -> Int -> IO CSize
    forall b. Ptr b -> Int -> IO CSize
    forall a b. Storable a => Ptr b -> Int -> IO a
    peekByteOff Ptr CRegex
    hsc_ptr Int
    48)) Ptr CRegex
    regex_ptr :: IO CSize
    {-# LINE 462 "src/Text/Regex/Posix/Wrap.hsc" #-}
            let nsub_int,nsub_bytes :: Int
                nsub_int = CSize -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral CSize
    nsub
                nsub_bytes = ((Int
    1 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    nsub_int) Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * (Int
    8))
    {-# LINE 465 "src/Text/Regex/Posix/Wrap.hsc" #-}
            -- add one because index zero covers the whole match
            allocaBytes nsub_bytes $ \Ptr CRegMatch
    p_match -> do
             Ptr CRegMatch
    -> String
    -> IO (Either WrapError [MatchArray])
    -> IO (Either WrapError [MatchArray])
    forall a b.
    Ptr a
    -> String -> IO (Either WrapError b) -> IO (Either WrapError b)
    nullTest Ptr CRegMatch
    p_match String
    "wrapMatchAll p_match" (IO (Either WrapError [MatchArray])
     -> IO (Either WrapError [MatchArray]))
    -> IO (Either WrapError [MatchArray])
    -> IO (Either WrapError [MatchArray])
    forall a b. (a -> b) -> a -> b
    $ do
              let flagsBOL :: ExecOption
    flagsBOL = (ExecOption -> ExecOption
    forall a. Bits a => a -> a
    complement ExecOption
    execNotBOL) ExecOption -> ExecOption -> ExecOption
    forall a. Bits a => a -> a -> a
    .&. ExecOption
    flags
                  flagsMIDDLE :: ExecOption
    flagsMIDDLE = ExecOption
    execNotBOL ExecOption -> ExecOption -> ExecOption
    forall a. Bits a => a -> a -> a
    .|. ExecOption
    flags
                  atBOL :: Int -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    atBOL Int
    pos = Ptr CRegex
    -> Ptr CChar
    -> CSize
    -> Ptr CRegMatch
    -> ExecOption
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    doMatch Ptr CRegex
    regex_ptr (Ptr CChar -> Int -> Ptr CChar
    forall a b. Ptr a -> Int -> Ptr b
    plusPtr Ptr CChar
    cstr Int
    pos) CSize
    nsub Ptr CRegMatch
    p_match ExecOption
    flagsBOL
                  atMIDDLE :: Int -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    atMIDDLE Int
    pos = Ptr CRegex
    -> Ptr CChar
    -> CSize
    -> Ptr CRegMatch
    -> ExecOption
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    doMatch Ptr CRegex
    regex_ptr (Ptr CChar -> Int -> Ptr CChar
    forall a b. Ptr a -> Int -> Ptr b
    plusPtr Ptr CChar
    cstr Int
    pos) CSize
    nsub Ptr CRegMatch
    p_match ExecOption
    flagsMIDDLE
                  loop :: ([MatchArray] -> b)
    -> Int -> (RegOffset, RegOffset) -> IO (Either WrapError b)
    loop [MatchArray] -> b
    acc Int
    old (RegOffset
    s,RegOffset
    e) | [MatchArray] -> b
    acc ([MatchArray] -> b) -> Bool -> Bool
    forall a b. a -> b -> b
    `seq` Int
    old Int -> Bool -> Bool
    forall a b. a -> b -> b
    `seq` Bool
    False = IO (Either WrapError b)
    forall a. HasCallStack => a
    undefined
                                     | RegOffset
    s RegOffset -> RegOffset -> Bool
    forall a. Eq a => a -> a -> Bool
    == RegOffset
    e = do
                    let pos :: Int
    pos = Int
    old Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + RegOffset -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral RegOffset
    e -- pos may be 0
                    atEnd <- Ptr CChar -> Int -> IO Bool
    isNull Ptr CChar
    cstr Int
    pos
                    if atEnd then return (Right (acc []))
                      else loop acc old (s,succ e)
                                     | Bool
    otherwise = do
                    let pos :: Int
    pos = Int
    old Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + RegOffset -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral RegOffset
    e -- pos must be greater than 0 (tricky but true)
                    prev'newline <- Ptr CChar -> Int -> IO Bool
    isNewline Ptr CChar
    cstr (Int -> Int
    forall a. Enum a => a -> a
    pred Int
    pos) -- safe
                    result <- if prev'newline then atBOL pos else atMIDDLE pos
                    case result of
                      Right Maybe [(RegOffset, RegOffset)]
    Nothing -> Either WrapError b -> IO (Either WrapError b)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (b -> Either WrapError b
    forall a b. b -> Either a b
    Right ([MatchArray] -> b
    acc []))
                      Right (Just parts :: [(RegOffset, RegOffset)]
    parts@((RegOffset, RegOffset)
    whole:[(RegOffset, RegOffset)]
    _)) -> let ma :: MatchArray
    ma = Int -> [(RegOffset, RegOffset)] -> MatchArray
    toMA Int
    pos [(RegOffset, RegOffset)]
    parts
                                                     in ([MatchArray] -> b)
    -> Int -> (RegOffset, RegOffset) -> IO (Either WrapError b)
    loop ([MatchArray] -> b
    acc([MatchArray] -> b)
    -> ([MatchArray] -> [MatchArray]) -> [MatchArray] -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .(MatchArray
    maMatchArray -> [MatchArray] -> [MatchArray]
    forall a. a -> [a] -> [a]
    :)) Int
    pos (RegOffset, RegOffset)
    whole
                      Left WrapError
    err -> Either WrapError b -> IO (Either WrapError b)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (WrapError -> Either WrapError b
    forall a b. a -> Either a b
    Left WrapError
    err)
                      Right (Just []) -> Either WrapError b -> IO (Either WrapError b)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (b -> Either WrapError b
    forall a b. b -> Either a b
    Right ([MatchArray] -> b
    acc [(Int -> [(RegOffset, RegOffset)] -> MatchArray
    toMA Int
    pos [])])) -- should never happen
              result <- Ptr CRegex
    -> Ptr CChar
    -> CSize
    -> Ptr CRegMatch
    -> ExecOption
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    doMatch Ptr CRegex
    regex_ptr Ptr CChar
    cstr CSize
    nsub Ptr CRegMatch
    p_match ExecOption
    flags
              case result of
                Right Maybe [(RegOffset, RegOffset)]
    Nothing -> Either WrapError [MatchArray] -> IO (Either WrapError [MatchArray])
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([MatchArray] -> Either WrapError [MatchArray]
    forall a b. b -> Either a b
    Right [])
                Right (Just parts :: [(RegOffset, RegOffset)]
    parts@((RegOffset, RegOffset)
    whole:[(RegOffset, RegOffset)]
    _)) -> let ma :: MatchArray
    ma = Int -> [(RegOffset, RegOffset)] -> MatchArray
    toMA Int
    0 [(RegOffset, RegOffset)]
    parts
                                                in ([MatchArray] -> [MatchArray])
    -> Int
    -> (RegOffset, RegOffset)
    -> IO (Either WrapError [MatchArray])
    forall {b}.
    ([MatchArray] -> b)
    -> Int -> (RegOffset, RegOffset) -> IO (Either WrapError b)
    loop (MatchArray
    maMatchArray -> [MatchArray] -> [MatchArray]
    forall a. a -> [a] -> [a]
    :) Int
    0 (RegOffset, RegOffset)
    whole
                Left WrapError
    err -> Either WrapError [MatchArray] -> IO (Either WrapError [MatchArray])
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (WrapError -> Either WrapError [MatchArray]
    forall a b. a -> Either a b
    Left WrapError
    err)
                Right (Just []) -> Either WrapError [MatchArray] -> IO (Either WrapError [MatchArray])
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([MatchArray] -> Either WrapError [MatchArray]
    forall a b. b -> Either a b
    Right [(Int -> [(RegOffset, RegOffset)] -> MatchArray
    toMA Int
    0 [])]) -- should never happen
      where
        toMA :: Int -> [(RegOffset,RegOffset)] -> Array Int (Int,Int)
        toMA :: Int -> [(RegOffset, RegOffset)] -> MatchArray
    toMA Int
    pos [] = (Int, Int) -> [(Int, Int)] -> MatchArray
    forall i e. Ix i => (i, i) -> [e] -> Array i e
    listArray (Int
    0,Int
    0) [(Int
    pos,Int
    0)] -- wtf?
        toMA Int
    pos [(RegOffset, RegOffset)]
    parts = (Int, Int) -> [(Int, Int)] -> MatchArray
    forall i e. Ix i => (i, i) -> [e] -> Array i e
    listArray (Int
    0,Int -> Int
    forall a. Enum a => a -> a
    pred ([(RegOffset, RegOffset)] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [(RegOffset, RegOffset)]
    parts))
          ([(Int, Int)] -> MatchArray)
    -> ([(RegOffset, RegOffset)] -> [(Int, Int)])
    -> [(RegOffset, RegOffset)]
    -> MatchArray
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((RegOffset, RegOffset) -> (Int, Int))
    -> [(RegOffset, RegOffset)] -> [(Int, Int)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(RegOffset
    s,RegOffset
    e)-> if RegOffset
    sRegOffset -> RegOffset -> Bool
    forall a. Ord a => a -> a -> Bool
    >=RegOffset
    0 then (Int
    posInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +RegOffset -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral RegOffset
    s, RegOffset -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (RegOffset
    eRegOffset -> RegOffset -> RegOffset
    forall a. Num a => a -> a -> a
    -RegOffset
    s)) else (-Int
    1,Int
    0))
          ([(RegOffset, RegOffset)] -> MatchArray)
    -> [(RegOffset, RegOffset)] -> MatchArray
    forall a b. (a -> b) -> a -> b
    $ [(RegOffset, RegOffset)]
    parts

    ---------
    wrapCount :: Regex -> Ptr CChar -> IO (Either WrapError Int)
    wrapCount regex :: Regex
    regex@(Regex ForeignPtr CRegex
    regex_fptr CompOption
    compileOptions ExecOption
    flags) Ptr CChar
    cstr = do
     Ptr CChar
    -> String -> IO (Either WrapError Int) -> IO (Either WrapError Int)
    forall a b.
    Ptr a
    -> String -> IO (Either WrapError b) -> IO (Either WrapError b)
    nullTest Ptr CChar
    cstr String
    "wrapCount cstr" (IO (Either WrapError Int) -> IO (Either WrapError Int))
    -> IO (Either WrapError Int) -> IO (Either WrapError Int)
    forall a b. (a -> b) -> a -> b
    $ do
      if (CompOption
    0 CompOption -> CompOption -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CompOption
    compNoSub CompOption -> CompOption -> CompOption
    forall a. Bits a => a -> a -> a
    .&. CompOption
    compileOptions)
        then do
          r <- Regex -> Ptr CChar -> IO (Either WrapError Bool)
    wrapTest Regex
    regex Ptr CChar
    cstr
          case r of
            Right Bool
    True -> Either WrapError Int -> IO (Either WrapError Int)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Int -> Either WrapError Int
    forall a b. b -> Either a b
    Right Int
    1)
            Right Bool
    False -> Either WrapError Int -> IO (Either WrapError Int)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Int -> Either WrapError Int
    forall a b. b -> Either a b
    Right Int
    0)
            Left WrapError
    err -> Either WrapError Int -> IO (Either WrapError Int)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (WrapError -> Either WrapError Int
    forall a b. a -> Either a b
    Left WrapError
    err)
        else do
          ForeignPtr CRegex
    -> (Ptr CRegex -> IO (Either WrapError Int))
    -> IO (Either WrapError Int)
    forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
    withForeignPtr ForeignPtr CRegex
    regex_fptr ((Ptr CRegex -> IO (Either WrapError Int))
     -> IO (Either WrapError Int))
    -> (Ptr CRegex -> IO (Either WrapError Int))
    -> IO (Either WrapError Int)
    forall a b. (a -> b) -> a -> b
    $ \Ptr CRegex
    regex_ptr -> do
            let nsub_bytes :: Int
    nsub_bytes = ((Int
    8))
    {-# LINE 515 "src/Text/Regex/Posix/Wrap.hsc" #-}
            Int
    -> (Ptr CRegMatch -> IO (Either WrapError Int))
    -> IO (Either WrapError Int)
    forall a b. Int -> (Ptr a -> IO b) -> IO b
    allocaBytes Int
    nsub_bytes ((Ptr CRegMatch -> IO (Either WrapError Int))
     -> IO (Either WrapError Int))
    -> (Ptr CRegMatch -> IO (Either WrapError Int))
    -> IO (Either WrapError Int)
    forall a b. (a -> b) -> a -> b
    $ \Ptr CRegMatch
    p_match -> do
             Ptr CRegMatch
    -> String -> IO (Either WrapError Int) -> IO (Either WrapError Int)
    forall a b.
    Ptr a
    -> String -> IO (Either WrapError b) -> IO (Either WrapError b)
    nullTest Ptr CRegMatch
    p_match String
    "wrapCount p_match" (IO (Either WrapError Int) -> IO (Either WrapError Int))
    -> IO (Either WrapError Int) -> IO (Either WrapError Int)
    forall a b. (a -> b) -> a -> b
    $ do
              let flagsBOL :: ExecOption
    flagsBOL = (ExecOption -> ExecOption
    forall a. Bits a => a -> a
    complement ExecOption
    execNotBOL) ExecOption -> ExecOption -> ExecOption
    forall a. Bits a => a -> a -> a
    .&. ExecOption
    flags
                  flagsMIDDLE :: ExecOption
    flagsMIDDLE = ExecOption
    execNotBOL ExecOption -> ExecOption -> ExecOption
    forall a. Bits a => a -> a -> a
    .|. ExecOption
    flags
                  atBOL :: Int -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    atBOL Int
    pos = Ptr CRegex
    -> Ptr CChar
    -> CSize
    -> Ptr CRegMatch
    -> ExecOption
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    doMatch Ptr CRegex
    regex_ptr (Ptr CChar -> Int -> Ptr CChar
    forall a b. Ptr a -> Int -> Ptr b
    plusPtr Ptr CChar
    cstr Int
    pos) CSize
    0 Ptr CRegMatch
    p_match ExecOption
    flagsBOL
                  atMIDDLE :: Int -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    atMIDDLE Int
    pos = Ptr CRegex
    -> Ptr CChar
    -> CSize
    -> Ptr CRegMatch
    -> ExecOption
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    doMatch Ptr CRegex
    regex_ptr (Ptr CChar -> Int -> Ptr CChar
    forall a b. Ptr a -> Int -> Ptr b
    plusPtr Ptr CChar
    cstr Int
    pos) CSize
    0 Ptr CRegMatch
    p_match ExecOption
    flagsMIDDLE
                  loop :: t -> Int -> (RegOffset, RegOffset) -> IO (Either WrapError t)
    loop t
    acc Int
    old (RegOffset
    s,RegOffset
    e) | t
    acc t -> Bool -> Bool
    forall a b. a -> b -> b
    `seq` Int
    old Int -> Bool -> Bool
    forall a b. a -> b -> b
    `seq` Bool
    False = IO (Either WrapError t)
    forall a. HasCallStack => a
    undefined
                                     | RegOffset
    s RegOffset -> RegOffset -> Bool
    forall a. Eq a => a -> a -> Bool
    == RegOffset
    e = do
                    let pos :: Int
    pos = Int
    old Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + RegOffset -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral RegOffset
    e -- 0 <= pos
                    atEnd <- Ptr CChar -> Int -> IO Bool
    isNull Ptr CChar
    cstr Int
    pos
                    if atEnd then return (Right acc)
                      else loop acc old (s,succ e)
                                     | Bool
    otherwise = do
                    let pos :: Int
    pos = Int
    old Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + RegOffset -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral RegOffset
    e -- 0 < pos
                    prev'newline <- Ptr CChar -> Int -> IO Bool
    isNewline Ptr CChar
    cstr (Int -> Int
    forall a. Enum a => a -> a
    pred Int
    pos) -- safe
                    result <- if prev'newline then atBOL pos else atMIDDLE pos
                    case result of
                      Right Maybe [(RegOffset, RegOffset)]
    Nothing -> Either WrapError t -> IO (Either WrapError t)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (t -> Either WrapError t
    forall a b. b -> Either a b
    Right t
    acc)
                      Right (Just ((RegOffset, RegOffset)
    whole:[(RegOffset, RegOffset)]
    _)) -> t -> Int -> (RegOffset, RegOffset) -> IO (Either WrapError t)
    loop (t -> t
    forall a. Enum a => a -> a
    succ t
    acc) Int
    pos (RegOffset, RegOffset)
    whole
                      Left WrapError
    err -> Either WrapError t -> IO (Either WrapError t)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (WrapError -> Either WrapError t
    forall a b. a -> Either a b
    Left WrapError
    err)
                      Right (Just []) -> Either WrapError t -> IO (Either WrapError t)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (t -> Either WrapError t
    forall a b. b -> Either a b
    Right t
    acc) -- should never happen
              result <- Ptr CRegex
    -> Ptr CChar
    -> CSize
    -> Ptr CRegMatch
    -> ExecOption
    -> IO (Either WrapError (Maybe [(RegOffset, RegOffset)]))
    doMatch Ptr CRegex
    regex_ptr Ptr CChar
    cstr CSize
    0 Ptr CRegMatch
    p_match ExecOption
    flags
              case result of
                Right Maybe [(RegOffset, RegOffset)]
    Nothing -> Either WrapError Int -> IO (Either WrapError Int)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Int -> Either WrapError Int
    forall a b. b -> Either a b
    Right Int
    0)
                Right (Just ((RegOffset, RegOffset)
    whole:[(RegOffset, RegOffset)]
    _)) -> Int -> Int -> (RegOffset, RegOffset) -> IO (Either WrapError Int)
    forall {t}.
    Enum t =>
    t -> Int -> (RegOffset, RegOffset) -> IO (Either WrapError t)
    loop Int
    1 Int
    0 (RegOffset, RegOffset)
    whole
                Left WrapError
    err -> Either WrapError Int -> IO (Either WrapError Int)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (WrapError -> Either WrapError Int
    forall a b. a -> Either a b
    Left WrapError
    err)
                Right (Just []) -> Either WrapError Int -> IO (Either WrapError Int)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Int -> Either WrapError Int
    forall a b. b -> Either a b
    Right Int
    0) -- should never happen

    {-

    -- This is the slower 0.66 version of the code (91s instead of 79s on 10^6 bytes)

    wrapMatchAll regex cstr = do
      let regex' = setExecOpts (execNotBOL .|. (getExecOpts regex)) regex
          at pos = wrapMatch regex' (plusPtr cstr pos)
          loop old (s,e) | s == e = return []
                         | otherwise = do
            let pos = old + fromIntegral e
            result <- at pos
            case unwrap result of
              Nothing -> return []
              Just [] -> return ((toMA pos []):[]) -- wtf?
              Just parts@(whole:_) -> do rest <- loop pos whole
                                         return ((toMA pos parts) : rest)
      result <- wrapMatch regex cstr
      case unwrap result of
        Nothing -> return []
        Just [] -> return ((toMA 0 []):[]) -- wtf?
        Just parts@(whole:_) -> do rest <- loop 0 whole
                                   return ((toMA 0 parts) : rest)
    ---------
    -- This was also changed to match wrapMatchAll after 0.66
    wrapCount regex cstr = do
      let regex' = setExecOpts (execNotBOL .|. (getExecOpts regex)) regex
          at pos = wrapMatch regex' (plusPtr cstr pos)
          loop acc old (s,e) | acc `seq` old `seq` False = undefined
                             | s == e = return acc
                             | otherwise = do
            let pos = old + fromIntegral e
            result <- at pos
            case unwrap result of
              Nothing -> return acc
              Just [] -> return (succ acc) -- wtf?
              Just (whole:_) -> loop (succ acc) pos whole
      result <- wrapMatch regex cstr
      case unwrap result of
        Nothing -> return 0
        Just [] -> return 1 -- wtf?
        Just (whole:_) -> loop 1 0 whole
    -}