{-|
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.Sequence(
  Regex
 ,CompOption
 ,ExecOption
 ,compile
 ,execute
 ,regexec
 ) where

import Data.Sequence(Seq)
import Data.Foldable as F(toList)

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

import Data.Array.IArray((!),elems)
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 (Seq Char) (Seq Char) where
  match :: Regex -> Seq Char -> Seq Char
match = forall a b. RegexLike a b => a -> b -> b
polymatch
  matchM :: forall (m :: * -> *).
MonadFail m =>
Regex -> Seq Char -> m (Seq Char)
matchM = forall a b (m :: * -> *).
(RegexLike a b, MonadFail m) =>
a -> b -> m b
polymatchM

instance RegexMaker Regex CompOption ExecOption (Seq Char) where
  makeRegexOptsM :: forall (m :: * -> *).
MonadFail m =>
CompOption -> ExecOption -> Seq Char -> m Regex
makeRegexOptsM CompOption
c ExecOption
e Seq Char
source =
    case String -> Either ParseError (Pattern, (MatchOffset, DoPa))
parseRegex (forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList Seq Char
source) of
      Left ParseError
err -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"parseRegex for Text.Regex.TDFA.Sequence failed:"forall a. [a] -> [a] -> [a]
++forall a. Show a => a -> String
show ParseError
err
      Right (Pattern, (MatchOffset, DoPa))
pattern -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (Pattern, (MatchOffset, DoPa)) -> CompOption -> ExecOption -> Regex
patternToRegex (Pattern, (MatchOffset, DoPa))
pattern CompOption
c ExecOption
e

instance RegexLike Regex (Seq Char) where
  matchOnce :: Regex -> Seq Char -> Maybe MatchArray
matchOnce Regex
r Seq Char
s = forall a. [a] -> Maybe a
listToMaybe (forall regex source.
RegexLike regex source =>
regex -> source -> [MatchArray]
matchAll Regex
r Seq Char
s)
  matchAll :: Regex -> Seq Char -> [MatchArray]
matchAll Regex
r Seq Char
s = forall text.
Uncons text =>
Regex -> MatchOffset -> Char -> text -> [MatchArray]
execMatch Regex
r MatchOffset
0 Char
'\n' Seq Char
s
  matchCount :: Regex -> Seq Char -> MatchOffset
matchCount Regex
r Seq Char
s = forall (t :: * -> *) a. Foldable t => t a -> MatchOffset
length (forall regex source.
RegexLike regex source =>
regex -> source -> [MatchArray]
matchAll Regex
r' Seq Char
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 -> Seq Char -> Bool
matchTest = forall text. Uncons text => Regex -> text -> Bool
Tester.matchTest
  matchOnceText :: Regex
-> Seq Char -> Maybe (Seq Char, MatchText (Seq Char), Seq Char)
matchOnceText Regex
regex Seq Char
source =
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\MatchArray
ma -> let (MatchOffset
o,MatchOffset
l) = MatchArray
maforall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!MatchOffset
0
                 in (forall source. Extract source => MatchOffset -> source -> source
before MatchOffset
o Seq Char
source
                    ,forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(MatchOffset, MatchOffset)
ol -> (forall source.
Extract source =>
(MatchOffset, MatchOffset) -> source -> source
extract (MatchOffset, MatchOffset)
ol Seq Char
source,(MatchOffset, MatchOffset)
ol)) MatchArray
ma
                    ,forall source. Extract source => MatchOffset -> source -> source
after (MatchOffset
oforall a. Num a => a -> a -> a
+MatchOffset
l) Seq Char
source))
         (forall regex source.
RegexLike regex source =>
regex -> source -> Maybe MatchArray
matchOnce Regex
regex Seq Char
source)
  matchAllText :: Regex -> Seq Char -> [MatchText (Seq Char)]
matchAllText Regex
regex Seq Char
source =
    forall a b. (a -> b) -> [a] -> [b]
map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(MatchOffset, MatchOffset)
ol -> (forall source.
Extract source =>
(MatchOffset, MatchOffset) -> source -> source
extract (MatchOffset, MatchOffset)
ol Seq Char
source,(MatchOffset, MatchOffset)
ol)))
        (forall regex source.
RegexLike regex source =>
regex -> source -> [MatchArray]
matchAll Regex
regex Seq Char
source)

compile :: CompOption -- ^ Flags (summed together)
        -> ExecOption -- ^ Flags (summed together)
        -> Seq Char   -- ^ The regular expression to compile
        -> Either String Regex -- ^ Returns: the compiled regular expression
compile :: CompOption -> ExecOption -> Seq Char -> Either String Regex
compile CompOption
compOpt ExecOption
execOpt Seq Char
bs =
  case String -> Either ParseError (Pattern, (MatchOffset, DoPa))
parseRegex (forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList Seq Char
bs) of
    Left ParseError
err -> forall a b. a -> Either a b
Left (String
"parseRegex for Text.Regex.TDFA.Sequence failed:"forall a. [a] -> [a] -> [a]
++forall a. Show a => a -> String
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
        -> Seq Char -- ^ String to match against
        -> Either String (Maybe MatchArray)
execute :: Regex -> Seq Char -> Either String (Maybe MatchArray)
execute Regex
r Seq Char
bs = forall a b. b -> Either a b
Right (forall regex source.
RegexLike regex source =>
regex -> source -> Maybe MatchArray
matchOnce Regex
r Seq Char
bs)

regexec :: Regex    -- ^ Compiled regular expression
        -> Seq Char -- ^ String to match against
        -> Either String (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))
regexec :: Regex
-> Seq Char
-> Either String (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))
regexec Regex
r Seq Char
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 Seq Char
txt of
    Just (Seq Char
pre, MatchText (Seq Char)
mt, Seq Char
post) | Seq Char
main:[Seq Char]
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 (Seq Char)
mt)
      -> forall a. a -> Maybe a
Just (Seq Char
pre, Seq Char
main, Seq Char
post, [Seq Char]
rest)
    Maybe (Seq Char, MatchText (Seq Char), Seq Char)
_ -> forall a. Maybe a
Nothing