{-|
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 = forall a b. RegexLike a b => a -> b -> b
polymatch
  matchM :: forall (m :: * -> *).
MonadFail m =>
Regex -> ByteString -> m ByteString
matchM = 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 = forall regex compOpt execOpt source (m :: * -> *).
(RegexMaker regex compOpt execOpt source, MonadFail m) =>
compOpt -> execOpt -> source -> 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 = forall a. [a] -> Maybe a
listToMaybe (forall regex source.
RegexLike regex source =>
regex -> source -> [MatchArray]
matchAll Regex
r ByteString
s)
  matchAll :: Regex -> ByteString -> [MatchArray]
matchAll Regex
r ByteString
s = 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 = forall (t :: * -> *) a. Foldable t => t a -> MatchOffset
length (forall regex source.
RegexLike regex source =>
regex -> source -> [MatchArray]
matchAll Regex
r' ByteString
s)
    where r' :: Regex
r' = Regex
r { regex_execOptions :: ExecOption
regex_execOptions = (Regex -> ExecOption
regex_execOptions Regex
r) {captureGroups :: Bool
captureGroups = Bool
False} }
  matchTest :: Regex -> ByteString -> Bool
matchTest = forall text. Uncons text => Regex -> text -> Bool
Tester.matchTest
  matchOnceText :: Regex
-> ByteString
-> Maybe (ByteString, MatchText ByteString, ByteString)
matchOnceText Regex
regex ByteString
source =
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\MatchArray
ma ->
            let (MatchOffset
o32,MatchOffset
l32) = MatchArray
maforall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!MatchOffset
0
                o :: Int64
o = forall a b. (Integral a, Num b) => a -> b
fi MatchOffset
o32
                l :: Int64
l = forall a b. (Integral a, Num b) => a -> b
fi MatchOffset
l32
            in (Int64 -> ByteString -> ByteString
L.take Int64
o ByteString
source
               ,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 = forall a b. (Integral a, Num b) => a -> b
fi MatchOffset
off32
                            len :: Int64
len = 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
oforall a. Num a => a -> a -> a
+Int64
l) ByteString
source))
         (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 seq :: forall a b. a -> b -> b
`seq` Bool
False = 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)
xforall (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 (forall a b. (Integral a, Num b) => a -> b
fi a
len32) (Int64 -> ByteString -> ByteString
L.drop (forall a b. (Integral a, Num b) => a -> b
fi (t
off32forall a. Num a => a -> a -> a
-t
i)) ByteString
t),(t, a)
pair)
              t' :: ByteString
t' = Int64 -> ByteString -> ByteString
L.drop (forall a b. (Integral a, Num b) => a -> b
fi (t
off0forall a. Num a => a -> a -> a
+t
len0forall a. Num a => a -> a -> a
-t
i)) ByteString
t
          in forall (a :: * -> * -> *) e' e i.
(IArray a e', IArray a e, Ix i) =>
(e' -> e) -> a i e' -> a i e
amap forall {a}. Integral a => (t, a) -> (ByteString, (t, a))
trans a i (t, t)
x forall a. a -> [a] -> [a]
: seq :: forall a b. a -> b -> b
seq ByteString
t' (t -> ByteString -> [a i (t, t)] -> [a i (ByteString, (t, t))]
go (t
off0forall a. Num a => a -> a -> a
+t
len0) ByteString
t' [a i (t, t)]
xs)
    in forall {a :: * -> * -> *} {t} {i}.
(IArray a (ByteString, (t, t)), IArray a (t, t), Ix i, Num i,
 Integral t) =>
t -> ByteString -> [a i (t, t)] -> [a i (ByteString, (t, t))]
go MatchOffset
0 ByteString
source (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 = 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 -> forall a b. a -> Either a b
Left ([Char]
"parseRegex for Text.Regex.TDFA.ByteString failed:"forall a. [a] -> [a] -> [a]
++forall a. Show a => a -> [Char]
show ParseError
err)
    Right (Pattern, (MatchOffset, DoPa))
pattern -> 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 = forall a b. b -> Either a b
Right (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 = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$
  case 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 <- forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst (forall (a :: * -> * -> *) e i. (IArray a e, Ix i) => a i e -> [e]
elems MatchText ByteString
mt)
      -> forall a. a -> Maybe a
Just (ByteString
pre, ByteString
main, ByteString
post, [ByteString]
rest)
    Maybe (ByteString, MatchText ByteString, ByteString)
_ -> forall a. Maybe a
Nothing