module Text.Regex.TDFA.NewDFA.Tester(matchTest) where
import Control.Monad(MonadPlus(..))
import qualified Data.IntMap.CharMap2 as CMap(findWithDefault)
import qualified Data.IntMap as IMap
import qualified Data.IntSet as ISet(null)
import Data.Sequence(Seq,ViewL(..),viewl)
import qualified Data.Sequence as Seq
import qualified Data.ByteString.Char8 as SBS
import qualified Data.ByteString.Lazy.Char8 as LBS
import Text.Regex.Base()
import Text.Regex.TDFA.Common hiding (indent)
import Text.Regex.TDFA.NewDFA.Uncons (Uncons(uncons))
matchTest :: Uncons text => Regex -> text -> Bool
matchTest (Regex { regex_dfa = dfaIn
, regex_isFrontAnchored = ifa
, regex_compOptions = CompOption { multiline = newline } } )
inputIn = ans where
ans = case ifa of
True -> single0 (d_dt dfaIn) inputIn
False -> multi0 (d_dt dfaIn) inputIn
!test0 = mkTest0 newline
!test = mkTest newline
multi0 (Testing' {dt_test=wt,dt_a=a,dt_b=b}) input =
if test0 wt input
then multi0 a input
else multi0 b input
multi0 (Simple' {dt_win=w,dt_trans=t, dt_other=o}) input
| IMap.null w =
case uncons input of
Nothing -> False
Just (c,input') ->
case CMap.findWithDefault o c t of
Transition {trans_many=DFA {d_dt=dt'}} -> multi dt' c input'
| otherwise = True
multi (Testing' {dt_test=wt,dt_a=a,dt_b=b}) prev input =
if test wt prev input
then multi a prev input
else multi b prev input
multi (Simple' {dt_win=w,dt_trans=t, dt_other=o}) _prev input
| IMap.null w =
case uncons input of
Nothing -> False
Just (c,input') ->
case CMap.findWithDefault o c t of
Transition {trans_many=DFA {d_dt=dt'}} -> multi dt' c input'
| otherwise = True
single0 (Testing' {dt_test=wt,dt_a=a,dt_b=b}) input =
if testFA0 wt input
then single0 a input
else single0 b input
single0 (Simple' {dt_win=w,dt_trans=t, dt_other=o}) input
| IMap.null w =
case uncons input of
Nothing -> False
Just (c,input') ->
case CMap.findWithDefault o c t of
Transition {trans_single=DFA {d_id=did',d_dt=dt'}}
| ISet.null did' -> False
| otherwise -> single dt' input'
| otherwise = True
single (Testing' {dt_test=wt,dt_a=a,dt_b=b}) input =
if testFA wt input
then single a input
else single b input
single (Simple' {dt_win=w,dt_trans=t, dt_other=o}) input
| IMap.null w =
case uncons input of
Nothing -> False
Just (c,input') ->
case CMap.findWithDefault o c t of
Transition {trans_single=DFA {d_id=did',d_dt=dt'}}
| ISet.null did' -> False
| otherwise -> single dt' input'
| otherwise = True
testFA0,testFA :: Uncons text => WhichTest -> text -> Bool
testFA0 Test_BOL _input = True
testFA0 Test_EOL input = case uncons input of
Nothing -> True
_ -> False
testFA Test_BOL _input = False
testFA Test_EOL input = case uncons input of
Nothing -> True
_ -> False
mkTest0 :: Uncons text => Bool -> WhichTest -> text -> Bool
mkTest0 isMultiline = if isMultiline then test_multiline else test_singleline
where test_multiline Test_BOL _input = True
test_multiline Test_EOL input = case uncons input of
Nothing -> True
Just (next,_) -> next == '\n'
test_singleline Test_BOL _input = True
test_singleline Test_EOL input = case uncons input of
Nothing -> True
_ -> False
mkTest :: Uncons text => Bool -> WhichTest -> Char -> text -> Bool
mkTest isMultiline = if isMultiline then test_multiline else test_singleline
where test_multiline Test_BOL prev _input = prev == '\n'
test_multiline Test_EOL _prev input = case uncons input of
Nothing -> True
Just (next,_) -> next == '\n'
test_singleline Test_BOL _prev _input = False
test_singleline Test_EOL _prev input = case uncons input of
Nothing -> True
_ -> False