    {-# LANGUAGE NoImplicitPrelude          #-}
    {-# LANGUAGE RecordWildCards            #-}
    {-# LANGUAGE MultiParamTypeClasses      #-}
    {-# LANGUAGE TypeSynonymInstances       #-}
    {-# LANGUAGE FlexibleInstances          #-}
    {-# LANGUAGE FlexibleContexts           #-}
    {-# LANGUAGE CPP                        #-}
    #if __GLASGOW_HASKELL__ >= 800
    {-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
    {-# LANGUAGE TemplateHaskellQuotes      #-}
    #else
    {-# LANGUAGE QuasiQuotes                #-}
    {-# LANGUAGE TemplateHaskell            #-}
    #endif
    {-# OPTIONS_GHC -fno-warn-orphans               #-}
    {-# OPTIONS_GHC -fno-warn-unused-imports        #-}

    module Text.RE.ZeInternals.TDFA
      ( -- * About
        -- $about

        -- * RE Type
        RE
      , regexType
      , reOptions
      , reSource
      , reCaptureNames
      , reRegex
      -- * IsOptions Class and REOptions Type
      , IsOption(..)
      , REOptions
      , defaultREOptions
      , noPreludeREOptions
      , unpackSimpleREOptions
      -- * Compiling Regular Expressions
      , compileRegex
      , compileRegexWith
      , compileRegexWithOptions
      , compileRegexWithOptionsForQQ
      -- * Compiling Search-Replace Templates
      , compileSearchReplace
      , compileSearchReplaceWith
      , compileSearchReplaceWithOptions
      -- * Escaping String
      , escape
      , escapeWith
      , escapeWithOptions
      , escapeREString
      -- * Macros Standard Environment
      , prelude
      , preludeEnv
      , preludeTestsFailing
      , preludeTable
      , preludeSummary
      , preludeSources
      , preludeSource
      -- * The Quasi Quoters
      , re
      , reMS
      , reMI
      , reBS
      , reBI
      , reMultilineSensitive
      , reMultilineInsensitive
      , reBlockSensitive
      , reBlockInsensitive
      , re_
      , cp
      ) where

    import           Control.Monad.Fail
    import           Data.Functor.Identity
    import           Language.Haskell.TH
    import           Language.Haskell.TH.Quote
    import           Prelude.Compat                       hiding (fail)
    import           Text.RE.REOptions
    import           Text.RE.Replace
    import           Text.RE.TestBench
    import           Text.RE.Tools
    import           Text.RE.ZeInternals
    import           Text.RE.ZeInternals.Types.Poss
    import           Text.Regex.TDFA

    -- | the RE type for this back end representing a well-formed, compiled
    -- RE
    data RE =
      RE
        { RE -> REOptions
    _re_options :: !REOptions
        , RE -> String
    _re_source  :: !String
        , RE -> CaptureNames
    _re_cnames  :: !CaptureNames
        , RE -> Regex
    _re_regex   :: !Regex
        }

    -- | some functions in the "Text.RE.TestBench" need the back end to
    -- be passed dynamically as a 'RegexType' parameters: use 'regexType'
    -- for this
    regexType :: RegexType
    regexType :: RegexType
    regexType =
      TestBenchMatcher -> RegexType
    mkTDFA (TestBenchMatcher -> RegexType) -> TestBenchMatcher -> RegexType
    forall a b. (a -> b) -> a -> b
    $ \String
    txt MacroEnv
    env MacroDescriptor
    md -> String
    txt String -> String -> Matches String
    forall source source1 target.
    (RegexMaker Regex CompOption ExecOption source,
     RegexContext Regex source1 target) =>
    source1 -> source -> target
    =~ RegexType -> WithCaptures -> MacroEnv -> MacroDescriptor -> String
    mdRegexSource RegexType
    regexType WithCaptures
    ExclCaptures MacroEnv
    env MacroDescriptor
    md

    -- | extract the 'REOptions' from the @RE@
    reOptions :: RE -> REOptions
    reOptions :: RE -> REOptions
    reOptions = RE -> REOptions
    _re_options

    -- | extract the RE source string from the @RE@
    reSource :: RE -> String
    reSource :: RE -> String
    reSource = RE -> String
    _re_source

    -- | extract the 'CaptureNames' from the @RE@
    reCaptureNames :: RE -> CaptureNames
    reCaptureNames :: RE -> CaptureNames
    reCaptureNames = RE -> CaptureNames
    _re_cnames

    -- | extract the back end compiled 'Regex' type from the @RE@
    reRegex :: RE -> Regex
    reRegex :: RE -> Regex
    reRegex = RE -> Regex
    _re_regex

    ------------------------------------------------------------------------
    -- IsOption & REOptions
    ------------------------------------------------------------------------

    -- | a number of types can be used to encode 'REOptions_', each of which
    -- is made a member of this class
    class IsOption o where
      -- | convert the @o@ type into an @REOptions@
      makeREOptions :: o -> REOptions

    -- | and the REOptions for this back end (see "Text.RE.REOptions"
    -- for details)
    type REOptions = REOptions_ RE CompOption ExecOption

    instance IsOption SimpleREOptions where
      makeREOptions :: SimpleREOptions -> REOptions
    makeREOptions    = SimpleREOptions -> REOptions
    unpackSimpleREOptions

    instance IsOption (Macros RE) where
      makeREOptions :: Macros RE -> REOptions
    makeREOptions Macros RE
    ms = Macros RE -> CompOption -> ExecOption -> REOptions
    forall r c e. Macros r -> c -> e -> REOptions_ r c e
    REOptions Macros RE
    ms CompOption
    def_comp_option ExecOption
    def_exec_option

    instance IsOption CompOption where
      makeREOptions :: CompOption -> REOptions
    makeREOptions CompOption
    co = Macros RE -> CompOption -> ExecOption -> REOptions
    forall r c e. Macros r -> c -> e -> REOptions_ r c e
    REOptions Macros RE
    prelude CompOption
    co ExecOption
    def_exec_option

    instance IsOption ExecOption where
      makeREOptions :: ExecOption -> REOptions
    makeREOptions ExecOption
    eo = Macros RE -> CompOption -> ExecOption -> REOptions
    forall r c e. Macros r -> c -> e -> REOptions_ r c e
    REOptions Macros RE
    prelude CompOption
    def_comp_option ExecOption
    eo

    instance IsOption REOptions where
      makeREOptions :: REOptions -> REOptions
    makeREOptions    = REOptions -> REOptions
    forall a. a -> a
    id

    instance IsOption () where
      makeREOptions :: () -> REOptions
    makeREOptions ()
    _  = SimpleREOptions -> REOptions
    unpackSimpleREOptions SimpleREOptions
    forall a. Bounded a => a
    minBound

    -- | the default 'REOptions'
    defaultREOptions :: REOptions
    defaultREOptions :: REOptions
    defaultREOptions = SimpleREOptions -> REOptions
    forall o. IsOption o => o -> REOptions
    makeREOptions (SimpleREOptions
    forall a. Bounded a => a
    minBound::SimpleREOptions)

    -- | the default 'REOptions' but with no RE macros defined
    noPreludeREOptions :: REOptions
    noPreludeREOptions :: REOptions
    noPreludeREOptions = REOptions
    defaultREOptions { optionsMacs = emptyMacros }

    -- | convert a universal 'SimpleReOptions' into the 'REOptions' used
    -- by this back end
    unpackSimpleREOptions :: SimpleREOptions -> REOptions
    unpackSimpleREOptions :: SimpleREOptions -> REOptions
    unpackSimpleREOptions SimpleREOptions
    sro =
      REOptions
        { optionsMacs :: Macros RE
    optionsMacs = Macros RE
    prelude
        , optionsComp :: CompOption
    optionsComp = CompOption
    comp
        , optionsExec :: ExecOption
    optionsExec = ExecOption
    forall regex compOpt execOpt.
    RegexOptions regex compOpt execOpt =>
    execOpt
    defaultExecOpt
        }
      where
        comp :: CompOption
    comp = CompOption
    forall regex compOpt execOpt.
    RegexOptions regex compOpt execOpt =>
    compOpt
    defaultCompOpt
          { caseSensitive = cs
          , multiline     = ml
          }

        (Bool
    ml,Bool
    cs) = case SimpleREOptions
    sro of
            SimpleREOptions
    MultilineSensitive    -> (,) Bool
    True  Bool
    True
            SimpleREOptions
    MultilineInsensitive  -> (,) Bool
    True  Bool
    False
            SimpleREOptions
    BlockSensitive        -> (,) Bool
    False Bool
    True
            SimpleREOptions
    BlockInsensitive      -> (,) Bool
    False Bool
    False

    ------------------------------------------------------------------------
    -- Compiling Regular Expressions
    ------------------------------------------------------------------------

    -- | compile a 'String' into a 'RE' with the default options,
    -- generating an error if the RE is not well formed
    compileRegex :: (Functor m,Monad m,MonadFail m) => String -> m RE
    compileRegex :: forall (m :: * -> *).
    (Functor m, Monad m, MonadFail m) =>
    String -> m RE
    compileRegex = SimpleREOptions -> String -> m RE
    forall (m :: * -> *).
    (Functor m, Monad m, MonadFail m) =>
    SimpleREOptions -> String -> m RE
    compileRegexWith SimpleREOptions
    forall a. Bounded a => a
    minBound

    -- | compile a 'String' into a 'RE' using the given @SimpleREOptions@,
    -- generating an error if the RE is not well formed
    compileRegexWith :: (Functor m,Monad m,MonadFail m) => SimpleREOptions -> String -> m RE
    compileRegexWith :: forall (m :: * -> *).
    (Functor m, Monad m, MonadFail m) =>
    SimpleREOptions -> String -> m RE
    compileRegexWith = SimpleREOptions -> String -> m RE
    forall o (m :: * -> *).
    (IsOption o, Functor m, Monad m, MonadFail m) =>
    o -> String -> m RE
    compileRegexWithOptions

    -- | compile a 'String' into a 'RE' using the given @SimpleREOptions@,
    -- generating an error if the RE is not well formed
    compileRegexWithOptions :: (IsOption o, Functor m, Monad   m, MonadFail m)
                            => o
                            -> String
                            -> m RE
    compileRegexWithOptions :: forall o (m :: * -> *).
    (IsOption o, Functor m, Monad m, MonadFail m) =>
    o -> String -> m RE
    compileRegexWithOptions = RegexParseMode -> REOptions -> String -> m RE
    forall (m :: * -> *).
    (Functor m, MonadFail m, Monad m) =>
    RegexParseMode -> REOptions -> String -> m RE
    compileRegex_ RegexParseMode
    RPM_raw (REOptions -> String -> m RE)
    -> (o -> REOptions) -> o -> String -> m RE
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . o -> REOptions
    forall o. IsOption o => o -> REOptions
    makeREOptions

    -- | compile a 'String' into a 'RE' for q quasi quoter, using the given
    -- @SimpleREOptions@, generating an error if the RE is not well formed
    compileRegexWithOptionsForQQ :: (IsOption o, Functor m, Monad   m,MonadFail m)
                                 => o
                                 -> String
                                 -> m RE
    compileRegexWithOptionsForQQ :: forall o (m :: * -> *).
    (IsOption o, Functor m, Monad m, MonadFail m) =>
    o -> String -> m RE
    compileRegexWithOptionsForQQ = RegexParseMode -> REOptions -> String -> m RE
    forall (m :: * -> *).
    (Functor m, MonadFail m, Monad m) =>
    RegexParseMode -> REOptions -> String -> m RE
    compileRegex_ RegexParseMode
    RPM_qq (REOptions -> String -> m RE)
    -> (o -> REOptions) -> o -> String -> m RE
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . o -> REOptions
    forall o. IsOption o => o -> REOptions
    makeREOptions

    ------------------------------------------------------------------------
    -- Compiling Search Replace Templates
    ------------------------------------------------------------------------

    -- | compile a SearchReplace template generating errors if the RE or
    -- the template are not well formed, all capture references being checked
    compileSearchReplace :: (Monad m,MonadFail m,Functor m,IsRegex RE s)
                         => String
                         -> String
                         -> m (SearchReplace RE s)
    compileSearchReplace :: forall (m :: * -> *) s.
    (Monad m, MonadFail m, Functor m, IsRegex RE s) =>
    String -> String -> m (SearchReplace RE s)
    compileSearchReplace = SimpleREOptions -> String -> String -> m (SearchReplace RE s)
    forall (m :: * -> *) s.
    (Monad m, MonadFail m, Functor m, IsRegex RE s) =>
    SimpleREOptions -> String -> String -> m (SearchReplace RE s)
    compileSearchReplaceWith SimpleREOptions
    forall a. Bounded a => a
    minBound

    -- | compile a SearchReplace template, with simple options, generating
    -- errors if the RE or the template are not well formed, all capture
    -- references being checked
    compileSearchReplaceWith :: (Monad m,MonadFail m,Functor m,IsRegex RE s)
                             => SimpleREOptions
                             -> String
                             -> String
                             -> m (SearchReplace RE s)
    compileSearchReplaceWith :: forall (m :: * -> *) s.
    (Monad m, MonadFail m, Functor m, IsRegex RE s) =>
    SimpleREOptions -> String -> String -> m (SearchReplace RE s)
    compileSearchReplaceWith SimpleREOptions
    sro = (String -> s)
    -> (String -> Either String RE)
    -> String
    -> String
    -> m (SearchReplace RE s)
    forall (m :: * -> *) s re.
    (Monad m, MonadFail m, Functor m) =>
    (String -> s)
    -> (String -> Either String re)
    -> String
    -> String
    -> m (SearchReplace re s)
    compileSearchAndReplace_ String -> s
    forall a. Replace a => String -> a
    packR ((String -> Either String RE)
     -> String -> String -> m (SearchReplace RE s))
    -> (String -> Either String RE)
    -> String
    -> String
    -> m (SearchReplace RE s)
    forall a b. (a -> b) -> a -> b
    $ Poss RE -> Either String RE
    forall a. Poss a -> Either String a
    poss2either (Poss RE -> Either String RE)
    -> (String -> Poss RE) -> String -> Either String RE
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SimpleREOptions -> String -> Poss RE
    forall (m :: * -> *).
    (Functor m, Monad m, MonadFail m) =>
    SimpleREOptions -> String -> m RE
    compileRegexWith SimpleREOptions
    sro

    -- | compile a SearchReplace template, with general options, generating
    -- errors if the RE or the template are not well formed, all capture
    -- references being checked
    compileSearchReplaceWithOptions :: (Monad m,MonadFail m,Functor m,IsRegex RE s)
                                    => REOptions
                                    -> String
                                    -> String
                                    -> m (SearchReplace RE s)
    compileSearchReplaceWithOptions :: forall (m :: * -> *) s.
    (Monad m, MonadFail m, Functor m, IsRegex RE s) =>
    REOptions -> String -> String -> m (SearchReplace RE s)
    compileSearchReplaceWithOptions REOptions
    os = (String -> s)
    -> (String -> Either String RE)
    -> String
    -> String
    -> m (SearchReplace RE s)
    forall (m :: * -> *) s re.
    (Monad m, MonadFail m, Functor m) =>
    (String -> s)
    -> (String -> Either String re)
    -> String
    -> String
    -> m (SearchReplace re s)
    compileSearchAndReplace_ String -> s
    forall a. Replace a => String -> a
    packR ((String -> Either String RE)
     -> String -> String -> m (SearchReplace RE s))
    -> (String -> Either String RE)
    -> String
    -> String
    -> m (SearchReplace RE s)
    forall a b. (a -> b) -> a -> b
    $ Poss RE -> Either String RE
    forall a. Poss a -> Either String a
    poss2either (Poss RE -> Either String RE)
    -> (String -> Poss RE) -> String -> Either String RE
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . REOptions -> String -> Poss RE
    forall o (m :: * -> *).
    (IsOption o, Functor m, Monad m, MonadFail m) =>
    o -> String -> m RE
    compileRegexWithOptions REOptions
    os

    ------------------------------------------------------------------------
    -- Escaping Strings
    ------------------------------------------------------------------------

    -- | convert a string into a RE that matches that string, and apply it
    -- to an argument continuation function to make up the RE string to be
    -- compiled; e.g., to compile a RE that will only match the string:
    --
    --  @maybe undefined id . escape ((\"^\"++) . (++\"$\"))@
    --
    escape :: (Functor m,Monad m,MonadFail m)
           => (String->String)
           -> String
           -> m RE
    escape :: forall (m :: * -> *).
    (Functor m, Monad m, MonadFail m) =>
    (String -> String) -> String -> m RE
    escape = SimpleREOptions -> (String -> String) -> String -> m RE
    forall (m :: * -> *).
    (Functor m, Monad m, MonadFail m) =>
    SimpleREOptions -> (String -> String) -> String -> m RE
    escapeWith SimpleREOptions
    forall a. Bounded a => a
    minBound

    -- | a variant of 'escape' where the 'SimpleREOptions' are specified
    escapeWith :: (Functor m,Monad m,MonadFail m)
               => SimpleREOptions
               -> (String->String)
               -> String
               -> m RE
    escapeWith :: forall (m :: * -> *).
    (Functor m, Monad m, MonadFail m) =>
    SimpleREOptions -> (String -> String) -> String -> m RE
    escapeWith = SimpleREOptions -> (String -> String) -> String -> m RE
    forall o (m :: * -> *).
    (IsOption o, Functor m, Monad m, MonadFail m) =>
    o -> (String -> String) -> String -> m RE
    escapeWithOptions

    -- | a variant of 'escapeWith' that allows an 'IsOption' RE option
    -- to be specified
    escapeWithOptions :: ( IsOption o, Functor m, Monad m,MonadFail m)
                      => o
                      -> (String->String)
                      -> String
                      -> m RE
    escapeWithOptions :: forall o (m :: * -> *).
    (IsOption o, Functor m, Monad m, MonadFail m) =>
    o -> (String -> String) -> String -> m RE
    escapeWithOptions o
    o String -> String
    f = o -> String -> m RE
    forall o (m :: * -> *).
    (IsOption o, Functor m, Monad m, MonadFail m) =>
    o -> String -> m RE
    compileRegexWithOptions o
    o (String -> m RE) -> (String -> String) -> String -> m RE
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    f (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    escapeREString

    ------------------------------------------------------------------------
    -- Macro Standard Environment
    ------------------------------------------------------------------------

    -- | the standard table of 'Macros' used to compile REs (which can be
    -- extended or replace: see "Text.RE.TestBench")
    prelude :: Macros RE
    prelude :: Macros RE
    prelude = Identity (Macros RE) -> Macros RE
    forall a. Identity a -> a
    runIdentity (Identity (Macros RE) -> Macros RE)
    -> Identity (Macros RE) -> Macros RE
    forall a b. (a -> b) -> a -> b
    $ (String -> Identity RE)
    -> RegexType -> WithCaptures -> Identity (Macros RE)
    forall (m :: * -> *) r.
    (Monad m, Functor m) =>
    (String -> m r) -> RegexType -> WithCaptures -> m (Macros r)
    preludeMacros String -> Identity RE
    mk RegexType
    regexType WithCaptures
    ExclCaptures
      where
        mk :: String -> Identity RE
    mk = RE -> Identity RE
    forall a. a -> Identity a
    Identity (RE -> Identity RE) -> (String -> RE) -> String -> Identity RE
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . RegexParseMode -> REOptions -> String -> RE
    unsafeCompileRegex_ RegexParseMode
    RPM_raw REOptions
    noPreludeREOptions

    -- | the standard 'MacroEnv' for this back end (see "Text.RE.TestBench")
    preludeEnv :: MacroEnv
    preludeEnv :: MacroEnv
    preludeEnv = RegexType -> MacroEnv
    preludeMacroEnv RegexType
    regexType

    -- | the macros in the standard environment that are failing their tests
    -- (checked by the test suite to be empty)
    preludeTestsFailing :: [MacroID]
    preludeTestsFailing :: [MacroID]
    preludeTestsFailing = MacroEnv -> [MacroID]
    badMacros (MacroEnv -> [MacroID]) -> MacroEnv -> [MacroID]
    forall a b. (a -> b) -> a -> b
    $ RegexType -> MacroEnv
    preludeMacroEnv RegexType
    regexType

    -- | a table the standard macros in markdown format
    preludeTable :: String
    preludeTable :: String
    preludeTable = RegexType -> String
    preludeMacroTable RegexType
    regexType

    -- | a summary of the macros in the standard environment for this back
    -- end in plain text
    preludeSummary :: PreludeMacro -> String
    preludeSummary :: PreludeMacro -> String
    preludeSummary = RegexType -> PreludeMacro -> String
    preludeMacroSummary RegexType
    regexType

    -- | a listing of the RE text for each macro in the standard environment
    -- with all macros expanded to normal form
    preludeSources :: String
    preludeSources :: String
    preludeSources = RegexType -> String
    preludeMacroSources RegexType
    regexType

    -- | the prelude source of a given macro in the standard environment
    preludeSource :: PreludeMacro -> String
    preludeSource :: PreludeMacro -> String
    preludeSource = RegexType -> PreludeMacro -> String
    preludeMacroSource RegexType
    regexType

    ------------------------------------------------------------------------
    -- Quasi Quoters
    ------------------------------------------------------------------------

    -- | @[re| ... |]@, is equivalent to @[reMultilineSensitive| ... |]@,
    -- compiling a case-sensitive, multi-line RE
    re                      :: QuasiQuoter
    re :: QuasiQuoter
    re                       = Maybe SimpleREOptions -> QuasiQuoter
    re' (Maybe SimpleREOptions -> QuasiQuoter)
    -> Maybe SimpleREOptions -> QuasiQuoter
    forall a b. (a -> b) -> a -> b
    $ SimpleREOptions -> Maybe SimpleREOptions
    forall a. a -> Maybe a
    Just SimpleREOptions
    forall a. Bounded a => a
    minBound

    -- | @[reMultilineSensitive| ... |]@, compiles a case-sensitive, multi-line RE
    reMultilineSensitive    :: QuasiQuoter
    reMultilineSensitive :: QuasiQuoter
    reMultilineSensitive     = Maybe SimpleREOptions -> QuasiQuoter
    re' (Maybe SimpleREOptions -> QuasiQuoter)
    -> Maybe SimpleREOptions -> QuasiQuoter
    forall a b. (a -> b) -> a -> b
    $ SimpleREOptions -> Maybe SimpleREOptions
    forall a. a -> Maybe a
    Just  SimpleREOptions
    MultilineSensitive

    -- | @[reMultilineInsensitive| ... |]@, compiles a case-insensitive, multi-line RE
    reMultilineInsensitive  :: QuasiQuoter
    reMultilineInsensitive :: QuasiQuoter
    reMultilineInsensitive   = Maybe SimpleREOptions -> QuasiQuoter
    re' (Maybe SimpleREOptions -> QuasiQuoter)
    -> Maybe SimpleREOptions -> QuasiQuoter
    forall a b. (a -> b) -> a -> b
    $ SimpleREOptions -> Maybe SimpleREOptions
    forall a. a -> Maybe a
    Just  SimpleREOptions
    MultilineInsensitive

    -- | @[reMultilineInsensitive| ... |]@, compiles a case-sensitive, non-multi-line RE
    reBlockSensitive        :: QuasiQuoter
    reBlockSensitive :: QuasiQuoter
    reBlockSensitive         = Maybe SimpleREOptions -> QuasiQuoter
    re' (Maybe SimpleREOptions -> QuasiQuoter)
    -> Maybe SimpleREOptions -> QuasiQuoter
    forall a b. (a -> b) -> a -> b
    $ SimpleREOptions -> Maybe SimpleREOptions
    forall a. a -> Maybe a
    Just  SimpleREOptions
    BlockSensitive

    -- | @[reMultilineInsensitive| ... |]@, compiles a case-insensitive, non-multi-line RE
    reBlockInsensitive      :: QuasiQuoter
    reBlockInsensitive :: QuasiQuoter
    reBlockInsensitive       = Maybe SimpleREOptions -> QuasiQuoter
    re' (Maybe SimpleREOptions -> QuasiQuoter)
    -> Maybe SimpleREOptions -> QuasiQuoter
    forall a b. (a -> b) -> a -> b
    $ SimpleREOptions -> Maybe SimpleREOptions
    forall a. a -> Maybe a
    Just  SimpleREOptions
    BlockInsensitive

    -- | @[reMS| ... |]@ is a shorthand for @[reMultilineSensitive| ... |]@
    reMS                     :: QuasiQuoter
    reMS :: QuasiQuoter
    reMS                     = QuasiQuoter
    reMultilineSensitive

    -- | @[reMI| ... |]@ is a shorthand for @[reMultilineInsensitive| ... |]@
    reMI                    :: QuasiQuoter
    reMI :: QuasiQuoter
    reMI                     = QuasiQuoter
    reMultilineInsensitive

    -- | @[reBS| ... |]@ is a shorthand for @[reBlockSensitive| ... |]@
    reBS                    :: QuasiQuoter
    reBS :: QuasiQuoter
    reBS                     = QuasiQuoter
    reBlockSensitive

    -- | @[reBI| ... |]@ is a shorthand for @[reBlockInsensitive| ... |]@
    reBI                    :: QuasiQuoter
    reBI :: QuasiQuoter
    reBI                     = QuasiQuoter
    reBlockInsensitive

    -- | @[re_| ... |]@ compiles a RE to produce a function that takes
    -- the RE options (e.g., a 'SimpleREOptions' value) and yields the
    -- RE compiled with those options. For example,
    --
    --   @countMatches $ s *=~ [re_|[0-9a-f]+|] MultilineInsensitive@
    --
    -- counts the number of hexadecimal digit strings in 's', allowing
    -- for upper- or lower-case hex digits (which is entirely equivalent
    -- in this example to just using @[reMultilineInsensitive|[0-9a-f]+|]@).
    re_                     :: QuasiQuoter
    re_ :: QuasiQuoter
    re_                      = Maybe SimpleREOptions -> QuasiQuoter
    re'   Maybe SimpleREOptions
    forall a. Maybe a
    Nothing

    ------------------------------------------------------------------------
    -- re Helpers
    ------------------------------------------------------------------------

    re' :: Maybe SimpleREOptions -> QuasiQuoter
    re' :: Maybe SimpleREOptions -> QuasiQuoter
    re' Maybe SimpleREOptions
    mb = case Maybe SimpleREOptions
    mb of
      Maybe SimpleREOptions
    Nothing  ->
        (String -> QuasiQuoter
    qq0 String
    "re'")
          { quoteExp = parse minBound (\String
    rs->[|flip unsafeCompileRegex rs|])
          }
      Just SimpleREOptions
    sro ->
        (String -> QuasiQuoter
    qq0 String
    "re'")
          { quoteExp = parse sro (\String
    rs->[|unsafeCompileRegexSimple sro rs|])
          }
      where
        parse :: SimpleREOptions -> (String->Q Exp) -> String -> Q Exp
        parse :: SimpleREOptions -> (String -> Q Exp) -> String -> Q Exp
    parse SimpleREOptions
    sro String -> Q Exp
    mk String
    rs = (String -> Q Exp) -> (RE -> Q Exp) -> Poss RE -> Q Exp
    forall b a. (String -> b) -> (a -> b) -> Poss a -> b
    poss String -> Q Exp
    forall a. HasCallStack => String -> a
    error (\RE
    _->String -> Q Exp
    mk String
    rs) (Poss RE -> Q Exp) -> Poss RE -> Q Exp
    forall a b. (a -> b) -> a -> b
    $ RegexParseMode -> REOptions -> String -> Poss RE
    forall (m :: * -> *).
    (Functor m, MonadFail m, Monad m) =>
    RegexParseMode -> REOptions -> String -> m RE
    compileRegex_ RegexParseMode
    RPM_qq REOptions
    os String
    rs
          where
            os :: REOptions
    os = SimpleREOptions -> REOptions
    unpackSimpleREOptions SimpleREOptions
    sro

    data RegexParseMode
      = RPM_qq
      | RPM_raw
      deriving (RegexParseMode -> RegexParseMode -> Bool
    (RegexParseMode -> RegexParseMode -> Bool)
    -> (RegexParseMode -> RegexParseMode -> Bool) -> Eq RegexParseMode
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: RegexParseMode -> RegexParseMode -> Bool
    == :: RegexParseMode -> RegexParseMode -> Bool
    $c/= :: RegexParseMode -> RegexParseMode -> Bool
    /= :: RegexParseMode -> RegexParseMode -> Bool
    Eq,Int -> RegexParseMode -> String -> String
    [RegexParseMode] -> String -> String
    RegexParseMode -> String
    (Int -> RegexParseMode -> String -> String)
    -> (RegexParseMode -> String)
    -> ([RegexParseMode] -> String -> String)
    -> Show RegexParseMode
    forall a.
    (Int -> a -> String -> String)
    -> (a -> String) -> ([a] -> String -> String) -> Show a
    $cshowsPrec :: Int -> RegexParseMode -> String -> String
    showsPrec :: Int -> RegexParseMode -> String -> String
    $cshow :: RegexParseMode -> String
    show :: RegexParseMode -> String
    $cshowList :: [RegexParseMode] -> String -> String
    showList :: [RegexParseMode] -> String -> String
    Show)

    unsafeCompileRegexSimple :: SimpleREOptions -> String -> RE
    unsafeCompileRegexSimple :: SimpleREOptions -> String -> RE
    unsafeCompileRegexSimple SimpleREOptions
    sro String
    re_s = RegexParseMode -> REOptions -> String -> RE
    unsafeCompileRegex_ RegexParseMode
    RPM_qq REOptions
    os String
    re_s
      where
        os :: REOptions
    os = SimpleREOptions -> REOptions
    unpackSimpleREOptions SimpleREOptions
    sro

    unsafeCompileRegex :: IsOption o
                       => o
                       -> String
                       -> RE
    unsafeCompileRegex :: forall o. IsOption o => o -> String -> RE
    unsafeCompileRegex = RegexParseMode -> REOptions -> String -> RE
    unsafeCompileRegex_ RegexParseMode
    RPM_qq (REOptions -> String -> RE)
    -> (o -> REOptions) -> o -> String -> RE
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . o -> REOptions
    forall o. IsOption o => o -> REOptions
    makeREOptions

    unsafeCompileRegex_ :: RegexParseMode -> REOptions -> String -> RE
    unsafeCompileRegex_ :: RegexParseMode -> REOptions -> String -> RE
    unsafeCompileRegex_ RegexParseMode
    rpm REOptions
    os = (String -> RE) -> (RE -> RE) -> Poss RE -> RE
    forall b a. (String -> b) -> (a -> b) -> Poss a -> b
    poss String -> RE
    forall {c}. String -> c
    oops RE -> RE
    forall a. a -> a
    id (Poss RE -> RE) -> (String -> Poss RE) -> String -> RE
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . RegexParseMode -> REOptions -> String -> Poss RE
    forall (m :: * -> *).
    (Functor m, MonadFail m, Monad m) =>
    RegexParseMode -> REOptions -> String -> m RE
    compileRegex_ RegexParseMode
    rpm REOptions
    os
      where
        oops :: String -> c
    oops = String -> c
    forall a. HasCallStack => String -> a
    error (String -> c) -> (String -> String) -> String -> c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String
    "unsafeCompileRegex: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++)

    compileRegex_ :: (Functor m,MonadFail m,Monad m)
                  => RegexParseMode
                  -> REOptions
                  -> String
                  -> m RE
    compileRegex_ :: forall (m :: * -> *).
    (Functor m, MonadFail m, Monad m) =>
    RegexParseMode -> REOptions -> String -> m RE
    compileRegex_ RegexParseMode
    rpm REOptions
    os String
    re_s = (CaptureNames -> Regex -> RE) -> (CaptureNames, Regex) -> RE
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry CaptureNames -> Regex -> RE
    mk ((CaptureNames, Regex) -> RE) -> m (CaptureNames, Regex) -> m RE
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> RegexParseMode -> REOptions -> String -> m (CaptureNames, Regex)
    forall (m :: * -> *).
    (Functor m, MonadFail m, Monad m) =>
    RegexParseMode -> REOptions -> String -> m (CaptureNames, Regex)
    compileRegex' RegexParseMode
    rpm REOptions
    os String
    re_s
      where
        mk :: CaptureNames -> Regex -> RE
    mk CaptureNames
    cnms Regex
    rx =
          RE
            { _re_options :: REOptions
    _re_options = REOptions
    os
            , _re_source :: String
    _re_source  = String
    re_s
            , _re_cnames :: CaptureNames
    _re_cnames  = CaptureNames
    cnms
            , _re_regex :: Regex
    _re_regex   = Regex
    rx
            }

    compileRegex' :: (Functor m,MonadFail m,Monad m)
                  => RegexParseMode
                  -> REOptions
                  -> String
                  -> m (CaptureNames,Regex)
    compileRegex' :: forall (m :: * -> *).
    (Functor m, MonadFail m, Monad m) =>
    RegexParseMode -> REOptions -> String -> m (CaptureNames, Regex)
    compileRegex' RegexParseMode
    rpm REOptions{ExecOption
    CompOption
    Macros RE
    optionsMacs :: forall r c e. REOptions_ r c e -> Macros r
    optionsComp :: forall r c e. REOptions_ r c e -> c
    optionsExec :: forall r c e. REOptions_ r c e -> e
    optionsMacs :: Macros RE
    optionsComp :: CompOption
    optionsExec :: ExecOption
    ..} String
    s0 = do
        ((_,cnms),s2) <- (String -> m ((Int, CaptureNames), String))
    -> (((Int, CaptureNames), String)
        -> m ((Int, CaptureNames), String))
    -> Either String ((Int, CaptureNames), String)
    -> m ((Int, CaptureNames), String)
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either String -> m ((Int, CaptureNames), String)
    forall a. String -> m a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail ((Int, CaptureNames), String) -> m ((Int, CaptureNames), String)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either String ((Int, CaptureNames), String)
     -> m ((Int, CaptureNames), String))
    -> Either String ((Int, CaptureNames), String)
    -> m ((Int, CaptureNames), String)
    forall a b. (a -> b) -> a -> b
    $ String -> Either String ((Int, CaptureNames), String)
    extractNamedCaptures String
    s1
        (,) cnms <$> makeRegexOptsM optionsComp optionsExec s2
      where
        s1 :: String
    s1 = (RE -> String) -> Macros RE -> String -> String
    forall r. (r -> String) -> Macros r -> String -> String
    expandMacros RE -> String
    reSource Macros RE
    optionsMacs (String -> String) -> String -> String
    forall a b. (a -> b) -> a -> b
    $ String -> String
    pp String
    s0

        pp :: String -> String
    pp = case RegexParseMode
    rpm of
          RegexParseMode
    RPM_qq  -> String -> String
    qq_prep
          RegexParseMode
    RPM_raw -> String -> String
    forall a. a -> a
    id

    ------------------------------------------------------------------------
    -- Preprocessing Literal REs
    ------------------------------------------------------------------------

    qq_prep :: String -> String
    qq_prep :: String -> String
    qq_prep String
    s0 = case String
    s0 of
        String
    ""  -> String
    ""
        Char
    c:String
    s -> case Char
    c of
          Char
    '\\' -> String -> String
    backslash String
    s
          Char
    _    -> Char
    c Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    qq_prep String
    s
      where
        backslash :: String -> String
    backslash String
    s1 = case String
    s1 of
          String
    ""  -> String
    "\\"
          Char
    c:String
    s -> case Char
    c of
            Char
    'a'  -> Char
    '\a'    Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    qq_prep String
    s
            Char
    'b'  -> Char
    '\b'    Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    qq_prep String
    s
            Char
    'f'  -> Char
    '\f'    Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    qq_prep String
    s
            Char
    'n'  -> Char
    '\n'    Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    qq_prep String
    s
            Char
    'r'  -> Char
    '\r'    Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    qq_prep String
    s
            Char
    't'  -> Char
    '\t'    Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    qq_prep String
    s
            Char
    'v'  -> Char
    '\v'    Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    qq_prep String
    s
            Char
    _    -> Char
    '\\'Char -> String -> String
    forall a. a -> [a] -> [a]
    : Char
    c Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    qq_prep String
    s

    ------------------------------------------------------------------------
    -- Options Helpers
    ------------------------------------------------------------------------

    def_comp_option :: CompOption
    def_comp_option :: CompOption
    def_comp_option = REOptions -> CompOption
    forall r c e. REOptions_ r c e -> c
    optionsComp REOptions
    defaultREOptions

    def_exec_option :: ExecOption
    def_exec_option :: ExecOption
    def_exec_option = REOptions -> ExecOption
    forall r c e. REOptions_ r c e -> e
    optionsExec REOptions
    defaultREOptions

    ------------------------------------------------------------------------
    -- Haddock Sections
    ------------------------------------------------------------------------

    -- $about
    --
    -- This module provides the regex PCRE back end. Most of the functions that
    -- you will need for day to day use are provided by the primary API modules
    -- (e.g., "Text.RE.TDFA.Text").