    {-|
    This modules provides 'RegexMaker' and 'RegexLike' instances for using
    @ByteString@ with the DFA backend ("Text.Regex.Lib.WrapDFAEngine" and
    "Text.Regex.Lazy.DFAEngineFPS").  This module is usually used via
    import "Text.Regex.TDFA".

    This exports instances of the high level API and the medium level
    API of 'compile','execute', and 'regexec'.
    -}
    module Text.Regex.TDFA.ByteString.Lazy(
      Regex
     ,CompOption
     ,ExecOption
     ,compile
     ,execute
     ,regexec
     ) where

    import Data.Array.IArray((!),elems,amap)
    import qualified Data.ByteString.Lazy.Char8 as L(ByteString,take,drop,unpack)

    import Text.Regex.Base(MatchArray,RegexContext(..),RegexMaker(..),RegexLike(..))
    import Text.Regex.Base.Impl(polymatch,polymatchM)
    import Text.Regex.TDFA.ReadRegex(parseRegex)
    import Text.Regex.TDFA.String() -- piggyback on RegexMaker for String
    import Text.Regex.TDFA.TDFA(patternToRegex)
    import Text.Regex.TDFA.Common(Regex(..),CompOption,ExecOption(captureGroups))

    import Data.Maybe(listToMaybe)
    import Text.Regex.TDFA.NewDFA.Engine(execMatch)
    import Text.Regex.TDFA.NewDFA.Tester as Tester(matchTest)

    {- By Chris Kuklewicz, 2007. BSD License, see the LICENSE file. -}

    instance RegexContext Regex L.ByteString L.ByteString where
      match :: Regex -> ByteString -> ByteString
    match = Regex -> ByteString -> ByteString
    forall a b. RegexLike a b => a -> b -> b
    polymatch
      matchM :: forall (m :: * -> *).
    MonadFail m =>
    Regex -> ByteString -> m ByteString
    matchM = Regex -> ByteString -> m ByteString
    forall a b (m :: * -> *).
    (RegexLike a b, MonadFail m) =>
    a -> b -> m b
    polymatchM

    instance RegexMaker Regex CompOption ExecOption L.ByteString where
      makeRegexOptsM :: forall (m :: * -> *).
    MonadFail m =>
    CompOption -> ExecOption -> ByteString -> m Regex
    makeRegexOptsM CompOption
    c ExecOption
    e ByteString
    source = CompOption -> ExecOption -> [Char] -> m Regex
    forall regex compOpt execOpt source (m :: * -> *).
    (RegexMaker regex compOpt execOpt source, MonadFail m) =>
    compOpt -> execOpt -> source -> m regex
    forall (m :: * -> *).
    MonadFail m =>
    CompOption -> ExecOption -> [Char] -> m Regex
    makeRegexOptsM CompOption
    c ExecOption
    e (ByteString -> [Char]
    L.unpack ByteString
    source)

    instance RegexLike Regex L.ByteString where
      matchOnce :: Regex -> ByteString -> Maybe MatchArray
    matchOnce Regex
    r ByteString
    s = [MatchArray] -> Maybe MatchArray
    forall a. [a] -> Maybe a
    listToMaybe (Regex -> ByteString -> [MatchArray]
    forall regex source.
    RegexLike regex source =>
    regex -> source -> [MatchArray]
    matchAll Regex
    r ByteString
    s)
      matchAll :: Regex -> ByteString -> [MatchArray]
    matchAll Regex
    r ByteString
    s = Regex -> MatchOffset -> Char -> ByteString -> [MatchArray]
    forall text.
    Uncons text =>
    Regex -> MatchOffset -> Char -> text -> [MatchArray]
    execMatch Regex
    r MatchOffset
    0 Char
    '\n' ByteString
    s
      matchCount :: Regex -> ByteString -> MatchOffset
    matchCount Regex
    r ByteString
    s = [MatchArray] -> MatchOffset
    forall a. [a] -> MatchOffset
    forall (t :: * -> *) a. Foldable t => t a -> MatchOffset
    length (Regex -> ByteString -> [MatchArray]
    forall regex source.
    RegexLike regex source =>
    regex -> source -> [MatchArray]
    matchAll Regex
    r' ByteString
    s)
        where r' :: Regex
    r' = Regex
    r { regex_execOptions = (regex_execOptions r) {captureGroups = False} }
      matchTest :: Regex -> ByteString -> Bool
    matchTest = Regex -> ByteString -> Bool
    forall text. Uncons text => Regex -> text -> Bool
    Tester.matchTest
      matchOnceText :: Regex
    -> ByteString
    -> Maybe (ByteString, MatchText ByteString, ByteString)
    matchOnceText Regex
    regex ByteString
    source =
        (MatchArray -> (ByteString, MatchText ByteString, ByteString))
    -> Maybe MatchArray
    -> Maybe (ByteString, MatchText ByteString, ByteString)
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\MatchArray
    ma ->
                let (MatchOffset
    o32,MatchOffset
    l32) = MatchArray
    maMatchArray -> MatchOffset -> (MatchOffset, MatchOffset)
    forall (a :: * -> * -> *) e i.
    (IArray a e, Ix i) =>
    a i e -> i -> e
    !MatchOffset
    0
                    o :: Int64
    o = MatchOffset -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fi MatchOffset
    o32
                    l :: Int64
    l = MatchOffset -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fi MatchOffset
    l32
                in (Int64 -> ByteString -> ByteString
    L.take Int64
    o ByteString
    source
                   ,((MatchOffset, MatchOffset)
     -> (ByteString, (MatchOffset, MatchOffset)))
    -> MatchArray -> MatchText ByteString
    forall a b. (a -> b) -> Array MatchOffset a -> Array MatchOffset b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\ol :: (MatchOffset, MatchOffset)
    ol@(MatchOffset
    off32,MatchOffset
    len32) ->
                            let off :: Int64
    off = MatchOffset -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fi MatchOffset
    off32
                                len :: Int64
    len = MatchOffset -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fi MatchOffset
    len32
                            in (Int64 -> ByteString -> ByteString
    L.take Int64
    len (Int64 -> ByteString -> ByteString
    L.drop Int64
    off ByteString
    source),(MatchOffset, MatchOffset)
    ol)) MatchArray
    ma
                   ,Int64 -> ByteString -> ByteString
    L.drop (Int64
    oInt64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    +Int64
    l) ByteString
    source))
             (Regex -> ByteString -> Maybe MatchArray
    forall regex source.
    RegexLike regex source =>
    regex -> source -> Maybe MatchArray
    matchOnce Regex
    regex ByteString
    source)
      matchAllText :: Regex -> ByteString -> [MatchText ByteString]
    matchAllText Regex
    regex ByteString
    source =
        let go :: t -> ByteString -> [a i (t, t)] -> [a i (ByteString, (t, t))]
    go t
    i ByteString
    _ [a i (t, t)]
    _ | t
    i t -> Bool -> Bool
    forall a b. a -> b -> b
    `seq` Bool
    False = [a i (ByteString, (t, t))]
    forall a. HasCallStack => a
    undefined
            go t
    _i ByteString
    _t [] = []
            go t
    i ByteString
    t (a i (t, t)
    x:[a i (t, t)]
    xs) =
              let (t
    off0,t
    len0) = a i (t, t)
    xa i (t, t) -> i -> (t, t)
    forall (a :: * -> * -> *) e i.
    (IArray a e, Ix i) =>
    a i e -> i -> e
    !i
    0
                  trans :: (t, a) -> (ByteString, (t, a))
    trans pair :: (t, a)
    pair@(t
    off32,a
    len32) = (Int64 -> ByteString -> ByteString
    L.take (a -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fi a
    len32) (Int64 -> ByteString -> ByteString
    L.drop (t -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fi (t
    off32t -> t -> t
    forall a. Num a => a -> a -> a
    -t
    i)) ByteString
    t),(t, a)
    pair)
                  t' :: ByteString
    t' = Int64 -> ByteString -> ByteString
    L.drop (t -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fi (t
    off0t -> t -> t
    forall a. Num a => a -> a -> a
    +t
    len0t -> t -> t
    forall a. Num a => a -> a -> a
    -t
    i)) ByteString
    t
              in ((t, t) -> (ByteString, (t, t)))
    -> a i (t, t) -> a i (ByteString, (t, t))
    forall (a :: * -> * -> *) e' e i.
    (IArray a e', IArray a e, Ix i) =>
    (e' -> e) -> a i e' -> a i e
    amap (t, t) -> (ByteString, (t, t))
    forall {a}. Integral a => (t, a) -> (ByteString, (t, a))
    trans a i (t, t)
    x a i (ByteString, (t, t))
    -> [a i (ByteString, (t, t))] -> [a i (ByteString, (t, t))]
    forall a. a -> [a] -> [a]
    : ByteString
    -> [a i (ByteString, (t, t))] -> [a i (ByteString, (t, t))]
    forall a b. a -> b -> b
    seq ByteString
    t' (t -> ByteString -> [a i (t, t)] -> [a i (ByteString, (t, t))]
    go (t
    off0t -> t -> t
    forall a. Num a => a -> a -> a
    +t
    len0) ByteString
    t' [a i (t, t)]
    xs)
        in MatchOffset -> ByteString -> [MatchArray] -> [MatchText ByteString]
    forall {a :: * -> * -> *} {t} {i}.
    (IArray a (t, t), IArray a (ByteString, (t, t)), Ix i, Integral t,
     Num i) =>
    t -> ByteString -> [a i (t, t)] -> [a i (ByteString, (t, t))]
    go MatchOffset
    0 ByteString
    source (Regex -> ByteString -> [MatchArray]
    forall regex source.
    RegexLike regex source =>
    regex -> source -> [MatchArray]
    matchAll Regex
    regex ByteString
    source)

    fi :: (Integral a, Num b) => a -> b
    fi :: forall a b. (Integral a, Num b) => a -> b
    fi = a -> b
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral

    compile :: CompOption -- ^ Flags (summed together)
            -> ExecOption -- ^ Flags (summed together)
            -> L.ByteString -- ^ The regular expression to compile
            -> Either String Regex -- ^ Returns: the compiled regular expression
    compile :: CompOption -> ExecOption -> ByteString -> Either [Char] Regex
    compile CompOption
    compOpt ExecOption
    execOpt ByteString
    bs =
      case [Char] -> Either ParseError (Pattern, (MatchOffset, DoPa))
    parseRegex (ByteString -> [Char]
    L.unpack ByteString
    bs) of
        Left ParseError
    err -> [Char] -> Either [Char] Regex
    forall a b. a -> Either a b
    Left ([Char]
    "parseRegex for Text.Regex.TDFA.ByteString failed:"[Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ParseError -> [Char]
    forall a. Show a => a -> [Char]
    show ParseError
    err)
        Right (Pattern, (MatchOffset, DoPa))
    pattern -> Regex -> Either [Char] Regex
    forall a b. b -> Either a b
    Right ((Pattern, (MatchOffset, DoPa)) -> CompOption -> ExecOption -> Regex
    patternToRegex (Pattern, (MatchOffset, DoPa))
    pattern CompOption
    compOpt ExecOption
    execOpt)

    execute :: Regex        -- ^ Compiled regular expression
            -> L.ByteString -- ^ ByteString to match against
            -> Either String (Maybe MatchArray)
    execute :: Regex -> ByteString -> Either [Char] (Maybe MatchArray)
    execute Regex
    r ByteString
    bs = Maybe MatchArray -> Either [Char] (Maybe MatchArray)
    forall a b. b -> Either a b
    Right (Regex -> ByteString -> Maybe MatchArray
    forall regex source.
    RegexLike regex source =>
    regex -> source -> Maybe MatchArray
    matchOnce Regex
    r ByteString
    bs)

    regexec :: Regex        -- ^ Compiled regular expression
            -> L.ByteString -- ^ ByteString to match against
            -> Either String (Maybe (L.ByteString, L.ByteString, L.ByteString, [L.ByteString]))
    regexec :: Regex
    -> ByteString
    -> Either
         [Char] (Maybe (ByteString, ByteString, ByteString, [ByteString]))
    regexec Regex
    r ByteString
    txt = Maybe (ByteString, ByteString, ByteString, [ByteString])
    -> Either
         [Char] (Maybe (ByteString, ByteString, ByteString, [ByteString]))
    forall a b. b -> Either a b
    Right (Maybe (ByteString, ByteString, ByteString, [ByteString])
     -> Either
          [Char] (Maybe (ByteString, ByteString, ByteString, [ByteString])))
    -> Maybe (ByteString, ByteString, ByteString, [ByteString])
    -> Either
         [Char] (Maybe (ByteString, ByteString, ByteString, [ByteString]))
    forall a b. (a -> b) -> a -> b
    $
      case Regex
    -> ByteString
    -> Maybe (ByteString, MatchText ByteString, ByteString)
    forall regex source.
    RegexLike regex source =>
    regex -> source -> Maybe (source, MatchText source, source)
    matchOnceText Regex
    r ByteString
    txt of
        Just (ByteString
    pre, MatchText ByteString
    mt, ByteString
    post) | ByteString
    main:[ByteString]
    rest <- ((ByteString, (MatchOffset, MatchOffset)) -> ByteString)
    -> [(ByteString, (MatchOffset, MatchOffset))] -> [ByteString]
    forall a b. (a -> b) -> [a] -> [b]
    map (ByteString, (MatchOffset, MatchOffset)) -> ByteString
    forall a b. (a, b) -> a
    fst (MatchText ByteString -> [(ByteString, (MatchOffset, MatchOffset))]
    forall (a :: * -> * -> *) e i. (IArray a e, Ix i) => a i e -> [e]
    elems MatchText ByteString
    mt)
          -> (ByteString, ByteString, ByteString, [ByteString])
    -> Maybe (ByteString, ByteString, ByteString, [ByteString])
    forall a. a -> Maybe a
    Just (ByteString
    pre, ByteString
    main, ByteString
    post, [ByteString]
    rest)
        Maybe (ByteString, MatchText ByteString, ByteString)
    _ -> Maybe (ByteString, ByteString, ByteString, [ByteString])
    forall a. Maybe a
    Nothing