regex 0.10.0.3 → 0.11.0.0
raw patch · 71 files changed
+4281/−4232 lines, 71 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Text.RE.Internal.AddCaptureNames: addCaptureNames :: Typeable a => CaptureNames -> a -> a
- Text.RE.Internal.AddCaptureNames: addCaptureNamesToMatch :: CaptureNames -> Match a -> Match a
- Text.RE.Internal.AddCaptureNames: addCaptureNamesToMatches :: CaptureNames -> Matches a -> Matches a
- Text.RE.Internal.EscapeREString: escapeREString :: String -> String
- Text.RE.Internal.EscapeREString: isMetaChar :: Char -> Bool
- Text.RE.Internal.NamedCaptures: BS :: Char -> Token
- Text.RE.Internal.NamedCaptures: Bra :: Token
- Text.RE.Internal.NamedCaptures: ECap :: (Maybe String) -> Token
- Text.RE.Internal.NamedCaptures: Other :: Char -> Token
- Text.RE.Internal.NamedCaptures: PCap :: Token
- Text.RE.Internal.NamedCaptures: PGrp :: Token
- Text.RE.Internal.NamedCaptures: cp :: QuasiQuoter
- Text.RE.Internal.NamedCaptures: data Token
- Text.RE.Internal.NamedCaptures: extractNamedCaptures :: String -> Either String ((Int, CaptureNames), String)
- Text.RE.Internal.NamedCaptures: formatTokens :: [Token] -> String
- Text.RE.Internal.NamedCaptures: formatTokens' :: FormatTokenREOptions -> [Token] -> String
- Text.RE.Internal.NamedCaptures: formatTokens0 :: [Token] -> String
- Text.RE.Internal.NamedCaptures: idFormatTokenREOptions :: FormatTokenREOptions
- Text.RE.Internal.NamedCaptures: instance GHC.Classes.Eq Text.RE.Internal.NamedCaptures.Token
- Text.RE.Internal.NamedCaptures: instance GHC.Generics.Generic Text.RE.Internal.NamedCaptures.Token
- Text.RE.Internal.NamedCaptures: instance GHC.Show.Show Text.RE.Internal.NamedCaptures.FormatTokenREOptions
- Text.RE.Internal.NamedCaptures: instance GHC.Show.Show Text.RE.Internal.NamedCaptures.Token
- Text.RE.Internal.NamedCaptures: scan :: String -> [Token]
- Text.RE.Internal.NamedCaptures: validToken :: Token -> Bool
- Text.RE.Internal.PreludeMacros: ExclCaptures :: WithCaptures
- Text.RE.Internal.PreludeMacros: InclCaptures :: WithCaptures
- Text.RE.Internal.PreludeMacros: MacroDescriptor :: !RegexSource -> ![String] -> ![String] -> ![TestResult] -> !(Maybe FunctionID) -> !String -> MacroDescriptor
- Text.RE.Internal.PreludeMacros: PM_address_ipv4 :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_date :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_date_slashes :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_datetime :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_datetime_8601 :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_datetime_clf :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_email_simple :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_frac :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_hex :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_id :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_id' :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_id_ :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_int :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_nat :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_shortmonth :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_string :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_string_simple :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_syslog_severity :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_time :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_timezone :: PreludeMacro
- Text.RE.Internal.PreludeMacros: PM_url :: PreludeMacro
- Text.RE.Internal.PreludeMacros: RegexSource :: String -> RegexSource
- Text.RE.Internal.PreludeMacros: [_RegexSource] :: RegexSource -> String
- Text.RE.Internal.PreludeMacros: [_md_counter_samples] :: MacroDescriptor -> ![String]
- Text.RE.Internal.PreludeMacros: [_md_description] :: MacroDescriptor -> !String
- Text.RE.Internal.PreludeMacros: [_md_parser] :: MacroDescriptor -> !(Maybe FunctionID)
- Text.RE.Internal.PreludeMacros: [_md_samples] :: MacroDescriptor -> ![String]
- Text.RE.Internal.PreludeMacros: [_md_source] :: MacroDescriptor -> !RegexSource
- Text.RE.Internal.PreludeMacros: [_md_test_results] :: MacroDescriptor -> ![TestResult]
- Text.RE.Internal.PreludeMacros: data MacroDescriptor
- Text.RE.Internal.PreludeMacros: data PreludeMacro
- Text.RE.Internal.PreludeMacros: data RegexType
- Text.RE.Internal.PreludeMacros: data WithCaptures
- Text.RE.Internal.PreludeMacros: instance GHC.Classes.Eq Text.RE.Internal.PreludeMacros.PreludeMacro
- Text.RE.Internal.PreludeMacros: instance GHC.Classes.Ord Text.RE.Internal.PreludeMacros.PreludeMacro
- Text.RE.Internal.PreludeMacros: instance GHC.Enum.Bounded Text.RE.Internal.PreludeMacros.PreludeMacro
- Text.RE.Internal.PreludeMacros: instance GHC.Enum.Enum Text.RE.Internal.PreludeMacros.PreludeMacro
- Text.RE.Internal.PreludeMacros: instance GHC.Show.Show Text.RE.Internal.PreludeMacros.PreludeMacro
- Text.RE.Internal.PreludeMacros: newtype RegexSource
- Text.RE.Internal.PreludeMacros: preludeMacroDescriptor :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
- Text.RE.Internal.PreludeMacros: preludeMacroEnv :: RegexType -> MacroEnv
- Text.RE.Internal.PreludeMacros: preludeMacroSource :: RegexType -> PreludeMacro -> String
- Text.RE.Internal.PreludeMacros: preludeMacroSources :: RegexType -> String
- Text.RE.Internal.PreludeMacros: preludeMacroSummary :: RegexType -> PreludeMacro -> String
- Text.RE.Internal.PreludeMacros: preludeMacroTable :: RegexType -> String
- Text.RE.Internal.PreludeMacros: preludeMacros :: (Monad m, Functor m) => (String -> m r) -> RegexType -> WithCaptures -> m (Macros r)
- Text.RE.Internal.PreludeMacros: presentPreludeMacro :: PreludeMacro -> String
- Text.RE.SearchReplace: SearchReplace :: !re -> !s -> SearchReplace re s
- Text.RE.SearchReplace: [getSearch] :: SearchReplace re s -> !re
- Text.RE.SearchReplace: [getTemplate] :: SearchReplace re s -> !s
- Text.RE.SearchReplace: data SearchReplace re s
- Text.RE.SearchReplace: searchReplaceAll :: IsRegex re s => SearchReplace re s -> s -> s
- Text.RE.SearchReplace: searchReplaceFirst :: IsRegex re s => SearchReplace re s -> s -> s
- Text.RE.TDFA.ByteString: instance Text.RE.Types.IsRegex.IsRegex Text.RE.TDFA.RE.RE Data.ByteString.Internal.ByteString
- Text.RE.TDFA.ByteString.Lazy: instance Text.RE.Types.IsRegex.IsRegex Text.RE.TDFA.RE.RE Data.ByteString.Lazy.Internal.ByteString
- Text.RE.TDFA.RE: compileRegex :: (Functor m, Monad m) => String -> m RE
- Text.RE.TDFA.RE: compileRegexWith :: (Functor m, Monad m) => SimpleREOptions -> String -> m RE
- Text.RE.TDFA.RE: compileRegexWithOptions :: (IsOption o RE CompOption ExecOption, Functor m, Monad m) => o -> String -> m RE
- Text.RE.TDFA.RE: compileSearchReplace :: (Monad m, Functor m, IsRegex RE s) => String -> String -> m (SearchReplace RE s)
- Text.RE.TDFA.RE: compileSearchReplaceWith :: (Monad m, Functor m, IsRegex RE s) => SimpleREOptions -> String -> String -> m (SearchReplace RE s)
- Text.RE.TDFA.RE: compileSearchReplaceWithREOptions :: (Monad m, Functor m, IsRegex RE s) => REOptions -> String -> String -> m (SearchReplace RE s)
- Text.RE.TDFA.RE: cp :: QuasiQuoter
- Text.RE.TDFA.RE: data RE
- Text.RE.TDFA.RE: defaultREOptions :: REOptions
- Text.RE.TDFA.RE: escape :: (Functor m, Monad m) => (String -> String) -> String -> m RE
- Text.RE.TDFA.RE: escapeREString :: String -> String
- Text.RE.TDFA.RE: escapeWith :: (Functor m, Monad m) => SimpleREOptions -> (String -> String) -> String -> m RE
- Text.RE.TDFA.RE: escapeWithOptions :: (IsOption o RE CompOption ExecOption, Functor m, Monad m) => o -> (String -> String) -> String -> m RE
- Text.RE.TDFA.RE: instance Text.RE.Types.REOptions.IsOption () Text.RE.TDFA.RE.RE Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption
- Text.RE.TDFA.RE: instance Text.RE.Types.REOptions.IsOption (Text.RE.Types.REOptions.Macros Text.RE.TDFA.RE.RE) Text.RE.TDFA.RE.RE Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption
- Text.RE.TDFA.RE: instance Text.RE.Types.REOptions.IsOption Text.RE.TDFA.RE.REOptions Text.RE.TDFA.RE.RE Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption
- Text.RE.TDFA.RE: instance Text.RE.Types.REOptions.IsOption Text.RE.Types.REOptions.SimpleREOptions Text.RE.TDFA.RE.RE Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption
- Text.RE.TDFA.RE: instance Text.RE.Types.REOptions.IsOption Text.Regex.TDFA.Common.CompOption Text.RE.TDFA.RE.RE Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption
- Text.RE.TDFA.RE: instance Text.RE.Types.REOptions.IsOption Text.Regex.TDFA.Common.ExecOption Text.RE.TDFA.RE.RE Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption
- Text.RE.TDFA.RE: noPreludeREOptions :: REOptions
- Text.RE.TDFA.RE: prelude :: Macros RE
- Text.RE.TDFA.RE: preludeEnv :: MacroEnv
- Text.RE.TDFA.RE: preludeSource :: PreludeMacro -> String
- Text.RE.TDFA.RE: preludeSources :: String
- Text.RE.TDFA.RE: preludeSummary :: PreludeMacro -> String
- Text.RE.TDFA.RE: preludeTable :: String
- Text.RE.TDFA.RE: preludeTestsFailing :: [MacroID]
- Text.RE.TDFA.RE: re :: QuasiQuoter
- Text.RE.TDFA.RE: reBI :: QuasiQuoter
- Text.RE.TDFA.RE: reBS :: QuasiQuoter
- Text.RE.TDFA.RE: reBlockInsensitive :: QuasiQuoter
- Text.RE.TDFA.RE: reBlockSensitive :: QuasiQuoter
- Text.RE.TDFA.RE: reCaptureNames :: RE -> CaptureNames
- Text.RE.TDFA.RE: reMI :: QuasiQuoter
- Text.RE.TDFA.RE: reMS :: QuasiQuoter
- Text.RE.TDFA.RE: reMultilineInsensitive :: QuasiQuoter
- Text.RE.TDFA.RE: reMultilineSensitive :: QuasiQuoter
- Text.RE.TDFA.RE: reOptions :: RE -> REOptions
- Text.RE.TDFA.RE: reRegex :: RE -> Regex
- Text.RE.TDFA.RE: reSource :: RE -> String
- Text.RE.TDFA.RE: re_ :: QuasiQuoter
- Text.RE.TDFA.RE: regexType :: RegexType
- Text.RE.TDFA.RE: type REOptions = REOptions_ RE CompOption ExecOption
- Text.RE.TDFA.RE: unpackSimpleREOptions :: SimpleREOptions -> REOptions
- Text.RE.TDFA.Sequence: instance Text.RE.Types.IsRegex.IsRegex Text.RE.TDFA.RE.RE (Data.Sequence.Seq GHC.Types.Char)
- Text.RE.TDFA.String: instance Text.RE.Types.IsRegex.IsRegex Text.RE.TDFA.RE.RE GHC.Base.String
- Text.RE.TDFA.Text: instance Text.RE.Types.IsRegex.IsRegex Text.RE.TDFA.RE.RE Data.Text.Internal.Text
- Text.RE.TDFA.Text.Lazy: instance Text.RE.Types.IsRegex.IsRegex Text.RE.TDFA.RE.RE Data.Text.Internal.Lazy.Text
- Text.RE.TestBench: FunctionID :: String -> FunctionID
- Text.RE.TestBench: MacroID :: String -> MacroID
- Text.RE.TestBench: TestResult :: String -> TestResult
- Text.RE.TestBench: [_FunctionID] :: FunctionID -> String
- Text.RE.TestBench: [_TestResult] :: TestResult -> String
- Text.RE.TestBench: [_md_counter_samples] :: MacroDescriptor -> ![String]
- Text.RE.TestBench: [_md_description] :: MacroDescriptor -> !String
- Text.RE.TestBench: [_md_parser] :: MacroDescriptor -> !(Maybe FunctionID)
- Text.RE.TestBench: [_md_samples] :: MacroDescriptor -> ![String]
- Text.RE.TestBench: [_md_source] :: MacroDescriptor -> !RegexSource
- Text.RE.TestBench: [_md_test_results] :: MacroDescriptor -> ![TestResult]
- Text.RE.TestBench: [getMacroID] :: MacroID -> String
- Text.RE.TestBench: badMacros :: MacroEnv -> [MacroID]
- Text.RE.TestBench: data RegexType
- Text.RE.TestBench: dumpMacroTable :: String -> RegexType -> MacroEnv -> IO ()
- Text.RE.TestBench: instance Data.String.IsString Text.RE.TestBench.FunctionID
- Text.RE.TestBench: instance Data.String.IsString Text.RE.TestBench.RegexSource
- Text.RE.TestBench: instance Data.String.IsString Text.RE.TestBench.TestResult
- Text.RE.TestBench: instance GHC.Arr.Ix Text.RE.TestBench.Col
- Text.RE.TestBench: instance GHC.Classes.Eq Text.RE.TestBench.Col
- Text.RE.TestBench: instance GHC.Classes.Eq Text.RE.TestBench.WithCaptures
- Text.RE.TestBench: instance GHC.Classes.Ord Text.RE.TestBench.Col
- Text.RE.TestBench: instance GHC.Classes.Ord Text.RE.TestBench.WithCaptures
- Text.RE.TestBench: instance GHC.Enum.Bounded Text.RE.TestBench.Col
- Text.RE.TestBench: instance GHC.Enum.Enum Text.RE.TestBench.Col
- Text.RE.TestBench: instance GHC.Show.Show Text.RE.TestBench.Col
- Text.RE.TestBench: instance GHC.Show.Show Text.RE.TestBench.FunctionID
- Text.RE.TestBench: instance GHC.Show.Show Text.RE.TestBench.MacroDescriptor
- Text.RE.TestBench: instance GHC.Show.Show Text.RE.TestBench.REToken
- Text.RE.TestBench: instance GHC.Show.Show Text.RE.TestBench.RegexSource
- Text.RE.TestBench: instance GHC.Show.Show Text.RE.TestBench.RegexType
- Text.RE.TestBench: instance GHC.Show.Show Text.RE.TestBench.TestResult
- Text.RE.TestBench: instance GHC.Show.Show Text.RE.TestBench.WithCaptures
- Text.RE.TestBench: isPCRE :: RegexType -> Bool
- Text.RE.TestBench: isTDFA :: RegexType -> Bool
- Text.RE.TestBench: mdRegexSource :: RegexType -> WithCaptures -> MacroEnv -> MacroDescriptor -> String
- Text.RE.TestBench: mkPCRE :: TestBenchMatcher -> RegexType
- Text.RE.TestBench: mkTDFA :: TestBenchMatcher -> RegexType
- Text.RE.TestBench: newtype FunctionID
- Text.RE.TestBench: newtype MacroID
- Text.RE.TestBench: newtype TestResult
- Text.RE.TestBench: presentRegexType :: RegexType -> String
- Text.RE.TestBench: testMacroDescriptors :: [MacroDescriptor] -> [TestResult]
- Text.RE.TestBench.Parsers: Alert :: Severity
- Text.RE.TestBench.Parsers: Crit :: Severity
- Text.RE.TestBench.Parsers: Debug :: Severity
- Text.RE.TestBench.Parsers: Emerg :: Severity
- Text.RE.TestBench.Parsers: Err :: Severity
- Text.RE.TestBench.Parsers: Info :: Severity
- Text.RE.TestBench.Parsers: Notice :: Severity
- Text.RE.TestBench.Parsers: Warning :: Severity
- Text.RE.TestBench.Parsers: data Severity
- Text.RE.TestBench.Parsers: instance GHC.Classes.Eq Text.RE.TestBench.Parsers.Severity
- Text.RE.TestBench.Parsers: instance GHC.Classes.Ord Text.RE.TestBench.Parsers.Severity
- Text.RE.TestBench.Parsers: instance GHC.Enum.Bounded Text.RE.TestBench.Parsers.Severity
- Text.RE.TestBench.Parsers: instance GHC.Enum.Enum Text.RE.TestBench.Parsers.Severity
- Text.RE.TestBench.Parsers: instance GHC.Show.Show Text.RE.TestBench.Parsers.Severity
- Text.RE.TestBench.Parsers: parseDate :: Replace a => a -> Maybe Day
- Text.RE.TestBench.Parsers: parseDateTime :: Replace a => a -> Maybe UTCTime
- Text.RE.TestBench.Parsers: parseDateTime8601 :: Replace a => a -> Maybe UTCTime
- Text.RE.TestBench.Parsers: parseDateTimeCLF :: Replace a => a -> Maybe UTCTime
- Text.RE.TestBench.Parsers: parseDouble :: Replace a => a -> Maybe Double
- Text.RE.TestBench.Parsers: parseHex :: Replace a => a -> Maybe Int
- Text.RE.TestBench.Parsers: parseIPv4Address :: Replace a => a -> Maybe IPV4Address
- Text.RE.TestBench.Parsers: parseInteger :: Replace a => a -> Maybe Int
- Text.RE.TestBench.Parsers: parseSeverity :: Replace a => a -> Maybe Severity
- Text.RE.TestBench.Parsers: parseShortMonth :: Replace a => a -> Maybe Int
- Text.RE.TestBench.Parsers: parseSimpleString :: Replace a => a -> Maybe Text
- Text.RE.TestBench.Parsers: parseSlashesDate :: Replace a => a -> Maybe Day
- Text.RE.TestBench.Parsers: parseString :: Replace a => a -> Maybe Text
- Text.RE.TestBench.Parsers: parseTimeOfDay :: Replace a => a -> Maybe TimeOfDay
- Text.RE.TestBench.Parsers: parseTimeZone :: Replace a => a -> Maybe TimeZone
- Text.RE.TestBench.Parsers: severityKeywords :: Severity -> (Text, [Text])
- Text.RE.TestBench.Parsers: shortMonthArray :: Array Int Text
- Text.RE.TestBench.Parsers: type IPV4Address = (Word8, Word8, Word8, Word8)
- Text.RE.Types.Capture: Capture :: !a -> !a -> !Int -> !Int -> Capture a
- Text.RE.Types.Capture: [captureLength] :: Capture a -> !Int
- Text.RE.Types.Capture: [captureOffset] :: Capture a -> !Int
- Text.RE.Types.Capture: [captureSource] :: Capture a -> !a
- Text.RE.Types.Capture: [capturedText] :: Capture a -> !a
- Text.RE.Types.Capture: capturePrefix :: Extract a => Capture a -> a
- Text.RE.Types.Capture: captureSuffix :: Extract a => Capture a -> a
- Text.RE.Types.Capture: data Capture a
- Text.RE.Types.Capture: hasCaptured :: Capture a -> Bool
- Text.RE.Types.Capture: instance GHC.Base.Functor Text.RE.Types.Capture.Capture
- Text.RE.Types.Capture: instance GHC.Classes.Eq a => GHC.Classes.Eq (Text.RE.Types.Capture.Capture a)
- Text.RE.Types.Capture: instance GHC.Show.Show a => GHC.Show.Show (Text.RE.Types.Capture.Capture a)
- Text.RE.Types.CaptureID: CaptureName :: Text -> CaptureName
- Text.RE.Types.CaptureID: CaptureOrdinal :: Int -> CaptureOrdinal
- Text.RE.Types.CaptureID: IsCaptureName :: CaptureName -> CaptureID
- Text.RE.Types.CaptureID: IsCaptureOrdinal :: CaptureOrdinal -> CaptureID
- Text.RE.Types.CaptureID: [getCaptureName] :: CaptureName -> Text
- Text.RE.Types.CaptureID: [getCaptureOrdinal] :: CaptureOrdinal -> Int
- Text.RE.Types.CaptureID: data CaptureID
- Text.RE.Types.CaptureID: findCaptureID :: CaptureID -> CaptureNames -> Int
- Text.RE.Types.CaptureID: instance Data.Hashable.Class.Hashable Text.RE.Types.CaptureID.CaptureName
- Text.RE.Types.CaptureID: instance GHC.Arr.Ix Text.RE.Types.CaptureID.CaptureOrdinal
- Text.RE.Types.CaptureID: instance GHC.Classes.Eq Text.RE.Types.CaptureID.CaptureID
- Text.RE.Types.CaptureID: instance GHC.Classes.Eq Text.RE.Types.CaptureID.CaptureName
- Text.RE.Types.CaptureID: instance GHC.Classes.Eq Text.RE.Types.CaptureID.CaptureOrdinal
- Text.RE.Types.CaptureID: instance GHC.Classes.Ord Text.RE.Types.CaptureID.CaptureID
- Text.RE.Types.CaptureID: instance GHC.Classes.Ord Text.RE.Types.CaptureID.CaptureName
- Text.RE.Types.CaptureID: instance GHC.Classes.Ord Text.RE.Types.CaptureID.CaptureOrdinal
- Text.RE.Types.CaptureID: instance GHC.Enum.Enum Text.RE.Types.CaptureID.CaptureOrdinal
- Text.RE.Types.CaptureID: instance GHC.Num.Num Text.RE.Types.CaptureID.CaptureOrdinal
- Text.RE.Types.CaptureID: instance GHC.Show.Show Text.RE.Types.CaptureID.CaptureID
- Text.RE.Types.CaptureID: instance GHC.Show.Show Text.RE.Types.CaptureID.CaptureName
- Text.RE.Types.CaptureID: instance GHC.Show.Show Text.RE.Types.CaptureID.CaptureOrdinal
- Text.RE.Types.CaptureID: newtype CaptureName
- Text.RE.Types.CaptureID: newtype CaptureOrdinal
- Text.RE.Types.CaptureID: noCaptureNames :: CaptureNames
- Text.RE.Types.CaptureID: type CaptureNames = HashMap CaptureName CaptureOrdinal
- Text.RE.Types.IsRegex: class Replace s => IsRegex re s where makeRegex = makeRegexWith minBound makeSearchReplace = makeSearchReplaceWith minBound makeEscaped = makeEscapedWith minBound makeEscapedWith o f = makeRegexWith o . f . packR . escapeREString . unpackR
- Text.RE.Types.IsRegex: makeEscaped :: (IsRegex re s, Functor m, Monad m) => (s -> s) -> s -> m re
- Text.RE.Types.IsRegex: makeEscapedWith :: (IsRegex re s, Functor m, Monad m) => SimpleREOptions -> (s -> s) -> s -> m re
- Text.RE.Types.IsRegex: makeRegex :: (IsRegex re s, Functor m, Monad m) => s -> m re
- Text.RE.Types.IsRegex: makeRegexWith :: (IsRegex re s, Functor m, Monad m) => SimpleREOptions -> s -> m re
- Text.RE.Types.IsRegex: makeSearchReplace :: (IsRegex re s, Functor m, Monad m, IsRegex re s) => s -> s -> m (SearchReplace re s)
- Text.RE.Types.IsRegex: makeSearchReplaceWith :: (IsRegex re s, Functor m, Monad m, IsRegex re s) => SimpleREOptions -> s -> s -> m (SearchReplace re s)
- Text.RE.Types.IsRegex: matchMany :: IsRegex re s => re -> s -> Matches s
- Text.RE.Types.IsRegex: matchOnce :: IsRegex re s => re -> s -> Match s
- Text.RE.Types.IsRegex: regexSource :: IsRegex re s => re -> s
- Text.RE.Types.LineNo: ZeroBasedLineNo :: Int -> LineNo
- Text.RE.Types.LineNo: [getZeroBasedLineNo] :: LineNo -> Int
- Text.RE.Types.LineNo: firstLine :: LineNo
- Text.RE.Types.LineNo: getLineNo :: LineNo -> Int
- Text.RE.Types.LineNo: instance GHC.Enum.Enum Text.RE.Types.LineNo.LineNo
- Text.RE.Types.LineNo: instance GHC.Show.Show Text.RE.Types.LineNo.LineNo
- Text.RE.Types.LineNo: lineNo :: Int -> LineNo
- Text.RE.Types.LineNo: newtype LineNo
- Text.RE.Types.Match: (!$$) :: Match a -> CaptureID -> a
- Text.RE.Types.Match: (!$$?) :: Match a -> CaptureID -> Maybe a
- Text.RE.Types.Match: (!$) :: Match a -> CaptureID -> Capture a
- Text.RE.Types.Match: (!$?) :: Match a -> CaptureID -> Maybe (Capture a)
- Text.RE.Types.Match: Match :: !a -> !CaptureNames -> !(Array CaptureOrdinal (Capture a)) -> Match a
- Text.RE.Types.Match: [captureNames] :: Match a -> !CaptureNames
- Text.RE.Types.Match: [matchArray] :: Match a -> !(Array CaptureOrdinal (Capture a))
- Text.RE.Types.Match: [matchSource] :: Match a -> !a
- Text.RE.Types.Match: capture :: CaptureID -> Match a -> Capture a
- Text.RE.Types.Match: captureMaybe :: CaptureID -> Match a -> Maybe (Capture a)
- Text.RE.Types.Match: captureText :: CaptureID -> Match a -> a
- Text.RE.Types.Match: captureTextMaybe :: CaptureID -> Match a -> Maybe a
- Text.RE.Types.Match: convertMatchText :: source -> MatchText source -> Match source
- Text.RE.Types.Match: data Match a
- Text.RE.Types.Match: emptyMatchArray :: Array CaptureOrdinal (Capture a)
- Text.RE.Types.Match: infixl 9 !$
- Text.RE.Types.Match: instance (Text.Regex.Base.RegexLike.RegexContext regex source (Text.Regex.Base.RegexLike.AllTextSubmatches (GHC.Arr.Array GHC.Types.Int) (source, (GHC.Types.Int, GHC.Types.Int))), Text.Regex.Base.RegexLike.RegexLike regex source) => Text.Regex.Base.RegexLike.RegexContext regex source (Text.RE.Types.Match.Match source)
- Text.RE.Types.Match: instance GHC.Base.Functor Text.RE.Types.Match.Match
- Text.RE.Types.Match: instance GHC.Classes.Eq a => GHC.Classes.Eq (Text.RE.Types.Match.Match a)
- Text.RE.Types.Match: instance GHC.Show.Show a => GHC.Show.Show (Text.RE.Types.Match.Match a)
- Text.RE.Types.Match: matchCapture :: Match a -> Maybe (Capture a)
- Text.RE.Types.Match: matchCaptures :: Match a -> Maybe (Capture a, [Capture a])
- Text.RE.Types.Match: matched :: Match a -> Bool
- Text.RE.Types.Match: matchedText :: Match a -> Maybe a
- Text.RE.Types.Match: noMatch :: a -> Match a
- Text.RE.Types.Matches: Matches :: !a -> ![Match a] -> Matches a
- Text.RE.Types.Matches: [allMatches] :: Matches a -> ![Match a]
- Text.RE.Types.Matches: [matchesSource] :: Matches a -> !a
- Text.RE.Types.Matches: anyMatches :: Matches a -> Bool
- Text.RE.Types.Matches: countMatches :: Matches a -> Int
- Text.RE.Types.Matches: data Matches a
- Text.RE.Types.Matches: instance (Text.Regex.Base.RegexLike.RegexContext regex source [Text.Regex.Base.RegexLike.MatchText source], Text.Regex.Base.RegexLike.RegexLike regex source) => Text.Regex.Base.RegexLike.RegexContext regex source (Text.RE.Types.Matches.Matches source)
- Text.RE.Types.Matches: instance GHC.Base.Functor Text.RE.Types.Matches.Matches
- Text.RE.Types.Matches: instance GHC.Classes.Eq a => GHC.Classes.Eq (Text.RE.Types.Matches.Matches a)
- Text.RE.Types.Matches: instance GHC.Show.Show a => GHC.Show.Show (Text.RE.Types.Matches.Matches a)
- Text.RE.Types.Matches: mainCaptures :: Matches a -> [Capture a]
- Text.RE.Types.Matches: matches :: Matches a -> [a]
- Text.RE.Types.REOptions: BlockInsensitive :: SimpleREOptions
- Text.RE.Types.REOptions: BlockSensitive :: SimpleREOptions
- Text.RE.Types.REOptions: MacroID :: String -> MacroID
- Text.RE.Types.REOptions: MultilineInsensitive :: SimpleREOptions
- Text.RE.Types.REOptions: MultilineSensitive :: SimpleREOptions
- Text.RE.Types.REOptions: REOptions :: !(Macros r) -> !c -> !e -> REOptions_ r c e
- Text.RE.Types.REOptions: [getMacroID] :: MacroID -> String
- Text.RE.Types.REOptions: [optionsComp] :: REOptions_ r c e -> !c
- Text.RE.Types.REOptions: [optionsExec] :: REOptions_ r c e -> !e
- Text.RE.Types.REOptions: [optionsMacs] :: REOptions_ r c e -> !(Macros r)
- Text.RE.Types.REOptions: class IsOption o r c e | e -> r, c -> e, e -> c, r -> c, c -> r, r -> e
- Text.RE.Types.REOptions: data REOptions_ r c e
- Text.RE.Types.REOptions: data SimpleREOptions
- Text.RE.Types.REOptions: emptyMacros :: Macros r
- Text.RE.Types.REOptions: instance (GHC.Show.Show e, GHC.Show.Show c, GHC.Show.Show r) => GHC.Show.Show (Text.RE.Types.REOptions.REOptions_ r c e)
- Text.RE.Types.REOptions: instance Data.Hashable.Class.Hashable Text.RE.Types.REOptions.MacroID
- Text.RE.Types.REOptions: instance Data.String.IsString Text.RE.Types.REOptions.MacroID
- Text.RE.Types.REOptions: instance GHC.Classes.Eq Text.RE.Types.REOptions.MacroID
- Text.RE.Types.REOptions: instance GHC.Classes.Eq Text.RE.Types.REOptions.SimpleREOptions
- Text.RE.Types.REOptions: instance GHC.Classes.Ord Text.RE.Types.REOptions.MacroID
- Text.RE.Types.REOptions: instance GHC.Classes.Ord Text.RE.Types.REOptions.SimpleREOptions
- Text.RE.Types.REOptions: instance GHC.Enum.Bounded Text.RE.Types.REOptions.SimpleREOptions
- Text.RE.Types.REOptions: instance GHC.Enum.Enum Text.RE.Types.REOptions.SimpleREOptions
- Text.RE.Types.REOptions: instance GHC.Show.Show Text.RE.Types.REOptions.MacroID
- Text.RE.Types.REOptions: instance GHC.Show.Show Text.RE.Types.REOptions.SimpleREOptions
- Text.RE.Types.REOptions: instance Language.Haskell.TH.Syntax.Lift Text.RE.Types.REOptions.SimpleREOptions
- Text.RE.Types.REOptions: makeREOptions :: IsOption o r c e => o -> REOptions_ r c e
- Text.RE.Types.REOptions: newtype MacroID
- Text.RE.Types.REOptions: type Macros r = HashMap MacroID r
- Text.RE.Types.Replace: ALL :: REContext
- Text.RE.Types.Replace: Location :: Int -> CaptureOrdinal -> Location
- Text.RE.Types.Replace: ReplaceMethods :: (a -> Int) -> ((a -> a) -> Capture a -> a) -> ReplaceMethods a
- Text.RE.Types.Replace: SUB :: REContext
- Text.RE.Types.Replace: TOP :: REContext
- Text.RE.Types.Replace: [locationCapture] :: Location -> CaptureOrdinal
- Text.RE.Types.Replace: [locationMatch] :: Location -> Int
- Text.RE.Types.Replace: [methodLength] :: ReplaceMethods a -> a -> Int
- Text.RE.Types.Replace: [methodSubst] :: ReplaceMethods a -> (a -> a) -> Capture a -> a
- Text.RE.Types.Replace: appendNewlineR :: Replace a => a -> a
- Text.RE.Types.Replace: class (Show a, Eq a, Ord a, Extract a, Monoid a) => Replace a where textifyR = pack . unpackR detextifyR = packR . unpack appendNewlineR = (<> packR "\n") substR f m@(Capture {..}) = capturePrefix m <> f capturedText <> captureSuffix m
- Text.RE.Types.Replace: data Location
- Text.RE.Types.Replace: data REContext
- Text.RE.Types.Replace: data ReplaceMethods a
- Text.RE.Types.Replace: detextifyR :: Replace a => Text -> a
- Text.RE.Types.Replace: expandMacros :: (r -> String) -> Macros r -> String -> String
- Text.RE.Types.Replace: expandMacros' :: (MacroID -> Maybe String) -> String -> String
- Text.RE.Types.Replace: instance GHC.Show.Show Text.RE.Types.Replace.Location
- Text.RE.Types.Replace: instance GHC.Show.Show Text.RE.Types.Replace.REContext
- Text.RE.Types.Replace: instance Text.RE.Types.Replace.Replace (Data.Sequence.Seq GHC.Types.Char)
- Text.RE.Types.Replace: instance Text.RE.Types.Replace.Replace Data.ByteString.Internal.ByteString
- Text.RE.Types.Replace: instance Text.RE.Types.Replace.Replace Data.ByteString.Lazy.Internal.ByteString
- Text.RE.Types.Replace: instance Text.RE.Types.Replace.Replace Data.Text.Internal.Lazy.Text
- Text.RE.Types.Replace: instance Text.RE.Types.Replace.Replace Data.Text.Internal.Text
- Text.RE.Types.Replace: instance Text.RE.Types.Replace.Replace [GHC.Types.Char]
- Text.RE.Types.Replace: isTopLocation :: Location -> Bool
- Text.RE.Types.Replace: lengthR :: Replace a => a -> Int
- Text.RE.Types.Replace: linesR :: Replace a => a -> [a]
- Text.RE.Types.Replace: packR :: Replace a => String -> a
- Text.RE.Types.Replace: parseTemplateR :: Replace a => a -> Match a -> Location -> Capture a -> Maybe a
- Text.RE.Types.Replace: replace :: Replace a => a -> Match a -> a
- Text.RE.Types.Replace: replaceAll :: Replace a => a -> Matches a -> a
- Text.RE.Types.Replace: replaceAllCaptures :: Replace a => REContext -> (Match a -> Location -> Capture a -> Maybe a) -> Matches a -> a
- Text.RE.Types.Replace: replaceAllCapturesM :: (Extract a, Monad m) => ReplaceMethods a -> REContext -> (Match a -> Location -> Capture a -> m (Maybe a)) -> Matches a -> m a
- Text.RE.Types.Replace: replaceAllCaptures_ :: Extract a => ReplaceMethods a -> REContext -> (Match a -> Location -> Capture a -> Maybe a) -> Matches a -> a
- Text.RE.Types.Replace: replaceCaptures :: Replace a => REContext -> (Match a -> Location -> Capture a -> Maybe a) -> Match a -> a
- Text.RE.Types.Replace: replaceCapturesM :: (Monad m, Extract a) => ReplaceMethods a -> REContext -> (Match a -> Location -> Capture a -> m (Maybe a)) -> Match a -> m a
- Text.RE.Types.Replace: replaceCaptures_ :: Extract a => ReplaceMethods a -> REContext -> (Match a -> Location -> Capture a -> Maybe a) -> Match a -> a
- Text.RE.Types.Replace: replaceMethods :: Replace a => ReplaceMethods a
- Text.RE.Types.Replace: substR :: Replace a => (a -> a) -> Capture a -> a
- Text.RE.Types.Replace: templateCaptures :: (Replace a, RegexContext Regex a (Matches a), RegexMaker Regex CompOption ExecOption String) => (a -> String) -> a -> [CaptureID]
- Text.RE.Types.Replace: textifyR :: Replace a => a -> Text
- Text.RE.Types.Replace: unlinesR :: Replace a => [a] -> a
- Text.RE.Types.Replace: unpackR :: Replace a => a -> String
- Text.RE.Types.SearchReplace: SearchReplace :: !re -> !s -> SearchReplace re s
- Text.RE.Types.SearchReplace: [getSearch] :: SearchReplace re s -> !re
- Text.RE.Types.SearchReplace: [getTemplate] :: SearchReplace re s -> !s
- Text.RE.Types.SearchReplace: data SearchReplace re s
- Text.RE.Types.SearchReplace: instance (GHC.Show.Show s, GHC.Show.Show re) => GHC.Show.Show (Text.RE.Types.SearchReplace.SearchReplace re s)
- Text.RE.Types.SearchReplace: instance GHC.Base.Functor (Text.RE.Types.SearchReplace.SearchReplace re)
+ Text.RE.IsRegex: SearchReplace :: !re -> !s -> SearchReplace re s
+ Text.RE.IsRegex: [getSearch] :: SearchReplace re s -> !re
+ Text.RE.IsRegex: [getTemplate] :: SearchReplace re s -> !s
+ Text.RE.IsRegex: class Replace s => IsRegex re s where makeRegex = makeRegexWith minBound makeSearchReplace = makeSearchReplaceWith minBound makeEscaped = makeEscapedWith minBound makeEscapedWith o f = makeRegexWith o . f . packR . escapeREString . unpackR
+ Text.RE.IsRegex: data SearchReplace re s
+ Text.RE.IsRegex: makeEscaped :: (IsRegex re s, Functor m, Monad m) => (s -> s) -> s -> m re
+ Text.RE.IsRegex: makeEscapedWith :: (IsRegex re s, Functor m, Monad m) => SimpleREOptions -> (s -> s) -> s -> m re
+ Text.RE.IsRegex: makeRegex :: (IsRegex re s, Functor m, Monad m) => s -> m re
+ Text.RE.IsRegex: makeRegexWith :: (IsRegex re s, Functor m, Monad m) => SimpleREOptions -> s -> m re
+ Text.RE.IsRegex: makeSearchReplace :: (IsRegex re s, Functor m, Monad m, IsRegex re s) => s -> s -> m (SearchReplace re s)
+ Text.RE.IsRegex: makeSearchReplaceWith :: (IsRegex re s, Functor m, Monad m, IsRegex re s) => SimpleREOptions -> s -> s -> m (SearchReplace re s)
+ Text.RE.IsRegex: matchMany :: IsRegex re s => re -> s -> Matches s
+ Text.RE.IsRegex: matchOnce :: IsRegex re s => re -> s -> Match s
+ Text.RE.IsRegex: regexSource :: IsRegex re s => re -> s
+ Text.RE.IsRegex: searchReplaceAll :: IsRegex re s => SearchReplace re s -> s -> s
+ Text.RE.IsRegex: searchReplaceFirst :: IsRegex re s => SearchReplace re s -> s -> s
+ Text.RE.REOptions: BlockInsensitive :: SimpleREOptions
+ Text.RE.REOptions: BlockSensitive :: SimpleREOptions
+ Text.RE.REOptions: MacroID :: String -> MacroID
+ Text.RE.REOptions: MultilineInsensitive :: SimpleREOptions
+ Text.RE.REOptions: MultilineSensitive :: SimpleREOptions
+ Text.RE.REOptions: REOptions :: !(Macros r) -> !c -> !e -> REOptions_ r c e
+ Text.RE.REOptions: [getMacroID] :: MacroID -> String
+ Text.RE.REOptions: [optionsComp] :: REOptions_ r c e -> !c
+ Text.RE.REOptions: [optionsExec] :: REOptions_ r c e -> !e
+ Text.RE.REOptions: [optionsMacs] :: REOptions_ r c e -> !(Macros r)
+ Text.RE.REOptions: class IsOption o r c e | e -> r, c -> e, e -> c, r -> c, c -> r, r -> e
+ Text.RE.REOptions: data REOptions_ r c e
+ Text.RE.REOptions: data SimpleREOptions
+ Text.RE.REOptions: emptyMacros :: Macros r
+ Text.RE.REOptions: instance (GHC.Show.Show e, GHC.Show.Show c, GHC.Show.Show r) => GHC.Show.Show (Text.RE.REOptions.REOptions_ r c e)
+ Text.RE.REOptions: instance Data.Hashable.Class.Hashable Text.RE.REOptions.MacroID
+ Text.RE.REOptions: instance Data.String.IsString Text.RE.REOptions.MacroID
+ Text.RE.REOptions: instance GHC.Classes.Eq Text.RE.REOptions.MacroID
+ Text.RE.REOptions: instance GHC.Classes.Eq Text.RE.REOptions.SimpleREOptions
+ Text.RE.REOptions: instance GHC.Classes.Ord Text.RE.REOptions.MacroID
+ Text.RE.REOptions: instance GHC.Classes.Ord Text.RE.REOptions.SimpleREOptions
+ Text.RE.REOptions: instance GHC.Enum.Bounded Text.RE.REOptions.SimpleREOptions
+ Text.RE.REOptions: instance GHC.Enum.Enum Text.RE.REOptions.SimpleREOptions
+ Text.RE.REOptions: instance GHC.Show.Show Text.RE.REOptions.MacroID
+ Text.RE.REOptions: instance GHC.Show.Show Text.RE.REOptions.SimpleREOptions
+ Text.RE.REOptions: instance Language.Haskell.TH.Syntax.Lift Text.RE.REOptions.SimpleREOptions
+ Text.RE.REOptions: makeREOptions :: IsOption o r c e => o -> REOptions_ r c e
+ Text.RE.REOptions: newtype MacroID
+ Text.RE.REOptions: type Macros r = HashMap MacroID r
+ Text.RE.Replace: ALL :: REContext
+ Text.RE.Replace: RELocation :: Int -> CaptureOrdinal -> RELocation
+ Text.RE.Replace: ReplaceMethods :: (a -> Int) -> ((a -> a) -> Capture a -> a) -> ReplaceMethods a
+ Text.RE.Replace: SUB :: REContext
+ Text.RE.Replace: TOP :: REContext
+ Text.RE.Replace: [locationCapture] :: RELocation -> CaptureOrdinal
+ Text.RE.Replace: [locationMatch] :: RELocation -> Int
+ Text.RE.Replace: [methodLength] :: ReplaceMethods a -> a -> Int
+ Text.RE.Replace: [methodSubst] :: ReplaceMethods a -> (a -> a) -> Capture a -> a
+ Text.RE.Replace: appendNewlineR :: Replace a => a -> a
+ Text.RE.Replace: class (Show a, Eq a, Ord a, Extract a, Monoid a) => Replace a where textifyR = pack . unpackR detextifyR = packR . unpack appendNewlineR = (<> packR "\n") substR f m@(Capture {..}) = capturePrefix m <> f capturedText <> captureSuffix m
+ Text.RE.Replace: data REContext
+ Text.RE.Replace: data RELocation
+ Text.RE.Replace: data ReplaceMethods a
+ Text.RE.Replace: detextifyR :: Replace a => Text -> a
+ Text.RE.Replace: isTopLocation :: RELocation -> Bool
+ Text.RE.Replace: lengthR :: Replace a => a -> Int
+ Text.RE.Replace: linesR :: Replace a => a -> [a]
+ Text.RE.Replace: packR :: Replace a => String -> a
+ Text.RE.Replace: parseTemplateR :: Replace a => a -> Match a -> RELocation -> Capture a -> Maybe a
+ Text.RE.Replace: replace :: Replace a => a -> Match a -> a
+ Text.RE.Replace: replaceAll :: Replace a => a -> Matches a -> a
+ Text.RE.Replace: replaceAllCaptures :: Replace a => REContext -> (Match a -> RELocation -> Capture a -> Maybe a) -> Matches a -> a
+ Text.RE.Replace: replaceAllCapturesM :: (Extract a, Monad m) => ReplaceMethods a -> REContext -> (Match a -> RELocation -> Capture a -> m (Maybe a)) -> Matches a -> m a
+ Text.RE.Replace: replaceAllCaptures_ :: Extract a => ReplaceMethods a -> REContext -> (Match a -> RELocation -> Capture a -> Maybe a) -> Matches a -> a
+ Text.RE.Replace: replaceCaptures :: Replace a => REContext -> (Match a -> RELocation -> Capture a -> Maybe a) -> Match a -> a
+ Text.RE.Replace: replaceCapturesM :: (Monad m, Extract a) => ReplaceMethods a -> REContext -> (Match a -> RELocation -> Capture a -> m (Maybe a)) -> Match a -> m a
+ Text.RE.Replace: replaceCaptures_ :: Extract a => ReplaceMethods a -> REContext -> (Match a -> RELocation -> Capture a -> Maybe a) -> Match a -> a
+ Text.RE.Replace: replaceMethods :: Replace a => ReplaceMethods a
+ Text.RE.Replace: substR :: Replace a => (a -> a) -> Capture a -> a
+ Text.RE.Replace: textifyR :: Replace a => a -> Text
+ Text.RE.Replace: unlinesR :: Replace a => [a] -> a
+ Text.RE.Replace: unpackR :: Replace a => a -> String
+ Text.RE.TDFA.ByteString: instance Text.RE.IsRegex.IsRegex Text.RE.ZeInternals.TDFA.RE Data.ByteString.Internal.ByteString
+ Text.RE.TDFA.ByteString.Lazy: instance Text.RE.IsRegex.IsRegex Text.RE.ZeInternals.TDFA.RE Data.ByteString.Lazy.Internal.ByteString
+ Text.RE.TDFA.Sequence: instance Text.RE.IsRegex.IsRegex Text.RE.ZeInternals.TDFA.RE (Data.Sequence.Seq GHC.Types.Char)
+ Text.RE.TDFA.String: instance Text.RE.IsRegex.IsRegex Text.RE.ZeInternals.TDFA.RE GHC.Base.String
+ Text.RE.TDFA.Text: instance Text.RE.IsRegex.IsRegex Text.RE.ZeInternals.TDFA.RE Data.Text.Internal.Text
+ Text.RE.TDFA.Text.Lazy: instance Text.RE.IsRegex.IsRegex Text.RE.ZeInternals.TDFA.RE Data.Text.Internal.Lazy.Text
+ Text.RE.TestBench: Alert :: Severity
+ Text.RE.TestBench: Crit :: Severity
+ Text.RE.TestBench: Debug :: Severity
+ Text.RE.TestBench: Emerg :: Severity
+ Text.RE.TestBench: Err :: Severity
+ Text.RE.TestBench: Info :: Severity
+ Text.RE.TestBench: Notice :: Severity
+ Text.RE.TestBench: Warning :: Severity
+ Text.RE.TestBench: [macroCounterSamples] :: MacroDescriptor -> ![String]
+ Text.RE.TestBench: [macroDescription] :: MacroDescriptor -> !String
+ Text.RE.TestBench: [macroParser] :: MacroDescriptor -> !(Maybe FunctionID)
+ Text.RE.TestBench: [macroSamples] :: MacroDescriptor -> ![String]
+ Text.RE.TestBench: [macroSource] :: MacroDescriptor -> !RegexSource
+ Text.RE.TestBench: [macroTestResults] :: MacroDescriptor -> ![TestResult]
+ Text.RE.TestBench: data Severity
+ Text.RE.TestBench: instance GHC.Classes.Eq Text.RE.TestBench.Severity
+ Text.RE.TestBench: instance GHC.Classes.Ord Text.RE.TestBench.Severity
+ Text.RE.TestBench: instance GHC.Enum.Bounded Text.RE.TestBench.Severity
+ Text.RE.TestBench: instance GHC.Enum.Enum Text.RE.TestBench.Severity
+ Text.RE.TestBench: instance GHC.Show.Show Text.RE.TestBench.Severity
+ Text.RE.TestBench: parseDate :: Replace a => a -> Maybe Day
+ Text.RE.TestBench: parseDateTime :: Replace a => a -> Maybe UTCTime
+ Text.RE.TestBench: parseDateTime8601 :: Replace a => a -> Maybe UTCTime
+ Text.RE.TestBench: parseDateTimeCLF :: Replace a => a -> Maybe UTCTime
+ Text.RE.TestBench: parseDouble :: Replace a => a -> Maybe Double
+ Text.RE.TestBench: parseHex :: Replace a => a -> Maybe Int
+ Text.RE.TestBench: parseIPv4Address :: Replace a => a -> Maybe IPV4Address
+ Text.RE.TestBench: parseInteger :: Replace a => a -> Maybe Int
+ Text.RE.TestBench: parseSeverity :: Replace a => a -> Maybe Severity
+ Text.RE.TestBench: parseShortMonth :: Replace a => a -> Maybe Int
+ Text.RE.TestBench: parseSimpleString :: Replace a => a -> Maybe Text
+ Text.RE.TestBench: parseSlashesDate :: Replace a => a -> Maybe Day
+ Text.RE.TestBench: parseString :: Replace a => a -> Maybe Text
+ Text.RE.TestBench: parseTimeOfDay :: Replace a => a -> Maybe TimeOfDay
+ Text.RE.TestBench: parseTimeZone :: Replace a => a -> Maybe TimeZone
+ Text.RE.TestBench: severityKeywords :: Severity -> (Text, [Text])
+ Text.RE.TestBench: shortMonthArray :: Array Int Text
+ Text.RE.TestBench: type IPV4Address = (Word8, Word8, Word8, Word8)
+ Text.RE.ZeInternals.AddCaptureNames: addCaptureNames :: Typeable a => CaptureNames -> a -> a
+ Text.RE.ZeInternals.AddCaptureNames: addCaptureNamesToMatch :: CaptureNames -> Match a -> Match a
+ Text.RE.ZeInternals.AddCaptureNames: addCaptureNamesToMatches :: CaptureNames -> Matches a -> Matches a
+ Text.RE.ZeInternals.EscapeREString: escapeREString :: String -> String
+ Text.RE.ZeInternals.EscapeREString: isMetaChar :: Char -> Bool
+ Text.RE.ZeInternals.NamedCaptures: BS :: Char -> Token
+ Text.RE.ZeInternals.NamedCaptures: Bra :: Token
+ Text.RE.ZeInternals.NamedCaptures: ECap :: (Maybe String) -> Token
+ Text.RE.ZeInternals.NamedCaptures: Other :: Char -> Token
+ Text.RE.ZeInternals.NamedCaptures: PCap :: Token
+ Text.RE.ZeInternals.NamedCaptures: PGrp :: Token
+ Text.RE.ZeInternals.NamedCaptures: cp :: QuasiQuoter
+ Text.RE.ZeInternals.NamedCaptures: data Token
+ Text.RE.ZeInternals.NamedCaptures: extractNamedCaptures :: String -> Either String ((Int, CaptureNames), String)
+ Text.RE.ZeInternals.NamedCaptures: formatTokens :: [Token] -> String
+ Text.RE.ZeInternals.NamedCaptures: formatTokens' :: FormatTokenREOptions -> [Token] -> String
+ Text.RE.ZeInternals.NamedCaptures: formatTokens0 :: [Token] -> String
+ Text.RE.ZeInternals.NamedCaptures: idFormatTokenREOptions :: FormatTokenREOptions
+ Text.RE.ZeInternals.NamedCaptures: instance GHC.Classes.Eq Text.RE.ZeInternals.NamedCaptures.Token
+ Text.RE.ZeInternals.NamedCaptures: instance GHC.Generics.Generic Text.RE.ZeInternals.NamedCaptures.Token
+ Text.RE.ZeInternals.NamedCaptures: instance GHC.Show.Show Text.RE.ZeInternals.NamedCaptures.FormatTokenREOptions
+ Text.RE.ZeInternals.NamedCaptures: instance GHC.Show.Show Text.RE.ZeInternals.NamedCaptures.Token
+ Text.RE.ZeInternals.NamedCaptures: scan :: String -> [Token]
+ Text.RE.ZeInternals.NamedCaptures: validToken :: Token -> Bool
+ Text.RE.ZeInternals.PreludeMacros: ExclCaptures :: WithCaptures
+ Text.RE.ZeInternals.PreludeMacros: InclCaptures :: WithCaptures
+ Text.RE.ZeInternals.PreludeMacros: MacroDescriptor :: !RegexSource -> ![String] -> ![String] -> ![TestResult] -> !(Maybe FunctionID) -> !String -> MacroDescriptor
+ Text.RE.ZeInternals.PreludeMacros: PM_address_ipv4 :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_date :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_date_slashes :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_datetime :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_datetime_8601 :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_datetime_clf :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_email_simple :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_frac :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_hex :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_id :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_id' :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_id_ :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_int :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_nat :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_shortmonth :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_string :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_string_simple :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_syslog_severity :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_time :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_timezone :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: PM_url :: PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: RegexSource :: String -> RegexSource
+ Text.RE.ZeInternals.PreludeMacros: [_RegexSource] :: RegexSource -> String
+ Text.RE.ZeInternals.PreludeMacros: [macroCounterSamples] :: MacroDescriptor -> ![String]
+ Text.RE.ZeInternals.PreludeMacros: [macroDescription] :: MacroDescriptor -> !String
+ Text.RE.ZeInternals.PreludeMacros: [macroParser] :: MacroDescriptor -> !(Maybe FunctionID)
+ Text.RE.ZeInternals.PreludeMacros: [macroSamples] :: MacroDescriptor -> ![String]
+ Text.RE.ZeInternals.PreludeMacros: [macroSource] :: MacroDescriptor -> !RegexSource
+ Text.RE.ZeInternals.PreludeMacros: [macroTestResults] :: MacroDescriptor -> ![TestResult]
+ Text.RE.ZeInternals.PreludeMacros: data MacroDescriptor
+ Text.RE.ZeInternals.PreludeMacros: data PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: data RegexType
+ Text.RE.ZeInternals.PreludeMacros: data WithCaptures
+ Text.RE.ZeInternals.PreludeMacros: instance GHC.Classes.Eq Text.RE.ZeInternals.PreludeMacros.PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: instance GHC.Classes.Ord Text.RE.ZeInternals.PreludeMacros.PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: instance GHC.Enum.Bounded Text.RE.ZeInternals.PreludeMacros.PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: instance GHC.Enum.Enum Text.RE.ZeInternals.PreludeMacros.PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: instance GHC.Show.Show Text.RE.ZeInternals.PreludeMacros.PreludeMacro
+ Text.RE.ZeInternals.PreludeMacros: newtype RegexSource
+ Text.RE.ZeInternals.PreludeMacros: preludeMacroDescriptor :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor
+ Text.RE.ZeInternals.PreludeMacros: preludeMacroEnv :: RegexType -> MacroEnv
+ Text.RE.ZeInternals.PreludeMacros: preludeMacroSource :: RegexType -> PreludeMacro -> String
+ Text.RE.ZeInternals.PreludeMacros: preludeMacroSources :: RegexType -> String
+ Text.RE.ZeInternals.PreludeMacros: preludeMacroSummary :: RegexType -> PreludeMacro -> String
+ Text.RE.ZeInternals.PreludeMacros: preludeMacroTable :: RegexType -> String
+ Text.RE.ZeInternals.PreludeMacros: preludeMacros :: (Monad m, Functor m) => (String -> m r) -> RegexType -> WithCaptures -> m (Macros r)
+ Text.RE.ZeInternals.PreludeMacros: presentPreludeMacro :: PreludeMacro -> String
+ Text.RE.ZeInternals.Replace: ALL :: REContext
+ Text.RE.ZeInternals.Replace: RELocation :: Int -> CaptureOrdinal -> RELocation
+ Text.RE.ZeInternals.Replace: ReplaceMethods :: (a -> Int) -> ((a -> a) -> Capture a -> a) -> ReplaceMethods a
+ Text.RE.ZeInternals.Replace: SUB :: REContext
+ Text.RE.ZeInternals.Replace: TOP :: REContext
+ Text.RE.ZeInternals.Replace: [locationCapture] :: RELocation -> CaptureOrdinal
+ Text.RE.ZeInternals.Replace: [locationMatch] :: RELocation -> Int
+ Text.RE.ZeInternals.Replace: [methodLength] :: ReplaceMethods a -> a -> Int
+ Text.RE.ZeInternals.Replace: [methodSubst] :: ReplaceMethods a -> (a -> a) -> Capture a -> a
+ Text.RE.ZeInternals.Replace: appendNewlineR :: Replace a => a -> a
+ Text.RE.ZeInternals.Replace: class (Show a, Eq a, Ord a, Extract a, Monoid a) => Replace a where textifyR = pack . unpackR detextifyR = packR . unpack appendNewlineR = (<> packR "\n") substR f m@(Capture {..}) = capturePrefix m <> f capturedText <> captureSuffix m
+ Text.RE.ZeInternals.Replace: data REContext
+ Text.RE.ZeInternals.Replace: data RELocation
+ Text.RE.ZeInternals.Replace: data ReplaceMethods a
+ Text.RE.ZeInternals.Replace: detextifyR :: Replace a => Text -> a
+ Text.RE.ZeInternals.Replace: expandMacros :: (r -> String) -> Macros r -> String -> String
+ Text.RE.ZeInternals.Replace: expandMacros' :: (MacroID -> Maybe String) -> String -> String
+ Text.RE.ZeInternals.Replace: instance GHC.Show.Show Text.RE.ZeInternals.Replace.REContext
+ Text.RE.ZeInternals.Replace: instance GHC.Show.Show Text.RE.ZeInternals.Replace.RELocation
+ Text.RE.ZeInternals.Replace: instance Text.RE.ZeInternals.Replace.Replace (Data.Sequence.Seq GHC.Types.Char)
+ Text.RE.ZeInternals.Replace: instance Text.RE.ZeInternals.Replace.Replace Data.ByteString.Internal.ByteString
+ Text.RE.ZeInternals.Replace: instance Text.RE.ZeInternals.Replace.Replace Data.ByteString.Lazy.Internal.ByteString
+ Text.RE.ZeInternals.Replace: instance Text.RE.ZeInternals.Replace.Replace Data.Text.Internal.Lazy.Text
+ Text.RE.ZeInternals.Replace: instance Text.RE.ZeInternals.Replace.Replace Data.Text.Internal.Text
+ Text.RE.ZeInternals.Replace: instance Text.RE.ZeInternals.Replace.Replace [GHC.Types.Char]
+ Text.RE.ZeInternals.Replace: isTopLocation :: RELocation -> Bool
+ Text.RE.ZeInternals.Replace: lengthR :: Replace a => a -> Int
+ Text.RE.ZeInternals.Replace: linesR :: Replace a => a -> [a]
+ Text.RE.ZeInternals.Replace: packR :: Replace a => String -> a
+ Text.RE.ZeInternals.Replace: parseTemplateR :: Replace a => a -> Match a -> RELocation -> Capture a -> Maybe a
+ Text.RE.ZeInternals.Replace: replace :: Replace a => a -> Match a -> a
+ Text.RE.ZeInternals.Replace: replaceAll :: Replace a => a -> Matches a -> a
+ Text.RE.ZeInternals.Replace: replaceAllCaptures :: Replace a => REContext -> (Match a -> RELocation -> Capture a -> Maybe a) -> Matches a -> a
+ Text.RE.ZeInternals.Replace: replaceAllCapturesM :: (Extract a, Monad m) => ReplaceMethods a -> REContext -> (Match a -> RELocation -> Capture a -> m (Maybe a)) -> Matches a -> m a
+ Text.RE.ZeInternals.Replace: replaceAllCaptures_ :: Extract a => ReplaceMethods a -> REContext -> (Match a -> RELocation -> Capture a -> Maybe a) -> Matches a -> a
+ Text.RE.ZeInternals.Replace: replaceCaptures :: Replace a => REContext -> (Match a -> RELocation -> Capture a -> Maybe a) -> Match a -> a
+ Text.RE.ZeInternals.Replace: replaceCapturesM :: (Monad m, Extract a) => ReplaceMethods a -> REContext -> (Match a -> RELocation -> Capture a -> m (Maybe a)) -> Match a -> m a
+ Text.RE.ZeInternals.Replace: replaceCaptures_ :: Extract a => ReplaceMethods a -> REContext -> (Match a -> RELocation -> Capture a -> Maybe a) -> Match a -> a
+ Text.RE.ZeInternals.Replace: replaceMethods :: Replace a => ReplaceMethods a
+ Text.RE.ZeInternals.Replace: substR :: Replace a => (a -> a) -> Capture a -> a
+ Text.RE.ZeInternals.Replace: templateCaptures :: (Replace a, RegexContext Regex a (Matches a), RegexMaker Regex CompOption ExecOption String) => (a -> String) -> a -> [CaptureID]
+ Text.RE.ZeInternals.Replace: textifyR :: Replace a => a -> Text
+ Text.RE.ZeInternals.Replace: unlinesR :: Replace a => [a] -> a
+ Text.RE.ZeInternals.Replace: unpackR :: Replace a => a -> String
+ Text.RE.ZeInternals.TDFA: compileRegex :: (Functor m, Monad m) => String -> m RE
+ Text.RE.ZeInternals.TDFA: compileRegexWith :: (Functor m, Monad m) => SimpleREOptions -> String -> m RE
+ Text.RE.ZeInternals.TDFA: compileRegexWithOptions :: (IsOption o RE CompOption ExecOption, Functor m, Monad m) => o -> String -> m RE
+ Text.RE.ZeInternals.TDFA: compileSearchReplace :: (Monad m, Functor m, IsRegex RE s) => String -> String -> m (SearchReplace RE s)
+ Text.RE.ZeInternals.TDFA: compileSearchReplaceWith :: (Monad m, Functor m, IsRegex RE s) => SimpleREOptions -> String -> String -> m (SearchReplace RE s)
+ Text.RE.ZeInternals.TDFA: compileSearchReplaceWithREOptions :: (Monad m, Functor m, IsRegex RE s) => REOptions -> String -> String -> m (SearchReplace RE s)
+ Text.RE.ZeInternals.TDFA: cp :: QuasiQuoter
+ Text.RE.ZeInternals.TDFA: data RE
+ Text.RE.ZeInternals.TDFA: defaultREOptions :: REOptions
+ Text.RE.ZeInternals.TDFA: escape :: (Functor m, Monad m) => (String -> String) -> String -> m RE
+ Text.RE.ZeInternals.TDFA: escapeREString :: String -> String
+ Text.RE.ZeInternals.TDFA: escapeWith :: (Functor m, Monad m) => SimpleREOptions -> (String -> String) -> String -> m RE
+ Text.RE.ZeInternals.TDFA: escapeWithOptions :: (IsOption o RE CompOption ExecOption, Functor m, Monad m) => o -> (String -> String) -> String -> m RE
+ Text.RE.ZeInternals.TDFA: instance Text.RE.REOptions.IsOption () Text.RE.ZeInternals.TDFA.RE Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption
+ Text.RE.ZeInternals.TDFA: instance Text.RE.REOptions.IsOption (Text.RE.REOptions.Macros Text.RE.ZeInternals.TDFA.RE) Text.RE.ZeInternals.TDFA.RE Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption
+ Text.RE.ZeInternals.TDFA: instance Text.RE.REOptions.IsOption Text.RE.REOptions.SimpleREOptions Text.RE.ZeInternals.TDFA.RE Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption
+ Text.RE.ZeInternals.TDFA: instance Text.RE.REOptions.IsOption Text.RE.ZeInternals.TDFA.REOptions Text.RE.ZeInternals.TDFA.RE Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption
+ Text.RE.ZeInternals.TDFA: instance Text.RE.REOptions.IsOption Text.Regex.TDFA.Common.CompOption Text.RE.ZeInternals.TDFA.RE Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption
+ Text.RE.ZeInternals.TDFA: instance Text.RE.REOptions.IsOption Text.Regex.TDFA.Common.ExecOption Text.RE.ZeInternals.TDFA.RE Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption
+ Text.RE.ZeInternals.TDFA: noPreludeREOptions :: REOptions
+ Text.RE.ZeInternals.TDFA: prelude :: Macros RE
+ Text.RE.ZeInternals.TDFA: preludeEnv :: MacroEnv
+ Text.RE.ZeInternals.TDFA: preludeSource :: PreludeMacro -> String
+ Text.RE.ZeInternals.TDFA: preludeSources :: String
+ Text.RE.ZeInternals.TDFA: preludeSummary :: PreludeMacro -> String
+ Text.RE.ZeInternals.TDFA: preludeTable :: String
+ Text.RE.ZeInternals.TDFA: preludeTestsFailing :: [MacroID]
+ Text.RE.ZeInternals.TDFA: re :: QuasiQuoter
+ Text.RE.ZeInternals.TDFA: reBI :: QuasiQuoter
+ Text.RE.ZeInternals.TDFA: reBS :: QuasiQuoter
+ Text.RE.ZeInternals.TDFA: reBlockInsensitive :: QuasiQuoter
+ Text.RE.ZeInternals.TDFA: reBlockSensitive :: QuasiQuoter
+ Text.RE.ZeInternals.TDFA: reCaptureNames :: RE -> CaptureNames
+ Text.RE.ZeInternals.TDFA: reMI :: QuasiQuoter
+ Text.RE.ZeInternals.TDFA: reMS :: QuasiQuoter
+ Text.RE.ZeInternals.TDFA: reMultilineInsensitive :: QuasiQuoter
+ Text.RE.ZeInternals.TDFA: reMultilineSensitive :: QuasiQuoter
+ Text.RE.ZeInternals.TDFA: reOptions :: RE -> REOptions
+ Text.RE.ZeInternals.TDFA: reRegex :: RE -> Regex
+ Text.RE.ZeInternals.TDFA: reSource :: RE -> String
+ Text.RE.ZeInternals.TDFA: re_ :: QuasiQuoter
+ Text.RE.ZeInternals.TDFA: regexType :: RegexType
+ Text.RE.ZeInternals.TDFA: type REOptions = REOptions_ RE CompOption ExecOption
+ Text.RE.ZeInternals.TDFA: unpackSimpleREOptions :: SimpleREOptions -> REOptions
+ Text.RE.ZeInternals.TestBench: ExclCaptures :: WithCaptures
+ Text.RE.ZeInternals.TestBench: FunctionID :: String -> FunctionID
+ Text.RE.ZeInternals.TestBench: InclCaptures :: WithCaptures
+ Text.RE.ZeInternals.TestBench: MacroDescriptor :: !RegexSource -> ![String] -> ![String] -> ![TestResult] -> !(Maybe FunctionID) -> !String -> MacroDescriptor
+ Text.RE.ZeInternals.TestBench: MacroID :: String -> MacroID
+ Text.RE.ZeInternals.TestBench: RegexSource :: String -> RegexSource
+ Text.RE.ZeInternals.TestBench: TestResult :: String -> TestResult
+ Text.RE.ZeInternals.TestBench: [_FunctionID] :: FunctionID -> String
+ Text.RE.ZeInternals.TestBench: [_RegexSource] :: RegexSource -> String
+ Text.RE.ZeInternals.TestBench: [_TestResult] :: TestResult -> String
+ Text.RE.ZeInternals.TestBench: [getMacroID] :: MacroID -> String
+ Text.RE.ZeInternals.TestBench: [macroCounterSamples] :: MacroDescriptor -> ![String]
+ Text.RE.ZeInternals.TestBench: [macroDescription] :: MacroDescriptor -> !String
+ Text.RE.ZeInternals.TestBench: [macroParser] :: MacroDescriptor -> !(Maybe FunctionID)
+ Text.RE.ZeInternals.TestBench: [macroSamples] :: MacroDescriptor -> ![String]
+ Text.RE.ZeInternals.TestBench: [macroSource] :: MacroDescriptor -> !RegexSource
+ Text.RE.ZeInternals.TestBench: [macroTestResults] :: MacroDescriptor -> ![TestResult]
+ Text.RE.ZeInternals.TestBench: badMacros :: MacroEnv -> [MacroID]
+ Text.RE.ZeInternals.TestBench: data MacroDescriptor
+ Text.RE.ZeInternals.TestBench: data RegexType
+ Text.RE.ZeInternals.TestBench: data WithCaptures
+ Text.RE.ZeInternals.TestBench: dumpMacroTable :: String -> RegexType -> MacroEnv -> IO ()
+ Text.RE.ZeInternals.TestBench: formatMacroSource :: RegexType -> WithCaptures -> MacroEnv -> MacroID -> String
+ Text.RE.ZeInternals.TestBench: formatMacroSources :: RegexType -> WithCaptures -> MacroEnv -> String
+ Text.RE.ZeInternals.TestBench: formatMacroSummary :: RegexType -> MacroEnv -> MacroID -> String
+ Text.RE.ZeInternals.TestBench: formatMacroTable :: RegexType -> MacroEnv -> String
+ Text.RE.ZeInternals.TestBench: instance Data.String.IsString Text.RE.ZeInternals.TestBench.FunctionID
+ Text.RE.ZeInternals.TestBench: instance Data.String.IsString Text.RE.ZeInternals.TestBench.RegexSource
+ Text.RE.ZeInternals.TestBench: instance Data.String.IsString Text.RE.ZeInternals.TestBench.TestResult
+ Text.RE.ZeInternals.TestBench: instance GHC.Arr.Ix Text.RE.ZeInternals.TestBench.Col
+ Text.RE.ZeInternals.TestBench: instance GHC.Classes.Eq Text.RE.ZeInternals.TestBench.Col
+ Text.RE.ZeInternals.TestBench: instance GHC.Classes.Eq Text.RE.ZeInternals.TestBench.WithCaptures
+ Text.RE.ZeInternals.TestBench: instance GHC.Classes.Ord Text.RE.ZeInternals.TestBench.Col
+ Text.RE.ZeInternals.TestBench: instance GHC.Classes.Ord Text.RE.ZeInternals.TestBench.WithCaptures
+ Text.RE.ZeInternals.TestBench: instance GHC.Enum.Bounded Text.RE.ZeInternals.TestBench.Col
+ Text.RE.ZeInternals.TestBench: instance GHC.Enum.Enum Text.RE.ZeInternals.TestBench.Col
+ Text.RE.ZeInternals.TestBench: instance GHC.Show.Show Text.RE.ZeInternals.TestBench.Col
+ Text.RE.ZeInternals.TestBench: instance GHC.Show.Show Text.RE.ZeInternals.TestBench.FunctionID
+ Text.RE.ZeInternals.TestBench: instance GHC.Show.Show Text.RE.ZeInternals.TestBench.MacroDescriptor
+ Text.RE.ZeInternals.TestBench: instance GHC.Show.Show Text.RE.ZeInternals.TestBench.REToken
+ Text.RE.ZeInternals.TestBench: instance GHC.Show.Show Text.RE.ZeInternals.TestBench.RegexSource
+ Text.RE.ZeInternals.TestBench: instance GHC.Show.Show Text.RE.ZeInternals.TestBench.RegexType
+ Text.RE.ZeInternals.TestBench: instance GHC.Show.Show Text.RE.ZeInternals.TestBench.TestResult
+ Text.RE.ZeInternals.TestBench: instance GHC.Show.Show Text.RE.ZeInternals.TestBench.WithCaptures
+ Text.RE.ZeInternals.TestBench: isPCRE :: RegexType -> Bool
+ Text.RE.ZeInternals.TestBench: isTDFA :: RegexType -> Bool
+ Text.RE.ZeInternals.TestBench: mdRegexSource :: RegexType -> WithCaptures -> MacroEnv -> MacroDescriptor -> String
+ Text.RE.ZeInternals.TestBench: mkMacros :: (Monad m, Functor m) => (String -> m r) -> RegexType -> WithCaptures -> MacroEnv -> m (Macros r)
+ Text.RE.ZeInternals.TestBench: mkPCRE :: TestBenchMatcher -> RegexType
+ Text.RE.ZeInternals.TestBench: mkTDFA :: TestBenchMatcher -> RegexType
+ Text.RE.ZeInternals.TestBench: newtype FunctionID
+ Text.RE.ZeInternals.TestBench: newtype MacroID
+ Text.RE.ZeInternals.TestBench: newtype RegexSource
+ Text.RE.ZeInternals.TestBench: newtype TestResult
+ Text.RE.ZeInternals.TestBench: presentRegexType :: RegexType -> String
+ Text.RE.ZeInternals.TestBench: runTests :: (Eq a, Show a) => RegexType -> (String -> Maybe a) -> [(String, a)] -> MacroEnv -> MacroID -> MacroDescriptor -> MacroDescriptor
+ Text.RE.ZeInternals.TestBench: runTests' :: (Eq a, Show a) => RegexType -> (Match String -> Maybe a) -> [(String, a)] -> MacroEnv -> MacroID -> MacroDescriptor -> MacroDescriptor
+ Text.RE.ZeInternals.TestBench: testMacroDescriptors :: [MacroDescriptor] -> [TestResult]
+ Text.RE.ZeInternals.TestBench: testMacroEnv :: String -> RegexType -> MacroEnv -> IO Bool
+ Text.RE.ZeInternals.TestBench: type MacroEnv = HashMap MacroID MacroDescriptor
+ Text.RE.ZeInternals.Types.Capture: Capture :: !a -> !a -> !Int -> !Int -> Capture a
+ Text.RE.ZeInternals.Types.Capture: [captureLength] :: Capture a -> !Int
+ Text.RE.ZeInternals.Types.Capture: [captureOffset] :: Capture a -> !Int
+ Text.RE.ZeInternals.Types.Capture: [captureSource] :: Capture a -> !a
+ Text.RE.ZeInternals.Types.Capture: [capturedText] :: Capture a -> !a
+ Text.RE.ZeInternals.Types.Capture: capturePrefix :: Extract a => Capture a -> a
+ Text.RE.ZeInternals.Types.Capture: captureSuffix :: Extract a => Capture a -> a
+ Text.RE.ZeInternals.Types.Capture: data Capture a
+ Text.RE.ZeInternals.Types.Capture: hasCaptured :: Capture a -> Bool
+ Text.RE.ZeInternals.Types.Capture: instance GHC.Base.Functor Text.RE.ZeInternals.Types.Capture.Capture
+ Text.RE.ZeInternals.Types.Capture: instance GHC.Classes.Eq a => GHC.Classes.Eq (Text.RE.ZeInternals.Types.Capture.Capture a)
+ Text.RE.ZeInternals.Types.Capture: instance GHC.Show.Show a => GHC.Show.Show (Text.RE.ZeInternals.Types.Capture.Capture a)
+ Text.RE.ZeInternals.Types.CaptureID: CaptureName :: Text -> CaptureName
+ Text.RE.ZeInternals.Types.CaptureID: CaptureOrdinal :: Int -> CaptureOrdinal
+ Text.RE.ZeInternals.Types.CaptureID: IsCaptureName :: CaptureName -> CaptureID
+ Text.RE.ZeInternals.Types.CaptureID: IsCaptureOrdinal :: CaptureOrdinal -> CaptureID
+ Text.RE.ZeInternals.Types.CaptureID: [getCaptureName] :: CaptureName -> Text
+ Text.RE.ZeInternals.Types.CaptureID: [getCaptureOrdinal] :: CaptureOrdinal -> Int
+ Text.RE.ZeInternals.Types.CaptureID: data CaptureID
+ Text.RE.ZeInternals.Types.CaptureID: findCaptureID :: CaptureID -> CaptureNames -> Int
+ Text.RE.ZeInternals.Types.CaptureID: instance Data.Hashable.Class.Hashable Text.RE.ZeInternals.Types.CaptureID.CaptureName
+ Text.RE.ZeInternals.Types.CaptureID: instance GHC.Arr.Ix Text.RE.ZeInternals.Types.CaptureID.CaptureOrdinal
+ Text.RE.ZeInternals.Types.CaptureID: instance GHC.Classes.Eq Text.RE.ZeInternals.Types.CaptureID.CaptureID
+ Text.RE.ZeInternals.Types.CaptureID: instance GHC.Classes.Eq Text.RE.ZeInternals.Types.CaptureID.CaptureName
+ Text.RE.ZeInternals.Types.CaptureID: instance GHC.Classes.Eq Text.RE.ZeInternals.Types.CaptureID.CaptureOrdinal
+ Text.RE.ZeInternals.Types.CaptureID: instance GHC.Classes.Ord Text.RE.ZeInternals.Types.CaptureID.CaptureID
+ Text.RE.ZeInternals.Types.CaptureID: instance GHC.Classes.Ord Text.RE.ZeInternals.Types.CaptureID.CaptureName
+ Text.RE.ZeInternals.Types.CaptureID: instance GHC.Classes.Ord Text.RE.ZeInternals.Types.CaptureID.CaptureOrdinal
+ Text.RE.ZeInternals.Types.CaptureID: instance GHC.Enum.Enum Text.RE.ZeInternals.Types.CaptureID.CaptureOrdinal
+ Text.RE.ZeInternals.Types.CaptureID: instance GHC.Num.Num Text.RE.ZeInternals.Types.CaptureID.CaptureOrdinal
+ Text.RE.ZeInternals.Types.CaptureID: instance GHC.Show.Show Text.RE.ZeInternals.Types.CaptureID.CaptureID
+ Text.RE.ZeInternals.Types.CaptureID: instance GHC.Show.Show Text.RE.ZeInternals.Types.CaptureID.CaptureName
+ Text.RE.ZeInternals.Types.CaptureID: instance GHC.Show.Show Text.RE.ZeInternals.Types.CaptureID.CaptureOrdinal
+ Text.RE.ZeInternals.Types.CaptureID: newtype CaptureName
+ Text.RE.ZeInternals.Types.CaptureID: newtype CaptureOrdinal
+ Text.RE.ZeInternals.Types.CaptureID: noCaptureNames :: CaptureNames
+ Text.RE.ZeInternals.Types.CaptureID: type CaptureNames = HashMap CaptureName CaptureOrdinal
+ Text.RE.ZeInternals.Types.LineNo: ZeroBasedLineNo :: Int -> LineNo
+ Text.RE.ZeInternals.Types.LineNo: [getZeroBasedLineNo] :: LineNo -> Int
+ Text.RE.ZeInternals.Types.LineNo: firstLine :: LineNo
+ Text.RE.ZeInternals.Types.LineNo: getLineNo :: LineNo -> Int
+ Text.RE.ZeInternals.Types.LineNo: instance GHC.Enum.Enum Text.RE.ZeInternals.Types.LineNo.LineNo
+ Text.RE.ZeInternals.Types.LineNo: instance GHC.Show.Show Text.RE.ZeInternals.Types.LineNo.LineNo
+ Text.RE.ZeInternals.Types.LineNo: lineNo :: Int -> LineNo
+ Text.RE.ZeInternals.Types.LineNo: newtype LineNo
+ Text.RE.ZeInternals.Types.Match: (!$$) :: Match a -> CaptureID -> a
+ Text.RE.ZeInternals.Types.Match: (!$$?) :: Match a -> CaptureID -> Maybe a
+ Text.RE.ZeInternals.Types.Match: (!$) :: Match a -> CaptureID -> Capture a
+ Text.RE.ZeInternals.Types.Match: (!$?) :: Match a -> CaptureID -> Maybe (Capture a)
+ Text.RE.ZeInternals.Types.Match: Match :: !a -> !CaptureNames -> !(Array CaptureOrdinal (Capture a)) -> Match a
+ Text.RE.ZeInternals.Types.Match: [captureNames] :: Match a -> !CaptureNames
+ Text.RE.ZeInternals.Types.Match: [matchArray] :: Match a -> !(Array CaptureOrdinal (Capture a))
+ Text.RE.ZeInternals.Types.Match: [matchSource] :: Match a -> !a
+ Text.RE.ZeInternals.Types.Match: capture :: CaptureID -> Match a -> Capture a
+ Text.RE.ZeInternals.Types.Match: captureMaybe :: CaptureID -> Match a -> Maybe (Capture a)
+ Text.RE.ZeInternals.Types.Match: captureText :: CaptureID -> Match a -> a
+ Text.RE.ZeInternals.Types.Match: captureTextMaybe :: CaptureID -> Match a -> Maybe a
+ Text.RE.ZeInternals.Types.Match: convertMatchText :: source -> MatchText source -> Match source
+ Text.RE.ZeInternals.Types.Match: data Match a
+ Text.RE.ZeInternals.Types.Match: emptyMatchArray :: Array CaptureOrdinal (Capture a)
+ Text.RE.ZeInternals.Types.Match: infixl 9 !$
+ Text.RE.ZeInternals.Types.Match: instance (Text.Regex.Base.RegexLike.RegexContext regex source (Text.Regex.Base.RegexLike.AllTextSubmatches (GHC.Arr.Array GHC.Types.Int) (source, (GHC.Types.Int, GHC.Types.Int))), Text.Regex.Base.RegexLike.RegexLike regex source) => Text.Regex.Base.RegexLike.RegexContext regex source (Text.RE.ZeInternals.Types.Match.Match source)
+ Text.RE.ZeInternals.Types.Match: instance GHC.Base.Functor Text.RE.ZeInternals.Types.Match.Match
+ Text.RE.ZeInternals.Types.Match: instance GHC.Classes.Eq a => GHC.Classes.Eq (Text.RE.ZeInternals.Types.Match.Match a)
+ Text.RE.ZeInternals.Types.Match: instance GHC.Show.Show a => GHC.Show.Show (Text.RE.ZeInternals.Types.Match.Match a)
+ Text.RE.ZeInternals.Types.Match: matchCapture :: Match a -> Maybe (Capture a)
+ Text.RE.ZeInternals.Types.Match: matchCaptures :: Match a -> Maybe (Capture a, [Capture a])
+ Text.RE.ZeInternals.Types.Match: matched :: Match a -> Bool
+ Text.RE.ZeInternals.Types.Match: matchedText :: Match a -> Maybe a
+ Text.RE.ZeInternals.Types.Match: noMatch :: a -> Match a
+ Text.RE.ZeInternals.Types.Matches: Matches :: !a -> ![Match a] -> Matches a
+ Text.RE.ZeInternals.Types.Matches: [allMatches] :: Matches a -> ![Match a]
+ Text.RE.ZeInternals.Types.Matches: [matchesSource] :: Matches a -> !a
+ Text.RE.ZeInternals.Types.Matches: anyMatches :: Matches a -> Bool
+ Text.RE.ZeInternals.Types.Matches: countMatches :: Matches a -> Int
+ Text.RE.ZeInternals.Types.Matches: data Matches a
+ Text.RE.ZeInternals.Types.Matches: instance (Text.Regex.Base.RegexLike.RegexContext regex source [Text.Regex.Base.RegexLike.MatchText source], Text.Regex.Base.RegexLike.RegexLike regex source) => Text.Regex.Base.RegexLike.RegexContext regex source (Text.RE.ZeInternals.Types.Matches.Matches source)
+ Text.RE.ZeInternals.Types.Matches: instance GHC.Base.Functor Text.RE.ZeInternals.Types.Matches.Matches
+ Text.RE.ZeInternals.Types.Matches: instance GHC.Classes.Eq a => GHC.Classes.Eq (Text.RE.ZeInternals.Types.Matches.Matches a)
+ Text.RE.ZeInternals.Types.Matches: instance GHC.Show.Show a => GHC.Show.Show (Text.RE.ZeInternals.Types.Matches.Matches a)
+ Text.RE.ZeInternals.Types.Matches: mainCaptures :: Matches a -> [Capture a]
+ Text.RE.ZeInternals.Types.Matches: matches :: Matches a -> [a]
+ Text.RE.ZeInternals.Types.SearchReplace: SearchReplace :: !re -> !s -> SearchReplace re s
+ Text.RE.ZeInternals.Types.SearchReplace: [getSearch] :: SearchReplace re s -> !re
+ Text.RE.ZeInternals.Types.SearchReplace: [getTemplate] :: SearchReplace re s -> !s
+ Text.RE.ZeInternals.Types.SearchReplace: data SearchReplace re s
+ Text.RE.ZeInternals.Types.SearchReplace: instance (GHC.Show.Show s, GHC.Show.Show re) => GHC.Show.Show (Text.RE.ZeInternals.Types.SearchReplace.SearchReplace re s)
+ Text.RE.ZeInternals.Types.SearchReplace: instance GHC.Base.Functor (Text.RE.ZeInternals.Types.SearchReplace.SearchReplace re)
- Text.RE.Tools: Function :: !re -> REContext -> !(LineNo -> Match s -> Location -> Capture s -> m (Maybe s)) -> Edit m re s
+ Text.RE.Tools: Function :: !re -> REContext -> !(LineNo -> Match s -> RELocation -> Capture s -> m (Maybe s)) -> Edit m re s
- Text.RE.Tools.Edit: Function :: !re -> REContext -> !(LineNo -> Match s -> Location -> Capture s -> m (Maybe s)) -> Edit m re s
+ Text.RE.Tools.Edit: Function :: !re -> REContext -> !(LineNo -> Match s -> RELocation -> Capture s -> m (Maybe s)) -> Edit m re s
- Text.RE.Tools.Sed: Function :: !re -> REContext -> !(LineNo -> Match s -> Location -> Capture s -> m (Maybe s)) -> Edit m re s
+ Text.RE.Tools.Sed: Function :: !re -> REContext -> !(LineNo -> Match s -> RELocation -> Capture s -> m (Maybe s)) -> Edit m re s
Files
- README.markdown +2/−0
- Text/RE.hs +4/−4
- Text/RE/Internal/AddCaptureNames.hs +0/−71
- Text/RE/Internal/EscapeREString.hs +0/−29
- Text/RE/Internal/NamedCaptures.lhs +0/−230
- Text/RE/Internal/PreludeMacros.hs +0/−909
- Text/RE/Internal/QQ.hs +0/−29
- Text/RE/Internal/SearchReplace.hs +0/−84
- Text/RE/Internal/SearchReplace/TDFA.hs +0/−54
- Text/RE/Internal/SearchReplace/TDFA/ByteString.hs +0/−58
- Text/RE/Internal/SearchReplace/TDFA/ByteString/Lazy.hs +0/−58
- Text/RE/Internal/SearchReplace/TDFA/Sequence.hs +0/−58
- Text/RE/Internal/SearchReplace/TDFA/String.hs +0/−58
- Text/RE/Internal/SearchReplace/TDFA/Text.hs +0/−58
- Text/RE/Internal/SearchReplace/TDFA/Text/Lazy.hs +0/−58
- Text/RE/Internal/SearchReplace/TDFAEdPrime.hs +0/−63
- Text/RE/IsRegex.lhs +60/−0
- Text/RE/REOptions.lhs +105/−0
- Text/RE/Replace.hs +23/−0
- Text/RE/SearchReplace.hs +0/−22
- Text/RE/Summa.hs +7/−7
- Text/RE/TDFA.hs +8/−9
- Text/RE/TDFA/ByteString.hs +8/−9
- Text/RE/TDFA/ByteString/Lazy.hs +8/−9
- Text/RE/TDFA/RE.hs +0/−429
- Text/RE/TDFA/Sequence.hs +8/−9
- Text/RE/TDFA/String.hs +8/−9
- Text/RE/TDFA/Text.hs +8/−9
- Text/RE/TDFA/Text/Lazy.hs +8/−9
- Text/RE/TestBench.hs +186/−0
- Text/RE/TestBench.lhs +0/−589
- Text/RE/TestBench/Parsers.hs +0/−166
- Text/RE/Tools/Edit.lhs +5/−6
- Text/RE/Tools/Grep.lhs +2/−2
- Text/RE/Tools/Lex.lhs +4/−4
- Text/RE/Tools/Sed.lhs +2/−2
- Text/RE/Types.hs +0/−27
- Text/RE/Types/Capture.lhs +0/−61
- Text/RE/Types/CaptureID.hs +0/−49
- Text/RE/Types/IsRegex.lhs +0/−46
- Text/RE/Types/LineNo.hs +0/−21
- Text/RE/Types/Match.lhs +0/−194
- Text/RE/Types/Matches.lhs +0/−80
- Text/RE/Types/REOptions.lhs +0/−94
- Text/RE/Types/Replace.lhs +0/−505
- Text/RE/Types/SearchReplace.hs +0/−15
- Text/RE/ZeInternals/AddCaptureNames.hs +71/−0
- Text/RE/ZeInternals/EscapeREString.hs +29/−0
- Text/RE/ZeInternals/NamedCaptures.lhs +230/−0
- Text/RE/ZeInternals/PreludeMacros.hs +909/−0
- Text/RE/ZeInternals/QQ.hs +29/−0
- Text/RE/ZeInternals/Replace.lhs +538/−0
- Text/RE/ZeInternals/SearchReplace.hs +84/−0
- Text/RE/ZeInternals/SearchReplace/TDFA.hs +54/−0
- Text/RE/ZeInternals/SearchReplace/TDFA/ByteString.hs +58/−0
- Text/RE/ZeInternals/SearchReplace/TDFA/ByteString/Lazy.hs +58/−0
- Text/RE/ZeInternals/SearchReplace/TDFA/Sequence.hs +58/−0
- Text/RE/ZeInternals/SearchReplace/TDFA/String.hs +58/−0
- Text/RE/ZeInternals/SearchReplace/TDFA/Text.hs +58/−0
- Text/RE/ZeInternals/SearchReplace/TDFA/Text/Lazy.hs +58/−0
- Text/RE/ZeInternals/SearchReplace/TDFAEdPrime.hs +62/−0
- Text/RE/ZeInternals/TDFA.hs +428/−0
- Text/RE/ZeInternals/TestBench.lhs +590/−0
- Text/RE/ZeInternals/Types/Capture.lhs +61/−0
- Text/RE/ZeInternals/Types/CaptureID.hs +49/−0
- Text/RE/ZeInternals/Types/LineNo.hs +21/−0
- Text/RE/ZeInternals/Types/Match.lhs +194/−0
- Text/RE/ZeInternals/Types/Matches.lhs +80/−0
- Text/RE/ZeInternals/Types/SearchReplace.hs +15/−0
- changelog +5/−0
- regex.cabal +28/−29
README.markdown view
@@ -68,6 +68,8 @@ ☒ 2017-03-28 v0.10.0.3 [Upgrade to LTS 8.6 and Improve Haddocks for Text.RE.{TDFA,PCRE}](https://github.com/iconnect/regex/milestone/13) + ☒ 2017-03-29 v0.11.0.0 [Simplify the API](https://github.com/iconnect/regex/milestone/14)+ ☐ 2017-03-31 v1.0.0.0 [First stable release](https://github.com/iconnect/regex/milestone/3) ☐ 2017-08-31 v2.0.0.0 [Fast text replacement with benchmarks](https://github.com/iconnect/regex/milestone/4)
Text/RE.hs view
@@ -29,8 +29,8 @@ , matchedText ) where -import Text.RE.Types.Match-import Text.RE.Types.Matches+import Text.RE.ZeInternals.Types.Match+import Text.RE.ZeInternals.Types.Matches -- $tutorial --@@ -55,7 +55,7 @@ -- -- * "Text.RE.TDFA.ByteString" -- * "Text.RE.TDFA.ByteString.Lazy"--- * "Text.RE.TDFA.RE"+-- * "Text.RE.ZeInternals.TDFA" -- * "Text.RE.TDFA.Sequence" -- * "Text.RE.TDFA.String" -- * "Text.RE.TDFA.Text"@@ -67,7 +67,7 @@ -- -- * Text.RE.PCRE.ByteString -- * Text.RE.PCRE.ByteString.Lazy--- * Text.RE.PCRE.RE+-- * Text.RE.ZeInternals.PCRE -- * Text.RE.PCRE.Sequence -- * Text.RE.PCRE.String -- * Text.RE.PCRE
− Text/RE/Internal/AddCaptureNames.hs
@@ -1,71 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE OverloadedStrings #-}--module Text.RE.Internal.AddCaptureNames where--import qualified Data.ByteString.Lazy.Char8 as LBS-import qualified Data.ByteString.Char8 as B-import Data.Dynamic-import Data.Maybe-import qualified Data.Sequence as S-import qualified Data.Text as T-import qualified Data.Text.Lazy as TL-import Prelude.Compat-import Text.RE-import Text.RE.Types.CaptureID-import Text.RE.Types.Match-import Unsafe.Coerce----- | a convenience function used by the API modules to insert--- capture names extracted from the parsed RE into the (*=~) result-addCaptureNamesToMatches :: CaptureNames -> Matches a -> Matches a-addCaptureNamesToMatches cnms mtchs =- mtchs { allMatches = map (addCaptureNamesToMatch cnms) $ allMatches mtchs }---- | a convenience function used by the API modules to insert--- capture names extracted from the parsed RE into the (?=~) result-addCaptureNamesToMatch :: CaptureNames -> Match a -> Match a-addCaptureNamesToMatch cnms mtch = mtch { captureNames = cnms }---- | a hairy dynamically-typed function used with the legacy (=~) and (=~~)--- to see if it can/should add the capture names extracted from the RE--- into the polymorphic result of the operator (it does for any Match--- or Matches type, provided it is parameterised over a recognised type).--- The test suite is all over this one, testing all of these cases.-addCaptureNames :: Typeable a => CaptureNames -> a -> a-addCaptureNames cnms x = fromMaybe x $ listToMaybe $ catMaybes- [ test_match x ( proxy :: String )- , test_matches x ( proxy :: String )- , test_match x ( proxy :: B.ByteString )- , test_matches x ( proxy :: B.ByteString )- , test_match x ( proxy :: LBS.ByteString )- , test_matches x ( proxy :: LBS.ByteString )- , test_match x ( proxy :: T.Text )- , test_matches x ( proxy :: T.Text )- , test_match x ( proxy :: TL.Text )- , test_matches x ( proxy :: TL.Text )- , test_match x ( proxy :: S.Seq Char )- , test_matches x ( proxy :: S.Seq Char )- ]- where- test_match :: Typeable t => r -> t -> Maybe r- test_match r t = f r t $ addCaptureNamesToMatch cnms <$> fromDynamic dyn- where- f :: r' -> t' -> Maybe (Match t') -> Maybe r'- f _ _ = unsafeCoerce-- test_matches :: Typeable t => r -> t -> Maybe r- test_matches r t = f r t $ addCaptureNamesToMatches cnms <$> fromDynamic dyn- where- f :: r' -> t' -> Maybe (Matches t') -> Maybe r'- f _ _ = unsafeCoerce-- dyn :: Dynamic- dyn = toDyn x-- proxy :: a- proxy = error "addCaptureNames"
− Text/RE/Internal/EscapeREString.hs
@@ -1,29 +0,0 @@-module Text.RE.Internal.EscapeREString where---- | Convert a string into a regular expression that will amtch that--- string-escapeREString :: String -> String-escapeREString = foldr esc []- where- esc c t | isMetaChar c = '\\' : c : t- | otherwise = c : t---- | returns True iff the charactr is an RE meta character--- ('[', '*', '{', etc.)-isMetaChar :: Char -> Bool-isMetaChar c = case c of- '^' -> True- '\\' -> True- '.' -> True- '|' -> True- '*' -> True- '?' -> True- '+' -> True- '(' -> True- ')' -> True- '[' -> True- ']' -> True- '{' -> True- '}' -> True- '$' -> True- _ -> False
− Text/RE/Internal/NamedCaptures.lhs
@@ -1,230 +0,0 @@-\begin{code}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 800-{-# LANGUAGE TemplateHaskellQuotes #-}-#else-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}-#endif--module Text.RE.Internal.NamedCaptures- ( cp- , extractNamedCaptures- , idFormatTokenREOptions- , Token(..)- , validToken- , formatTokens- , formatTokens'- , formatTokens0- , scan- ) where--import Data.Char-import qualified Data.HashMap.Strict as HM-import qualified Data.Text as T-import GHC.Generics-import qualified Language.Haskell.TH as TH-import Language.Haskell.TH.Quote-import Text.RE-import Text.RE.Internal.PreludeMacros-import Text.RE.Internal.QQ-import Text.RE.TestBench-import Text.RE.Tools.Lex-import Text.RE.Types.CaptureID-import Text.RE.Types.Match-import Text.Regex.TDFA----- | quasi quoter for CaptureID ([cp|0|],[cp|y|], etc.)-cp :: QuasiQuoter-cp =- (qq0 "cp")- { quoteExp = parse_capture- }---- | extract the CaptureNames from an RE or return an error diagnostic--- if the RE is not well formed; also returs the total number of captures--- in the RE-extractNamedCaptures :: String -> Either String ((Int,CaptureNames),String)-extractNamedCaptures s = Right (analyseTokens tks,formatTokens tks)- where- tks = scan s-\end{code}---Token--------\begin{code}--- | our RE scanner returns a list of these tokens-data Token- = ECap (Maybe String)- | PGrp- | PCap- | Bra- | BS Char- | Other Char- deriving (Show,Generic,Eq)---- | check that a token is well formed-validToken :: Token -> Bool-validToken tkn = case tkn of- ECap mb -> maybe True check_ecap mb- PGrp -> True- PCap -> True- Bra -> True- BS c -> is_dot c- Other c -> is_dot c- where- check_ecap s = not (null s) && all not_br s- is_dot c = c/='\n'- not_br c = not $ c `elem` "{}\n"--\end{code}---Analysing [Token] -> CaptureNames------------------------------------\begin{code}--- | analyse a token stream, returning the number of captures and the--- 'CaptureNames'-analyseTokens :: [Token] -> (Int,CaptureNames)-analyseTokens tks0 = case count_em 1 tks0 of- (n,as) -> (n-1, HM.fromList as)- where- count_em n [] = (n,[])- count_em n (tk:tks) = case count_em (n `seq` n+d) tks of- (n',as) -> (n',bd++as)- where- (d,bd) = case tk of- ECap (Just nm) -> (,) 1 [(CaptureName $ T.pack nm,CaptureOrdinal n)]- ECap Nothing -> (,) 1 []- PGrp -> (,) 0 []- PCap -> (,) 1 []- Bra -> (,) 1 []- BS _ -> (,) 0 []- Other _ -> (,) 0 []-\end{code}---Scanning Regex Strings-------------------------\begin{code}--- | scan a RE string into a list of RE Token-scan :: String -> [Token]-scan = alex' match al oops- where- al :: [(Regex,Match String->Maybe Token)]- al =- [ mk "\\$\\{([^{}]+)\\}\\(" $ ECap . Just . x_1- , mk "\\$\\(" $ const $ ECap Nothing- , mk "\\(\\?:" $ const PGrp- , mk "\\(\\?" $ const PCap- , mk "\\(" $ const Bra- , mk "\\\\(.)" $ BS . s2c . x_1- , mk "(.)" $ Other . s2c . x_1- ]-- x_1 = captureText $ IsCaptureOrdinal $ CaptureOrdinal 1-- s2c [c] = c- s2c _ = error "scan:s2c:internal error"-- mk s f = (either error id $ makeRegexM s,Just . f)-- oops = error "reScanner"-\end{code}---Parsing captures-------------------\begin{code}-parse_capture :: String -> TH.Q TH.Exp-parse_capture s = case all isDigit s of- True -> [|IsCaptureOrdinal $ CaptureOrdinal $ read s|]- False -> [|IsCaptureName $ CaptureName $ T.pack s|]-\end{code}---Formatting [Token]---------------------\begin{code}--- | format [Token] into an RE string-formatTokens :: [Token] -> String-formatTokens = formatTokens' defFormatTokenREOptions---- | options for the general Token formatter below-data FormatTokenREOptions =- FormatTokenREOptions- { _fto_regex_type :: Maybe RegexType -- ^ Posix, PCRE or indeterminate REs?- , _fto_min_caps :: Bool -- ^ remove captures where possible- , _fto_incl_caps :: Bool -- ^ include the captures in the output- }- deriving (Show)---- | the default configuration for the Token formatter-defFormatTokenREOptions :: FormatTokenREOptions-defFormatTokenREOptions =- FormatTokenREOptions- { _fto_regex_type = Nothing- , _fto_min_caps = False- , _fto_incl_caps = False- }---- | a configuration that will preserve the parsed regular expression--- in the output-idFormatTokenREOptions :: FormatTokenREOptions-idFormatTokenREOptions =- FormatTokenREOptions- { _fto_regex_type = Nothing- , _fto_min_caps = False- , _fto_incl_caps = True- }---- | the general Token formatter, generating REs according to the options-formatTokens' :: FormatTokenREOptions -> [Token] -> String-formatTokens' FormatTokenREOptions{..} = foldr f ""- where- f tk tl = t_s ++ tl- where- t_s = case tk of- ECap mb -> ecap mb- PGrp -> if maybe False isTDFA _fto_regex_type then "(" else "(?:"- PCap -> "(?"- Bra -> bra _fto_min_caps- BS c -> "\\" ++ [c]- Other c -> [c]-- ecap mb = case _fto_incl_caps of- True -> case mb of- Nothing -> "$("- Just nm -> "${"++nm++"}("- False -> bra _fto_min_caps-- bra mc = case mc && maybe False isPCRE _fto_regex_type of- True -> "(?:"- False -> "("-\end{code}--\begin{code}--- this is a reference of formatTokens defFormatTokenREOptions,--- used for testing the latter-formatTokens0 :: [Token] -> String-formatTokens0 = foldr f ""- where- f tk tl = t_s ++ tl- where- t_s = case tk of- ECap _ -> "("- PGrp -> "(?:"- PCap -> "(?"- Bra -> "("- BS c -> "\\" ++ [c]- Other c -> [c]-\end{code}
− Text/RE/Internal/PreludeMacros.hs
@@ -1,909 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 800-{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}-#endif--module Text.RE.Internal.PreludeMacros- ( RegexType- , WithCaptures(..)- , MacroDescriptor(..)- , RegexSource(..)- , PreludeMacro(..)- , presentPreludeMacro- , preludeMacros- , preludeMacroTable- , preludeMacroSummary- , preludeMacroSources- , preludeMacroSource- , preludeMacroEnv- , preludeMacroDescriptor- ) where--import Data.Array-import qualified Data.HashMap.Lazy as HML-import Data.List-import Data.Maybe-import qualified Data.Text as T-import Data.Time-import Prelude.Compat-import Text.RE.Types.REOptions-import Text.RE.TestBench.Parsers-import Text.RE.TestBench----- | generate the standard prelude Macros used to parse REs-preludeMacros :: (Monad m,Functor m)- => (String->m r)- -> RegexType- -> WithCaptures- -> m (Macros r)-preludeMacros prs rty wc = mkMacros prs rty wc $ preludeMacroEnv rty---- | format the standard prelude macros in a markdown table-preludeMacroTable :: RegexType -> String-preludeMacroTable rty = formatMacroTable rty $ preludeMacroEnv rty---- | generate a textual summary of the prelude macros-preludeMacroSummary :: RegexType -> PreludeMacro -> String-preludeMacroSummary rty =- formatMacroSummary rty (preludeMacroEnv rty) . prelude_macro_id---- | generate a plain text table giving the RE for each macro with all--- macros expanded (to NF)-preludeMacroSources :: RegexType -> String-preludeMacroSources rty =- formatMacroSources rty ExclCaptures $ preludeMacroEnv rty---- | generate plain text giving theexpanded RE for a single macro-preludeMacroSource :: RegexType -> PreludeMacro -> String-preludeMacroSource rty =- formatMacroSource rty ExclCaptures (preludeMacroEnv rty) . prelude_macro_id---- | generate the `MacroEnv` for the standard prelude macros-preludeMacroEnv :: RegexType -> MacroEnv-preludeMacroEnv rty = fix $ prelude_macro_env rty--prelude_macro_env :: RegexType -> MacroEnv -> MacroEnv-prelude_macro_env rty env = HML.fromList $ catMaybes- [ (,) (prelude_macro_id pm) <$> preludeMacroDescriptor rty env pm- | pm<-[minBound..maxBound]- ]---- | generate the `MacroDescriptor` for a given `PreludeMacro`-preludeMacroDescriptor :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-preludeMacroDescriptor rty env pm = case pm of- PM_nat -> natural_macro rty env pm- PM_hex -> natural_hex_macro rty env pm- PM_int -> integer_macro rty env pm- PM_frac -> decimal_macro rty env pm- PM_string -> string_macro rty env pm- PM_string_simple -> string_simple_macro rty env pm- PM_id -> id_macro rty env pm- PM_id' -> id'_macro rty env pm- PM_id_ -> id__macro rty env pm- PM_date -> date_macro rty env pm- PM_date_slashes -> date_slashes_macro rty env pm- PM_time -> time_macro rty env pm- PM_timezone -> timezone_macro rty env pm- PM_datetime -> datetime_macro rty env pm- PM_datetime_8601 -> datetime_8601_macro rty env pm- PM_datetime_clf -> datetime_clf_macro rty env pm- PM_shortmonth -> shortmonth_macro rty env pm- PM_address_ipv4 -> address_ipv4_macros rty env pm- PM_email_simple -> email_simple_macro rty env pm- PM_url -> url_macro rty env pm- PM_syslog_severity -> syslog_severity_macro rty env pm---- | an enumeration of all of the prelude macros-data PreludeMacro- -- numbers- = PM_nat- | PM_hex- | PM_int- | PM_frac- -- strings- | PM_string- | PM_string_simple- -- identifiers- | PM_id- | PM_id'- | PM_id_- -- dates & times- | PM_date- | PM_date_slashes- | PM_time- | PM_timezone- | PM_datetime- | PM_datetime_8601- | PM_datetime_clf- | PM_shortmonth- -- addresses- | PM_address_ipv4- | PM_email_simple- | PM_url- -- syslog- | PM_syslog_severity- deriving (Bounded,Enum,Ord,Eq,Show)---- | naming the macros-presentPreludeMacro :: PreludeMacro -> String-presentPreludeMacro pm = case pm of- PM_id_ -> prelude_prefix++"id-"- _ -> fmt pm- where- fmt = (prelude_prefix++) . map tr . drop 3 . show-- tr '_' = '.'- tr c = c---- | all prelude macros are prefixed with this-prelude_prefix :: String-prelude_prefix = "%"--prelude_macro_id :: PreludeMacro -> MacroID-prelude_macro_id = MacroID . presentPreludeMacro--natural_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor-natural_macro rty env pm = Just $ run_tests rty parseInteger samples env pm- MacroDescriptor- { _md_source = "[0-9]+"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseInteger"- , _md_description = "a string of one or more decimal digits"- }- where- samples :: [(String,Int)]- samples =- [ (,) "0" 0- , (,) "1234567890" 1234567890- , (,) "00" 0- , (,) "01" 1- ]-- counter_samples =- [ ""- , "0A"- , "-1"- ]--natural_hex_macro :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-natural_hex_macro rty env pm = Just $ run_tests rty parseHex samples env pm- MacroDescriptor- { _md_source = "[0-9a-fA-F]+"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseHex"- , _md_description = "a string of one or more hexadecimal digits"- }- where- samples :: [(String,Int)]- samples =- [ (,) "0" 0x0- , (,) "12345678" 0x12345678- , (,) "0abcdef" 0xabcdef- , (,) "0ABCDEF" 0xabcdef- , (,) "00" 0x0- , (,) "010" 0x10- ]-- counter_samples =- [ ""- , "0x10"- , "0z"- , "-1a"- ]--integer_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor-integer_macro rty env pm = Just $ run_tests rty parseInteger samples env pm- MacroDescriptor- { _md_source = "-?[0-9]+"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseInteger"- , _md_description = "a decimal integer"- }- where- samples :: [(String,Int)]- samples =- [ (,) "0" 0- , (,) "1234567890" 1234567890- , (,) "00" 0- , (,) "01" 1- , (,) "-1" $ -1- , (,) "-0" 0- ]-- counter_samples =- [ ""- , "0A"- , "+0"- ]---- | a digit string macro-decimal_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor-decimal_macro rty env pm = Just $ run_tests rty parseDouble samples env pm- MacroDescriptor- { _md_source = "-?[0-9]+(?:\\.[0-9]+)?"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseInteger"- , _md_description = "a decimal integer"- }- where- samples :: [(String,Double)]- samples =- [ (,) "0" 0- , (,) "1234567890" 1234567890- , (,) "00" 0- , (,) "01" 1- , (,) "-1" $ -1- , (,) "-0" 0- , (,) "0.1234567890" 0.1234567890- , (,) "-1.0" $ -1.0- ]-- counter_samples =- [ ""- , "0A"- , "+0"- , "0."- , ".0"- , "."- , "-"- , "-."- , "-1."- , "-.1"- ]--string_macro :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-string_macro rty env pm- | isPCRE rty = Nothing- | otherwise =- Just $ run_tests rty (fmap T.unpack . parseString) samples env pm- MacroDescriptor- { _md_source = "\"(?:[^\"\\]+|\\\\[\\\"])*\""- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseString"- , _md_description = "a double-quote string, with simple \\ escapes for \\s and \"s"- }- where- samples :: [(String,String)]- samples =- [ (,) "\"\"" ""- , (,) "\"foo\"" "foo"- , (,) "\"\\\"\"" "\""- , (,) "\"\\\"\\\"\"" "\"\""- , (,) "\"\\\"\\\\\\\"\"" "\"\\\""- , (,) "\"\\\"foo\\\"\"" "\"foo\""- , (,) "\"\"" ""- ]-- counter_samples =- [ "\""- , "\"aa"- ]--string_simple_macro :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-string_simple_macro rty env pm =- Just $ run_tests rty (fmap T.unpack . parseSimpleString) samples env pm- MacroDescriptor- { _md_source = "\"[^\"[:cntrl:]]*\""- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseSimpleString"- , _md_description = "a decimal integer"- }- where- samples :: [(String,String)]- samples =- [ (,) "\"\"" ""- , (,) "\"foo\"" "foo"- , (,) "\"\\\"" "\\"- , (,) "\"\"" ""- ]-- counter_samples =- [ ""- , "\""- , "\"\\\"\""- , "\"\\\"\\\"\""- , "\"\\\"\\\\\\\"\""- , "\"\\\"foo\\\"\""- , "\"aa"- ]--id_macro :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-id_macro rty env pm =- Just $ run_tests rty Just samples env pm- MacroDescriptor- { _md_source = "_*[a-zA-Z][a-zA-Z0-9_]*"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Nothing- , _md_description = "a standard C-style alphanumeric identifier (with _s)"- }- where- samples :: [(String,String)]- samples =- [ f "a"- , f "A"- , f "A1"- , f "a_"- , f "a1_B2"- , f "_abc"- , f "__abc"- ]- where- f s = (s,s)-- counter_samples =- [ ""- , "1"- , "_"- , "__"- , "__1"- , "1a"- , "a'"- ]--id'_macro :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-id'_macro rty env pm =- Just $ run_tests rty Just samples env pm- MacroDescriptor- { _md_source = "_*[a-zA-Z][a-zA-Z0-9_']*"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Nothing- , _md_description = "a standard Haskell-style alphanumeric identifier (with '_'s and '''s)"- }- where- samples :: [(String,String)]- samples =- [ f "a"- , f "A"- , f "A1"- , f "a_"- , f "a1_B2"- , f "_abc"- , f "__abc"- , f "a'"- , f "_a'"- , f "a'b"- ]- where- f s = (s,s)-- counter_samples =- [ ""- , "1"- , "_"- , "__"- , "__1"- , "1a"- , "'"- , "'a"- , "_'"- , "_1'"- ]--id__macro :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-id__macro rty env pm =- Just $ run_tests rty Just samples env pm- MacroDescriptor- { _md_source = "_*[a-zA-Z][a-zA-Z0-9_'-]*"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Nothing- , _md_description = "an identifier with -s"- }- where- samples :: [(String,String)]- samples =- [ f "a"- , f "A"- , f "A1"- , f "a_"- , f "a1_B2"- , f "_abc"- , f "__abc"- , f "a'"- , f "_a'"- , f "a'b"- , f "a-"- , f "a1-B2"- , f "a1-B2-"- ]- where- f s = (s,s)-- counter_samples =- [ ""- , "1"- , "_"- , "__"- , "__1"- , "1a"- , "'"- , "'a"- , "_'"- , "_1'"- ]--date_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor-date_macro rty env pm =- Just $ run_tests rty parseDate samples env pm- MacroDescriptor- { _md_source = "[0-9]{4}-[0-9]{2}-[0-9]{2}"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseDate"- , _md_description = "a YYYY-MM-DD format date"- }- where- samples :: [(String,Day)]- samples =- [ f "2016-12-31"- , f "0001-01-01"- , f "1000-01-01"- ]- where- f s = (s,read s)-- counter_samples =- [ ""- , "2016/01/31"- , "2016-1-31"- , "2016-01-1"- , "2016-001-01"- ]--date_slashes_macro :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-date_slashes_macro rty env pm =- Just $ run_tests rty parseSlashesDate samples env pm- MacroDescriptor- { _md_source = "[0-9]{4}/[0-9]{2}/[0-9]{2}"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseSlashesDate"- , _md_description = "a YYYY/MM/DD format date"- }- where- samples :: [(String,Day)]- samples =- [ f "2016/12/31"- , f "0001/01/01"- , f "1000/01/01"- ]- where- f s = (s,read $ map tr s)- where- tr '/' = '-'- tr c = c-- counter_samples =- [ ""- , "2016-01-31"- , "2016/1/31"- , "2016/01/1"- , "2016/001/01"- ]--time_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor-time_macro rty env pm =- Just $ run_tests rty parseTimeOfDay samples env pm- MacroDescriptor- { _md_source = "[0-9]{2}:[0-9]{2}:[0-9]{2}(?:[.][0-9]+)?"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseTimeOfDay"- , _md_description = "a HH:MM:SS[.Q+]"- }- where- samples :: [(String,TimeOfDay)]- samples =- [ f "00:00:00" 00 00 0- , f "23:59:59" 23 59 59- , f "00:00:00.1234567890" 00 00 $ 123456789 / 1000000000- ]- where- f s h m ps = (s,TimeOfDay h m ps)-- counter_samples =- [ ""- , "235959"- , "10:20"- , "A00:00:00"- , "00:00:00A"- , "23:59:59."- ]--timezone_macro :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-timezone_macro rty env pm =- Just $ run_tests rty parseTimeZone samples env pm- MacroDescriptor- { _md_source = "(?:Z|[+-][0-9]{2}:?[0-9]{2})"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseTimeZone"- , _md_description = "an IOS-8601 TZ specification"- }- where- samples :: [(String,TimeZone)]- samples =- [ f "Z" $ minutesToTimeZone 0- , f "+00:00" $ minutesToTimeZone 0- , f "+0000" $ minutesToTimeZone 0- , f "+0200" $ minutesToTimeZone 120- , f "-0100" $ minutesToTimeZone $ -60- ]- where- f = (,)-- counter_samples =- [ ""- , "00"- , "A00:00"- , "UTC"- , "EST"- , " EST"- ]--datetime_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor-datetime_macro rty env pm = Just $ run_tests rty parseDateTime samples env pm- MacroDescriptor- { _md_source = "@{%date}[ T]@{%time}(?:@{%timezone}| UTC)?"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseDateTime"- , _md_description = "ISO-8601 format date and time + simple variants"- }- where- samples :: [(String,UTCTime)]- samples =- [ f "2016-12-31 23:37:22.525343 UTC" "2016-12-31 23:37:22.525343Z"- , f "2016-12-31 23:37:22.525343" "2016-12-31 23:37:22.525343Z"- , f "2016-12-31 23:37:22" "2016-12-31 23:37:22Z"- , f "2016-12-31T23:37:22+0100" "2016-12-31 23:37:22+0100"- , f "2016-12-31T23:37:22-01:00" "2016-12-31 23:37:22-0100"- , f "2016-12-31T23:37:22-23:59" "2016-12-31 23:37:22-2359"- , f "2016-12-31T23:37:22Z" "2016-12-31 23:37:22Z"- ]- where- f :: String -> String -> (String,UTCTime)- f s r_s = (s,read r_s)-- counter_samples =- [ ""- , "2016-12-31 23:37:22.525343 EST"- ]--datetime_8601_macro :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-datetime_8601_macro rty env pm =- Just $ run_tests rty parseDateTime samples env pm- MacroDescriptor- { _md_source = "@{%date}T@{%time}@{%timezone}"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseDateTime8601"- , _md_description = "YYYY-MM-DDTHH:MM:SS[.Q*](Z|[+-]HHMM) format date and time"- }- where- samples :: [(String,UTCTime)]- samples =- [ f "2016-12-31T23:37:22.343Z" "2016-12-31 23:37:22.343Z"- , f "2016-12-31T23:37:22-0100" "2016-12-31 23:37:22-0100"- , f "2016-12-31T23:37:22+23:59" "2016-12-31 23:37:22+2359"- ]- where- f :: String -> String -> (String,UTCTime)- f s r_s = (s,read r_s)-- counter_samples =- [ ""- , "2016-12-31 23:37:22.525343 EST"- ]--datetime_clf_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor-datetime_clf_macro rty env pm =- Just $ run_tests rty parseDateTimeCLF samples env pm- MacroDescriptor- { _md_source = re- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseDateTimeCLF"- , _md_description = "Common Log Format date+time: %d/%b/%Y:%H:%M:%S %z"- }- where- samples :: [(String,UTCTime)]- samples =- [ f "10/Oct/2000:13:55:36 -0700" "2000-10-10 13:55:36-0700"- , f "10/Oct/2000:13:55:36 +07:00" "2000-10-10 13:55:36+0700"- ]- where- f :: String -> String -> (String,UTCTime)- f s r_s = (s,read r_s)-- counter_samples =- [ ""- , "2016-12-31T23:37+0100"- , "10/Oct/2000:13:55:36-0700"- , "10/OCT/2000:13:55:36 -0700"- , "10/Oct/2000:13:55 -0700"- , "10/Oct/2000:13:55Z"- ]-- re = RegexSource $ unwords- [ "[0-9]{2}/@{%shortmonth}/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2}"- , "[+-][0-9]{2}:?[0-9]{2}"- ]--shortmonth_macro :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-shortmonth_macro rty env pm =- Just $ run_tests rty parseShortMonth samples env pm- MacroDescriptor- { _md_source = bracketedRegexSource $- intercalate "|" $ map T.unpack $ elems shortMonthArray- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseShortMonth"- , _md_description = "three letter month name: Jan-Dec"- }- where- samples :: [(String,Int)]- samples =- [ f "Jan" 1- , f "Feb" 2- , f "Dec" 12- ]- where- f = (,)-- counter_samples =- [ ""- , "jan"- , "DEC"- , "January"- , "01"- , "1"- ]--address_ipv4_macros :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-address_ipv4_macros rty env pm =- Just $ run_tests rty parseIPv4Address samples env pm- MacroDescriptor- { _md_source = "[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseSeverity"- , _md_description = "an a.b.c.d IPv4 address"- }- where- samples :: [(String,IPV4Address)]- samples =- [ f "0.0.0.0" ( 0, 0, 0, 0)- , f "123.45.6.78" (123, 45, 6, 78)- , f "9.9.9.9" ( 9, 9, 9, 9)- , f "255.255.255.255" (255,255,255,255)- ]- where- f = (,)-- counter_samples =- [ ""- , "foo"- , "1234.0.0.0"- , "1.2.3"- , "1.2.3."- , "1.2..4"- , "www.example.com"- , "2001:0db8:85a3:0000:0000:8a2e:0370:7334"- ]--syslog_severity_macro :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-syslog_severity_macro rty env pm =- Just $ run_tests rty parseSeverity samples env pm- MacroDescriptor- { _md_source = re- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Just "parseSeverity"- , _md_description = "syslog severity keyword (debug-emerg)"- }- where- samples :: [(String,Severity)]- samples =- [ f "emerg" Emerg- , f "panic" Emerg- , f "alert" Alert- , f "crit" Crit- , f "err" Err- , f "error" Err- , f "warn" Warning- , f "warning" Warning- , f "notice" Notice- , f "info" Info- , f "debug" Debug- ]- where- f = (,)-- counter_samples =- [ ""- , "Emergency"- , "ALERT"- ]-- re = if isPCRE rty- then re_pcre- else re_tdfa-- re_tdfa = bracketedRegexSource $- intercalate "|" $- [ T.unpack kw- | (kw0,kws) <- map severityKeywords [minBound..maxBound]- , kw <- kw0:kws- ]-- re_pcre = bracketedRegexSource $- intercalate "|" $- [ T.unpack kw- | (kw0,kws) <- map severityKeywords $- filter (/=Err) [minBound..maxBound]- , kw <- kw0:kws- ] ++ ["err(?:or)?"]--email_simple_macro :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-email_simple_macro rty env pm =- Just $ run_tests rty Just samples env pm- MacroDescriptor- { _md_source = "[a-zA-Z0-9%_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9.-]+"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Nothing- , _md_description = "an email address"- }- where- samples :: [(String,String)]- samples =- [ f "user-name%foo.bar.com@an-example.com"- ]- where- f s = (s,s)-- counter_samples =- [ ""- , "not-an-email-address"- , "@not-an-email-address"- ]--- | see https://mathiasbynens.be/demo/url-regex--- (based on @stephenhay URL)-url_macro :: RegexType- -> MacroEnv- -> PreludeMacro- -> Maybe MacroDescriptor-url_macro rty env pm =- Just $ run_tests rty Just samples env pm- MacroDescriptor- { _md_source = "([hH][tT][tT][pP][sS]?|[fF][tT][pP])://[^[:space:]/$.?#].[^[:space:]]*"- , _md_samples = map fst samples- , _md_counter_samples = counter_samples- , _md_test_results = []- , _md_parser = Nothing- , _md_description = "a URL"- }- where- samples :: [(String,String)]- samples =- [ f "https://mathiasbynens.be/demo/url-regex"- , f "http://foo.com/blah_blah"- , f "http://foo.com/blah_blah/"- , f "http://foo.com/blah_blah_(wikipedia)"- , f "http://foo.com/blah_blah_(wikipedia)_(again)"- , f "http://www.example.com/wpstyle/?p=364"- , f "HTTPS://foo.bar/?q=Test%20URL-encoded%20stuff"- , f "HTTP://223.255.255.254"- , f "ftp://223.255.255.254"- , f "FTP://223.255.255.254"- ]- where- f s = (s,s)-- counter_samples =- [ ""- , "http://"- , "http://."- , "http://.."- , "http://../"- , "http://?"- , "http://??"- , "http://foo.bar?q=Spaces should be encoded"- , "//"- , "http://##/"- , "http://##"- , "http://##/"- ]--run_tests :: (Eq a,Show a)- => RegexType- -> (String->Maybe a)- -> [(String,a)]- -> MacroEnv- -> PreludeMacro- -> MacroDescriptor- -> MacroDescriptor-run_tests rty parser vector env =- runTests rty parser vector env . prelude_macro_id--bracketedRegexSource :: String -> RegexSource-bracketedRegexSource re_s = RegexSource $ "(?:" ++ re_s ++ ")"--fix :: (a->a) -> a-fix f = f (fix f)
− Text/RE/Internal/QQ.hs
@@ -1,29 +0,0 @@-{-# LANGUAGE DeriveDataTypeable #-}--module Text.RE.Internal.QQ where--import Control.Exception-import Data.Typeable-import Language.Haskell.TH.Quote----- | used to throw an exception reporting an abuse of a quasi quoter-data QQFailure =- QQFailure- { _qqf_context :: String -- ^ in what context was the quasi quoter used- , _qqf_component :: String -- ^ how was the quasi quoter being abused- }- deriving (Show,Typeable)--instance Exception QQFailure where---- | a quasi quoter that can be used in no context (to be extended with--- the appropriate quasi quoter parser)-qq0 :: String -> QuasiQuoter-qq0 ctx =- QuasiQuoter- { quoteExp = const $ throw $ QQFailure ctx "expression"- , quotePat = const $ throw $ QQFailure ctx "pattern"- , quoteType = const $ throw $ QQFailure ctx "type"- , quoteDec = const $ throw $ QQFailure ctx "declaration"- }
− Text/RE/Internal/SearchReplace.hs
@@ -1,84 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE RecordWildCards #-}-{-# 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 #-}--module Text.RE.Internal.SearchReplace- ( unsafeCompileSearchReplace_- , compileSearchReplace_- , compileSearchAndReplace_- ) where--import qualified Data.HashMap.Strict as HMS-import Prelude.Compat-import Text.RE.Internal.NamedCaptures-import Text.RE.Types.Capture-import Text.RE.Types.CaptureID-import Text.RE.Types.Matches-import Text.RE.Types.Replace-import Text.RE.Types.SearchReplace-import qualified Text.Regex.TDFA as TDFA----- | warapper on 'compileSearchReplace_' that will generate an error--- if any compilation errors are found-unsafeCompileSearchReplace_ :: (String->s)- -> (String->Either String re)- -> String- -> SearchReplace re s-unsafeCompileSearchReplace_ pk cf = either err id . compileSearchReplace_ pk cf- where- err msg = error $ "unsafeCompileSearchReplace_: " ++ msg---- | compile a SearchReplace template generating errors if the RE or--- the template are not well formed -- all capture references being checked-compileSearchReplace_ :: (Monad m,Functor m)- => (String->s)- -> (String->Either String re)- -> String- -> m (SearchReplace re s)-compileSearchReplace_ pack compile_re sr_tpl = either fail return $ do- case mainCaptures $ sr_tpl $=~ "///" of- [cap] ->- compileSearchAndReplace_ pack compile_re- (capturePrefix cap) (captureSuffix cap)- _ -> Left $ "bad search-replace template syntax: " ++ sr_tpl---- | compile 'SearcgReplace' from two strings containing the RE--- and the replacement template-compileSearchAndReplace_ :: (Monad m,Functor m)- => (String->s)- -> (String->Either String re)- -> String- -> String- -> m (SearchReplace re s)-compileSearchAndReplace_ pack compile_re re_s tpl = either fail return $ do- re <- compile_re re_s- ((n,cnms),_) <- extractNamedCaptures re_s- mapM_ (check n cnms) $ templateCaptures id tpl- return $ SearchReplace re $ pack tpl- where- check :: Int -> CaptureNames -> CaptureID -> Either String ()- check n cnms cid = case cid of- IsCaptureOrdinal co -> check_co n co- IsCaptureName cn -> check_cn cnms cn-- check_co n (CaptureOrdinal i) = case i <= n of- True -> return ()- False -> Left $ "capture ordinal out of range: " ++- show i ++ " >= " ++ show n-- check_cn cnms cnm = case cnm `HMS.member` cnms of- True -> return ()- False -> Left $ "capture name not defined: " ++- show (getCaptureName cnm)--($=~) :: String -> String -> Matches String-($=~) = (TDFA.=~)
− Text/RE/Internal/SearchReplace/TDFA.hs
@@ -1,54 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 800-{-# LANGUAGE TemplateHaskellQuotes #-}-#else-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}-#endif--module Text.RE.Internal.SearchReplace.TDFA- ( ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_- ) where--import Language.Haskell.TH-import Language.Haskell.TH.Quote-import Prelude.Compat-import Text.RE.Internal.SearchReplace.TDFAEdPrime-import Text.RE.Types.REOptions----- | the @[ed| ... /// ... |]@ quasi quoters-ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_ :: QuasiQuoter--ed = ed' cast $ Just minBound-edMS = edMultilineSensitive-edMI = edMultilineInsensitive-edBS = edBlockSensitive-edBI = edBlockInsensitive-edMultilineSensitive = ed' cast $ Just MultilineSensitive-edMultilineInsensitive = ed' cast $ Just MultilineInsensitive-edBlockSensitive = ed' cast $ Just BlockSensitive-edBlockInsensitive = ed' cast $ Just BlockInsensitive-ed_ = ed' cast Nothing--cast :: Q Exp-cast = [|id|]
− Text/RE/Internal/SearchReplace/TDFA/ByteString.hs
@@ -1,58 +0,0 @@-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 800-{-# LANGUAGE TemplateHaskellQuotes #-}-#else-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}-#endif--module Text.RE.Internal.SearchReplace.TDFA.ByteString- ( ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_- ) where--import qualified Data.ByteString.Char8 as B-import Language.Haskell.TH-import Language.Haskell.TH.Quote-import Text.RE.TDFA.RE-import Text.RE.Internal.SearchReplace.TDFAEdPrime-import Text.RE.SearchReplace-import Text.RE.Types.REOptions----- | the @[ed| ... /// ... |]@ quasi quoters-ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_ :: QuasiQuoter--ed = ed' sr_cast $ Just minBound-edMS = edMultilineSensitive-edMI = edMultilineInsensitive-edBS = edBlockSensitive-edBI = edBlockInsensitive-edMultilineSensitive = ed' sr_cast $ Just MultilineSensitive-edMultilineInsensitive = ed' sr_cast $ Just MultilineInsensitive-edBlockSensitive = ed' sr_cast $ Just BlockSensitive-edBlockInsensitive = ed' sr_cast $ Just BlockInsensitive-ed_ = ed' fn_cast Nothing--sr_cast :: Q Exp-sr_cast = [|\x -> x :: SearchReplace RE B.ByteString|]--fn_cast :: Q Exp-fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE B.ByteString|]
− Text/RE/Internal/SearchReplace/TDFA/ByteString/Lazy.hs
@@ -1,58 +0,0 @@-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 800-{-# LANGUAGE TemplateHaskellQuotes #-}-#else-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}-#endif--module Text.RE.Internal.SearchReplace.TDFA.ByteString.Lazy- ( ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_- ) where--import qualified Data.ByteString.Lazy.Char8 as LBS-import Language.Haskell.TH-import Language.Haskell.TH.Quote-import Text.RE.TDFA.RE-import Text.RE.Internal.SearchReplace.TDFAEdPrime-import Text.RE.SearchReplace-import Text.RE.Types.REOptions----- | the @[ed| ... /// ... |]@ quasi quoters-ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_ :: QuasiQuoter--ed = ed' sr_cast $ Just minBound-edMS = edMultilineSensitive-edMI = edMultilineInsensitive-edBS = edBlockSensitive-edBI = edBlockInsensitive-edMultilineSensitive = ed' sr_cast $ Just MultilineSensitive-edMultilineInsensitive = ed' sr_cast $ Just MultilineInsensitive-edBlockSensitive = ed' sr_cast $ Just BlockSensitive-edBlockInsensitive = ed' sr_cast $ Just BlockInsensitive-ed_ = ed' fn_cast Nothing--sr_cast :: Q Exp-sr_cast = [|\x -> x :: SearchReplace RE LBS.ByteString|]--fn_cast :: Q Exp-fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE LBS.ByteString|]
− Text/RE/Internal/SearchReplace/TDFA/Sequence.hs
@@ -1,58 +0,0 @@-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 800-{-# LANGUAGE TemplateHaskellQuotes #-}-#else-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}-#endif--module Text.RE.Internal.SearchReplace.TDFA.Sequence- ( ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_- ) where--import qualified Data.Sequence as S-import Language.Haskell.TH-import Language.Haskell.TH.Quote-import Text.RE.TDFA.RE-import Text.RE.Internal.SearchReplace.TDFAEdPrime-import Text.RE.SearchReplace-import Text.RE.Types.REOptions----- | the @[ed| ... /// ... |]@ quasi quoters-ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_ :: QuasiQuoter--ed = ed' sr_cast $ Just minBound-edMS = edMultilineSensitive-edMI = edMultilineInsensitive-edBS = edBlockSensitive-edBI = edBlockInsensitive-edMultilineSensitive = ed' sr_cast $ Just MultilineSensitive-edMultilineInsensitive = ed' sr_cast $ Just MultilineInsensitive-edBlockSensitive = ed' sr_cast $ Just BlockSensitive-edBlockInsensitive = ed' sr_cast $ Just BlockInsensitive-ed_ = ed' fn_cast Nothing--sr_cast :: Q Exp-sr_cast = [|\x -> x :: SearchReplace RE (S.Seq Char)|]--fn_cast :: Q Exp-fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE (S.Seq Char)|]
− Text/RE/Internal/SearchReplace/TDFA/String.hs
@@ -1,58 +0,0 @@-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 800-{-# LANGUAGE TemplateHaskellQuotes #-}-#else-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}-#endif--module Text.RE.Internal.SearchReplace.TDFA.String- ( ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_- ) where---import Language.Haskell.TH-import Language.Haskell.TH.Quote-import Text.RE.TDFA.RE-import Text.RE.Internal.SearchReplace.TDFAEdPrime-import Text.RE.SearchReplace-import Text.RE.Types.REOptions----- | the @[ed| ... /// ... |]@ quasi quoters-ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_ :: QuasiQuoter--ed = ed' sr_cast $ Just minBound-edMS = edMultilineSensitive-edMI = edMultilineInsensitive-edBS = edBlockSensitive-edBI = edBlockInsensitive-edMultilineSensitive = ed' sr_cast $ Just MultilineSensitive-edMultilineInsensitive = ed' sr_cast $ Just MultilineInsensitive-edBlockSensitive = ed' sr_cast $ Just BlockSensitive-edBlockInsensitive = ed' sr_cast $ Just BlockInsensitive-ed_ = ed' fn_cast Nothing--sr_cast :: Q Exp-sr_cast = [|\x -> x :: SearchReplace RE String|]--fn_cast :: Q Exp-fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE String|]
− Text/RE/Internal/SearchReplace/TDFA/Text.hs
@@ -1,58 +0,0 @@-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 800-{-# LANGUAGE TemplateHaskellQuotes #-}-#else-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}-#endif--module Text.RE.Internal.SearchReplace.TDFA.Text- ( ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_- ) where--import qualified Data.Text as T-import Language.Haskell.TH-import Language.Haskell.TH.Quote-import Text.RE.TDFA.RE-import Text.RE.Internal.SearchReplace.TDFAEdPrime-import Text.RE.SearchReplace-import Text.RE.Types.REOptions----- | the @[ed| ... /// ... |]@ quasi quoters-ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_ :: QuasiQuoter--ed = ed' sr_cast $ Just minBound-edMS = edMultilineSensitive-edMI = edMultilineInsensitive-edBS = edBlockSensitive-edBI = edBlockInsensitive-edMultilineSensitive = ed' sr_cast $ Just MultilineSensitive-edMultilineInsensitive = ed' sr_cast $ Just MultilineInsensitive-edBlockSensitive = ed' sr_cast $ Just BlockSensitive-edBlockInsensitive = ed' sr_cast $ Just BlockInsensitive-ed_ = ed' fn_cast Nothing--sr_cast :: Q Exp-sr_cast = [|\x -> x :: SearchReplace RE T.Text|]--fn_cast :: Q Exp-fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE T.Text|]
− Text/RE/Internal/SearchReplace/TDFA/Text/Lazy.hs
@@ -1,58 +0,0 @@-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 800-{-# LANGUAGE TemplateHaskellQuotes #-}-#else-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}-#endif--module Text.RE.Internal.SearchReplace.TDFA.Text.Lazy- ( ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_- ) where--import qualified Data.Text.Lazy as TL-import Language.Haskell.TH-import Language.Haskell.TH.Quote-import Text.RE.TDFA.RE-import Text.RE.Internal.SearchReplace.TDFAEdPrime-import Text.RE.SearchReplace-import Text.RE.Types.REOptions----- | the @[ed| ... /// ... |]@ quasi quoters-ed- , edMS- , edMI- , edBS- , edBI- , edMultilineSensitive- , edMultilineInsensitive- , edBlockSensitive- , edBlockInsensitive- , ed_ :: QuasiQuoter--ed = ed' sr_cast $ Just minBound-edMS = edMultilineSensitive-edMI = edMultilineInsensitive-edBS = edBlockSensitive-edBI = edBlockInsensitive-edMultilineSensitive = ed' sr_cast $ Just MultilineSensitive-edMultilineInsensitive = ed' sr_cast $ Just MultilineInsensitive-edBlockSensitive = ed' sr_cast $ Just BlockSensitive-edBlockInsensitive = ed' sr_cast $ Just BlockInsensitive-ed_ = ed' fn_cast Nothing--sr_cast :: Q Exp-sr_cast = [|\x -> x :: SearchReplace RE TL.Text|]--fn_cast :: Q Exp-fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE TL.Text|]
− Text/RE/Internal/SearchReplace/TDFAEdPrime.hs
@@ -1,63 +0,0 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 800-{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}-{-# LANGUAGE TemplateHaskellQuotes #-}-#else-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}-#endif--module Text.RE.Internal.SearchReplace.TDFAEdPrime- ( ed'- ) where--import Language.Haskell.TH-import Language.Haskell.TH.Quote-import Prelude.Compat-import Text.RE.Internal.SearchReplace-import Text.RE.Internal.QQ-import Text.RE.TDFA.RE-import Text.RE.SearchReplace-import Text.RE.Types.IsRegex-import Text.RE.Types.REOptions-import Text.RE.Types.Replace-import Text.Regex.TDFA----- | construct a quasi quoter from a casting function and @Just sro@--- if the options are known, otherwise a function take takes the--- 'SimpleREOptions' and constructs the 'SearchReplace' template-ed' :: Q Exp -> Maybe SimpleREOptions -> QuasiQuoter-ed' qe mb = case mb of- Nothing ->- (qq0 "ed'")- { quoteExp = parse minBound $ \rs -> AppE <$> qe <*> [|flip unsafe_compile_sr rs|]- }- Just sro ->- (qq0 "ed'")- { quoteExp = parse sro $ \rs -> AppE <$> qe <*> [|unsafe_compile_sr_simple sro rs|]- }- where- parse :: SimpleREOptions -> (String->Q Exp) -> String -> Q Exp- parse sro mk ts = either error (\_->mk ts) ei- where- ei :: Either String (SearchReplace RE String)- ei = compileSearchReplace_ id (compileRegexWith sro) ts--unsafe_compile_sr_simple :: IsRegex RE s- => SimpleREOptions- -> String- -> SearchReplace RE s-unsafe_compile_sr_simple sro =- unsafe_compile_sr $ unpackSimpleREOptions sro--unsafe_compile_sr :: ( IsOption o RE CompOption ExecOption- , IsRegex RE s- )- => o- -> String- -> SearchReplace RE s-unsafe_compile_sr os =- unsafeCompileSearchReplace_ packR $ compileRegexWithOptions os
+ Text/RE/IsRegex.lhs view
@@ -0,0 +1,60 @@+\begin{code}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 800+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}+#endif++module Text.RE.IsRegex+ ( IsRegex(..)+ , SearchReplace(..)+ , searchReplaceAll+ , searchReplaceFirst+ ) where++import Text.RE.ZeInternals.EscapeREString+import Text.RE.ZeInternals.Types.Match+import Text.RE.ZeInternals.Types.Matches+import Text.RE.REOptions+import Text.RE.Replace+import Text.RE.ZeInternals.Types.SearchReplace+\end{code}++\begin{code}+-- | the 'IsRegex' class allows polymorhic tools to be written that+-- will work with a variety of regex back ends and text types+class Replace s => IsRegex re s where+ -- | finding the first match+ matchOnce :: re -> s -> Match s+ -- | finding all matches+ matchMany :: re -> s -> Matches s+ -- | compiling an RE, failing if the RE is not well formed+ makeRegex :: (Functor m,Monad m) => s -> m re+ -- | comiling an RE, specifying the 'SimpleREOptions'+ makeRegexWith :: (Functor m,Monad m) => SimpleREOptions -> s -> m re+ -- | compiling a 'SearchReplace' template from the RE text and the template Text, failing if they are not well formed+ makeSearchReplace :: (Functor m,Monad m,IsRegex re s) => s -> s -> m (SearchReplace re s)+ -- | compiling a 'SearchReplace' template specifing the 'SimpleREOptions' for the RE+ makeSearchReplaceWith :: (Functor m,Monad m,IsRegex re s) => SimpleREOptions -> s -> s -> m (SearchReplace re s)+ -- | incorporate an escaped string into a compiled RE with the default options+ makeEscaped :: (Functor m,Monad m) => (s->s) -> s -> m re+ -- | incorporate an escaped string into a compiled RE with the specified 'SimpleREOptions'+ makeEscapedWith :: (Functor m,Monad m) => SimpleREOptions -> (s->s) -> s -> m re+ -- | extract the text of the RE from the RE+ regexSource :: re -> s++ makeRegex = makeRegexWith minBound+ makeSearchReplace = makeSearchReplaceWith minBound+ makeEscaped = makeEscapedWith minBound+ makeEscapedWith o f = makeRegexWith o . f . packR . escapeREString . unpackR++-- | searching and replacing the first occurrence+searchReplaceAll :: IsRegex re s => SearchReplace re s -> s -> s+searchReplaceAll SearchReplace{..} = replaceAll getTemplate . matchMany getSearch++-- | searching and replaceing all occurrences+searchReplaceFirst :: IsRegex re s => SearchReplace re s -> s -> s+searchReplaceFirst SearchReplace{..} = replace getTemplate . matchOnce getSearch+\end{code}
+ Text/RE/REOptions.lhs view
@@ -0,0 +1,105 @@+\begin{code}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 800+{-# LANGUAGE TemplateHaskellQuotes #-}+#else+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+#endif++module Text.RE.REOptions+ (+ -- * SimpleREOptions+ SimpleREOptions(..)+ -- * REOptions_+ , REOptions_(..)+ -- * IsOption+ , IsOption(..)+ -- * Macros+ , Macros+ , MacroID(..)+ , emptyMacros+ ) where++import Data.Hashable+import qualified Data.HashMap.Strict as HM+import Data.String+import Language.Haskell.TH+import Language.Haskell.TH.Syntax+\end{code}++\begin{code}+-- | the default API uses these simple, universal RE options,+-- which get auto-converted into the apropriate back-end 'REOptions_'+data SimpleREOptions+ = MultilineSensitive -- ^ case-sensitive with ^ and $ matching the start and end of a line+ | MultilineInsensitive -- ^ case-insensitive with ^ and $ matsh the start and end of a line+ | BlockSensitive -- ^ case-sensitive with ^ and $ matching the start and end of the input text+ | BlockInsensitive -- ^ case-insensitive with ^ and $ matching the start and end of the input text+ deriving (Bounded,Enum,Eq,Ord,Show)+\end{code}++\begin{code}+-- | we need to use this in the quasi quoters to specify @SimpleREOptions@+-- selected by the quasi quoter+instance Lift SimpleREOptions where+ lift sro = case sro of+ MultilineSensitive -> conE 'MultilineSensitive+ MultilineInsensitive -> conE 'MultilineInsensitive+ BlockSensitive -> conE 'BlockSensitive+ BlockInsensitive -> conE 'BlockInsensitive+\end{code}++\begin{code}+-- | the general options for an RE are dependent on which back end is+-- being used and are parameterised over the @RE@ type for the back end,+-- and its @CompOption@ and @ExecOption@ types (the compile-time and+-- execution time options, respectively); each back end will define an+-- @REOptions@ type that fills out these three type parameters with the+-- apropriate types+data REOptions_ r c e =+ REOptions+ { optionsMacs :: !(Macros r) -- ^ the available TestBench RE macros+ , optionsComp :: !c -- ^ the back end compile-time options+ , optionsExec :: !e -- ^ the back end execution-time options+ }+ deriving (Show)+\end{code}++\begin{code}+-- | a number of types can be used to encode @REOptions@, each of which+-- can be made a member of this class.+class IsOption o r c e |+ e -> r, c -> e , e -> c, r -> c, c -> r, r -> e where+ -- | convert the @o@ type into an @REOptions r c e@+ makeREOptions :: o -> REOptions_ r c e+\end{code}++\begin{code}+-- | our macro tables are parameterised over the backend @RE@ type and+-- and just associate each @MacroID@ with an @RE@+type Macros r = HM.HashMap MacroID r+\end{code}++\begin{code}+-- | @MacroID@ is just a wrapped @String@ type with an @IsString@+-- instance+newtype MacroID =+ MacroID { getMacroID :: String }+ deriving (IsString,Ord,Eq,Show)+\end{code}++\begin{code}+-- | @MacroID@ is used with @HM.HashMap@ to build macro lookup tables+instance Hashable MacroID where+ hashWithSalt i = hashWithSalt i . getMacroID+\end{code}++\begin{code}+-- | a macro table containing no entries+emptyMacros :: Macros r+emptyMacros = HM.empty+\end{code}
+ Text/RE/Replace.hs view
@@ -0,0 +1,23 @@+module Text.RE.Replace+ (+ -- * REContext and RELocation+ REContext(..)+ , RELocation(..)+ , isTopLocation+ -- * replaceAll+ , replaceAll+ , replaceAllCaptures+ , replaceAllCaptures_+ , replaceAllCapturesM+ -- * replace+ , replace+ , replaceCaptures+ , replaceCaptures_+ , replaceCapturesM+ -- * Replace and ReplaceMethods+ , Replace(..)+ , ReplaceMethods(..)+ , replaceMethods+ ) where++import Text.RE.ZeInternals.Replace
− Text/RE/SearchReplace.hs
@@ -1,22 +0,0 @@-{-# LANGUAGE RecordWildCards #-}--module Text.RE.SearchReplace- (- -- * Serach and Replace- SearchReplace(..)- , searchReplaceFirst- , searchReplaceAll- ) where--import Text.RE.Types.IsRegex-import Text.RE.Types.Replace-import Text.RE.Types.SearchReplace----- | searching and replacing the first occurrence-searchReplaceAll :: IsRegex re s => SearchReplace re s -> s -> s-searchReplaceAll SearchReplace{..} = replaceAll getTemplate . matchMany getSearch---- | searching and replaceing all occurrences-searchReplaceFirst :: IsRegex re s => SearchReplace re s -> s -> s-searchReplaceFirst SearchReplace{..} = replace getTemplate . matchOnce getSearch
Text/RE/Summa.hs view
@@ -1,20 +1,20 @@ module Text.RE.Summa ( -- $collection- module Text.RE.SearchReplace+ module Text.RE.IsRegex+ , module Text.RE.Replace , module Text.RE.TestBench , module Text.RE.Tools- , module Text.RE.Types ) where -import Text.RE.SearchReplace+import Text.RE.IsRegex+import Text.RE.Replace import Text.RE.TestBench import Text.RE.Tools-import Text.RE.Types -- $collection -- -- This module collects together all of the generic regex APIs not--- exported by the API modules specific to each back end. The regex+-- exported by the back-end-specific API modules. The regex -- API is modular with only the most common types and functions being--- exported by these modules. The remining modules may be imported--- individually or en masse by importing this module.+-- exported by these modules but the remining modules may be imported+-- en masse by importing this module.
Text/RE/TDFA.hs view
@@ -44,9 +44,9 @@ , escape , escapeWith , escapeREString- , module Text.RE.TDFA.RE+ , module Text.RE.ZeInternals.TDFA -- * The [ed| ... |] quasi quoters- , module Text.RE.Internal.SearchReplace.TDFA+ , module Text.RE.ZeInternals.SearchReplace.TDFA -- * The Operator Instances -- $instances , module Text.RE.TDFA.ByteString@@ -59,19 +59,18 @@ import qualified Text.Regex.Base as B import Text.RE-import Text.RE.Internal.AddCaptureNames-import Text.RE.Internal.SearchReplace.TDFA-import Text.RE.TDFA.RE+import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.ZeInternals.SearchReplace.TDFA+import Text.RE.ZeInternals.TDFA import qualified Text.Regex.TDFA as TDFA-import Text.RE.SearchReplace import Text.RE.TDFA.ByteString() import Text.RE.TDFA.ByteString.Lazy() import Text.RE.TDFA.Sequence() import Text.RE.TDFA.String() import Text.RE.TDFA.Text() import Text.RE.TDFA.Text.Lazy()-import Text.RE.Types.IsRegex-import Text.RE.Types.REOptions+import Text.RE.IsRegex+import Text.RE.REOptions -- | find all matches in text; e.g., to count the number of naturals in s:@@ -133,7 +132,7 @@ -- -- * "Text.RE.TDFA.ByteString" -- * "Text.RE.TDFA.ByteString.Lazy"--- * "Text.RE.TDFA.RE"+-- * "Text.RE.ZeInternals.TDFA" -- * "Text.RE.TDFA.Sequence" -- * "Text.RE.TDFA.String" -- * "Text.RE.TDFA.Text"
Text/RE/TDFA/ByteString.hs view
@@ -44,8 +44,8 @@ , escape , escapeWith , escapeREString- , module Text.RE.TDFA.RE- , module Text.RE.Internal.SearchReplace.TDFA.ByteString+ , module Text.RE.ZeInternals.TDFA+ , module Text.RE.ZeInternals.SearchReplace.TDFA.ByteString ) where import Prelude.Compat@@ -53,13 +53,12 @@ import Data.Typeable import Text.Regex.Base import Text.RE-import Text.RE.Internal.AddCaptureNames-import Text.RE.Internal.SearchReplace.TDFA.ByteString-import Text.RE.SearchReplace-import Text.RE.Types.IsRegex-import Text.RE.Types.REOptions-import Text.RE.Types.Replace-import Text.RE.TDFA.RE+import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.ZeInternals.SearchReplace.TDFA.ByteString+import Text.RE.IsRegex+import Text.RE.REOptions+import Text.RE.Replace+import Text.RE.ZeInternals.TDFA import qualified Text.Regex.TDFA as TDFA
Text/RE/TDFA/ByteString/Lazy.hs view
@@ -44,8 +44,8 @@ , escape , escapeWith , escapeREString- , module Text.RE.TDFA.RE- , module Text.RE.Internal.SearchReplace.TDFA.ByteString.Lazy+ , module Text.RE.ZeInternals.TDFA+ , module Text.RE.ZeInternals.SearchReplace.TDFA.ByteString.Lazy ) where import Prelude.Compat@@ -53,13 +53,12 @@ import Data.Typeable import Text.Regex.Base import Text.RE-import Text.RE.Internal.AddCaptureNames-import Text.RE.Internal.SearchReplace.TDFA.ByteString.Lazy-import Text.RE.SearchReplace-import Text.RE.Types.IsRegex-import Text.RE.Types.REOptions-import Text.RE.Types.Replace-import Text.RE.TDFA.RE+import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.ZeInternals.SearchReplace.TDFA.ByteString.Lazy+import Text.RE.IsRegex+import Text.RE.REOptions+import Text.RE.Replace+import Text.RE.ZeInternals.TDFA import qualified Text.Regex.TDFA as TDFA
− Text/RE/TDFA/RE.hs
@@ -1,429 +0,0 @@-{-# 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 #-}--module Text.RE.TDFA.RE- ( -- * About- -- $about-- -- * RE Type- RE- , regexType- , reOptions- , reSource- , reCaptureNames- , reRegex- -- * REOptions Type- , REOptions- , defaultREOptions- , noPreludeREOptions- -- * Compiling Regular Expressions- , compileRegex- , compileRegexWith- , compileRegexWithOptions- -- * Compiling Search-Replace Templates- , compileSearchReplace- , compileSearchReplaceWith- , compileSearchReplaceWithREOptions- -- * Escaping String- , escape- , escapeWith- , escapeWithOptions- , escapeREString- -- * Macros Standard Environment- , prelude- , preludeEnv- , preludeTestsFailing- , preludeTable- , preludeSummary- , preludeSources- , preludeSource- , unpackSimpleREOptions- -- * The Quasi Quoters- , re- , reMS- , reMI- , reBS- , reBI- , reMultilineSensitive- , reMultilineInsensitive- , reBlockSensitive- , reBlockInsensitive- , re_- , cp- ) where--import Data.Functor.Identity-import Language.Haskell.TH-import Language.Haskell.TH.Quote-import Prelude.Compat-import Text.RE.Internal.EscapeREString-import Text.RE.Internal.NamedCaptures-import Text.RE.Internal.PreludeMacros-import Text.RE.Internal.QQ-import Text.RE.Internal.SearchReplace-import Text.RE.SearchReplace-import Text.RE.TestBench-import Text.RE.Types.CaptureID-import Text.RE.Types.IsRegex-import Text.RE.Types.REOptions-import Text.RE.Types.Replace-import Text.Regex.TDFA----- | the RE type for this back end representing a well-formed, compiled--- RE-data RE =- RE- { _re_options :: !REOptions- , _re_source :: !String- , _re_cnames :: !CaptureNames- , _re_regex :: !Regex- }---- | some functions in the "Text.RE.TestBench" need the back end to--- be passed dynamically as a 'RegexType' parameters: use 'regexType'--- fpr this backend-regexType :: RegexType-regexType =- mkTDFA $ \txt env md -> txt =~ mdRegexSource regexType ExclCaptures env md---- | extract the 'REOptions' from the @RE@-reOptions :: RE -> REOptions-reOptions = _re_options---- | extract the RE source string from the @RE@-reSource :: RE -> String-reSource = _re_source---- | extract the 'CaptureNames' from the @RE@-reCaptureNames :: RE -> CaptureNames-reCaptureNames = _re_cnames---- | extract the back end compiled 'Regex' type from the @RE@-reRegex :: RE -> Regex-reRegex = _re_regex------------------------------------------------------------------------------ REOptions----------------------------------------------------------------------------- | and the REOptions for this back end (see "Text.RE.Types.REOptions"--- for details)-type REOptions = REOptions_ RE CompOption ExecOption--instance IsOption SimpleREOptions RE CompOption ExecOption where- makeREOptions = unpackSimpleREOptions--instance IsOption (Macros RE) RE CompOption ExecOption where- makeREOptions ms = REOptions ms def_comp_option def_exec_option--instance IsOption CompOption RE CompOption ExecOption where- makeREOptions co = REOptions prelude co def_exec_option--instance IsOption ExecOption RE CompOption ExecOption where- makeREOptions eo = REOptions prelude def_comp_option eo--instance IsOption REOptions RE CompOption ExecOption where- makeREOptions = id--instance IsOption () RE CompOption ExecOption where- makeREOptions _ = unpackSimpleREOptions minBound---- | the default 'REOptions'-defaultREOptions :: REOptions-defaultREOptions = makeREOptions (minBound::SimpleREOptions)---- | the default 'REOptions' but with no RE macros defined-noPreludeREOptions :: REOptions-noPreludeREOptions = defaultREOptions { optionsMacs = emptyMacros }---- | convert a universal 'SimpleReOptions' into the 'REOptions' used--- by this back end-unpackSimpleREOptions :: SimpleREOptions -> REOptions-unpackSimpleREOptions sro =- REOptions- { optionsMacs = prelude- , optionsComp = comp- , optionsExec = defaultExecOpt- }- where- comp = defaultCompOpt- { caseSensitive = cs- , multiline = ml- }-- (ml,cs) = case sro of- MultilineSensitive -> (,) True True- MultilineInsensitive -> (,) True False- BlockSensitive -> (,) False True- BlockInsensitive -> (,) False 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) => String -> m RE-compileRegex = compileRegexWithOptions ()---- | 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) => SimpleREOptions -> String -> m RE-compileRegexWith = compileRegexWithOptions---- | compile a 'String' into a 'RE' using the given @SimpleREOptions@,--- generating an error if the RE is not well formed-compileRegexWithOptions :: ( IsOption o RE CompOption ExecOption- , Functor m- , Monad m- )- => o- -> String- -> m RE-compileRegexWithOptions = compileRegex_ . 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,Functor m,IsRegex RE s)- => String- -> String- -> m (SearchReplace RE s)-compileSearchReplace = compileSearchReplaceWith 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,Functor m,IsRegex RE s)- => SimpleREOptions- -> String- -> String- -> m (SearchReplace RE s)-compileSearchReplaceWith sro = compileSearchAndReplace_ packR $ compileRegexWith 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-compileSearchReplaceWithREOptions :: (Monad m,Functor m,IsRegex RE s)- => REOptions- -> String- -> String- -> m (SearchReplace RE s)-compileSearchReplaceWithREOptions os = compileSearchAndReplace_ packR $ compileRegexWithOptions 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-escape :: (Functor m,Monad m)- => (String->String)- -> String- -> m RE-escape = escapeWith minBound---- | 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 with the default options-escapeWith :: (Functor m,Monad m)- => SimpleREOptions- -> (String->String)- -> String- -> m RE-escapeWith = escapeWithOptions---- | 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 the given options-escapeWithOptions :: ( IsOption o RE CompOption ExecOption- , Functor m- , Monad m- )- => o- -> (String->String)- -> String- -> m RE-escapeWithOptions o f = compileRegexWithOptions o . f . 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 = runIdentity $ preludeMacros mk regexType ExclCaptures- where- mk = Identity . unsafeCompileRegex_ noPreludeREOptions---- | the standard 'MacroEnv' for this back end (see "Text.RE.TestBench")-preludeEnv :: MacroEnv-preludeEnv = preludeMacroEnv regexType---- | the macros in the standard environment that are failing their tests--- (checked by the test suite to be empty)-preludeTestsFailing :: [MacroID]-preludeTestsFailing = badMacros $ preludeMacroEnv regexType---- | a table the standard macros in markdown format-preludeTable :: String-preludeTable = preludeMacroTable regexType---- | a summary of the macros in the standard environment for this back--- end in plain text-preludeSummary :: PreludeMacro -> String-preludeSummary = preludeMacroSummary regexType---- | a listing of the RE text for each macro in the standard environment--- with all macros expanded to normal form-preludeSources :: String-preludeSources = preludeMacroSources regexType---- | the prolude source of a given macro in the standard environment-preludeSource :: PreludeMacro -> String-preludeSource = preludeMacroSource regexType------------------------------------------------------------------------------ Quasi Quoters----------------------------------------------------------------------------- | the @[re| ... |]@ and @[ed| ... /// ... |]@ quasi quoters-re- , reMS- , reMI- , reBS- , reBI- , reMultilineSensitive- , reMultilineInsensitive- , reBlockSensitive- , reBlockInsensitive- , re_ :: QuasiQuoter- -- , ed- -- , edMS- -- , edMI- -- , edBS- -- , edBI- -- , edMultilineSensitive- -- , edMultilineInsensitive- -- , edBlockSensitive- -- , edBlockInsensitive- -- , ed_ :: QuasiQuoter--re = re' $ Just minBound-reMS = reMultilineSensitive-reMI = reMultilineInsensitive-reBS = reBlockSensitive-reBI = reBlockInsensitive-reMultilineSensitive = re' $ Just MultilineSensitive-reMultilineInsensitive = re' $ Just MultilineInsensitive-reBlockSensitive = re' $ Just BlockSensitive-reBlockInsensitive = re' $ Just BlockInsensitive-re_ = re' Nothing------------------------------------------------------------------------------ re Helpers---------------------------------------------------------------------------re' :: Maybe SimpleREOptions -> QuasiQuoter-re' mb = case mb of- Nothing ->- (qq0 "re'")- { quoteExp = parse minBound (\rs->[|flip unsafeCompileRegex rs|])- }- Just sro ->- (qq0 "re'")- { quoteExp = parse sro (\rs->[|unsafeCompileRegexSimple sro rs|])- }- where- parse :: SimpleREOptions -> (String->Q Exp) -> String -> Q Exp- parse sro mk rs = either error (\_->mk rs) $ compileRegex_ os rs- where- os = unpackSimpleREOptions sro--unsafeCompileRegexSimple :: SimpleREOptions -> String -> RE-unsafeCompileRegexSimple sro re_s = unsafeCompileRegex_ os re_s- where- os = unpackSimpleREOptions sro--unsafeCompileRegex :: IsOption o RE CompOption ExecOption- => o- -> String- -> RE-unsafeCompileRegex = unsafeCompileRegex_ . makeREOptions--unsafeCompileRegex_ :: REOptions -> String -> RE-unsafeCompileRegex_ os = either oops id . compileRegex_ os- where- oops = error . ("unsafeCompileRegex: " ++)--compileRegex' :: (Functor m,Monad m)- => REOptions- -> String- -> m (CaptureNames,Regex)-compileRegex' REOptions{..} s0 = do- ((_,cnms),s2) <- either fail return $ extractNamedCaptures s1- (,) cnms <$> makeRegexOptsM optionsComp optionsExec s2- where- s1 = expandMacros reSource optionsMacs s0--compileRegex_ :: (Functor m,Monad m)- => REOptions- -> String- -> m RE-compileRegex_ os re_s = uncurry mk <$> compileRegex' os re_s- where- mk cnms rx =- RE- { _re_options = os- , _re_source = re_s- , _re_cnames = cnms- , _re_regex = rx- }------------------------------------------------------------------------------ Options Helpers---------------------------------------------------------------------------def_comp_option :: CompOption-def_comp_option = optionsComp defaultREOptions--def_exec_option :: ExecOption-def_exec_option = optionsExec 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").
Text/RE/TDFA/Sequence.hs view
@@ -44,8 +44,8 @@ , escape , escapeWith , escapeREString- , module Text.RE.TDFA.RE- , module Text.RE.Internal.SearchReplace.TDFA.Sequence+ , module Text.RE.ZeInternals.TDFA+ , module Text.RE.ZeInternals.SearchReplace.TDFA.Sequence ) where import Prelude.Compat@@ -53,13 +53,12 @@ import Data.Typeable import Text.Regex.Base import Text.RE-import Text.RE.Internal.AddCaptureNames-import Text.RE.Internal.SearchReplace.TDFA.Sequence-import Text.RE.SearchReplace-import Text.RE.Types.IsRegex-import Text.RE.Types.REOptions-import Text.RE.Types.Replace-import Text.RE.TDFA.RE+import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.ZeInternals.SearchReplace.TDFA.Sequence+import Text.RE.IsRegex+import Text.RE.REOptions+import Text.RE.Replace+import Text.RE.ZeInternals.TDFA import qualified Text.Regex.TDFA as TDFA
Text/RE/TDFA/String.hs view
@@ -44,8 +44,8 @@ , escape , escapeWith , escapeREString- , module Text.RE.TDFA.RE- , module Text.RE.Internal.SearchReplace.TDFA.String+ , module Text.RE.ZeInternals.TDFA+ , module Text.RE.ZeInternals.SearchReplace.TDFA.String ) where import Prelude.Compat@@ -53,13 +53,12 @@ import Data.Typeable import Text.Regex.Base import Text.RE-import Text.RE.Internal.AddCaptureNames-import Text.RE.Internal.SearchReplace.TDFA.String-import Text.RE.SearchReplace-import Text.RE.Types.IsRegex-import Text.RE.Types.REOptions-import Text.RE.Types.Replace-import Text.RE.TDFA.RE+import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.ZeInternals.SearchReplace.TDFA.String+import Text.RE.IsRegex+import Text.RE.REOptions+import Text.RE.Replace+import Text.RE.ZeInternals.TDFA import qualified Text.Regex.TDFA as TDFA
Text/RE/TDFA/Text.hs view
@@ -44,8 +44,8 @@ , escape , escapeWith , escapeREString- , module Text.RE.TDFA.RE- , module Text.RE.Internal.SearchReplace.TDFA.Text+ , module Text.RE.ZeInternals.TDFA+ , module Text.RE.ZeInternals.SearchReplace.TDFA.Text ) where import Prelude.Compat@@ -53,13 +53,12 @@ import Data.Typeable import Text.Regex.Base import Text.RE-import Text.RE.Internal.AddCaptureNames-import Text.RE.Internal.SearchReplace.TDFA.Text-import Text.RE.SearchReplace-import Text.RE.Types.IsRegex-import Text.RE.Types.REOptions-import Text.RE.Types.Replace-import Text.RE.TDFA.RE+import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.ZeInternals.SearchReplace.TDFA.Text+import Text.RE.IsRegex+import Text.RE.REOptions+import Text.RE.Replace+import Text.RE.ZeInternals.TDFA import qualified Text.Regex.TDFA as TDFA
Text/RE/TDFA/Text/Lazy.hs view
@@ -44,8 +44,8 @@ , escape , escapeWith , escapeREString- , module Text.RE.TDFA.RE- , module Text.RE.Internal.SearchReplace.TDFA.Text.Lazy+ , module Text.RE.ZeInternals.TDFA+ , module Text.RE.ZeInternals.SearchReplace.TDFA.Text.Lazy ) where import Prelude.Compat@@ -53,13 +53,12 @@ import Data.Typeable import Text.Regex.Base import Text.RE-import Text.RE.Internal.AddCaptureNames-import Text.RE.Internal.SearchReplace.TDFA.Text.Lazy-import Text.RE.SearchReplace-import Text.RE.Types.IsRegex-import Text.RE.Types.REOptions-import Text.RE.Types.Replace-import Text.RE.TDFA.RE+import Text.RE.ZeInternals.AddCaptureNames+import Text.RE.ZeInternals.SearchReplace.TDFA.Text.Lazy+import Text.RE.IsRegex+import Text.RE.REOptions+import Text.RE.Replace+import Text.RE.ZeInternals.TDFA import qualified Text.Regex.TDFA as TDFA
+ Text/RE/TestBench.hs view
@@ -0,0 +1,186 @@+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}+{-# LANGUAGE OverloadedStrings #-}++module Text.RE.TestBench+ (+ -- * The Test Bench+ MacroEnv+ , MacroDescriptor(..)+ , RegexSource(..)+ , WithCaptures(..)+ -- ** Constructing a MacrosEnv+ , mkMacros+ -- ** Formatting Macros+ , formatMacroTable+ , formatMacroSummary+ , formatMacroSources+ , formatMacroSource+ -- ** Formatting Macros+ , testMacroEnv+ , runTests+ , runTests'+ -- * Parsing+ , parseInteger+ , parseHex+ , parseDouble+ , parseString+ , parseSimpleString+ , parseDate+ , parseSlashesDate+ , parseTimeOfDay+ , parseTimeZone+ , parseDateTime+ , parseDateTime8601+ , parseDateTimeCLF+ , parseShortMonth+ , shortMonthArray+ , IPV4Address+ , parseIPv4Address+ , Severity(..)+ , parseSeverity+ , severityKeywords+-- , module Text.RE.ZeInternals.TestBench+ ) where++import Data.Array+import qualified Data.HashMap.Strict as HM+import Data.Maybe+import qualified Data.Text as T+import Data.Time+import qualified Data.Time.Locale.Compat as LC+import Data.Word+import Text.Printf+import Text.Read+import Text.RE.Replace+import Text.RE.ZeInternals.TestBench+++parseInteger :: Replace a => a -> Maybe Int+parseInteger = readMaybe . unpackR++parseHex :: Replace a => a -> Maybe Int+parseHex = readMaybe . ("0x"++) . unpackR++parseDouble :: Replace a => a -> Maybe Double+parseDouble = readMaybe . unpackR++parseString :: Replace a => a -> Maybe T.Text+parseString = readMaybe . unpackR++parseSimpleString :: Replace a => a -> Maybe T.Text+parseSimpleString = Just . T.dropEnd 1 . T.drop 1 . textifyR++date_templates, time_templates, timezone_templates,+ date_time_8601_templates, date_time_templates :: [String]+date_templates = ["%F"]+time_templates = ["%H:%M:%S","%H:%M:%S%Q","%H:%M"]+timezone_templates = ["Z","%z"]+date_time_8601_templates =+ [ printf "%sT%s%s" dt tm tz+ | dt <- date_templates+ , tm <- time_templates+ , tz <- timezone_templates+ ]+date_time_templates =+ [ printf "%s%c%s%s" dt sc tm tz+ | dt <- date_templates+ , sc <- ['T',' ']+ , tm <- time_templates+ , tz <- timezone_templates ++ [" UTC",""]+ ]++parseDate :: Replace a => a -> Maybe Day+parseDate = parse_time date_templates++parseSlashesDate :: Replace a => a -> Maybe Day+parseSlashesDate = parse_time ["%Y/%m/%d"]++parseTimeOfDay :: Replace a => a -> Maybe TimeOfDay+parseTimeOfDay = parse_time time_templates++parseTimeZone :: Replace a => a -> Maybe TimeZone+parseTimeZone = parse_time timezone_templates++parseDateTime :: Replace a => a -> Maybe UTCTime+parseDateTime = parse_time date_time_templates++parseDateTime8601 :: Replace a => a -> Maybe UTCTime+parseDateTime8601 = parse_time date_time_8601_templates++parseDateTimeCLF :: Replace a => a -> Maybe UTCTime+parseDateTimeCLF = parse_time ["%d/%b/%Y:%H:%M:%S %z"]++parseShortMonth :: Replace a => a -> Maybe Int+parseShortMonth = flip HM.lookup short_month_hm . unpackR++parse_time :: (ParseTime t,Replace s) => [String] -> s -> Maybe t+parse_time tpls = prs . unpackR+ where+ prs s = listToMaybe $ catMaybes+ [ parseTime LC.defaultTimeLocale fmt s+ | fmt<-tpls+ ]++short_month_hm :: HM.HashMap String Int+short_month_hm = HM.fromList [ (T.unpack $ shortMonthArray!i,i) | i<-[1..12] ]++shortMonthArray :: Array Int T.Text+shortMonthArray = listArray (1,12) $+ T.words "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"++type IPV4Address = (Word8,Word8,Word8,Word8)++parseIPv4Address :: Replace a => a -> Maybe IPV4Address+parseIPv4Address = prs . words_by (=='.') . unpackR+ where+ prs [a_s,b_s,c_s,d_s] = do+ a <- readMaybe a_s+ b <- readMaybe b_s+ c <- readMaybe c_s+ d <- readMaybe d_s+ case all is_o [a,b,c,d] of+ True -> Just (toEnum a,toEnum b,toEnum c,toEnum d)+ False -> Nothing+ prs _ = Nothing++ is_o x = 0 <= x && x <= 255++data Severity+ = Emerg+ | Alert+ | Crit+ | Err+ | Warning+ | Notice+ | Info+ | Debug+ deriving (Bounded,Enum,Ord,Eq,Show)++parseSeverity :: Replace a => a -> Maybe Severity+parseSeverity = flip HM.lookup severity_hm . textifyR++severity_hm :: HM.HashMap T.Text Severity+severity_hm = HM.fromList+ [ (kw,pri)+ | pri<-[minBound..maxBound]+ , let (kw0,kws) = severityKeywords pri+ , kw <- kw0:kws+ ]++severityKeywords :: Severity -> (T.Text,[T.Text])+severityKeywords pri = case pri of+ Emerg -> (,) "emerg" ["panic"]+ Alert -> (,) "alert" []+ Crit -> (,) "crit" []+ Err -> (,) "err" ["error"]+ Warning -> (,) "warning" ["warn"]+ Notice -> (,) "notice" []+ Info -> (,) "info" []+ Debug -> (,) "debug" []++words_by :: (Char->Bool) -> String -> [String]+words_by f s = case dropWhile f s of+ "" -> []+ s' -> w : words_by f s''+ where+ (w, s'') = break f s'
− Text/RE/TestBench.lhs
@@ -1,589 +0,0 @@-\begin{code}-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 800-{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}-#endif--module Text.RE.TestBench- ( MacroID(..)- , RegexType- , mkTDFA- , mkPCRE- , isTDFA- , isPCRE- , presentRegexType- , MacroEnv- , WithCaptures(..)- , MacroDescriptor(..)- , TestResult(..)- , RegexSource(..)- , FunctionID(..)- , mkMacros- , testMacroEnv- , badMacros- , runTests- , runTests'- , formatMacroTable- , dumpMacroTable- , formatMacroSummary- , formatMacroSources- , formatMacroSource- , testMacroDescriptors- , mdRegexSource- -- * Parsers- , module Text.RE.TestBench.Parsers- -- * Text.RE- , module Text.RE- ) where--import Data.Array-import Data.Char-import qualified Data.HashMap.Lazy as HML-import qualified Data.List as L-import Data.Maybe-import Data.Ord-import Data.String-import Text.Printf-import Prelude.Compat-import Text.RE-import Text.RE.TestBench.Parsers-import Text.RE.Types.Capture-import Text.RE.Types.REOptions-import Text.RE.Types.Match-import Text.RE.Types.Matches-import Text.RE.Types.Replace-\end{code}--Types--------\begin{code}--type TestBenchMatcher =- String -> MacroEnv -> MacroDescriptor -> Matches String---- | what kind of back end will be compiling the RE, and its match--- function-data RegexType- = TDFA TestBenchMatcher- | PCRE TestBenchMatcher---- | test RegexType for TDFA/PCREness-isTDFA, isPCRE :: RegexType -> Bool--isTDFA (TDFA _) = True-isTDFA (PCRE _) = False--isPCRE (TDFA _) = False-isPCRE (PCRE _) = True--mkTDFA, mkPCRE :: TestBenchMatcher -> RegexType-mkTDFA = TDFA-mkPCRE = PCRE--presentRegexType :: RegexType -> String-presentRegexType (TDFA _) = "TDFA"-presentRegexType (PCRE _) = "PCRE"--instance Show RegexType where- show (TDFA _) = "TDFA <function>"- show (PCRE _) = "PCRE <function>"---- | do we need the captures in the RE or whould they be stripped out--- where possible-data WithCaptures- = InclCaptures- | ExclCaptures- deriving (Eq,Ord,Show)---- | each macro can reference others, the whole environment being--- required for each macro, so we use a Lazy HashMap-type MacroEnv = HML.HashMap MacroID MacroDescriptor---- | describes a macro, giving the text of the RE and a si=ummary--- description-data MacroDescriptor =- MacroDescriptor- { _md_source :: !RegexSource -- ^ the RE- , _md_samples :: ![String] -- ^ some sample matches- , _md_counter_samples :: ![String] -- ^ some sample non-matches- , _md_test_results :: ![TestResult] -- ^ validation test results- , _md_parser :: !(Maybe FunctionID) -- ^ WA, the parser function- , _md_description :: !String -- ^ summary comment- }- deriving (Show)---- | list of failures on a validation run-newtype TestResult =- TestResult { _TestResult :: String }- deriving (IsString,Show)---- | a RE that should work for POSIX and PCRE with open brackets ('(')--- represented as follows:--- \( mere symbol--- (?: used for grouping only, not for captures--- (}: used for captures only, not for grouping--- (]: used for captures and grouping--- ( do not modify-newtype RegexSource =- RegexSource { _RegexSource :: String }- deriving (IsString,Show)---- | name of the Haskell parser function for parsing the text matched--- by a macro-newtype FunctionID =- FunctionID { _FunctionID :: String }- deriving (IsString,Show)---- | we are only interested in the open parentheses used for--- grouping and/or capturing; if neither grouping or capturing then--- there is no initial '(' or '(?:', just the suffic text-data REToken =- REToken- { _ret_prefix :: String -- ^ following text optional ( or (?:- , _ret_fixed :: Bool -- ^ a '(' that is not safe to modify- , _ret_grouping :: Bool -- ^ is this a grouping group- , _ret_capturing :: Bool -- ^ is this a capturing group- }- deriving (Show)-\end{code}---mkMacros-----------\begin{code}-mkMacros :: (Monad m,Functor m)- => (String->m r)- -> RegexType- -> WithCaptures- -> MacroEnv- -> m (Macros r)-mkMacros prs rty wc env =- HML.fromList <$> mapM (uncurry mk) (HML.toList env)- where- mk mid md = (,) mid <$> prs (mdRegexSource rty wc env md)-\end{code}---testMacroEnv, badMacros--------------------------\begin{code}-testMacroEnv :: String -> RegexType -> MacroEnv -> IO Bool-testMacroEnv lab rty m_env = case badMacros m_env of- [] -> return True- fails -> do- putStrLn $ lab' ++ " has failing tests for these macros: "- putStr $ unlines $ [ " "++getMacroID mid | mid<-fails ]- putStrLn $ "The whole table:"- putStrLn $ "========================================================"- putStr $ formatMacroTable rty m_env- putStrLn $ "========================================================"- return False- where- lab' = lab ++ " [" ++ presentRegexType rty ++"]"--badMacros :: MacroEnv -> [MacroID]-badMacros m_env =- [ mid- | (mid,MacroDescriptor{..}) <- HML.toList m_env- , not $ null _md_test_results- ]--runTests :: (Eq a,Show a)- => RegexType- -> (String->Maybe a)- -> [(String,a)]- -> MacroEnv- -> MacroID- -> MacroDescriptor- -> MacroDescriptor-runTests rty parser = runTests' rty parser'- where- parser' caps = fmap capturedText (matchCapture caps) >>= parser--runTests' :: (Eq a,Show a)- => RegexType- -> (Match String->Maybe a)- -> [(String,a)]- -> MacroEnv- -> MacroID- -> MacroDescriptor- -> MacroDescriptor-runTests' rty parser vector env mid md@MacroDescriptor{..} =- md { _md_test_results = test_results }- where- test_results = concat- [ concat $ map test vector- , concat $ map test_neg _md_counter_samples- ]-- test (src,x) = test' mid rty parser x $ match_ src env md-- test_neg src = test_neg' mid rty parser $ match_ src env md-- match_ = case rty of- TDFA tbmf -> tbmf- PCRE tbmf -> tbmf-\end{code}---dumpMacroTable, formatMacroTable, formatMacroSummary, formatMacroSources, formatMacroSource----------------------------------------------------------------------------------------------\begin{code}-dumpMacroTable :: String -> RegexType -> MacroEnv -> IO ()-dumpMacroTable lab rty m_env = do- writeFile fp_t $ formatMacroTable rty m_env- writeFile fp_s $ formatMacroSources rty ExclCaptures m_env- where- fp_t = "docs/" ++ rty_s ++ "-" ++ lab ++ ".txt"- fp_s = "docs/" ++ rty_s ++ "-" ++ lab ++ "-src.txt"-- rty_s = map toLower $ presentRegexType rty-\end{code}--\begin{code}-formatMacroTable :: RegexType -> MacroEnv -> String-formatMacroTable rty env = unlines $- format_table macro_table_hdr- [ macro_table_row rty mid md- | (mid,md) <- L.sortBy (comparing fst) $ HML.toList env- ]-\end{code}--\begin{code}-formatMacroSummary :: RegexType -> MacroEnv -> MacroID -> String-formatMacroSummary rty env mid = maybe oops prep $ HML.lookup mid env- where- prep :: MacroDescriptor -> String- prep md = unlines $ concat $ map (fmt md) [minBound..maxBound]-- fmt :: MacroDescriptor -> Col -> [String]- fmt md c =- [ printf "%-15s : %s" (present_col c) ini- ] ++ map (" "++) lns- where- (ini,lns) = case macro_attribute rty mid md c of- [] -> (,) "" []- [ln] -> (,) ln []- lns_ -> (,) "" lns_-- oops = error $ getMacroID mid ++ ": macro not defined in this environment"-\end{code}--\begin{code}-formatMacroSources :: RegexType- -> WithCaptures- -> MacroEnv- -> String-formatMacroSources rty wc env = unlines $- [ printf "%-20s : %s" (getMacroID mid) $ formatMacroSource rty wc env mid- | mid <- L.sort $ HML.keys env- ]-\end{code}--\begin{code}-formatMacroSource :: RegexType- -> WithCaptures- -> MacroEnv- -> MacroID- -> String-formatMacroSource rty wc env mid =- mdRegexSource rty wc env $ fromMaybe oops $ HML.lookup mid env- where- oops = error $ "formatMacroSource: not found: " ++ getMacroID mid-\end{code}---testMacroDescriptors, regexSource------------------------------------\begin{code}-testMacroDescriptors :: [MacroDescriptor] -> [TestResult]-testMacroDescriptors = concat . map _md_test_results--regexSource :: RegexType -> WithCaptures -> RegexSource -> String-regexSource rty wc = format_tokens rty wc . scan_re-\end{code}---Formatting helpers---------------------\begin{code}-type TableRow = Array Col [String]--data Col- = C_name- | C_caps- | C_regex- | C_examples- | C_anti_examples- | C_fails- | C_parser- | C_comment- deriving (Ix,Bounded,Enum,Ord,Eq,Show)--present_col :: Col -> String-present_col = map tr . drop 2 . show- where- tr '_' = '-'- tr c = c--macro_table_hdr :: TableRow-macro_table_hdr = listArray (minBound,maxBound)- [ [present_col c]- | c<-[minBound..maxBound]- ]--macro_table_row :: RegexType -> MacroID -> MacroDescriptor -> TableRow-macro_table_row rty mid md =- listArray (minBound,maxBound) $- map (macro_attribute rty mid md) [minBound..maxBound]--macro_attribute :: RegexType- -> MacroID- -> MacroDescriptor- -> Col- -> [String]-macro_attribute rty mid MacroDescriptor{..} c =- case c of- C_name -> [getMacroID mid]- C_caps -> [show $ min_captures rty $ scan_re _md_source]- C_regex -> [regexSource rty ExclCaptures _md_source]- C_examples -> _md_samples- C_anti_examples -> _md_counter_samples- C_fails -> map _TestResult _md_test_results- C_parser -> [maybe "-" _FunctionID _md_parser]- C_comment -> [_md_description]--format_table :: TableRow -> [TableRow] -> [String]-format_table hdr rows0 = concat- [ format_row cws hdr'- , format_row cws dsh- , concat $ map (format_row cws) rows- ]- where- dsh = listArray (minBound,maxBound)- [ [replicate n '-'] | n<-elems cws ]-- hdr' = hdr // [(,) C_regex $ [take n $ concat $ repeat "regex="] ]- where- n = min 29 $ cws!C_regex-- cws = widths $ hdr : rows-- rows = map wrap_row rows0--field_width :: Int-field_width = 40--wrap_row :: TableRow -> TableRow-wrap_row = fmap $ concat . map f- where- f, g :: String -> [String]-- f cts = (ini ++ ['\\' | not (null rst)]) : g rst- where- (ini,rst) = splitAt (1+field_width) cts-- g "" = []- g cts = ('\\' : ini ++ ['\\' | not (null rst)]) : g rst- where- (ini,rst) = splitAt field_width cts---widths :: [TableRow] -> Array Col Int-widths rows = listArray (minBound,maxBound)- [ maximum $ concat [ map length $ row!c | row<-rows ]- | c<-[minBound..maxBound]- ]--format_row :: Array Col Int -> TableRow -> [String]-format_row cw_arr row =- [ ("|"++) $ L.intercalate "|"- [ field cw_arr row c i | c<-[minBound..maxBound] ]- | i <- [0..depth-1]- ]- where- depth = maximum [ length $ row!c | c<-[minBound..maxBound] ]--field :: Array Col Int -> TableRow -> Col -> Int -> String-field cws row c i = ljust (cws!c) $ sel i $ row!c--sel :: Int -> [String] -> String-sel i ss = case drop i ss of- [] -> ""- s:_ -> s--ljust :: Int -> String -> String-ljust w s = s ++ replicate n ' '- where- n = max 0 $ w - length s--min_captures :: RegexType -> [REToken] -> Int-min_captures rty rets = length- [ ()- | REToken{..}<-rets- , _ret_fixed || (_ret_grouping && isTDFA rty)- ]-\end{code}---Formatting tokens--------------------\begin{code}-format_tokens :: RegexType -> WithCaptures -> [REToken] -> String-format_tokens rty wc = foldr f ""- where- f REToken{..} rst = _ret_prefix ++ bra ++ xket rst- where- bra = case _ret_fixed of- True -> "("- False ->- case (,) _ret_grouping (_ret_capturing && wc==InclCaptures) of- (False,False) -> ""- (True ,False) -> if isPCRE rty then "(?:" else "("- (False,True ) -> "("- (True ,True ) -> "("-- xket =- case not _ret_grouping && _ret_capturing && wc==ExclCaptures of- True -> delete_ket 0- False -> id--delete_ket :: Int -> String -> String-delete_ket _ "" = error "delete_ket: end of input"-delete_ket n (c:t) = case c of- '\\' -> case t of- "" -> error "delete_ket: end of input"- c':t' -> c : c' : delete_ket n t'- ')' -> case n of- 0 -> t- _ -> c : delete_ket (n-1) t- '(' -> c : delete_ket (n+1) t- _ -> c : delete_ket n t-\end{code}---scan_re----------\begin{code}-scan_re :: RegexSource -> [REToken]-scan_re (RegexSource src0) = loop src0- where- loop "" = []- loop src =- case rst of- '\\':t -> case t of- "" -> REToken (ini++['\\']) False False False : []- c':t' -> REToken (ini++['\\',c']) False False False : loop t'- '(' :t -> case t of- c:':':t'- | c=='?' -> REToken ini False True False : loop t'- | c=='}' -> REToken ini False False True : loop t'- | c==']' -> REToken ini False True True : loop t'- _ -> REToken ini True True True : loop t- _ -> [REToken src False False False]- where- (ini,rst) = break chk src-- chk '\\' = True- chk '(' = True- chk _ = False-\end{code}---mdRegexSource----------------\begin{code}-mdRegexSource :: RegexType- -> WithCaptures- -> MacroEnv- -> MacroDescriptor- -> String-mdRegexSource rty wc env md =- expandMacros' lu $ regexSource rty wc $ _md_source md- where- lu = fmap (regexSource rty wc . _md_source) .- flip HML.lookup env-\end{code}---test', test_neg'-------------------\begin{code}-test' :: (Eq a,Show a)- => MacroID- -> RegexType- -> (Match String->Maybe a)- -> a- -> Matches String- -> [TestResult]-test' mid rty prs x Matches{..} = either (:[]) (const []) $ do- cs <- case allMatches of- [cs] -> return cs- _ -> oops "RE failed to parse"- mtx <- case matchCapture cs of- Nothing -> oops $ "RE parse failure: " ++ show cs- Just c -> return $ capturedText c- case mtx == matchesSource of- True -> return ()- False -> oops "RE failed to match the whole text"- x' <- case prs cs of- Nothing -> oops "matched text failed to parse"- Just x' -> return x'- case x'==x of- True -> return ()- False -> oops "parser failed to yield the expected result"- where- oops = Left . test_diagnostic mid False rty matchesSource--test_neg' :: MacroID- -> RegexType- -> (Match String->Maybe a)- -> Matches String- -> [TestResult]-test_neg' mid rty prs Matches{..} = either id (const []) $ do- case allMatches of- [] -> return ()- cz -> case ms of- [] -> return ()- _ -> Left [oops "RE parse succeeded"]- where- ms =- [ ()- | cs <- cz- , Just c <- [matchCapture cs]- , let t = capturedText c- , t == matchesSource- , isJust $ prs cs- ]-- where- oops = test_diagnostic mid True rty matchesSource--test_diagnostic :: MacroID- -> Bool- -> RegexType- -> String- -> String- -> TestResult-test_diagnostic mid is_neg rty tst msg =- TestResult $- printf "%-20s [%s %s] : %s (%s)" mid_s neg_s rty_s msg tst- where- mid_s = getMacroID mid- neg_s = if is_neg then "-ve" else "+ve" :: String- rty_s = presentRegexType rty-\end{code}
− Text/RE/TestBench/Parsers.hs
@@ -1,166 +0,0 @@-{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}-{-# LANGUAGE OverloadedStrings #-}--module Text.RE.TestBench.Parsers- ( parseInteger- , parseHex- , parseDouble- , parseString- , parseSimpleString- , parseDate- , parseSlashesDate- , parseTimeOfDay- , parseTimeZone- , parseDateTime- , parseDateTime8601- , parseDateTimeCLF- , parseShortMonth- , shortMonthArray- , IPV4Address- , parseIPv4Address- , Severity(..)- , parseSeverity- , severityKeywords- ) where--import Data.Array-import qualified Data.HashMap.Strict as HM-import Data.Maybe-import qualified Data.Text as T-import Data.Time-import qualified Data.Time.Locale.Compat as LC-import Data.Word-import Text.Printf-import Text.Read-import Text.RE.Types.Replace---parseInteger :: Replace a => a -> Maybe Int-parseInteger = readMaybe . unpackR--parseHex :: Replace a => a -> Maybe Int-parseHex = readMaybe . ("0x"++) . unpackR--parseDouble :: Replace a => a -> Maybe Double-parseDouble = readMaybe . unpackR--parseString :: Replace a => a -> Maybe T.Text-parseString = readMaybe . unpackR--parseSimpleString :: Replace a => a -> Maybe T.Text-parseSimpleString = Just . T.dropEnd 1 . T.drop 1 . textifyR--date_templates, time_templates, timezone_templates,- date_time_8601_templates, date_time_templates :: [String]-date_templates = ["%F"]-time_templates = ["%H:%M:%S","%H:%M:%S%Q","%H:%M"]-timezone_templates = ["Z","%z"]-date_time_8601_templates =- [ printf "%sT%s%s" dt tm tz- | dt <- date_templates- , tm <- time_templates- , tz <- timezone_templates- ]-date_time_templates =- [ printf "%s%c%s%s" dt sc tm tz- | dt <- date_templates- , sc <- ['T',' ']- , tm <- time_templates- , tz <- timezone_templates ++ [" UTC",""]- ]--parseDate :: Replace a => a -> Maybe Day-parseDate = parse_time date_templates--parseSlashesDate :: Replace a => a -> Maybe Day-parseSlashesDate = parse_time ["%Y/%m/%d"]--parseTimeOfDay :: Replace a => a -> Maybe TimeOfDay-parseTimeOfDay = parse_time time_templates--parseTimeZone :: Replace a => a -> Maybe TimeZone-parseTimeZone = parse_time timezone_templates--parseDateTime :: Replace a => a -> Maybe UTCTime-parseDateTime = parse_time date_time_templates--parseDateTime8601 :: Replace a => a -> Maybe UTCTime-parseDateTime8601 = parse_time date_time_8601_templates--parseDateTimeCLF :: Replace a => a -> Maybe UTCTime-parseDateTimeCLF = parse_time ["%d/%b/%Y:%H:%M:%S %z"]--parseShortMonth :: Replace a => a -> Maybe Int-parseShortMonth = flip HM.lookup short_month_hm . unpackR--parse_time :: (ParseTime t,Replace s) => [String] -> s -> Maybe t-parse_time tpls = prs . unpackR- where- prs s = listToMaybe $ catMaybes- [ parseTime LC.defaultTimeLocale fmt s- | fmt<-tpls- ]--short_month_hm :: HM.HashMap String Int-short_month_hm = HM.fromList [ (T.unpack $ shortMonthArray!i,i) | i<-[1..12] ]--shortMonthArray :: Array Int T.Text-shortMonthArray = listArray (1,12) $- T.words "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"--type IPV4Address = (Word8,Word8,Word8,Word8)--parseIPv4Address :: Replace a => a -> Maybe IPV4Address-parseIPv4Address = prs . words_by (=='.') . unpackR- where- prs [a_s,b_s,c_s,d_s] = do- a <- readMaybe a_s- b <- readMaybe b_s- c <- readMaybe c_s- d <- readMaybe d_s- case all is_o [a,b,c,d] of- True -> Just (toEnum a,toEnum b,toEnum c,toEnum d)- False -> Nothing- prs _ = Nothing-- is_o x = 0 <= x && x <= 255--data Severity- = Emerg- | Alert- | Crit- | Err- | Warning- | Notice- | Info- | Debug- deriving (Bounded,Enum,Ord,Eq,Show)--parseSeverity :: Replace a => a -> Maybe Severity-parseSeverity = flip HM.lookup severity_hm . textifyR--severity_hm :: HM.HashMap T.Text Severity-severity_hm = HM.fromList- [ (kw,pri)- | pri<-[minBound..maxBound]- , let (kw0,kws) = severityKeywords pri- , kw <- kw0:kws- ]--severityKeywords :: Severity -> (T.Text,[T.Text])-severityKeywords pri = case pri of- Emerg -> (,) "emerg" ["panic"]- Alert -> (,) "alert" []- Crit -> (,) "crit" []- Err -> (,) "err" ["error"]- Warning -> (,) "warning" ["warn"]- Notice -> (,) "notice" []- Info -> (,) "info" []- Debug -> (,) "debug" []--words_by :: (Char->Bool) -> String -> [String]-words_by f s = case dropWhile f s of- "" -> []- s' -> w : words_by f s''- where- (w, s'') = break f s'
Text/RE/Tools/Edit.lhs view
@@ -29,11 +29,10 @@ import Data.Maybe import Prelude.Compat import Text.RE-import Text.RE.Types.Capture-import Text.RE.Types.IsRegex-import Text.RE.Types.LineNo-import Text.RE.Types.Replace-import Text.RE.Types.SearchReplace+import Text.RE.ZeInternals.Types.Capture+import Text.RE.IsRegex+import Text.RE.ZeInternals.Types.LineNo+import Text.RE.Replace -- | an 'Edits' script will, for each line in the file, either perform@@ -46,7 +45,7 @@ -- | each Edit action specifies how the match should be processed data Edit m re s = Template !(SearchReplace re s)- | Function !re REContext !(LineNo->Match s->Location->Capture s->m (Maybe s))+ | Function !re REContext !(LineNo->Match s->RELocation->Capture s->m (Maybe s)) | LineEdit !re !(LineNo->Matches s->m (LineEdit s)) -- | a LineEdit is the most general action thar can be performed on a line
Text/RE/Tools/Grep.lhs view
@@ -28,8 +28,8 @@ import Prelude.Compat import Text.Printf import Text.RE-import Text.RE.Types.IsRegex-import Text.RE.Types.LineNo+import Text.RE.IsRegex+import Text.RE.ZeInternals.Types.LineNo -- | operates a bit like classic @grep@ printing out the lines matched
Text/RE/Tools/Lex.lhs view
@@ -12,10 +12,10 @@ import Prelude.Compat import Text.RE-import Text.RE.Types.Capture-import Text.RE.Types.IsRegex-import Text.RE.Types.Match-import Text.RE.Types.Replace+import Text.RE.ZeInternals.Types.Capture+import Text.RE.IsRegex+import Text.RE.ZeInternals.Types.Match+import Text.RE.Replace -- | a simple regex-based scanner interpretter for prototyping
Text/RE/Tools/Sed.lhs view
@@ -32,8 +32,8 @@ import Prelude.Compat import Text.RE import Text.RE.Tools.Edit-import Text.RE.Types.IsRegex-import Text.RE.Types.Replace+import Text.RE.IsRegex+import Text.RE.Replace -- | read a file, apply an 'Edits' script to each line it and
− Text/RE/Types.hs
@@ -1,27 +0,0 @@-module Text.RE.Types- ( -- $collection- module Text.RE.Types.Capture- , module Text.RE.Types.CaptureID- , module Text.RE.Types.IsRegex- , module Text.RE.Types.LineNo- , module Text.RE.Types.Match- , module Text.RE.Types.Matches- , module Text.RE.Types.REOptions- , module Text.RE.Types.Replace- , module Text.RE.Types.SearchReplace- ) where--import Text.RE.Types.Capture-import Text.RE.Types.CaptureID-import Text.RE.Types.IsRegex-import Text.RE.Types.LineNo-import Text.RE.Types.Match-import Text.RE.Types.Matches-import Text.RE.Types.REOptions-import Text.RE.Types.Replace-import Text.RE.Types.SearchReplace---- $collection------ This module collects together all of the @Text.RE.Types.*@ modules--- to make it easy to import them all en masse.
− Text/RE/Types/Capture.lhs
@@ -1,61 +0,0 @@-\begin{code}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE DeriveDataTypeable #-}-\end{code}--\begin{code}-module Text.RE.Types.Capture- ( Capture(..)- , hasCaptured- , capturePrefix- , captureSuffix- ) where-\end{code}--\begin{code}-import Text.Regex.Base-\end{code}----\begin{code}--- | the matching of a single sub-expression against part of the source--- text-data Capture a =- Capture- { captureSource :: !a -- ^ the whole text that was searched- , capturedText :: !a -- ^ the text that was matched- , captureOffset :: !Int -- ^ the number of characters preceding the- -- match with -1 used if no text was captured- -- by the RE (not even the empty string)- , captureLength :: !Int -- ^ the number of chacter in the captured- -- sub-string- }- deriving (Show,Eq)-\end{code}--\begin{code}-instance Functor Capture where- fmap f c@Capture{..} =- c- { captureSource = f captureSource- , capturedText = f capturedText- }-\end{code}--\begin{code}--- | test if the capture has matched any text-hasCaptured :: Capture a -> Bool-hasCaptured = (>=0) . captureOffset---- | returns the text preceding the match-capturePrefix :: Extract a => Capture a -> a-capturePrefix Capture{..} = before captureOffset captureSource---- | returns the text after the match-captureSuffix :: Extract a => Capture a -> a-captureSuffix Capture{..} = after (captureOffset+captureLength) captureSource-\end{code}
− Text/RE/Types/CaptureID.hs
@@ -1,49 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}--module Text.RE.Types.CaptureID where--import Data.Ix-import Data.Hashable-import qualified Data.HashMap.Strict as HMS-import Data.Maybe-import qualified Data.Text as T----- | CaptureID identifies captures, either by number--- (e.g., [cp|1|]) or name (e.g., [cp|foo|]).-data CaptureID- = IsCaptureOrdinal CaptureOrdinal -- [cp|3|]- | IsCaptureName CaptureName -- [cp|y|]- deriving (Show,Ord,Eq)---- | the dictionary for named captures stored in compiled regular--- expressions associates-type CaptureNames = HMS.HashMap CaptureName CaptureOrdinal---- | an empty 'CaptureNames' dictionary-noCaptureNames :: CaptureNames-noCaptureNames = HMS.empty---- | a 'CaptureName' is just the text of the name-newtype CaptureName = CaptureName { getCaptureName :: T.Text }- deriving (Show,Ord,Eq)--instance Hashable CaptureName where- hashWithSalt i = hashWithSalt i . getCaptureName---- | a 'CaptureOrdinal' is just the number of the capture, starting--- with 0 for the whole of the text matched, then in leftmost,--- outermost-newtype CaptureOrdinal = CaptureOrdinal { getCaptureOrdinal :: Int }- deriving (Show,Ord,Eq,Enum,Ix,Num)---- | look up a 'CaptureID' in the 'CaptureNames' dictionary-findCaptureID :: CaptureID -> CaptureNames -> Int-findCaptureID (IsCaptureOrdinal o) _ = getCaptureOrdinal o-findCaptureID (IsCaptureName n) hms =- getCaptureOrdinal $ fromMaybe oops $ HMS.lookup n hms- where- oops = error $ unlines $- ("lookupCaptureID: " ++ T.unpack t ++ " not found in:") :- [ " "++T.unpack (getCaptureName nm) | nm <- HMS.keys hms ]- t = getCaptureName n
− Text/RE/Types/IsRegex.lhs
@@ -1,46 +0,0 @@-\begin{code}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 800-{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}-#endif--module Text.RE.Types.IsRegex where--import Text.RE.Internal.EscapeREString-import Text.RE.Types.Match-import Text.RE.Types.Matches-import Text.RE.Types.REOptions-import Text.RE.Types.Replace-import Text.RE.Types.SearchReplace-\end{code}--\begin{code}--- | the 'IsRegex' class allows tools to be written that will work with--- regex back end text type supported by the back end-class Replace s => IsRegex re s where- -- | finding the first match- matchOnce :: re -> s -> Match s- -- | finding all matches- matchMany :: re -> s -> Matches s- -- | compiling an RE, failing if the RE is not well formed- makeRegex :: (Functor m,Monad m) => s -> m re- -- | comiling an RE, specifying the 'SimpleREOptions'- makeRegexWith :: (Functor m,Monad m) => SimpleREOptions -> s -> m re- -- | compiling a 'SearchReplace' template from the RE text and the template Text, failing if they are not well formed- makeSearchReplace :: (Functor m,Monad m,IsRegex re s) => s -> s -> m (SearchReplace re s)- -- | compiling a 'SearchReplace' template specifing the 'SimpleREOptions' for the RE- makeSearchReplaceWith :: (Functor m,Monad m,IsRegex re s) => SimpleREOptions -> s -> s -> m (SearchReplace re s)- -- | incorporate an escaped string into a compiled RE with the default options- makeEscaped :: (Functor m,Monad m) => (s->s) -> s -> m re- -- | incorporate an escaped string into a compiled RE with the specified 'SimpleREOptions'- makeEscapedWith :: (Functor m,Monad m) => SimpleREOptions -> (s->s) -> s -> m re- -- | extract the text of the RE from the RE- regexSource :: re -> s-- makeRegex = makeRegexWith minBound- makeSearchReplace = makeSearchReplaceWith minBound- makeEscaped = makeEscapedWith minBound- makeEscapedWith o f = makeRegexWith o . f . packR . escapeREString . unpackR-\end{code}
− Text/RE/Types/LineNo.hs
@@ -1,21 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}--module Text.RE.Types.LineNo where----- | our line numbers are of the proper zero-based kind-newtype LineNo =- ZeroBasedLineNo { getZeroBasedLineNo :: Int }- deriving (Show,Enum)---- | the first line in a file-firstLine :: LineNo-firstLine = ZeroBasedLineNo 0---- | extract a conventional 1-based line number-getLineNo :: LineNo -> Int-getLineNo = succ . getZeroBasedLineNo---- | inject a conventional 1-based line number-lineNo :: Int -> LineNo-lineNo = ZeroBasedLineNo . pred
− Text/RE/Types/Match.lhs
@@ -1,194 +0,0 @@-\begin{code}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE DeriveDataTypeable #-}-\end{code}--\begin{code}-module Text.RE.Types.Match- ( Match(..)- , noMatch- , emptyMatchArray- , matched- , matchedText- , matchCapture- , matchCaptures- , (!$$)- , captureText- , (!$$?)- , captureTextMaybe- , (!$)- , capture- , (!$?)- , captureMaybe- , convertMatchText- ) where-\end{code}--\begin{code}-import Data.Array-import Data.Maybe-import Data.Typeable-import Text.Regex.Base-import Text.RE.Types.Capture-import Text.RE.Types.CaptureID--infixl 9 !$, !$$-\end{code}--\begin{code}--- | the result of matching a RE to a text once, listing the text that--- was matched and the named captures in the RE and all of the substrings--- matched, with the text captured by the whole RE; a complete failure--- to match will be represented with an empty array (with bounds (0,-1))-data Match a =- Match- { matchSource :: !a -- ^ the whole source text- , captureNames :: !CaptureNames -- ^ the RE's capture names- , matchArray :: !(Array CaptureOrdinal (Capture a))- -- ^ 0..n-1 captures,- -- starting with the- -- text matched by the- -- whole RE- }- deriving (Show,Eq,Typeable)-\end{code}--\begin{code}--- | Construct a Match that does not match anything.-noMatch :: a -> Match a-noMatch t = Match t noCaptureNames emptyMatchArray---- | an empty array of Capture-emptyMatchArray :: Array CaptureOrdinal (Capture a)-emptyMatchArray = listArray (CaptureOrdinal 0,CaptureOrdinal $ -1) []-\end{code}--\begin{code}-instance Functor Match where- fmap f Match{..} =- Match- { matchSource = f matchSource- , captureNames = captureNames- , matchArray = fmap (fmap f) matchArray- }-\end{code}--\begin{code}--- | tests whether the RE matched the source text at all-matched :: Match a -> Bool-matched = isJust . matchCapture---- | tests whether the RE matched the source text at all-matchedText :: Match a -> Maybe a-matchedText = fmap capturedText . matchCapture---- | the top-level capture if the source text matched the RE,--- Nothing otherwise-matchCapture :: Match a -> Maybe (Capture a)-matchCapture = fmap fst . matchCaptures---- | the top-level capture and the sub captures if the text matched--- the RE, Nothing otherwise-matchCaptures :: Match a -> Maybe (Capture a,[Capture a])-matchCaptures Match{..} = case rangeSize (bounds matchArray) == 0 of- True -> Nothing- False -> Just (matchArray!0,drop 1 $ elems matchArray)---- | an alternative for captureText-(!$$) :: Match a -> CaptureID -> a-(!$$) = flip captureText---- | look up the text of the nth capture, 0 being the match of the whole--- RE against the source text, 1, the first bracketed sub-expression to--- be matched and so on-captureText :: CaptureID -> Match a -> a-captureText cid mtch = capturedText $ capture cid mtch---- | an alternative for captureTextMaybe-(!$$?) :: Match a -> CaptureID -> Maybe a-(!$$?) = flip captureTextMaybe---- | look up the text of the nth capture (0 being the match of the--- whole), returning Nothing if the Match doesn't contain the capture-captureTextMaybe :: CaptureID -> Match a -> Maybe a-captureTextMaybe cid mtch = do- cap <- mtch !$? cid- case hasCaptured cap of- True -> Just $ capturedText cap- False -> Nothing---- | an alternative for capture-(!$) :: Match a -> CaptureID -> Capture a-(!$) = flip capture---- | look up the nth capture, 0 being the match of the whole RE against--- the source text, 1, the first bracketed sub-expression to be matched--- and so on-capture :: CaptureID -> Match a -> Capture a-capture cid mtch = fromMaybe oops $ mtch !$? cid- where- oops = error $ "capture: out of bounds (" ++ show cid ++ ")"---- | an alternative for capture captureMaybe-(!$?) :: Match a -> CaptureID -> Maybe (Capture a)-(!$?) = flip captureMaybe---- | look up the nth capture, 0 being the match of the whole RE against--- the source text, 1, the first bracketed sub-expression to be matched--- and so on, returning Nothing if there is no such capture, or if the--- capture failed to capture anything (being in a failed alternate)-captureMaybe :: CaptureID -> Match a -> Maybe (Capture a)-captureMaybe cid mtch@Match{..} = do- cap <- case bounds matchArray `inRange` CaptureOrdinal i of- True -> Just $ matchArray ! CaptureOrdinal i- False -> Nothing- case hasCaptured cap of- True -> Just cap- False -> Nothing- where- i = lookupCaptureID cid mtch--lookupCaptureID :: CaptureID -> Match a -> Int-lookupCaptureID cid Match{..} = findCaptureID cid captureNames-\end{code}---\begin{code}--- | this instance hooks 'Match' into regex-base: regex consumers need--- not worry about any of this-instance- ( RegexContext regex source (AllTextSubmatches (Array Int) (source,(Int,Int)))- , RegexLike regex source- ) =>- RegexContext regex source (Match source) where- match r s = convertMatchText s $ getAllTextSubmatches $ match r s- matchM r s = do- y <- matchM r s- return $ convertMatchText s $ getAllTextSubmatches y-\end{code}--\begin{code}--- | convert a regex-base native MatchText into a regex Match type-convertMatchText :: source -> MatchText source -> Match source-convertMatchText hay arr =- Match- { matchSource = hay- , captureNames = noCaptureNames- , matchArray =- ixmap (CaptureOrdinal lo,CaptureOrdinal hi) getCaptureOrdinal $- fmap f arr- }- where- (lo,hi) = bounds arr-- f (ndl,(off,len)) =- Capture- { captureSource = hay- , capturedText = ndl- , captureOffset = off- , captureLength = len- }-\end{code}
− Text/RE/Types/Matches.lhs
@@ -1,80 +0,0 @@-\begin{code}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE DeriveDataTypeable #-}-\end{code}--\begin{code}-module Text.RE.Types.Matches- ( Matches(..)- , anyMatches- , countMatches- , matches- , mainCaptures- ) where-\end{code}--\begin{code}-import Data.Typeable-import Text.Regex.Base-import Text.RE.Types.Capture-import Text.RE.Types.CaptureID-import Text.RE.Types.Match-\end{code}---\begin{code}--- | the result type to use when every match is needed, not just the--- first match of the RE against the source-data Matches a =- Matches- { matchesSource :: !a -- ^ the source text being matched- , allMatches :: ![Match a] -- ^ all 'Match' instances found, left to right- }- deriving (Show,Eq,Typeable)-\end{code}--\begin{code}-instance Functor Matches where- fmap f Matches{..} =- Matches- { matchesSource = f matchesSource- , allMatches = map (fmap f) allMatches- }-\end{code}--\begin{code}--- | tests whether the RE matched the source text at all-anyMatches :: Matches a -> Bool-anyMatches = not . null . allMatches---- | count the matches-countMatches :: Matches a -> Int-countMatches = length . allMatches---- | list the Matches-matches :: Matches a -> [a]-matches = map capturedText . mainCaptures---- | extract the main capture from each match-mainCaptures :: Matches a -> [Capture a]-mainCaptures ac = [ capture c0 cs | cs<-allMatches ac ]- where- c0 = IsCaptureOrdinal $ CaptureOrdinal 0-\end{code}--\begin{code}--- | this instance hooks 'Matches' into regex-base: regex consumers need--- not worry about any of this-instance- ( RegexContext regex source [MatchText source]- , RegexLike regex source- ) =>- RegexContext regex source (Matches source) where- match r s = Matches s $ map (convertMatchText s) $ match r s- matchM r s = do- y <- matchM r s- return $ Matches s $ map (convertMatchText s) y-\end{code}
− Text/RE/Types/REOptions.lhs
@@ -1,94 +0,0 @@-\begin{code}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 800-{-# LANGUAGE TemplateHaskellQuotes #-}-#else-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}-#endif--module Text.RE.Types.REOptions where--import Data.Hashable-import qualified Data.HashMap.Strict as HM-import Data.String-import Language.Haskell.TH-import Language.Haskell.TH.Syntax-\end{code}--\begin{code}--- | the default API uses these simple, universal RE options,--- which get auto-converted into the apropriate 'REOptions_' actually--- as apropriate the chosen back end-data SimpleREOptions- = MultilineSensitive -- ^ case-sensitive with ^ and $ matching the start and end of a line- | MultilineInsensitive -- ^ case-insensitive with ^ and $ matsh the start and end of a line- | BlockSensitive -- ^ case-sensitive with ^ and $ matching the start and end of the input text- | BlockInsensitive -- ^ case-insensitive with ^ and $ matching the start and end of the input text- deriving (Bounded,Enum,Eq,Ord,Show)-\end{code}--\begin{code}--- | we need to use this in the quasi quoters to specify @SimpleREOptions@--- selected by the quasi quoter-instance Lift SimpleREOptions where- lift sro = case sro of- MultilineSensitive -> conE 'MultilineSensitive- MultilineInsensitive -> conE 'MultilineInsensitive- BlockSensitive -> conE 'BlockSensitive- BlockInsensitive -> conE 'BlockInsensitive-\end{code}--\begin{code}--- | the general options for an RE are dependent on which back end is--- being used and are parameterised over the @RE@ type for the back end,--- and its @CompOption@ and @ExecOption@ types (the compile-time and--- execution time options, respectively); each back end will define an--- @REOptions@ type that fills out these three type parameters with the--- apropriate types-data REOptions_ r c e =- REOptions- { optionsMacs :: !(Macros r) -- ^ the available TestBench RE macros- , optionsComp :: !c -- ^ the back end compile-time options- , optionsExec :: !e -- ^ the back end execution-time options- }- deriving (Show)-\end{code}--\begin{code}--- | a number of types can be used to encode @REOptions@, each of which--- can be made a member of this class.-class IsOption o r c e |- e -> r, c -> e , e -> c, r -> c, c -> r, r -> e where- -- | convert the @o@ type into an @REOptions r c e@- makeREOptions :: o -> REOptions_ r c e-\end{code}--\begin{code}--- | @MacroID@ is just a wrapped @String@ type with an @IsString@--- instance-newtype MacroID =- MacroID { getMacroID :: String }- deriving (IsString,Ord,Eq,Show)-\end{code}--\begin{code}--- | @MacroID@ is used with @HM.HashMap@ to build macro lookup tables-instance Hashable MacroID where- hashWithSalt i = hashWithSalt i . getMacroID-\end{code}--\begin{code}--- | our macro tables are parameterised over the backend @RE@ type and--- and just associate each @MacroID@ with an @RE@-type Macros r = HM.HashMap MacroID r-\end{code}--\begin{code}--- | a macro table containing no entries-emptyMacros :: Macros r-emptyMacros = HM.empty-\end{code}
− Text/RE/Types/Replace.lhs
@@ -1,505 +0,0 @@-\begin{code}-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}--module Text.RE.Types.Replace- ( Replace(..)- , ReplaceMethods(..)- , replaceMethods- , REContext(..)- , Location(..)- , isTopLocation- , replace- , replaceAll- , replaceAllCaptures- , replaceAllCaptures_- , replaceAllCapturesM- , replaceCaptures- , replaceCaptures_- , replaceCapturesM- , expandMacros- , expandMacros'- , templateCaptures- ) where--import Control.Applicative-import Data.Array-import qualified Data.ByteString.Char8 as B-import qualified Data.ByteString.Lazy.Char8 as LBS-import Data.Char-import qualified Data.Foldable as F-import Data.Functor.Identity-import qualified Data.HashMap.Strict as HM-import Data.Maybe-import Data.Monoid-import qualified Data.Sequence as S-import qualified Data.Text as T-import qualified Data.Text.Encoding as TE-import qualified Data.Text.Lazy as LT-import Prelude.Compat-import Text.RE.Types.Capture-import Text.RE.Types.CaptureID-import Text.RE.Types.Match-import Text.RE.Types.Matches-import Text.RE.Types.REOptions-import Text.Read-import Text.Regex.TDFA-import Text.Regex.TDFA.Text()-import Text.Regex.TDFA.Text.Lazy()-\end{code}---\begin{code}--- | Replace provides the missing methods needed to replace the matched--- text; lengthR is the minimum implementation-class (Show a,Eq a,Ord a,Extract a,Monoid a) => Replace a where- -- | length function for a- lengthR :: a -> Int- -- | inject String into a- packR :: String -> a- -- | project a onto a String- unpackR :: a -> String- -- | inject into Text- textifyR :: a -> T.Text- -- | project Text onto a- detextifyR :: T.Text -> a- -- | split into lines- linesR :: a -> [a]- -- | concatenate a list of lines- unlinesR :: [a] -> a- -- | append a newline- appendNewlineR :: a -> a- -- | apply a substitution function to a Capture- substR :: (a->a) -> Capture a -> a- -- | convert a template containing $0, $1, etc., in the first- -- argument, into a 'phi' replacement function for use with- -- replaceAllCaptures and replaceCaptures- parseTemplateR :: a -> Match a -> Location -> Capture a -> Maybe a-- textifyR = T.pack . unpackR- detextifyR = packR . T.unpack- appendNewlineR = (<> packR "\n")-- substR f m@Capture{..} =- capturePrefix m <> f capturedText <> captureSuffix m-\end{code}--\begin{code}--- | a selction of the Replace methods can be encapsulated with ReplaceMethods--- for the higher-order replacement functions-data ReplaceMethods a =- ReplaceMethods- { methodLength :: a -> Int- , methodSubst :: (a->a) -> Capture a -> a- }---- | replaceMethods encapsulates ReplaceMethods a from a Replace a context-replaceMethods :: Replace a => ReplaceMethods a-replaceMethods =- ReplaceMethods- { methodLength = lengthR- , methodSubst = substR- }-\end{code}--\begin{code}--- | @REContext@ specifies which contexts the substitutions should be applied-data REContext- = TOP -- ^ substitutions should be applied to the top-level only,- -- the text that matched the whole RE- | SUB -- ^ substitutions should only be applied to the text- -- captured by bracketed sub-REs- | ALL -- ^ the substitution function should be applied to all- -- captures, the top level and the sub-expression captures- deriving (Show)---- | the @Location@ information passed into the substitution function--- specifies which sub-expression is being substituted-data Location =- Location- { locationMatch :: Int- -- ^ the zero-based, i-th string to be matched,- -- when matching all strings, zero when only the- -- first string is being matched- , locationCapture :: CaptureOrdinal- -- ^ 0, when matching the top-level string- -- matched by the whole RE, 1 for the top-most,- -- left-most redex captured by bracketed- -- sub-REs, etc.- }- deriving (Show)-\end{code}--\begin{code}--- | True iff the location references a complete match--- (i.e., not a bracketed capture)-isTopLocation :: Location -> Bool-isTopLocation = (==0) . locationCapture-\end{code}--\begin{code}--- | replace all with a template, $0 for whole text, $1 for first--- capture, etc.-replaceAll :: Replace a- => a- -> Matches a- -> a-replaceAll tpl ac = replaceAllCaptures TOP (parseTemplateR tpl) ac-\end{code}--\begin{code}--- | substitutes using a function that takes the full Match--- context and returns the same replacement text as the _phi_phi--- context.-replaceAllCaptures :: Replace a- => REContext- -> (Match a->Location->Capture a->Maybe a)- -> Matches a- -> a-\end{code}--\begin{code}-replaceAllCaptures = replaceAllCaptures_ replaceMethods-\end{code}--\begin{code}--- | replaceAllCaptures_ is like like replaceAllCaptures but takes the--- Replace methods through the ReplaceMethods argument-replaceAllCaptures_ :: Extract a- => ReplaceMethods a- -> REContext- -> (Match a->Location->Capture a->Maybe a)- -> Matches a- -> a-replaceAllCaptures_ s ctx phi ac =- runIdentity $ replaceAllCapturesM s ctx (lift_phi phi) ac-\end{code}--\begin{code}--- | replaceAllCapturesM is just a monadically generalised version of--- replaceAllCaptures_-replaceAllCapturesM :: (Extract a,Monad m)- => ReplaceMethods a- -> REContext- -> (Match a->Location->Capture a->m (Maybe a))- -> Matches a- -> m a-replaceAllCapturesM r ctx phi_ Matches{..} =- replaceCapturesM r ALL phi $ Match matchesSource cnms arr- where- phi _ (Location _ i) = case arr_c!i of- Just caps -> phi_ caps . uncurry Location $ arr_i ! i- Nothing -> const $ return Nothing-- arr_c = listArray bds $- concat $- [ repl (rangeSize $ bounds $ matchArray cs) cs- | cs <- allMatches- ]-- arr_i = listArray bds j_ks-- arr = listArray bds $- [ arr_ ! k- | arr_ <- map matchArray allMatches- , k <- indices arr_- ]-- bds = (0,CaptureOrdinal $ length j_ks-1)-- j_ks =- [ (j,k)- | (j,arr_) <- zip [0..] $ map matchArray allMatches- , k <- indices arr_- ]-- repl 0 _ = []- repl n x = case ctx of- TOP -> Just x : replicate (n-1) Nothing- SUB -> Nothing : replicate (n-1) (Just x)- ALL -> replicate n $ Just x-- cnms = fromMaybe noCaptureNames $ listToMaybe $ map captureNames allMatches-\end{code}--\begin{code}--- | replace with a template containing $0 for whole text,--- $1 for first capture, etc.-replace :: Replace a- => a- -> Match a- -> a-replace tpl c = replaceCaptures TOP (parseTemplateR tpl) c-\end{code}--\begin{code}--- | substitutes using a function that takes the full Match--- context and returns the same replacement text as the _phi_phi--- context.-replaceCaptures :: Replace a- => REContext- -> (Match a->Location->Capture a->Maybe a)- -> Match a- -> a-replaceCaptures = replaceCaptures_ replaceMethods-\end{code}--\begin{code}--- | replaceCaptures_ is like replaceCaptures but takes the Replace methods--- through the ReplaceMethods argument-replaceCaptures_ :: Extract a- => ReplaceMethods a- -> REContext- -> (Match a->Location->Capture a->Maybe a)- -> Match a- -> a-replaceCaptures_ s ctx phi caps =- runIdentity $ replaceCapturesM s ctx (lift_phi phi) caps-\end{code}--\begin{code}--- | replaceCapturesM is just a monadically generalised version of--- replaceCaptures_-replaceCapturesM :: (Monad m,Extract a)- => ReplaceMethods a- -> REContext- -> (Match a->Location->Capture a->m (Maybe a))- -> Match a- -> m a-replaceCapturesM ReplaceMethods{..} ctx phi_ caps@Match{..} = do- (hay',_) <- foldr sc (return (matchSource,[])) $- zip [0..] $ elems matchArray- return hay'- where- sc (i,cap0) act = do- (hay,ds) <- act- let ndl = capturedText cap- cap = adj hay ds cap0- mb <- phi i cap- case mb of- Nothing -> return (hay,ds)- Just ndl' ->- return- ( methodSubst (const ndl') cap- , (captureOffset cap,len'-len) : ds- )- where- len' = methodLength ndl'- len = methodLength ndl-- adj hay ds cap =- Capture- { captureSource = hay- , capturedText = before len $ after off0 hay- , captureOffset = off0- , captureLength = len- }- where- len = len0 + sum- [ delta- | (off,delta) <- ds- , off < off0 + len0- ]- len0 = captureLength cap- off0 = captureOffset cap-- phi i cap = case ctx of- TOP | i/=0 -> return Nothing- SUB | i==0 ->return Nothing- _ ->- case not $ hasCaptured cap of- True -> return Nothing- False -> phi_ caps (Location 0 i) cap-\end{code}--\begin{code}--- the Replace instances--instance Replace [Char] where- lengthR = length- packR = id- unpackR = id- textifyR = T.pack- detextifyR = T.unpack- linesR = lines- unlinesR = unlines- appendNewlineR = (<>"\n")- parseTemplateR = parseTemplateR' id--instance Replace B.ByteString where- lengthR = B.length- packR = B.pack- unpackR = B.unpack- textifyR = TE.decodeUtf8- detextifyR = TE.encodeUtf8- linesR = B.lines- unlinesR = B.unlines- appendNewlineR = (<>"\n")- parseTemplateR = parseTemplateR' B.unpack--instance Replace LBS.ByteString where- lengthR = fromEnum . LBS.length- packR = LBS.pack- unpackR = LBS.unpack- textifyR = TE.decodeUtf8 . LBS.toStrict- linesR = LBS.lines- unlinesR = LBS.unlines- detextifyR = LBS.fromStrict . TE.encodeUtf8- appendNewlineR = (<>"\n")- parseTemplateR = parseTemplateR' LBS.unpack--instance Replace (S.Seq Char) where- lengthR = S.length- packR = S.fromList- unpackR = F.toList- linesR = map packR . lines . unpackR- unlinesR = packR . unlines . map unpackR- parseTemplateR = parseTemplateR' F.toList--instance Replace T.Text where- lengthR = T.length- packR = T.pack- unpackR = T.unpack- textifyR = id- detextifyR = id- linesR = T.lines- unlinesR = T.unlines- appendNewlineR = (<>"\n")- parseTemplateR = parseTemplateR' T.unpack--instance Replace LT.Text where- lengthR = fromEnum . LT.length- packR = LT.pack- unpackR = LT.unpack- textifyR = LT.toStrict- detextifyR = LT.fromStrict- linesR = LT.lines- unlinesR = LT.unlines- appendNewlineR = (<>"\n")- parseTemplateR = parseTemplateR' LT.unpack-\end{code}--\begin{code}--- | expand all of the @{..} macros in the RE in the argument String--- according to the Macros argument, preprocessing the RE String--- according to the Mode argument (used internally)-expandMacros :: (r->String) -> Macros r -> String -> String-expandMacros x_src hm s =- case HM.null hm of- True -> s- False -> expandMacros' (fmap x_src . flip HM.lookup hm) s-\end{code}--\begin{code}--- | expand the @{..} macos in the argument string using the given--- function-expandMacros' :: (MacroID->Maybe String) -> String -> String-expandMacros' lu = fixpoint e_m- where- e_m re_s = replaceAllCaptures TOP phi $ re_s $=~ "@(@|\\{([^{}]+)\\})"- where- phi mtch _ cap = case txt == "@@" of- True -> Just "@"- False -> Just $ fromMaybe txt $ lu ide- where- txt = capturedText cap- ide = MacroID $ capturedText $ capture c2 mtch- c2 = IsCaptureOrdinal $ CaptureOrdinal 2-\end{code}--\begin{code}-lift_phi :: Monad m- => (Match a->Location->Capture a->Maybe a)- -> (Match a->Location->Capture a->m (Maybe a))-lift_phi phi_ = phi- where- phi caps' loc' cap' = return $ phi_ caps' loc' cap'-\end{code}--\begin{code}--- | parse the replacement template in second argument, substititing--- the capture references with corresponding captures from the Match--- in the third argument (the result of a single match of the RE--- against the input text to be matched); Nothing is returned if the--- inputs are not well formed (currently all inputs are well formed)-parseTemplateR' :: ( Replace a- , RegexContext Regex a (Matches a)- , RegexMaker Regex CompOption ExecOption String- )- => (a->String)- -> a- -> Match a- -> Location- -> Capture a- -> Maybe a-parseTemplateR' unpack tpl mtch _ _ =- Just $ replaceAllCaptures TOP phi $ scan_template tpl- where- phi t_mtch _ _ = either Just this $ parse_template_capture unpack t_mtch-- this cid = capturedText <$> mtch !$? cid---- | list all of the CaptureID references in the replace template in--- the second argument-templateCaptures :: ( Replace a- , RegexContext Regex a (Matches a)- , RegexMaker Regex CompOption ExecOption String- )- => (a->String)- -> a- -> [CaptureID]-templateCaptures unpack tpl =- [ cid- | mtch <- allMatches $ scan_template tpl- , Right cid <- [parse_template_capture unpack mtch]- ]---- | parse a Match generated by acan_template, returning @Left "$")--- iff the capture reference is an escaped @$@ (i.e., @$$@)-parse_template_capture :: (a->String) -> Match a -> Either a CaptureID-parse_template_capture unpack t_mtch = case t_mtch !$? c2 of- Just cap -> case readMaybe stg of- Nothing -> Right $ IsCaptureName $ CaptureName $ T.pack stg- Just cn -> Right $ IsCaptureOrdinal $ CaptureOrdinal cn- where- stg = unpack $ capturedText cap- Nothing -> case s == "$" of- True -> Left t- False -> Right $ IsCaptureOrdinal $ CaptureOrdinal $ read s- where- s = unpack t- t = capturedText $ capture c1 t_mtch-- c1 = IsCaptureOrdinal $ CaptureOrdinal 1- c2 = IsCaptureOrdinal $ CaptureOrdinal 2---- | scan a replacement template, returning a Match for each capture--- reference in the template (like $1, ${foo})-scan_template :: ( Replace a- , RegexContext Regex a (Matches a)- , RegexMaker Regex CompOption ExecOption String- )- => a- -> Matches a-scan_template tpl = tpl $=~ "\\$(\\$|[0-9]|\\{([^{}]+)\\})"-\end{code}--\begin{code}-fixpoint :: (Eq a) => (a->a) -> a -> a-fixpoint f = chk . iterate f- where- chk (x:x':_) | x==x' = x- chk xs = chk $ tail xs-\end{code}--\begin{code}-($=~) :: ( RegexContext Regex source target- , RegexMaker Regex CompOption ExecOption String- )- => source -> String -> target-($=~) = (=~)-\end{code}
− Text/RE/Types/SearchReplace.hs
@@ -1,15 +0,0 @@--module Text.RE.Types.SearchReplace- ( SearchReplace(..)- ) where---- | contains a compiled RE and replacement template-data SearchReplace re s =- SearchReplace- { getSearch :: !re -- ^ the RE- , getTemplate :: !s -- ^ the replacement template- }- deriving (Show)--instance Functor (SearchReplace re) where- fmap f (SearchReplace re x) = SearchReplace re (f x)
+ Text/RE/ZeInternals/AddCaptureNames.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE OverloadedStrings #-}++module Text.RE.ZeInternals.AddCaptureNames where++import qualified Data.ByteString.Lazy.Char8 as LBS+import qualified Data.ByteString.Char8 as B+import Data.Dynamic+import Data.Maybe+import qualified Data.Sequence as S+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import Prelude.Compat+import Text.RE+import Text.RE.ZeInternals.Types.CaptureID+import Text.RE.ZeInternals.Types.Match+import Unsafe.Coerce+++-- | a convenience function used by the API modules to insert+-- capture names extracted from the parsed RE into the (*=~) result+addCaptureNamesToMatches :: CaptureNames -> Matches a -> Matches a+addCaptureNamesToMatches cnms mtchs =+ mtchs { allMatches = map (addCaptureNamesToMatch cnms) $ allMatches mtchs }++-- | a convenience function used by the API modules to insert+-- capture names extracted from the parsed RE into the (?=~) result+addCaptureNamesToMatch :: CaptureNames -> Match a -> Match a+addCaptureNamesToMatch cnms mtch = mtch { captureNames = cnms }++-- | a hairy dynamically-typed function used with the legacy (=~) and (=~~)+-- to see if it can/should add the capture names extracted from the RE+-- into the polymorphic result of the operator (it does for any Match+-- or Matches type, provided it is parameterised over a recognised type).+-- The test suite is all over this one, testing all of these cases.+addCaptureNames :: Typeable a => CaptureNames -> a -> a+addCaptureNames cnms x = fromMaybe x $ listToMaybe $ catMaybes+ [ test_match x ( proxy :: String )+ , test_matches x ( proxy :: String )+ , test_match x ( proxy :: B.ByteString )+ , test_matches x ( proxy :: B.ByteString )+ , test_match x ( proxy :: LBS.ByteString )+ , test_matches x ( proxy :: LBS.ByteString )+ , test_match x ( proxy :: T.Text )+ , test_matches x ( proxy :: T.Text )+ , test_match x ( proxy :: TL.Text )+ , test_matches x ( proxy :: TL.Text )+ , test_match x ( proxy :: S.Seq Char )+ , test_matches x ( proxy :: S.Seq Char )+ ]+ where+ test_match :: Typeable t => r -> t -> Maybe r+ test_match r t = f r t $ addCaptureNamesToMatch cnms <$> fromDynamic dyn+ where+ f :: r' -> t' -> Maybe (Match t') -> Maybe r'+ f _ _ = unsafeCoerce++ test_matches :: Typeable t => r -> t -> Maybe r+ test_matches r t = f r t $ addCaptureNamesToMatches cnms <$> fromDynamic dyn+ where+ f :: r' -> t' -> Maybe (Matches t') -> Maybe r'+ f _ _ = unsafeCoerce++ dyn :: Dynamic+ dyn = toDyn x++ proxy :: a+ proxy = error "addCaptureNames"
+ Text/RE/ZeInternals/EscapeREString.hs view
@@ -0,0 +1,29 @@+module Text.RE.ZeInternals.EscapeREString where++-- | Convert a string into a regular expression that will amtch that+-- string+escapeREString :: String -> String+escapeREString = foldr esc []+ where+ esc c t | isMetaChar c = '\\' : c : t+ | otherwise = c : t++-- | returns True iff the charactr is an RE meta character+-- ('[', '*', '{', etc.)+isMetaChar :: Char -> Bool+isMetaChar c = case c of+ '^' -> True+ '\\' -> True+ '.' -> True+ '|' -> True+ '*' -> True+ '?' -> True+ '+' -> True+ '(' -> True+ ')' -> True+ '[' -> True+ ']' -> True+ '{' -> True+ '}' -> True+ '$' -> True+ _ -> False
+ Text/RE/ZeInternals/NamedCaptures.lhs view
@@ -0,0 +1,230 @@+\begin{code}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 800+{-# LANGUAGE TemplateHaskellQuotes #-}+#else+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+#endif++module Text.RE.ZeInternals.NamedCaptures+ ( cp+ , extractNamedCaptures+ , idFormatTokenREOptions+ , Token(..)+ , validToken+ , formatTokens+ , formatTokens'+ , formatTokens0+ , scan+ ) where++import Data.Char+import qualified Data.HashMap.Strict as HM+import qualified Data.Text as T+import GHC.Generics+import qualified Language.Haskell.TH as TH+import Language.Haskell.TH.Quote+import Text.RE+import Text.RE.ZeInternals.PreludeMacros+import Text.RE.ZeInternals.QQ+import Text.RE.ZeInternals.TestBench+import Text.RE.Tools.Lex+import Text.RE.ZeInternals.Types.CaptureID+import Text.RE.ZeInternals.Types.Match+import Text.Regex.TDFA+++-- | quasi quoter for CaptureID ([cp|0|],[cp|y|], etc.)+cp :: QuasiQuoter+cp =+ (qq0 "cp")+ { quoteExp = parse_capture+ }++-- | extract the CaptureNames from an RE or return an error diagnostic+-- if the RE is not well formed; also returs the total number of captures+-- in the RE+extractNamedCaptures :: String -> Either String ((Int,CaptureNames),String)+extractNamedCaptures s = Right (analyseTokens tks,formatTokens tks)+ where+ tks = scan s+\end{code}+++Token+-----++\begin{code}+-- | our RE scanner returns a list of these tokens+data Token+ = ECap (Maybe String)+ | PGrp+ | PCap+ | Bra+ | BS Char+ | Other Char+ deriving (Show,Generic,Eq)++-- | check that a token is well formed+validToken :: Token -> Bool+validToken tkn = case tkn of+ ECap mb -> maybe True check_ecap mb+ PGrp -> True+ PCap -> True+ Bra -> True+ BS c -> is_dot c+ Other c -> is_dot c+ where+ check_ecap s = not (null s) && all not_br s+ is_dot c = c/='\n'+ not_br c = not $ c `elem` "{}\n"++\end{code}+++Analysing [Token] -> CaptureNames+---------------------------------++\begin{code}+-- | analyse a token stream, returning the number of captures and the+-- 'CaptureNames'+analyseTokens :: [Token] -> (Int,CaptureNames)+analyseTokens tks0 = case count_em 1 tks0 of+ (n,as) -> (n-1, HM.fromList as)+ where+ count_em n [] = (n,[])+ count_em n (tk:tks) = case count_em (n `seq` n+d) tks of+ (n',as) -> (n',bd++as)+ where+ (d,bd) = case tk of+ ECap (Just nm) -> (,) 1 [(CaptureName $ T.pack nm,CaptureOrdinal n)]+ ECap Nothing -> (,) 1 []+ PGrp -> (,) 0 []+ PCap -> (,) 1 []+ Bra -> (,) 1 []+ BS _ -> (,) 0 []+ Other _ -> (,) 0 []+\end{code}+++Scanning Regex Strings+----------------------++\begin{code}+-- | scan a RE string into a list of RE Token+scan :: String -> [Token]+scan = alex' match al oops+ where+ al :: [(Regex,Match String->Maybe Token)]+ al =+ [ mk "\\$\\{([^{}]+)\\}\\(" $ ECap . Just . x_1+ , mk "\\$\\(" $ const $ ECap Nothing+ , mk "\\(\\?:" $ const PGrp+ , mk "\\(\\?" $ const PCap+ , mk "\\(" $ const Bra+ , mk "\\\\(.)" $ BS . s2c . x_1+ , mk "(.)" $ Other . s2c . x_1+ ]++ x_1 = captureText $ IsCaptureOrdinal $ CaptureOrdinal 1++ s2c [c] = c+ s2c _ = error "scan:s2c:internal error"++ mk s f = (either error id $ makeRegexM s,Just . f)++ oops = error "reScanner"+\end{code}+++Parsing captures+----------------++\begin{code}+parse_capture :: String -> TH.Q TH.Exp+parse_capture s = case all isDigit s of+ True -> [|IsCaptureOrdinal $ CaptureOrdinal $ read s|]+ False -> [|IsCaptureName $ CaptureName $ T.pack s|]+\end{code}+++Formatting [Token]+------------------++\begin{code}+-- | format [Token] into an RE string+formatTokens :: [Token] -> String+formatTokens = formatTokens' defFormatTokenREOptions++-- | options for the general Token formatter below+data FormatTokenREOptions =+ FormatTokenREOptions+ { _fto_regex_type :: Maybe RegexType -- ^ Posix, PCRE or indeterminate REs?+ , _fto_min_caps :: Bool -- ^ remove captures where possible+ , _fto_incl_caps :: Bool -- ^ include the captures in the output+ }+ deriving (Show)++-- | the default configuration for the Token formatter+defFormatTokenREOptions :: FormatTokenREOptions+defFormatTokenREOptions =+ FormatTokenREOptions+ { _fto_regex_type = Nothing+ , _fto_min_caps = False+ , _fto_incl_caps = False+ }++-- | a configuration that will preserve the parsed regular expression+-- in the output+idFormatTokenREOptions :: FormatTokenREOptions+idFormatTokenREOptions =+ FormatTokenREOptions+ { _fto_regex_type = Nothing+ , _fto_min_caps = False+ , _fto_incl_caps = True+ }++-- | the general Token formatter, generating REs according to the options+formatTokens' :: FormatTokenREOptions -> [Token] -> String+formatTokens' FormatTokenREOptions{..} = foldr f ""+ where+ f tk tl = t_s ++ tl+ where+ t_s = case tk of+ ECap mb -> ecap mb+ PGrp -> if maybe False isTDFA _fto_regex_type then "(" else "(?:"+ PCap -> "(?"+ Bra -> bra _fto_min_caps+ BS c -> "\\" ++ [c]+ Other c -> [c]++ ecap mb = case _fto_incl_caps of+ True -> case mb of+ Nothing -> "$("+ Just nm -> "${"++nm++"}("+ False -> bra _fto_min_caps++ bra mc = case mc && maybe False isPCRE _fto_regex_type of+ True -> "(?:"+ False -> "("+\end{code}++\begin{code}+-- this is a reference of formatTokens defFormatTokenREOptions,+-- used for testing the latter+formatTokens0 :: [Token] -> String+formatTokens0 = foldr f ""+ where+ f tk tl = t_s ++ tl+ where+ t_s = case tk of+ ECap _ -> "("+ PGrp -> "(?:"+ PCap -> "(?"+ Bra -> "("+ BS c -> "\\" ++ [c]+ Other c -> [c]+\end{code}
+ Text/RE/ZeInternals/PreludeMacros.hs view
@@ -0,0 +1,909 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 800+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}+#endif++module Text.RE.ZeInternals.PreludeMacros+ ( RegexType+ , WithCaptures(..)+ , MacroDescriptor(..)+ , RegexSource(..)+ , PreludeMacro(..)+ , presentPreludeMacro+ , preludeMacros+ , preludeMacroTable+ , preludeMacroSummary+ , preludeMacroSources+ , preludeMacroSource+ , preludeMacroEnv+ , preludeMacroDescriptor+ ) where++import Data.Array+import qualified Data.HashMap.Lazy as HML+import Data.List+import Data.Maybe+import qualified Data.Text as T+import Data.Time+import Prelude.Compat+import Text.RE.TestBench+import Text.RE.ZeInternals.TestBench+import Text.RE.REOptions+++-- | generate the standard prelude Macros used to parse REs+preludeMacros :: (Monad m,Functor m)+ => (String->m r)+ -> RegexType+ -> WithCaptures+ -> m (Macros r)+preludeMacros prs rty wc = mkMacros prs rty wc $ preludeMacroEnv rty++-- | format the standard prelude macros in a markdown table+preludeMacroTable :: RegexType -> String+preludeMacroTable rty = formatMacroTable rty $ preludeMacroEnv rty++-- | generate a textual summary of the prelude macros+preludeMacroSummary :: RegexType -> PreludeMacro -> String+preludeMacroSummary rty =+ formatMacroSummary rty (preludeMacroEnv rty) . prelude_macro_id++-- | generate a plain text table giving the RE for each macro with all+-- macros expanded (to NF)+preludeMacroSources :: RegexType -> String+preludeMacroSources rty =+ formatMacroSources rty ExclCaptures $ preludeMacroEnv rty++-- | generate plain text giving theexpanded RE for a single macro+preludeMacroSource :: RegexType -> PreludeMacro -> String+preludeMacroSource rty =+ formatMacroSource rty ExclCaptures (preludeMacroEnv rty) . prelude_macro_id++-- | generate the `MacroEnv` for the standard prelude macros+preludeMacroEnv :: RegexType -> MacroEnv+preludeMacroEnv rty = fix $ prelude_macro_env rty++prelude_macro_env :: RegexType -> MacroEnv -> MacroEnv+prelude_macro_env rty env = HML.fromList $ catMaybes+ [ (,) (prelude_macro_id pm) <$> preludeMacroDescriptor rty env pm+ | pm<-[minBound..maxBound]+ ]++-- | generate the `MacroDescriptor` for a given `PreludeMacro`+preludeMacroDescriptor :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+preludeMacroDescriptor rty env pm = case pm of+ PM_nat -> natural_macro rty env pm+ PM_hex -> natural_hex_macro rty env pm+ PM_int -> integer_macro rty env pm+ PM_frac -> decimal_macro rty env pm+ PM_string -> string_macro rty env pm+ PM_string_simple -> string_simple_macro rty env pm+ PM_id -> id_macro rty env pm+ PM_id' -> id'_macro rty env pm+ PM_id_ -> id__macro rty env pm+ PM_date -> date_macro rty env pm+ PM_date_slashes -> date_slashes_macro rty env pm+ PM_time -> time_macro rty env pm+ PM_timezone -> timezone_macro rty env pm+ PM_datetime -> datetime_macro rty env pm+ PM_datetime_8601 -> datetime_8601_macro rty env pm+ PM_datetime_clf -> datetime_clf_macro rty env pm+ PM_shortmonth -> shortmonth_macro rty env pm+ PM_address_ipv4 -> address_ipv4_macros rty env pm+ PM_email_simple -> email_simple_macro rty env pm+ PM_url -> url_macro rty env pm+ PM_syslog_severity -> syslog_severity_macro rty env pm++-- | an enumeration of all of the prelude macros+data PreludeMacro+ -- numbers+ = PM_nat+ | PM_hex+ | PM_int+ | PM_frac+ -- strings+ | PM_string+ | PM_string_simple+ -- identifiers+ | PM_id+ | PM_id'+ | PM_id_+ -- dates & times+ | PM_date+ | PM_date_slashes+ | PM_time+ | PM_timezone+ | PM_datetime+ | PM_datetime_8601+ | PM_datetime_clf+ | PM_shortmonth+ -- addresses+ | PM_address_ipv4+ | PM_email_simple+ | PM_url+ -- syslog+ | PM_syslog_severity+ deriving (Bounded,Enum,Ord,Eq,Show)++-- | naming the macros+presentPreludeMacro :: PreludeMacro -> String+presentPreludeMacro pm = case pm of+ PM_id_ -> prelude_prefix++"id-"+ _ -> fmt pm+ where+ fmt = (prelude_prefix++) . map tr . drop 3 . show++ tr '_' = '.'+ tr c = c++-- | all prelude macros are prefixed with this+prelude_prefix :: String+prelude_prefix = "%"++prelude_macro_id :: PreludeMacro -> MacroID+prelude_macro_id = MacroID . presentPreludeMacro++natural_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor+natural_macro rty env pm = Just $ run_tests rty parseInteger samples env pm+ MacroDescriptor+ { macroSource = "[0-9]+"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseInteger"+ , macroDescription = "a string of one or more decimal digits"+ }+ where+ samples :: [(String,Int)]+ samples =+ [ (,) "0" 0+ , (,) "1234567890" 1234567890+ , (,) "00" 0+ , (,) "01" 1+ ]++ counter_samples =+ [ ""+ , "0A"+ , "-1"+ ]++natural_hex_macro :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+natural_hex_macro rty env pm = Just $ run_tests rty parseHex samples env pm+ MacroDescriptor+ { macroSource = "[0-9a-fA-F]+"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseHex"+ , macroDescription = "a string of one or more hexadecimal digits"+ }+ where+ samples :: [(String,Int)]+ samples =+ [ (,) "0" 0x0+ , (,) "12345678" 0x12345678+ , (,) "0abcdef" 0xabcdef+ , (,) "0ABCDEF" 0xabcdef+ , (,) "00" 0x0+ , (,) "010" 0x10+ ]++ counter_samples =+ [ ""+ , "0x10"+ , "0z"+ , "-1a"+ ]++integer_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor+integer_macro rty env pm = Just $ run_tests rty parseInteger samples env pm+ MacroDescriptor+ { macroSource = "-?[0-9]+"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseInteger"+ , macroDescription = "a decimal integer"+ }+ where+ samples :: [(String,Int)]+ samples =+ [ (,) "0" 0+ , (,) "1234567890" 1234567890+ , (,) "00" 0+ , (,) "01" 1+ , (,) "-1" $ -1+ , (,) "-0" 0+ ]++ counter_samples =+ [ ""+ , "0A"+ , "+0"+ ]++-- | a digit string macro+decimal_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor+decimal_macro rty env pm = Just $ run_tests rty parseDouble samples env pm+ MacroDescriptor+ { macroSource = "-?[0-9]+(?:\\.[0-9]+)?"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseInteger"+ , macroDescription = "a decimal integer"+ }+ where+ samples :: [(String,Double)]+ samples =+ [ (,) "0" 0+ , (,) "1234567890" 1234567890+ , (,) "00" 0+ , (,) "01" 1+ , (,) "-1" $ -1+ , (,) "-0" 0+ , (,) "0.1234567890" 0.1234567890+ , (,) "-1.0" $ -1.0+ ]++ counter_samples =+ [ ""+ , "0A"+ , "+0"+ , "0."+ , ".0"+ , "."+ , "-"+ , "-."+ , "-1."+ , "-.1"+ ]++string_macro :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+string_macro rty env pm+ | isPCRE rty = Nothing+ | otherwise =+ Just $ run_tests rty (fmap T.unpack . parseString) samples env pm+ MacroDescriptor+ { macroSource = "\"(?:[^\"\\]+|\\\\[\\\"])*\""+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseString"+ , macroDescription = "a double-quote string, with simple \\ escapes for \\s and \"s"+ }+ where+ samples :: [(String,String)]+ samples =+ [ (,) "\"\"" ""+ , (,) "\"foo\"" "foo"+ , (,) "\"\\\"\"" "\""+ , (,) "\"\\\"\\\"\"" "\"\""+ , (,) "\"\\\"\\\\\\\"\"" "\"\\\""+ , (,) "\"\\\"foo\\\"\"" "\"foo\""+ , (,) "\"\"" ""+ ]++ counter_samples =+ [ "\""+ , "\"aa"+ ]++string_simple_macro :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+string_simple_macro rty env pm =+ Just $ run_tests rty (fmap T.unpack . parseSimpleString) samples env pm+ MacroDescriptor+ { macroSource = "\"[^\"[:cntrl:]]*\""+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseSimpleString"+ , macroDescription = "a decimal integer"+ }+ where+ samples :: [(String,String)]+ samples =+ [ (,) "\"\"" ""+ , (,) "\"foo\"" "foo"+ , (,) "\"\\\"" "\\"+ , (,) "\"\"" ""+ ]++ counter_samples =+ [ ""+ , "\""+ , "\"\\\"\""+ , "\"\\\"\\\"\""+ , "\"\\\"\\\\\\\"\""+ , "\"\\\"foo\\\"\""+ , "\"aa"+ ]++id_macro :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+id_macro rty env pm =+ Just $ run_tests rty Just samples env pm+ MacroDescriptor+ { macroSource = "_*[a-zA-Z][a-zA-Z0-9_]*"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Nothing+ , macroDescription = "a standard C-style alphanumeric identifier (with _s)"+ }+ where+ samples :: [(String,String)]+ samples =+ [ f "a"+ , f "A"+ , f "A1"+ , f "a_"+ , f "a1_B2"+ , f "_abc"+ , f "__abc"+ ]+ where+ f s = (s,s)++ counter_samples =+ [ ""+ , "1"+ , "_"+ , "__"+ , "__1"+ , "1a"+ , "a'"+ ]++id'_macro :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+id'_macro rty env pm =+ Just $ run_tests rty Just samples env pm+ MacroDescriptor+ { macroSource = "_*[a-zA-Z][a-zA-Z0-9_']*"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Nothing+ , macroDescription = "a standard Haskell-style alphanumeric identifier (with '_'s and '''s)"+ }+ where+ samples :: [(String,String)]+ samples =+ [ f "a"+ , f "A"+ , f "A1"+ , f "a_"+ , f "a1_B2"+ , f "_abc"+ , f "__abc"+ , f "a'"+ , f "_a'"+ , f "a'b"+ ]+ where+ f s = (s,s)++ counter_samples =+ [ ""+ , "1"+ , "_"+ , "__"+ , "__1"+ , "1a"+ , "'"+ , "'a"+ , "_'"+ , "_1'"+ ]++id__macro :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+id__macro rty env pm =+ Just $ run_tests rty Just samples env pm+ MacroDescriptor+ { macroSource = "_*[a-zA-Z][a-zA-Z0-9_'-]*"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Nothing+ , macroDescription = "an identifier with -s"+ }+ where+ samples :: [(String,String)]+ samples =+ [ f "a"+ , f "A"+ , f "A1"+ , f "a_"+ , f "a1_B2"+ , f "_abc"+ , f "__abc"+ , f "a'"+ , f "_a'"+ , f "a'b"+ , f "a-"+ , f "a1-B2"+ , f "a1-B2-"+ ]+ where+ f s = (s,s)++ counter_samples =+ [ ""+ , "1"+ , "_"+ , "__"+ , "__1"+ , "1a"+ , "'"+ , "'a"+ , "_'"+ , "_1'"+ ]++date_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor+date_macro rty env pm =+ Just $ run_tests rty parseDate samples env pm+ MacroDescriptor+ { macroSource = "[0-9]{4}-[0-9]{2}-[0-9]{2}"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseDate"+ , macroDescription = "a YYYY-MM-DD format date"+ }+ where+ samples :: [(String,Day)]+ samples =+ [ f "2016-12-31"+ , f "0001-01-01"+ , f "1000-01-01"+ ]+ where+ f s = (s,read s)++ counter_samples =+ [ ""+ , "2016/01/31"+ , "2016-1-31"+ , "2016-01-1"+ , "2016-001-01"+ ]++date_slashes_macro :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+date_slashes_macro rty env pm =+ Just $ run_tests rty parseSlashesDate samples env pm+ MacroDescriptor+ { macroSource = "[0-9]{4}/[0-9]{2}/[0-9]{2}"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseSlashesDate"+ , macroDescription = "a YYYY/MM/DD format date"+ }+ where+ samples :: [(String,Day)]+ samples =+ [ f "2016/12/31"+ , f "0001/01/01"+ , f "1000/01/01"+ ]+ where+ f s = (s,read $ map tr s)+ where+ tr '/' = '-'+ tr c = c++ counter_samples =+ [ ""+ , "2016-01-31"+ , "2016/1/31"+ , "2016/01/1"+ , "2016/001/01"+ ]++time_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor+time_macro rty env pm =+ Just $ run_tests rty parseTimeOfDay samples env pm+ MacroDescriptor+ { macroSource = "[0-9]{2}:[0-9]{2}:[0-9]{2}(?:[.][0-9]+)?"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseTimeOfDay"+ , macroDescription = "a HH:MM:SS[.Q+]"+ }+ where+ samples :: [(String,TimeOfDay)]+ samples =+ [ f "00:00:00" 00 00 0+ , f "23:59:59" 23 59 59+ , f "00:00:00.1234567890" 00 00 $ 123456789 / 1000000000+ ]+ where+ f s h m ps = (s,TimeOfDay h m ps)++ counter_samples =+ [ ""+ , "235959"+ , "10:20"+ , "A00:00:00"+ , "00:00:00A"+ , "23:59:59."+ ]++timezone_macro :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+timezone_macro rty env pm =+ Just $ run_tests rty parseTimeZone samples env pm+ MacroDescriptor+ { macroSource = "(?:Z|[+-][0-9]{2}:?[0-9]{2})"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseTimeZone"+ , macroDescription = "an IOS-8601 TZ specification"+ }+ where+ samples :: [(String,TimeZone)]+ samples =+ [ f "Z" $ minutesToTimeZone 0+ , f "+00:00" $ minutesToTimeZone 0+ , f "+0000" $ minutesToTimeZone 0+ , f "+0200" $ minutesToTimeZone 120+ , f "-0100" $ minutesToTimeZone $ -60+ ]+ where+ f = (,)++ counter_samples =+ [ ""+ , "00"+ , "A00:00"+ , "UTC"+ , "EST"+ , " EST"+ ]++datetime_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor+datetime_macro rty env pm = Just $ run_tests rty parseDateTime samples env pm+ MacroDescriptor+ { macroSource = "@{%date}[ T]@{%time}(?:@{%timezone}| UTC)?"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseDateTime"+ , macroDescription = "ISO-8601 format date and time + simple variants"+ }+ where+ samples :: [(String,UTCTime)]+ samples =+ [ f "2016-12-31 23:37:22.525343 UTC" "2016-12-31 23:37:22.525343Z"+ , f "2016-12-31 23:37:22.525343" "2016-12-31 23:37:22.525343Z"+ , f "2016-12-31 23:37:22" "2016-12-31 23:37:22Z"+ , f "2016-12-31T23:37:22+0100" "2016-12-31 23:37:22+0100"+ , f "2016-12-31T23:37:22-01:00" "2016-12-31 23:37:22-0100"+ , f "2016-12-31T23:37:22-23:59" "2016-12-31 23:37:22-2359"+ , f "2016-12-31T23:37:22Z" "2016-12-31 23:37:22Z"+ ]+ where+ f :: String -> String -> (String,UTCTime)+ f s r_s = (s,read r_s)++ counter_samples =+ [ ""+ , "2016-12-31 23:37:22.525343 EST"+ ]++datetime_8601_macro :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+datetime_8601_macro rty env pm =+ Just $ run_tests rty parseDateTime samples env pm+ MacroDescriptor+ { macroSource = "@{%date}T@{%time}@{%timezone}"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseDateTime8601"+ , macroDescription = "YYYY-MM-DDTHH:MM:SS[.Q*](Z|[+-]HHMM) format date and time"+ }+ where+ samples :: [(String,UTCTime)]+ samples =+ [ f "2016-12-31T23:37:22.343Z" "2016-12-31 23:37:22.343Z"+ , f "2016-12-31T23:37:22-0100" "2016-12-31 23:37:22-0100"+ , f "2016-12-31T23:37:22+23:59" "2016-12-31 23:37:22+2359"+ ]+ where+ f :: String -> String -> (String,UTCTime)+ f s r_s = (s,read r_s)++ counter_samples =+ [ ""+ , "2016-12-31 23:37:22.525343 EST"+ ]++datetime_clf_macro :: RegexType -> MacroEnv -> PreludeMacro -> Maybe MacroDescriptor+datetime_clf_macro rty env pm =+ Just $ run_tests rty parseDateTimeCLF samples env pm+ MacroDescriptor+ { macroSource = re+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseDateTimeCLF"+ , macroDescription = "Common Log Format date+time: %d/%b/%Y:%H:%M:%S %z"+ }+ where+ samples :: [(String,UTCTime)]+ samples =+ [ f "10/Oct/2000:13:55:36 -0700" "2000-10-10 13:55:36-0700"+ , f "10/Oct/2000:13:55:36 +07:00" "2000-10-10 13:55:36+0700"+ ]+ where+ f :: String -> String -> (String,UTCTime)+ f s r_s = (s,read r_s)++ counter_samples =+ [ ""+ , "2016-12-31T23:37+0100"+ , "10/Oct/2000:13:55:36-0700"+ , "10/OCT/2000:13:55:36 -0700"+ , "10/Oct/2000:13:55 -0700"+ , "10/Oct/2000:13:55Z"+ ]++ re = RegexSource $ unwords+ [ "[0-9]{2}/@{%shortmonth}/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2}"+ , "[+-][0-9]{2}:?[0-9]{2}"+ ]++shortmonth_macro :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+shortmonth_macro rty env pm =+ Just $ run_tests rty parseShortMonth samples env pm+ MacroDescriptor+ { macroSource = bracketedRegexSource $+ intercalate "|" $ map T.unpack $ elems shortMonthArray+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseShortMonth"+ , macroDescription = "three letter month name: Jan-Dec"+ }+ where+ samples :: [(String,Int)]+ samples =+ [ f "Jan" 1+ , f "Feb" 2+ , f "Dec" 12+ ]+ where+ f = (,)++ counter_samples =+ [ ""+ , "jan"+ , "DEC"+ , "January"+ , "01"+ , "1"+ ]++address_ipv4_macros :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+address_ipv4_macros rty env pm =+ Just $ run_tests rty parseIPv4Address samples env pm+ MacroDescriptor+ { macroSource = "[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseSeverity"+ , macroDescription = "an a.b.c.d IPv4 address"+ }+ where+ samples :: [(String,IPV4Address)]+ samples =+ [ f "0.0.0.0" ( 0, 0, 0, 0)+ , f "123.45.6.78" (123, 45, 6, 78)+ , f "9.9.9.9" ( 9, 9, 9, 9)+ , f "255.255.255.255" (255,255,255,255)+ ]+ where+ f = (,)++ counter_samples =+ [ ""+ , "foo"+ , "1234.0.0.0"+ , "1.2.3"+ , "1.2.3."+ , "1.2..4"+ , "www.example.com"+ , "2001:0db8:85a3:0000:0000:8a2e:0370:7334"+ ]++syslog_severity_macro :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+syslog_severity_macro rty env pm =+ Just $ run_tests rty parseSeverity samples env pm+ MacroDescriptor+ { macroSource = re+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Just "parseSeverity"+ , macroDescription = "syslog severity keyword (debug-emerg)"+ }+ where+ samples :: [(String,Severity)]+ samples =+ [ f "emerg" Emerg+ , f "panic" Emerg+ , f "alert" Alert+ , f "crit" Crit+ , f "err" Err+ , f "error" Err+ , f "warn" Warning+ , f "warning" Warning+ , f "notice" Notice+ , f "info" Info+ , f "debug" Debug+ ]+ where+ f = (,)++ counter_samples =+ [ ""+ , "Emergency"+ , "ALERT"+ ]++ re = if isPCRE rty+ then re_pcre+ else re_tdfa++ re_tdfa = bracketedRegexSource $+ intercalate "|" $+ [ T.unpack kw+ | (kw0,kws) <- map severityKeywords [minBound..maxBound]+ , kw <- kw0:kws+ ]++ re_pcre = bracketedRegexSource $+ intercalate "|" $+ [ T.unpack kw+ | (kw0,kws) <- map severityKeywords $+ filter (/=Err) [minBound..maxBound]+ , kw <- kw0:kws+ ] ++ ["err(?:or)?"]++email_simple_macro :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+email_simple_macro rty env pm =+ Just $ run_tests rty Just samples env pm+ MacroDescriptor+ { macroSource = "[a-zA-Z0-9%_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9.-]+"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Nothing+ , macroDescription = "an email address"+ }+ where+ samples :: [(String,String)]+ samples =+ [ f "user-name%foo.bar.com@an-example.com"+ ]+ where+ f s = (s,s)++ counter_samples =+ [ ""+ , "not-an-email-address"+ , "@not-an-email-address"+ ]+-- | see https://mathiasbynens.be/demo/url-regex+-- (based on @stephenhay URL)+url_macro :: RegexType+ -> MacroEnv+ -> PreludeMacro+ -> Maybe MacroDescriptor+url_macro rty env pm =+ Just $ run_tests rty Just samples env pm+ MacroDescriptor+ { macroSource = "([hH][tT][tT][pP][sS]?|[fF][tT][pP])://[^[:space:]/$.?#].[^[:space:]]*"+ , macroSamples = map fst samples+ , macroCounterSamples = counter_samples+ , macroTestResults = []+ , macroParser = Nothing+ , macroDescription = "a URL"+ }+ where+ samples :: [(String,String)]+ samples =+ [ f "https://mathiasbynens.be/demo/url-regex"+ , f "http://foo.com/blah_blah"+ , f "http://foo.com/blah_blah/"+ , f "http://foo.com/blah_blah_(wikipedia)"+ , f "http://foo.com/blah_blah_(wikipedia)_(again)"+ , f "http://www.example.com/wpstyle/?p=364"+ , f "HTTPS://foo.bar/?q=Test%20URL-encoded%20stuff"+ , f "HTTP://223.255.255.254"+ , f "ftp://223.255.255.254"+ , f "FTP://223.255.255.254"+ ]+ where+ f s = (s,s)++ counter_samples =+ [ ""+ , "http://"+ , "http://."+ , "http://.."+ , "http://../"+ , "http://?"+ , "http://??"+ , "http://foo.bar?q=Spaces should be encoded"+ , "//"+ , "http://##/"+ , "http://##"+ , "http://##/"+ ]++run_tests :: (Eq a,Show a)+ => RegexType+ -> (String->Maybe a)+ -> [(String,a)]+ -> MacroEnv+ -> PreludeMacro+ -> MacroDescriptor+ -> MacroDescriptor+run_tests rty parser vector env =+ runTests rty parser vector env . prelude_macro_id++bracketedRegexSource :: String -> RegexSource+bracketedRegexSource re_s = RegexSource $ "(?:" ++ re_s ++ ")"++fix :: (a->a) -> a+fix f = f (fix f)
+ Text/RE/ZeInternals/QQ.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE DeriveDataTypeable #-}++module Text.RE.ZeInternals.QQ where++import Control.Exception+import Data.Typeable+import Language.Haskell.TH.Quote+++-- | used to throw an exception reporting an abuse of a quasi quoter+data QQFailure =+ QQFailure+ { _qqf_context :: String -- ^ in what context was the quasi quoter used+ , _qqf_component :: String -- ^ how was the quasi quoter being abused+ }+ deriving (Show,Typeable)++instance Exception QQFailure where++-- | a quasi quoter that can be used in no context (to be extended with+-- the appropriate quasi quoter parser)+qq0 :: String -> QuasiQuoter+qq0 ctx =+ QuasiQuoter+ { quoteExp = const $ throw $ QQFailure ctx "expression"+ , quotePat = const $ throw $ QQFailure ctx "pattern"+ , quoteType = const $ throw $ QQFailure ctx "type"+ , quoteDec = const $ throw $ QQFailure ctx "declaration"+ }
+ Text/RE/ZeInternals/Replace.lhs view
@@ -0,0 +1,538 @@+\begin{code}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}++module Text.RE.ZeInternals.Replace+ (+ -- * REContext and RELocation+ REContext(..)+ , RELocation(..)+ , isTopLocation+ -- * replaceAll+ , replaceAll+ , replaceAllCaptures+ , replaceAllCaptures_+ , replaceAllCapturesM+ -- * replace+ , replace+ , replaceCaptures+ , replaceCaptures_+ , replaceCapturesM+ -- * expandMacros+ , expandMacros+ , expandMacros'+ -- * templateCaptures+ , templateCaptures+ -- * Replace and ReplaceMethods+ , Replace(..)+ , ReplaceMethods(..)+ , replaceMethods+ ) where++import Control.Applicative+import Data.Array+import qualified Data.ByteString.Char8 as B+import qualified Data.ByteString.Lazy.Char8 as LBS+import Data.Char+import qualified Data.Foldable as F+import Data.Functor.Identity+import qualified Data.HashMap.Strict as HM+import Data.Maybe+import Data.Monoid+import qualified Data.Sequence as S+import qualified Data.Text as T+import qualified Data.Text.Encoding as TE+import qualified Data.Text.Lazy as LT+import Prelude.Compat+import Text.RE.ZeInternals.Types.Capture+import Text.RE.ZeInternals.Types.CaptureID+import Text.RE.ZeInternals.Types.Match+import Text.RE.ZeInternals.Types.Matches+import Text.RE.REOptions+import Text.Read+import Text.Regex.TDFA+import Text.Regex.TDFA.Text()+import Text.Regex.TDFA.Text.Lazy()+\end{code}+++ReContext and RELocation+------------------------++\begin{code}+-- | @REContext@ specifies which contexts the substitutions should be applied+data REContext+ = TOP -- ^ substitutions should be applied to the top-level only,+ -- the text that matched the whole RE+ | SUB -- ^ substitutions should only be applied to the text+ -- captured by bracketed sub-REs+ | ALL -- ^ the substitution function should be applied to all+ -- captures, the top level and the sub-expression captures+ deriving (Show)++-- | the @RELocation@ information passed into the substitution function+-- specifies which sub-expression is being substituted+data RELocation =+ RELocation+ { locationMatch :: Int+ -- ^ the zero-based, i-th string to be matched,+ -- when matching all strings, zero when only the+ -- first string is being matched+ , locationCapture :: CaptureOrdinal+ -- ^ 0, when matching the top-level string+ -- matched by the whole RE, 1 for the top-most,+ -- left-most redex captured by bracketed+ -- sub-REs, etc.+ }+ deriving (Show)+\end{code}++\begin{code}+-- | True iff the location references a complete match+-- (i.e., not a bracketed capture)+isTopLocation :: RELocation -> Bool+isTopLocation = (==0) . locationCapture+\end{code}++\begin{code}+-- | replace all with a template, $0 for whole text, $1 for first+-- capture, etc.+replaceAll :: Replace a+ => a+ -> Matches a+ -> a+replaceAll tpl ac = replaceAllCaptures TOP (parseTemplateR tpl) ac+\end{code}++\begin{code}+-- | substitutes using a function that takes the full Match+-- context and returns the same replacement text as the _phi_phi+-- context.+replaceAllCaptures :: Replace a+ => REContext+ -> (Match a->RELocation->Capture a->Maybe a)+ -> Matches a+ -> a+\end{code}++\begin{code}+replaceAllCaptures = replaceAllCaptures_ replaceMethods+\end{code}++\begin{code}+-- | replaceAllCaptures_ is like like replaceAllCaptures but takes the+-- Replace methods through the ReplaceMethods argument+replaceAllCaptures_ :: Extract a+ => ReplaceMethods a+ -> REContext+ -> (Match a->RELocation->Capture a->Maybe a)+ -> Matches a+ -> a+replaceAllCaptures_ s ctx phi ac =+ runIdentity $ replaceAllCapturesM s ctx (lift_phi phi) ac+\end{code}++\begin{code}+-- | replaceAllCapturesM is just a monadically generalised version of+-- replaceAllCaptures_+replaceAllCapturesM :: (Extract a,Monad m)+ => ReplaceMethods a+ -> REContext+ -> (Match a->RELocation->Capture a->m (Maybe a))+ -> Matches a+ -> m a+replaceAllCapturesM r ctx phi_ Matches{..} =+ replaceCapturesM r ALL phi $ Match matchesSource cnms arr+ where+ phi _ (RELocation _ i) = case arr_c!i of+ Just caps -> phi_ caps . uncurry RELocation $ arr_i ! i+ Nothing -> const $ return Nothing++ arr_c = listArray bds $+ concat $+ [ repl (rangeSize $ bounds $ matchArray cs) cs+ | cs <- allMatches+ ]++ arr_i = listArray bds j_ks++ arr = listArray bds $+ [ arr_ ! k+ | arr_ <- map matchArray allMatches+ , k <- indices arr_+ ]++ bds = (0,CaptureOrdinal $ length j_ks-1)++ j_ks =+ [ (j,k)+ | (j,arr_) <- zip [0..] $ map matchArray allMatches+ , k <- indices arr_+ ]++ repl 0 _ = []+ repl n x = case ctx of+ TOP -> Just x : replicate (n-1) Nothing+ SUB -> Nothing : replicate (n-1) (Just x)+ ALL -> replicate n $ Just x++ cnms = fromMaybe noCaptureNames $ listToMaybe $ map captureNames allMatches+\end{code}++\begin{code}+-- | replace with a template containing $0 for whole text,+-- $1 for first capture, etc.+replace :: Replace a+ => a+ -> Match a+ -> a+replace tpl c = replaceCaptures TOP (parseTemplateR tpl) c+\end{code}++\begin{code}+-- | substitutes using a function that takes the full Match+-- context and returns the same replacement text as the _phi_phi+-- context.+replaceCaptures :: Replace a+ => REContext+ -> (Match a->RELocation->Capture a->Maybe a)+ -> Match a+ -> a+replaceCaptures = replaceCaptures_ replaceMethods+\end{code}++\begin{code}+-- | replaceCaptures_ is like replaceCaptures but takes the Replace methods+-- through the ReplaceMethods argument+replaceCaptures_ :: Extract a+ => ReplaceMethods a+ -> REContext+ -> (Match a->RELocation->Capture a->Maybe a)+ -> Match a+ -> a+replaceCaptures_ s ctx phi caps =+ runIdentity $ replaceCapturesM s ctx (lift_phi phi) caps+\end{code}++\begin{code}+-- | replaceCapturesM is just a monadically generalised version of+-- replaceCaptures_+replaceCapturesM :: (Monad m,Extract a)+ => ReplaceMethods a+ -> REContext+ -> (Match a->RELocation->Capture a->m (Maybe a))+ -> Match a+ -> m a+replaceCapturesM ReplaceMethods{..} ctx phi_ caps@Match{..} = do+ (hay',_) <- foldr sc (return (matchSource,[])) $+ zip [0..] $ elems matchArray+ return hay'+ where+ sc (i,cap0) act = do+ (hay,ds) <- act+ let ndl = capturedText cap+ cap = adj hay ds cap0+ mb <- phi i cap+ case mb of+ Nothing -> return (hay,ds)+ Just ndl' ->+ return+ ( methodSubst (const ndl') cap+ , (captureOffset cap,len'-len) : ds+ )+ where+ len' = methodLength ndl'+ len = methodLength ndl++ adj hay ds cap =+ Capture+ { captureSource = hay+ , capturedText = before len $ after off0 hay+ , captureOffset = off0+ , captureLength = len+ }+ where+ len = len0 + sum+ [ delta+ | (off,delta) <- ds+ , off < off0 + len0+ ]+ len0 = captureLength cap+ off0 = captureOffset cap++ phi i cap = case ctx of+ TOP | i/=0 -> return Nothing+ SUB | i==0 ->return Nothing+ _ ->+ case not $ hasCaptured cap of+ True -> return Nothing+ False -> phi_ caps (RELocation 0 i) cap+\end{code}++expandMacros+------------++\begin{code}+-- | expand all of the @{..} macros in the RE in the argument String+-- according to the Macros argument, preprocessing the RE String+-- according to the Mode argument (used internally)+expandMacros :: (r->String) -> Macros r -> String -> String+expandMacros x_src hm s =+ case HM.null hm of+ True -> s+ False -> expandMacros' (fmap x_src . flip HM.lookup hm) s+\end{code}++\begin{code}+-- | expand the @{..} macos in the argument string using the given+-- function+expandMacros' :: (MacroID->Maybe String) -> String -> String+expandMacros' lu = fixpoint e_m+ where+ e_m re_s = replaceAllCaptures TOP phi $ re_s $=~ "@(@|\\{([^{}]+)\\})"+ where+ phi mtch _ cap = case txt == "@@" of+ True -> Just "@"+ False -> Just $ fromMaybe txt $ lu ide+ where+ txt = capturedText cap+ ide = MacroID $ capturedText $ capture c2 mtch+ c2 = IsCaptureOrdinal $ CaptureOrdinal 2+\end{code}++\begin{code}+lift_phi :: Monad m+ => (Match a->RELocation->Capture a->Maybe a)+ -> (Match a->RELocation->Capture a->m (Maybe a))+lift_phi phi_ = phi+ where+ phi caps' loc' cap' = return $ phi_ caps' loc' cap'+\end{code}+++templateCaptures+----------------++\begin{code}+-- | list all of the CaptureID references in the replace template in+-- the second argument+templateCaptures :: ( Replace a+ , RegexContext Regex a (Matches a)+ , RegexMaker Regex CompOption ExecOption String+ )+ => (a->String)+ -> a+ -> [CaptureID]+templateCaptures unpack tpl =+ [ cid+ | mtch <- allMatches $ scan_template tpl+ , Right cid <- [parse_template_capture unpack mtch]+ ]++-- | parse a Match generated by acan_template, returning @Left "$")+-- iff the capture reference is an escaped @$@ (i.e., @$$@)+parse_template_capture :: (a->String) -> Match a -> Either a CaptureID+parse_template_capture unpack t_mtch = case t_mtch !$? c2 of+ Just cap -> case readMaybe stg of+ Nothing -> Right $ IsCaptureName $ CaptureName $ T.pack stg+ Just cn -> Right $ IsCaptureOrdinal $ CaptureOrdinal cn+ where+ stg = unpack $ capturedText cap+ Nothing -> case s == "$" of+ True -> Left t+ False -> Right $ IsCaptureOrdinal $ CaptureOrdinal $ read s+ where+ s = unpack t+ t = capturedText $ capture c1 t_mtch++ c1 = IsCaptureOrdinal $ CaptureOrdinal 1+ c2 = IsCaptureOrdinal $ CaptureOrdinal 2++-- | scan a replacement template, returning a Match for each capture+-- reference in the template (like $1, ${foo})+scan_template :: ( Replace a+ , RegexContext Regex a (Matches a)+ , RegexMaker Regex CompOption ExecOption String+ )+ => a+ -> Matches a+scan_template tpl = tpl $=~ "\\$(\\$|[0-9]|\\{([^{}]+)\\})"+\end{code}+++Replace and ReplaceMethods+--------------------------++\begin{code}+-- | Replace provides the missing needed to replace the matched+-- text in a @Replace a => Match a@.+class (Show a,Eq a,Ord a,Extract a,Monoid a) => Replace a where+ -- | length function for a+ lengthR :: a -> Int+ -- | inject String into a+ packR :: String -> a+ -- | project a onto a String+ unpackR :: a -> String+ -- | inject into Text+ textifyR :: a -> T.Text+ -- | project Text onto a+ detextifyR :: T.Text -> a+ -- | split into lines+ linesR :: a -> [a]+ -- | concatenate a list of lines+ unlinesR :: [a] -> a+ -- | append a newline+ appendNewlineR :: a -> a+ -- | apply a substitution function to a Capture+ substR :: (a->a) -> Capture a -> a+ -- | convert a template containing $0, $1, etc., in the first+ -- argument, into a 'phi' replacement function for use with+ -- replaceAllCaptures and replaceCaptures+ parseTemplateR :: a -> Match a -> RELocation -> Capture a -> Maybe a++ textifyR = T.pack . unpackR+ detextifyR = packR . T.unpack+ appendNewlineR = (<> packR "\n")++ substR f m@Capture{..} =+ capturePrefix m <> f capturedText <> captureSuffix m+\end{code}++\begin{code}+-- | a selction of the Replace methods can be encapsulated with ReplaceMethods+-- for the higher-order replacement functions+data ReplaceMethods a =+ ReplaceMethods+ { methodLength :: a -> Int+ , methodSubst :: (a->a) -> Capture a -> a+ }++-- | replaceMethods encapsulates ReplaceMethods a from a Replace a context+replaceMethods :: Replace a => ReplaceMethods a+replaceMethods =+ ReplaceMethods+ { methodLength = lengthR+ , methodSubst = substR+ }+\end{code}+++The Replace Instances+---------------------++\begin{code}+instance Replace [Char] where+ lengthR = length+ packR = id+ unpackR = id+ textifyR = T.pack+ detextifyR = T.unpack+ linesR = lines+ unlinesR = unlines+ appendNewlineR = (<>"\n")+ parseTemplateR = parseTemplateR' id++instance Replace B.ByteString where+ lengthR = B.length+ packR = B.pack+ unpackR = B.unpack+ textifyR = TE.decodeUtf8+ detextifyR = TE.encodeUtf8+ linesR = B.lines+ unlinesR = B.unlines+ appendNewlineR = (<>"\n")+ parseTemplateR = parseTemplateR' B.unpack++instance Replace LBS.ByteString where+ lengthR = fromEnum . LBS.length+ packR = LBS.pack+ unpackR = LBS.unpack+ textifyR = TE.decodeUtf8 . LBS.toStrict+ linesR = LBS.lines+ unlinesR = LBS.unlines+ detextifyR = LBS.fromStrict . TE.encodeUtf8+ appendNewlineR = (<>"\n")+ parseTemplateR = parseTemplateR' LBS.unpack++instance Replace (S.Seq Char) where+ lengthR = S.length+ packR = S.fromList+ unpackR = F.toList+ linesR = map packR . lines . unpackR+ unlinesR = packR . unlines . map unpackR+ parseTemplateR = parseTemplateR' F.toList++instance Replace T.Text where+ lengthR = T.length+ packR = T.pack+ unpackR = T.unpack+ textifyR = id+ detextifyR = id+ linesR = T.lines+ unlinesR = T.unlines+ appendNewlineR = (<>"\n")+ parseTemplateR = parseTemplateR' T.unpack++instance Replace LT.Text where+ lengthR = fromEnum . LT.length+ packR = LT.pack+ unpackR = LT.unpack+ textifyR = LT.toStrict+ detextifyR = LT.fromStrict+ linesR = LT.lines+ unlinesR = LT.unlines+ appendNewlineR = (<>"\n")+ parseTemplateR = parseTemplateR' LT.unpack+\end{code}+++Parsing Replace Templates+-------------------------++\begin{code}+-- | parse the replacement template in second argument, substititing+-- the capture references with corresponding captures from the Match+-- in the third argument (the result of a single match of the RE+-- against the input text to be matched); Nothing is returned if the+-- inputs are not well formed (currently all inputs are well formed)+parseTemplateR' :: ( Replace a+ , RegexContext Regex a (Matches a)+ , RegexMaker Regex CompOption ExecOption String+ )+ => (a->String)+ -> a+ -> Match a+ -> RELocation+ -> Capture a+ -> Maybe a+parseTemplateR' unpack tpl mtch _ _ =+ Just $ replaceAllCaptures TOP phi $ scan_template tpl+ where+ phi t_mtch _ _ = either Just this $ parse_template_capture unpack t_mtch++ this cid = capturedText <$> mtch !$? cid+\end{code}+++Helpers+-------++\begin{code}+fixpoint :: (Eq a) => (a->a) -> a -> a+fixpoint f = chk . iterate f+ where+ chk (x:x':_) | x==x' = x+ chk xs = chk $ tail xs+\end{code}++\begin{code}+($=~) :: ( RegexContext Regex source target+ , RegexMaker Regex CompOption ExecOption String+ )+ => source -> String -> target+($=~) = (=~)+\end{code}
+ Text/RE/ZeInternals/SearchReplace.hs view
@@ -0,0 +1,84 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE RecordWildCards #-}+{-# 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 #-}++module Text.RE.ZeInternals.SearchReplace+ ( unsafeCompileSearchReplace_+ , compileSearchReplace_+ , compileSearchAndReplace_+ ) where++import qualified Data.HashMap.Strict as HMS+import Prelude.Compat+import Text.RE.ZeInternals.NamedCaptures+import Text.RE.ZeInternals.Replace+import Text.RE.ZeInternals.Types.Capture+import Text.RE.ZeInternals.Types.CaptureID+import Text.RE.ZeInternals.Types.Matches+import Text.RE.ZeInternals.Types.SearchReplace+import qualified Text.Regex.TDFA as TDFA+++-- | warapper on 'compileSearchReplace_' that will generate an error+-- if any compilation errors are found+unsafeCompileSearchReplace_ :: (String->s)+ -> (String->Either String re)+ -> String+ -> SearchReplace re s+unsafeCompileSearchReplace_ pk cf = either err id . compileSearchReplace_ pk cf+ where+ err msg = error $ "unsafeCompileSearchReplace_: " ++ msg++-- | compile a SearchReplace template generating errors if the RE or+-- the template are not well formed -- all capture references being checked+compileSearchReplace_ :: (Monad m,Functor m)+ => (String->s)+ -> (String->Either String re)+ -> String+ -> m (SearchReplace re s)+compileSearchReplace_ pack compile_re sr_tpl = either fail return $ do+ case mainCaptures $ sr_tpl $=~ "///" of+ [cap] ->+ compileSearchAndReplace_ pack compile_re+ (capturePrefix cap) (captureSuffix cap)+ _ -> Left $ "bad search-replace template syntax: " ++ sr_tpl++-- | compile 'SearcgReplace' from two strings containing the RE+-- and the replacement template+compileSearchAndReplace_ :: (Monad m,Functor m)+ => (String->s)+ -> (String->Either String re)+ -> String+ -> String+ -> m (SearchReplace re s)+compileSearchAndReplace_ pack compile_re re_s tpl = either fail return $ do+ re <- compile_re re_s+ ((n,cnms),_) <- extractNamedCaptures re_s+ mapM_ (check n cnms) $ templateCaptures id tpl+ return $ SearchReplace re $ pack tpl+ where+ check :: Int -> CaptureNames -> CaptureID -> Either String ()+ check n cnms cid = case cid of+ IsCaptureOrdinal co -> check_co n co+ IsCaptureName cn -> check_cn cnms cn++ check_co n (CaptureOrdinal i) = case i <= n of+ True -> return ()+ False -> Left $ "capture ordinal out of range: " +++ show i ++ " >= " ++ show n++ check_cn cnms cnm = case cnm `HMS.member` cnms of+ True -> return ()+ False -> Left $ "capture name not defined: " +++ show (getCaptureName cnm)++($=~) :: String -> String -> Matches String+($=~) = (TDFA.=~)
+ Text/RE/ZeInternals/SearchReplace/TDFA.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 800+{-# LANGUAGE TemplateHaskellQuotes #-}+#else+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+#endif++module Text.RE.ZeInternals.SearchReplace.TDFA+ ( ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_+ ) where++import Language.Haskell.TH+import Language.Haskell.TH.Quote+import Prelude.Compat+import Text.RE.ZeInternals.SearchReplace.TDFAEdPrime+import Text.RE.REOptions+++-- | the @[ed| ... /// ... |]@ quasi quoters+ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_ :: QuasiQuoter++ed = ed' cast $ Just minBound+edMS = edMultilineSensitive+edMI = edMultilineInsensitive+edBS = edBlockSensitive+edBI = edBlockInsensitive+edMultilineSensitive = ed' cast $ Just MultilineSensitive+edMultilineInsensitive = ed' cast $ Just MultilineInsensitive+edBlockSensitive = ed' cast $ Just BlockSensitive+edBlockInsensitive = ed' cast $ Just BlockInsensitive+ed_ = ed' cast Nothing++cast :: Q Exp+cast = [|id|]
+ Text/RE/ZeInternals/SearchReplace/TDFA/ByteString.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 800+{-# LANGUAGE TemplateHaskellQuotes #-}+#else+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+#endif++module Text.RE.ZeInternals.SearchReplace.TDFA.ByteString+ ( ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_+ ) where++import qualified Data.ByteString.Char8 as B+import Language.Haskell.TH+import Language.Haskell.TH.Quote+import Text.RE.ZeInternals.TDFA+import Text.RE.ZeInternals.SearchReplace.TDFAEdPrime+import Text.RE.REOptions+import Text.RE.ZeInternals.Types.SearchReplace+++-- | the @[ed| ... /// ... |]@ quasi quoters+ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_ :: QuasiQuoter++ed = ed' sr_cast $ Just minBound+edMS = edMultilineSensitive+edMI = edMultilineInsensitive+edBS = edBlockSensitive+edBI = edBlockInsensitive+edMultilineSensitive = ed' sr_cast $ Just MultilineSensitive+edMultilineInsensitive = ed' sr_cast $ Just MultilineInsensitive+edBlockSensitive = ed' sr_cast $ Just BlockSensitive+edBlockInsensitive = ed' sr_cast $ Just BlockInsensitive+ed_ = ed' fn_cast Nothing++sr_cast :: Q Exp+sr_cast = [|\x -> x :: SearchReplace RE B.ByteString|]++fn_cast :: Q Exp+fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE B.ByteString|]
+ Text/RE/ZeInternals/SearchReplace/TDFA/ByteString/Lazy.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 800+{-# LANGUAGE TemplateHaskellQuotes #-}+#else+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+#endif++module Text.RE.ZeInternals.SearchReplace.TDFA.ByteString.Lazy+ ( ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_+ ) where++import qualified Data.ByteString.Lazy.Char8 as LBS+import Language.Haskell.TH+import Language.Haskell.TH.Quote+import Text.RE.ZeInternals.TDFA+import Text.RE.ZeInternals.SearchReplace.TDFAEdPrime+import Text.RE.REOptions+import Text.RE.ZeInternals.Types.SearchReplace+++-- | the @[ed| ... /// ... |]@ quasi quoters+ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_ :: QuasiQuoter++ed = ed' sr_cast $ Just minBound+edMS = edMultilineSensitive+edMI = edMultilineInsensitive+edBS = edBlockSensitive+edBI = edBlockInsensitive+edMultilineSensitive = ed' sr_cast $ Just MultilineSensitive+edMultilineInsensitive = ed' sr_cast $ Just MultilineInsensitive+edBlockSensitive = ed' sr_cast $ Just BlockSensitive+edBlockInsensitive = ed' sr_cast $ Just BlockInsensitive+ed_ = ed' fn_cast Nothing++sr_cast :: Q Exp+sr_cast = [|\x -> x :: SearchReplace RE LBS.ByteString|]++fn_cast :: Q Exp+fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE LBS.ByteString|]
+ Text/RE/ZeInternals/SearchReplace/TDFA/Sequence.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 800+{-# LANGUAGE TemplateHaskellQuotes #-}+#else+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+#endif++module Text.RE.ZeInternals.SearchReplace.TDFA.Sequence+ ( ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_+ ) where++import qualified Data.Sequence as S+import Language.Haskell.TH+import Language.Haskell.TH.Quote+import Text.RE.ZeInternals.TDFA+import Text.RE.ZeInternals.SearchReplace.TDFAEdPrime+import Text.RE.REOptions+import Text.RE.ZeInternals.Types.SearchReplace+++-- | the @[ed| ... /// ... |]@ quasi quoters+ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_ :: QuasiQuoter++ed = ed' sr_cast $ Just minBound+edMS = edMultilineSensitive+edMI = edMultilineInsensitive+edBS = edBlockSensitive+edBI = edBlockInsensitive+edMultilineSensitive = ed' sr_cast $ Just MultilineSensitive+edMultilineInsensitive = ed' sr_cast $ Just MultilineInsensitive+edBlockSensitive = ed' sr_cast $ Just BlockSensitive+edBlockInsensitive = ed' sr_cast $ Just BlockInsensitive+ed_ = ed' fn_cast Nothing++sr_cast :: Q Exp+sr_cast = [|\x -> x :: SearchReplace RE (S.Seq Char)|]++fn_cast :: Q Exp+fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE (S.Seq Char)|]
+ Text/RE/ZeInternals/SearchReplace/TDFA/String.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 800+{-# LANGUAGE TemplateHaskellQuotes #-}+#else+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+#endif++module Text.RE.ZeInternals.SearchReplace.TDFA.String+ ( ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_+ ) where+++import Language.Haskell.TH+import Language.Haskell.TH.Quote+import Text.RE.ZeInternals.TDFA+import Text.RE.ZeInternals.SearchReplace.TDFAEdPrime+import Text.RE.REOptions+import Text.RE.ZeInternals.Types.SearchReplace+++-- | the @[ed| ... /// ... |]@ quasi quoters+ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_ :: QuasiQuoter++ed = ed' sr_cast $ Just minBound+edMS = edMultilineSensitive+edMI = edMultilineInsensitive+edBS = edBlockSensitive+edBI = edBlockInsensitive+edMultilineSensitive = ed' sr_cast $ Just MultilineSensitive+edMultilineInsensitive = ed' sr_cast $ Just MultilineInsensitive+edBlockSensitive = ed' sr_cast $ Just BlockSensitive+edBlockInsensitive = ed' sr_cast $ Just BlockInsensitive+ed_ = ed' fn_cast Nothing++sr_cast :: Q Exp+sr_cast = [|\x -> x :: SearchReplace RE String|]++fn_cast :: Q Exp+fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE String|]
+ Text/RE/ZeInternals/SearchReplace/TDFA/Text.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 800+{-# LANGUAGE TemplateHaskellQuotes #-}+#else+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+#endif++module Text.RE.ZeInternals.SearchReplace.TDFA.Text+ ( ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_+ ) where++import qualified Data.Text as T+import Language.Haskell.TH+import Language.Haskell.TH.Quote+import Text.RE.ZeInternals.TDFA+import Text.RE.ZeInternals.SearchReplace.TDFAEdPrime+import Text.RE.REOptions+import Text.RE.ZeInternals.Types.SearchReplace+++-- | the @[ed| ... /// ... |]@ quasi quoters+ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_ :: QuasiQuoter++ed = ed' sr_cast $ Just minBound+edMS = edMultilineSensitive+edMI = edMultilineInsensitive+edBS = edBlockSensitive+edBI = edBlockInsensitive+edMultilineSensitive = ed' sr_cast $ Just MultilineSensitive+edMultilineInsensitive = ed' sr_cast $ Just MultilineInsensitive+edBlockSensitive = ed' sr_cast $ Just BlockSensitive+edBlockInsensitive = ed' sr_cast $ Just BlockInsensitive+ed_ = ed' fn_cast Nothing++sr_cast :: Q Exp+sr_cast = [|\x -> x :: SearchReplace RE T.Text|]++fn_cast :: Q Exp+fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE T.Text|]
+ Text/RE/ZeInternals/SearchReplace/TDFA/Text/Lazy.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 800+{-# LANGUAGE TemplateHaskellQuotes #-}+#else+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+#endif++module Text.RE.ZeInternals.SearchReplace.TDFA.Text.Lazy+ ( ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_+ ) where++import qualified Data.Text.Lazy as TL+import Language.Haskell.TH+import Language.Haskell.TH.Quote+import Text.RE.ZeInternals.TDFA+import Text.RE.ZeInternals.SearchReplace.TDFAEdPrime+import Text.RE.REOptions+import Text.RE.ZeInternals.Types.SearchReplace+++-- | the @[ed| ... /// ... |]@ quasi quoters+ed+ , edMS+ , edMI+ , edBS+ , edBI+ , edMultilineSensitive+ , edMultilineInsensitive+ , edBlockSensitive+ , edBlockInsensitive+ , ed_ :: QuasiQuoter++ed = ed' sr_cast $ Just minBound+edMS = edMultilineSensitive+edMI = edMultilineInsensitive+edBS = edBlockSensitive+edBI = edBlockInsensitive+edMultilineSensitive = ed' sr_cast $ Just MultilineSensitive+edMultilineInsensitive = ed' sr_cast $ Just MultilineInsensitive+edBlockSensitive = ed' sr_cast $ Just BlockSensitive+edBlockInsensitive = ed' sr_cast $ Just BlockInsensitive+ed_ = ed' fn_cast Nothing++sr_cast :: Q Exp+sr_cast = [|\x -> x :: SearchReplace RE TL.Text|]++fn_cast :: Q Exp+fn_cast = [|\x -> x :: SimpleREOptions -> SearchReplace RE TL.Text|]
+ Text/RE/ZeInternals/SearchReplace/TDFAEdPrime.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 800+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}+{-# LANGUAGE TemplateHaskellQuotes #-}+#else+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+#endif++module Text.RE.ZeInternals.SearchReplace.TDFAEdPrime+ ( ed'+ ) where++import Language.Haskell.TH+import Language.Haskell.TH.Quote+import Prelude.Compat+import Text.RE.ZeInternals.SearchReplace+import Text.RE.ZeInternals.QQ+import Text.RE.ZeInternals.TDFA+import Text.RE.IsRegex+import Text.RE.REOptions+import Text.RE.Replace+import Text.Regex.TDFA+++-- | construct a quasi quoter from a casting function and @Just sro@+-- if the options are known, otherwise a function take takes the+-- 'SimpleREOptions' and constructs the 'SearchReplace' template+ed' :: Q Exp -> Maybe SimpleREOptions -> QuasiQuoter+ed' qe mb = case mb of+ Nothing ->+ (qq0 "ed'")+ { quoteExp = parse minBound $ \rs -> AppE <$> qe <*> [|flip unsafe_compile_sr rs|]+ }+ Just sro ->+ (qq0 "ed'")+ { quoteExp = parse sro $ \rs -> AppE <$> qe <*> [|unsafe_compile_sr_simple sro rs|]+ }+ where+ parse :: SimpleREOptions -> (String->Q Exp) -> String -> Q Exp+ parse sro mk ts = either error (\_->mk ts) ei+ where+ ei :: Either String (SearchReplace RE String)+ ei = compileSearchReplace_ id (compileRegexWith sro) ts++unsafe_compile_sr_simple :: IsRegex RE s+ => SimpleREOptions+ -> String+ -> SearchReplace RE s+unsafe_compile_sr_simple sro =+ unsafe_compile_sr $ unpackSimpleREOptions sro++unsafe_compile_sr :: ( IsOption o RE CompOption ExecOption+ , IsRegex RE s+ )+ => o+ -> String+ -> SearchReplace RE s+unsafe_compile_sr os =+ unsafeCompileSearchReplace_ packR $ compileRegexWithOptions os
+ Text/RE/ZeInternals/TDFA.hs view
@@ -0,0 +1,428 @@+{-# 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 #-}++module Text.RE.ZeInternals.TDFA+ ( -- * About+ -- $about++ -- * RE Type+ RE+ , regexType+ , reOptions+ , reSource+ , reCaptureNames+ , reRegex+ -- * REOptions Type+ , REOptions+ , defaultREOptions+ , noPreludeREOptions+ -- * Compiling Regular Expressions+ , compileRegex+ , compileRegexWith+ , compileRegexWithOptions+ -- * Compiling Search-Replace Templates+ , compileSearchReplace+ , compileSearchReplaceWith+ , compileSearchReplaceWithREOptions+ -- * Escaping String+ , escape+ , escapeWith+ , escapeWithOptions+ , escapeREString+ -- * Macros Standard Environment+ , prelude+ , preludeEnv+ , preludeTestsFailing+ , preludeTable+ , preludeSummary+ , preludeSources+ , preludeSource+ , unpackSimpleREOptions+ -- * The Quasi Quoters+ , re+ , reMS+ , reMI+ , reBS+ , reBI+ , reMultilineSensitive+ , reMultilineInsensitive+ , reBlockSensitive+ , reBlockInsensitive+ , re_+ , cp+ ) where++import Data.Functor.Identity+import Language.Haskell.TH+import Language.Haskell.TH.Quote+import Prelude.Compat+import Text.RE.IsRegex+import Text.RE.REOptions+import Text.RE.ZeInternals.EscapeREString+import Text.RE.ZeInternals.NamedCaptures+import Text.RE.ZeInternals.PreludeMacros+import Text.RE.ZeInternals.Replace+import Text.RE.ZeInternals.QQ+import Text.RE.ZeInternals.SearchReplace+import Text.RE.ZeInternals.TestBench+import Text.RE.ZeInternals.Types.CaptureID+import Text.Regex.TDFA+++-- | the RE type for this back end representing a well-formed, compiled+-- RE+data RE =+ RE+ { _re_options :: !REOptions+ , _re_source :: !String+ , _re_cnames :: !CaptureNames+ , _re_regex :: !Regex+ }++-- | some functions in the "Text.RE.TestBench" need the back end to+-- be passed dynamically as a 'RegexType' parameters: use 'regexType'+-- fpr this backend+regexType :: RegexType+regexType =+ mkTDFA $ \txt env md -> txt =~ mdRegexSource regexType ExclCaptures env md++-- | extract the 'REOptions' from the @RE@+reOptions :: RE -> REOptions+reOptions = _re_options++-- | extract the RE source string from the @RE@+reSource :: RE -> String+reSource = _re_source++-- | extract the 'CaptureNames' from the @RE@+reCaptureNames :: RE -> CaptureNames+reCaptureNames = _re_cnames++-- | extract the back end compiled 'Regex' type from the @RE@+reRegex :: RE -> Regex+reRegex = _re_regex+++------------------------------------------------------------------------+-- REOptions+------------------------------------------------------------------------++-- | and the REOptions for this back end (see "Text.RE.REOptions"+-- for details)+type REOptions = REOptions_ RE CompOption ExecOption++instance IsOption SimpleREOptions RE CompOption ExecOption where+ makeREOptions = unpackSimpleREOptions++instance IsOption (Macros RE) RE CompOption ExecOption where+ makeREOptions ms = REOptions ms def_comp_option def_exec_option++instance IsOption CompOption RE CompOption ExecOption where+ makeREOptions co = REOptions prelude co def_exec_option++instance IsOption ExecOption RE CompOption ExecOption where+ makeREOptions eo = REOptions prelude def_comp_option eo++instance IsOption REOptions RE CompOption ExecOption where+ makeREOptions = id++instance IsOption () RE CompOption ExecOption where+ makeREOptions _ = unpackSimpleREOptions minBound++-- | the default 'REOptions'+defaultREOptions :: REOptions+defaultREOptions = makeREOptions (minBound::SimpleREOptions)++-- | the default 'REOptions' but with no RE macros defined+noPreludeREOptions :: REOptions+noPreludeREOptions = defaultREOptions { optionsMacs = emptyMacros }++-- | convert a universal 'SimpleReOptions' into the 'REOptions' used+-- by this back end+unpackSimpleREOptions :: SimpleREOptions -> REOptions+unpackSimpleREOptions sro =+ REOptions+ { optionsMacs = prelude+ , optionsComp = comp+ , optionsExec = defaultExecOpt+ }+ where+ comp = defaultCompOpt+ { caseSensitive = cs+ , multiline = ml+ }++ (ml,cs) = case sro of+ MultilineSensitive -> (,) True True+ MultilineInsensitive -> (,) True False+ BlockSensitive -> (,) False True+ BlockInsensitive -> (,) False 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) => String -> m RE+compileRegex = compileRegexWithOptions ()++-- | 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) => SimpleREOptions -> String -> m RE+compileRegexWith = compileRegexWithOptions++-- | compile a 'String' into a 'RE' using the given @SimpleREOptions@,+-- generating an error if the RE is not well formed+compileRegexWithOptions :: ( IsOption o RE CompOption ExecOption+ , Functor m+ , Monad m+ )+ => o+ -> String+ -> m RE+compileRegexWithOptions = compileRegex_ . 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,Functor m,IsRegex RE s)+ => String+ -> String+ -> m (SearchReplace RE s)+compileSearchReplace = compileSearchReplaceWith 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,Functor m,IsRegex RE s)+ => SimpleREOptions+ -> String+ -> String+ -> m (SearchReplace RE s)+compileSearchReplaceWith sro = compileSearchAndReplace_ packR $ compileRegexWith 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+compileSearchReplaceWithREOptions :: (Monad m,Functor m,IsRegex RE s)+ => REOptions+ -> String+ -> String+ -> m (SearchReplace RE s)+compileSearchReplaceWithREOptions os = compileSearchAndReplace_ packR $ compileRegexWithOptions 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+escape :: (Functor m,Monad m)+ => (String->String)+ -> String+ -> m RE+escape = escapeWith minBound++-- | 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 with the default options+escapeWith :: (Functor m,Monad m)+ => SimpleREOptions+ -> (String->String)+ -> String+ -> m RE+escapeWith = escapeWithOptions++-- | 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 the given options+escapeWithOptions :: ( IsOption o RE CompOption ExecOption+ , Functor m+ , Monad m+ )+ => o+ -> (String->String)+ -> String+ -> m RE+escapeWithOptions o f = compileRegexWithOptions o . f . 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 = runIdentity $ preludeMacros mk regexType ExclCaptures+ where+ mk = Identity . unsafeCompileRegex_ noPreludeREOptions++-- | the standard 'MacroEnv' for this back end (see "Text.RE.TestBench")+preludeEnv :: MacroEnv+preludeEnv = preludeMacroEnv regexType++-- | the macros in the standard environment that are failing their tests+-- (checked by the test suite to be empty)+preludeTestsFailing :: [MacroID]+preludeTestsFailing = badMacros $ preludeMacroEnv regexType++-- | a table the standard macros in markdown format+preludeTable :: String+preludeTable = preludeMacroTable regexType++-- | a summary of the macros in the standard environment for this back+-- end in plain text+preludeSummary :: PreludeMacro -> String+preludeSummary = preludeMacroSummary regexType++-- | a listing of the RE text for each macro in the standard environment+-- with all macros expanded to normal form+preludeSources :: String+preludeSources = preludeMacroSources regexType++-- | the prolude source of a given macro in the standard environment+preludeSource :: PreludeMacro -> String+preludeSource = preludeMacroSource regexType+++------------------------------------------------------------------------+-- Quasi Quoters+------------------------------------------------------------------------++-- | the @[re| ... |]@ and @[ed| ... /// ... |]@ quasi quoters+re+ , reMS+ , reMI+ , reBS+ , reBI+ , reMultilineSensitive+ , reMultilineInsensitive+ , reBlockSensitive+ , reBlockInsensitive+ , re_ :: QuasiQuoter+ -- , ed+ -- , edMS+ -- , edMI+ -- , edBS+ -- , edBI+ -- , edMultilineSensitive+ -- , edMultilineInsensitive+ -- , edBlockSensitive+ -- , edBlockInsensitive+ -- , ed_ :: QuasiQuoter++re = re' $ Just minBound+reMS = reMultilineSensitive+reMI = reMultilineInsensitive+reBS = reBlockSensitive+reBI = reBlockInsensitive+reMultilineSensitive = re' $ Just MultilineSensitive+reMultilineInsensitive = re' $ Just MultilineInsensitive+reBlockSensitive = re' $ Just BlockSensitive+reBlockInsensitive = re' $ Just BlockInsensitive+re_ = re' Nothing+++------------------------------------------------------------------------+-- re Helpers+------------------------------------------------------------------------++re' :: Maybe SimpleREOptions -> QuasiQuoter+re' mb = case mb of+ Nothing ->+ (qq0 "re'")+ { quoteExp = parse minBound (\rs->[|flip unsafeCompileRegex rs|])+ }+ Just sro ->+ (qq0 "re'")+ { quoteExp = parse sro (\rs->[|unsafeCompileRegexSimple sro rs|])+ }+ where+ parse :: SimpleREOptions -> (String->Q Exp) -> String -> Q Exp+ parse sro mk rs = either error (\_->mk rs) $ compileRegex_ os rs+ where+ os = unpackSimpleREOptions sro++unsafeCompileRegexSimple :: SimpleREOptions -> String -> RE+unsafeCompileRegexSimple sro re_s = unsafeCompileRegex_ os re_s+ where+ os = unpackSimpleREOptions sro++unsafeCompileRegex :: IsOption o RE CompOption ExecOption+ => o+ -> String+ -> RE+unsafeCompileRegex = unsafeCompileRegex_ . makeREOptions++unsafeCompileRegex_ :: REOptions -> String -> RE+unsafeCompileRegex_ os = either oops id . compileRegex_ os+ where+ oops = error . ("unsafeCompileRegex: " ++)++compileRegex' :: (Functor m,Monad m)+ => REOptions+ -> String+ -> m (CaptureNames,Regex)+compileRegex' REOptions{..} s0 = do+ ((_,cnms),s2) <- either fail return $ extractNamedCaptures s1+ (,) cnms <$> makeRegexOptsM optionsComp optionsExec s2+ where+ s1 = expandMacros reSource optionsMacs s0++compileRegex_ :: (Functor m,Monad m)+ => REOptions+ -> String+ -> m RE+compileRegex_ os re_s = uncurry mk <$> compileRegex' os re_s+ where+ mk cnms rx =+ RE+ { _re_options = os+ , _re_source = re_s+ , _re_cnames = cnms+ , _re_regex = rx+ }+++------------------------------------------------------------------------+-- Options Helpers+------------------------------------------------------------------------++def_comp_option :: CompOption+def_comp_option = optionsComp defaultREOptions++def_exec_option :: ExecOption+def_exec_option = optionsExec 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").
+ Text/RE/ZeInternals/TestBench.lhs view
@@ -0,0 +1,590 @@+\begin{code}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 800+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}+#endif++module Text.RE.ZeInternals.TestBench+ ( MacroID(..)+ , RegexType+ , mkTDFA+ , mkPCRE+ , isTDFA+ , isPCRE+ , presentRegexType+ , MacroEnv+ , WithCaptures(..)+ , MacroDescriptor(..)+ , TestResult(..)+ , RegexSource(..)+ , FunctionID(..)+ , mkMacros+ , testMacroEnv+ , badMacros+ , runTests+ , runTests'+ , formatMacroTable+ , dumpMacroTable+ , formatMacroSummary+ , formatMacroSources+ , formatMacroSource+ , testMacroDescriptors+ , mdRegexSource+ ) where++import Data.Array+import Data.Char+import qualified Data.HashMap.Lazy as HML+import qualified Data.List as L+import Data.Maybe+import Data.Ord+import Data.String+import Text.Printf+import Prelude.Compat+import Text.RE.REOptions+import Text.RE.ZeInternals.Replace+import Text.RE.ZeInternals.Types.Capture+import Text.RE.ZeInternals.Types.Match+import Text.RE.ZeInternals.Types.Matches+\end{code}++Types+-----++\begin{code}++type TestBenchMatcher =+ String -> MacroEnv -> MacroDescriptor -> Matches String++-- | what kind of back end will be compiling the RE, and its match+-- function+data RegexType+ = TDFA TestBenchMatcher+ | PCRE TestBenchMatcher++-- | test RegexType for TDFA/PCREness+isTDFA, isPCRE :: RegexType -> Bool++isTDFA (TDFA _) = True+isTDFA (PCRE _) = False++isPCRE (TDFA _) = False+isPCRE (PCRE _) = True++mkTDFA, mkPCRE :: TestBenchMatcher -> RegexType+mkTDFA = TDFA+mkPCRE = PCRE++presentRegexType :: RegexType -> String+presentRegexType (TDFA _) = "TDFA"+presentRegexType (PCRE _) = "PCRE"++instance Show RegexType where+ show (TDFA _) = "TDFA <function>"+ show (PCRE _) = "PCRE <function>"++-- | do we need the captures in the RE or whould they be stripped out+-- where possible+data WithCaptures+ = InclCaptures -- ^ include all captures+ | ExclCaptures -- ^ remove captures where possible+ deriving (Eq,Ord,Show)++-- | each macro can reference others, the whole environment being+-- required for each macro, so we use a Lazy HashMap+type MacroEnv = HML.HashMap MacroID MacroDescriptor++-- | describes a macro, giving the text of the RE and a si=ummary+-- description+data MacroDescriptor =+ MacroDescriptor+ { macroSource :: !RegexSource -- ^ the RE+ , macroSamples :: ![String] -- ^ some sample matches+ , macroCounterSamples :: ![String] -- ^ some sample non-matches+ , macroTestResults :: ![TestResult] -- ^ validation test results+ , macroParser :: !(Maybe FunctionID) -- ^ WA, the parser function+ , macroDescription :: !String -- ^ summary comment+ }+ deriving (Show)++-- | list of failures on a validation run+newtype TestResult =+ TestResult { _TestResult :: String }+ deriving (IsString,Show)++-- | a RE that should work for POSIX and PCRE with open brackets ('(')+-- represented as follows:+-- \( mere symbol+-- (?: used for grouping only, not for captures+-- (}: used for captures only, not for grouping+-- (]: used for captures and grouping+-- ( do not modify+newtype RegexSource =+ RegexSource { _RegexSource :: String }+ deriving (IsString,Show)++-- | name of the Haskell parser function for parsing the text matched+-- by a macro+newtype FunctionID =+ FunctionID { _FunctionID :: String }+ deriving (IsString,Show)++-- | we are only interested in the open parentheses used for+-- grouping and/or capturing; if neither grouping or capturing then+-- there is no initial '(' or '(?:', just the suffic text+data REToken =+ REToken+ { _ret_prefix :: String -- ^ following text optional ( or (?:+ , _ret_fixed :: Bool -- ^ a '(' that is not safe to modify+ , _ret_grouping :: Bool -- ^ is this a grouping group+ , _ret_capturing :: Bool -- ^ is this a capturing group+ }+ deriving (Show)+\end{code}+++mkMacros+--------++\begin{code}+-- | construct a macro table suitable for use with the RE compilers+mkMacros :: (Monad m,Functor m)+ => (String->m r)+ -> RegexType+ -> WithCaptures+ -> MacroEnv+ -> m (Macros r)+mkMacros prs rty wc env =+ HML.fromList <$> mapM (uncurry mk) (HML.toList env)+ where+ mk mid md = (,) mid <$> prs (mdRegexSource rty wc env md)+\end{code}+++testMacroEnv, badMacros+-----------------------++\begin{code}+-- | test that a MacroEnv is passing all of its built-in tests+testMacroEnv :: String -> RegexType -> MacroEnv -> IO Bool+testMacroEnv lab rty m_env = case badMacros m_env of+ [] -> return True+ fails -> do+ putStrLn $ lab' ++ " has failing tests for these macros: "+ putStr $ unlines $ [ " "++getMacroID mid | mid<-fails ]+ putStrLn $ "The whole table:"+ putStrLn $ "========================================================"+ putStr $ formatMacroTable rty m_env+ putStrLn $ "========================================================"+ return False+ where+ lab' = lab ++ " [" ++ presentRegexType rty ++"]"++badMacros :: MacroEnv -> [MacroID]+badMacros m_env =+ [ mid+ | (mid,MacroDescriptor{..}) <- HML.toList m_env+ , not $ null macroTestResults+ ]++runTests :: (Eq a,Show a)+ => RegexType+ -> (String->Maybe a)+ -> [(String,a)]+ -> MacroEnv+ -> MacroID+ -> MacroDescriptor+ -> MacroDescriptor+runTests rty parser = runTests' rty parser'+ where+ parser' caps = fmap capturedText (matchCapture caps) >>= parser++runTests' :: (Eq a,Show a)+ => RegexType+ -> (Match String->Maybe a)+ -> [(String,a)]+ -> MacroEnv+ -> MacroID+ -> MacroDescriptor+ -> MacroDescriptor+runTests' rty parser vector env mid md@MacroDescriptor{..} =+ md { macroTestResults = test_results }+ where+ test_results = concat+ [ concat $ map test vector+ , concat $ map test_neg macroCounterSamples+ ]++ test (src,x) = test' mid rty parser x $ match_ src env md++ test_neg src = test_neg' mid rty parser $ match_ src env md++ match_ = case rty of+ TDFA tbmf -> tbmf+ PCRE tbmf -> tbmf+\end{code}+++dumpMacroTable, formatMacroTable, formatMacroSummary, formatMacroSources, formatMacroSource+-------------------------------------------------------------------------------------------++\begin{code}+-- | dump a MacroEnv into the docs directory+dumpMacroTable :: String -> RegexType -> MacroEnv -> IO ()+dumpMacroTable lab rty m_env = do+ writeFile fp_t $ formatMacroTable rty m_env+ writeFile fp_s $ formatMacroSources rty ExclCaptures m_env+ where+ fp_t = "docs/" ++ rty_s ++ "-" ++ lab ++ ".txt"+ fp_s = "docs/" ++ rty_s ++ "-" ++ lab ++ "-src.txt"++ rty_s = map toLower $ presentRegexType rty+\end{code}++\begin{code}+-- | format a macros table as a markdown table+formatMacroTable :: RegexType -> MacroEnv -> String+formatMacroTable rty env = unlines $+ format_table macro_table_hdr+ [ macro_table_row rty mid md+ | (mid,md) <- L.sortBy (comparing fst) $ HML.toList env+ ]+\end{code}++\begin{code}+-- | generate a plain text summary of a macro+formatMacroSummary :: RegexType -> MacroEnv -> MacroID -> String+formatMacroSummary rty env mid = maybe oops prep $ HML.lookup mid env+ where+ prep :: MacroDescriptor -> String+ prep md = unlines $ concat $ map (fmt md) [minBound..maxBound]++ fmt :: MacroDescriptor -> Col -> [String]+ fmt md c =+ [ printf "%-15s : %s" (present_col c) ini+ ] ++ map (" "++) lns+ where+ (ini,lns) = case macro_attribute rty mid md c of+ [] -> (,) "" []+ [ln] -> (,) ln []+ lns_ -> (,) "" lns_++ oops = error $ getMacroID mid ++ ": macro not defined in this environment"+\end{code}++\begin{code}+-- | list the source REs for each macro in plain text+formatMacroSources :: RegexType+ -> WithCaptures+ -> MacroEnv+ -> String+formatMacroSources rty wc env = unlines $+ [ printf "%-20s : %s" (getMacroID mid) $ formatMacroSource rty wc env mid+ | mid <- L.sort $ HML.keys env+ ]+\end{code}++\begin{code}+-- | list the source of a single macro in plain text+formatMacroSource :: RegexType+ -> WithCaptures+ -> MacroEnv+ -> MacroID+ -> String+formatMacroSource rty wc env mid =+ mdRegexSource rty wc env $ fromMaybe oops $ HML.lookup mid env+ where+ oops = error $ "formatMacroSource: not found: " ++ getMacroID mid+\end{code}+++testMacroDescriptors, regexSource+---------------------------------++\begin{code}+testMacroDescriptors :: [MacroDescriptor] -> [TestResult]+testMacroDescriptors = concat . map macroTestResults++regexSource :: RegexType -> WithCaptures -> RegexSource -> String+regexSource rty wc = format_tokens rty wc . scan_re+\end{code}+++Formatting helpers+------------------++\begin{code}+type TableRow = Array Col [String]++data Col+ = C_name+ | C_caps+ | C_regex+ | C_examples+ | C_anti_examples+ | C_fails+ | C_parser+ | C_comment+ deriving (Ix,Bounded,Enum,Ord,Eq,Show)++present_col :: Col -> String+present_col = map tr . drop 2 . show+ where+ tr '_' = '-'+ tr c = c++macro_table_hdr :: TableRow+macro_table_hdr = listArray (minBound,maxBound)+ [ [present_col c]+ | c<-[minBound..maxBound]+ ]++macro_table_row :: RegexType -> MacroID -> MacroDescriptor -> TableRow+macro_table_row rty mid md =+ listArray (minBound,maxBound) $+ map (macro_attribute rty mid md) [minBound..maxBound]++macro_attribute :: RegexType+ -> MacroID+ -> MacroDescriptor+ -> Col+ -> [String]+macro_attribute rty mid MacroDescriptor{..} c =+ case c of+ C_name -> [getMacroID mid]+ C_caps -> [show $ min_captures rty $ scan_re macroSource]+ C_regex -> [regexSource rty ExclCaptures macroSource]+ C_examples -> macroSamples+ C_anti_examples -> macroCounterSamples+ C_fails -> map _TestResult macroTestResults+ C_parser -> [maybe "-" _FunctionID macroParser]+ C_comment -> [macroDescription]++format_table :: TableRow -> [TableRow] -> [String]+format_table hdr rows0 = concat+ [ format_row cws hdr'+ , format_row cws dsh+ , concat $ map (format_row cws) rows+ ]+ where+ dsh = listArray (minBound,maxBound)+ [ [replicate n '-'] | n<-elems cws ]++ hdr' = hdr // [(,) C_regex $ [take n $ concat $ repeat "regex="] ]+ where+ n = min 29 $ cws!C_regex++ cws = widths $ hdr : rows++ rows = map wrap_row rows0++field_width :: Int+field_width = 40++wrap_row :: TableRow -> TableRow+wrap_row = fmap $ concat . map f+ where+ f, g :: String -> [String]++ f cts = (ini ++ ['\\' | not (null rst)]) : g rst+ where+ (ini,rst) = splitAt (1+field_width) cts++ g "" = []+ g cts = ('\\' : ini ++ ['\\' | not (null rst)]) : g rst+ where+ (ini,rst) = splitAt field_width cts+++widths :: [TableRow] -> Array Col Int+widths rows = listArray (minBound,maxBound)+ [ maximum $ concat [ map length $ row!c | row<-rows ]+ | c<-[minBound..maxBound]+ ]++format_row :: Array Col Int -> TableRow -> [String]+format_row cw_arr row =+ [ ("|"++) $ L.intercalate "|"+ [ field cw_arr row c i | c<-[minBound..maxBound] ]+ | i <- [0..depth-1]+ ]+ where+ depth = maximum [ length $ row!c | c<-[minBound..maxBound] ]++field :: Array Col Int -> TableRow -> Col -> Int -> String+field cws row c i = ljust (cws!c) $ sel i $ row!c++sel :: Int -> [String] -> String+sel i ss = case drop i ss of+ [] -> ""+ s:_ -> s++ljust :: Int -> String -> String+ljust w s = s ++ replicate n ' '+ where+ n = max 0 $ w - length s++min_captures :: RegexType -> [REToken] -> Int+min_captures rty rets = length+ [ ()+ | REToken{..}<-rets+ , _ret_fixed || (_ret_grouping && isTDFA rty)+ ]+\end{code}+++Formatting tokens+-----------------++\begin{code}+format_tokens :: RegexType -> WithCaptures -> [REToken] -> String+format_tokens rty wc = foldr f ""+ where+ f REToken{..} rst = _ret_prefix ++ bra ++ xket rst+ where+ bra = case _ret_fixed of+ True -> "("+ False ->+ case (,) _ret_grouping (_ret_capturing && wc==InclCaptures) of+ (False,False) -> ""+ (True ,False) -> if isPCRE rty then "(?:" else "("+ (False,True ) -> "("+ (True ,True ) -> "("++ xket =+ case not _ret_grouping && _ret_capturing && wc==ExclCaptures of+ True -> delete_ket 0+ False -> id++delete_ket :: Int -> String -> String+delete_ket _ "" = error "delete_ket: end of input"+delete_ket n (c:t) = case c of+ '\\' -> case t of+ "" -> error "delete_ket: end of input"+ c':t' -> c : c' : delete_ket n t'+ ')' -> case n of+ 0 -> t+ _ -> c : delete_ket (n-1) t+ '(' -> c : delete_ket (n+1) t+ _ -> c : delete_ket n t+\end{code}+++scan_re+-------++\begin{code}+scan_re :: RegexSource -> [REToken]+scan_re (RegexSource src0) = loop src0+ where+ loop "" = []+ loop src =+ case rst of+ '\\':t -> case t of+ "" -> REToken (ini++['\\']) False False False : []+ c':t' -> REToken (ini++['\\',c']) False False False : loop t'+ '(' :t -> case t of+ c:':':t'+ | c=='?' -> REToken ini False True False : loop t'+ | c=='}' -> REToken ini False False True : loop t'+ | c==']' -> REToken ini False True True : loop t'+ _ -> REToken ini True True True : loop t+ _ -> [REToken src False False False]+ where+ (ini,rst) = break chk src++ chk '\\' = True+ chk '(' = True+ chk _ = False+\end{code}+++mdRegexSource+-------------++\begin{code}+mdRegexSource :: RegexType+ -> WithCaptures+ -> MacroEnv+ -> MacroDescriptor+ -> String+mdRegexSource rty wc env md =+ expandMacros' lu $ regexSource rty wc $ macroSource md+ where+ lu = fmap (regexSource rty wc . macroSource) .+ flip HML.lookup env+\end{code}+++test', test_neg'+----------------++\begin{code}+test' :: (Eq a,Show a)+ => MacroID+ -> RegexType+ -> (Match String->Maybe a)+ -> a+ -> Matches String+ -> [TestResult]+test' mid rty prs x Matches{..} = either (:[]) (const []) $ do+ cs <- case allMatches of+ [cs] -> return cs+ _ -> oops "RE failed to parse"+ mtx <- case matchCapture cs of+ Nothing -> oops $ "RE parse failure: " ++ show cs+ Just c -> return $ capturedText c+ case mtx == matchesSource of+ True -> return ()+ False -> oops "RE failed to match the whole text"+ x' <- case prs cs of+ Nothing -> oops "matched text failed to parse"+ Just x' -> return x'+ case x'==x of+ True -> return ()+ False -> oops "parser failed to yield the expected result"+ where+ oops = Left . test_diagnostic mid False rty matchesSource++test_neg' :: MacroID+ -> RegexType+ -> (Match String->Maybe a)+ -> Matches String+ -> [TestResult]+test_neg' mid rty prs Matches{..} = either id (const []) $ do+ case allMatches of+ [] -> return ()+ cz -> case ms of+ [] -> return ()+ _ -> Left [oops "RE parse succeeded"]+ where+ ms =+ [ ()+ | cs <- cz+ , Just c <- [matchCapture cs]+ , let t = capturedText c+ , t == matchesSource+ , isJust $ prs cs+ ]++ where+ oops = test_diagnostic mid True rty matchesSource++test_diagnostic :: MacroID+ -> Bool+ -> RegexType+ -> String+ -> String+ -> TestResult+test_diagnostic mid is_neg rty tst msg =+ TestResult $+ printf "%-20s [%s %s] : %s (%s)" mid_s neg_s rty_s msg tst+ where+ mid_s = getMacroID mid+ neg_s = if is_neg then "-ve" else "+ve" :: String+ rty_s = presentRegexType rty+\end{code}
+ Text/RE/ZeInternals/Types/Capture.lhs view
@@ -0,0 +1,61 @@+\begin{code}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE DeriveDataTypeable #-}+\end{code}++\begin{code}+module Text.RE.ZeInternals.Types.Capture+ ( Capture(..)+ , hasCaptured+ , capturePrefix+ , captureSuffix+ ) where+\end{code}++\begin{code}+import Text.Regex.Base+\end{code}++++\begin{code}+-- | the matching of a single sub-expression against part of the source+-- text+data Capture a =+ Capture+ { captureSource :: !a -- ^ the whole text that was searched+ , capturedText :: !a -- ^ the text that was matched+ , captureOffset :: !Int -- ^ the number of characters preceding the+ -- match with -1 used if no text was captured+ -- by the RE (not even the empty string)+ , captureLength :: !Int -- ^ the number of chacter in the captured+ -- sub-string+ }+ deriving (Show,Eq)+\end{code}++\begin{code}+instance Functor Capture where+ fmap f c@Capture{..} =+ c+ { captureSource = f captureSource+ , capturedText = f capturedText+ }+\end{code}++\begin{code}+-- | test if the capture has matched any text+hasCaptured :: Capture a -> Bool+hasCaptured = (>=0) . captureOffset++-- | returns the text preceding the match+capturePrefix :: Extract a => Capture a -> a+capturePrefix Capture{..} = before captureOffset captureSource++-- | returns the text after the match+captureSuffix :: Extract a => Capture a -> a+captureSuffix Capture{..} = after (captureOffset+captureLength) captureSource+\end{code}
+ Text/RE/ZeInternals/Types/CaptureID.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++module Text.RE.ZeInternals.Types.CaptureID where++import Data.Ix+import Data.Hashable+import qualified Data.HashMap.Strict as HMS+import Data.Maybe+import qualified Data.Text as T+++-- | CaptureID identifies captures, either by number+-- (e.g., [cp|1|]) or name (e.g., [cp|foo|]).+data CaptureID+ = IsCaptureOrdinal CaptureOrdinal -- [cp|3|]+ | IsCaptureName CaptureName -- [cp|y|]+ deriving (Show,Ord,Eq)++-- | the dictionary for named captures stored in compiled regular+-- expressions associates+type CaptureNames = HMS.HashMap CaptureName CaptureOrdinal++-- | an empty 'CaptureNames' dictionary+noCaptureNames :: CaptureNames+noCaptureNames = HMS.empty++-- | a 'CaptureName' is just the text of the name+newtype CaptureName = CaptureName { getCaptureName :: T.Text }+ deriving (Show,Ord,Eq)++instance Hashable CaptureName where+ hashWithSalt i = hashWithSalt i . getCaptureName++-- | a 'CaptureOrdinal' is just the number of the capture, starting+-- with 0 for the whole of the text matched, then in leftmost,+-- outermost+newtype CaptureOrdinal = CaptureOrdinal { getCaptureOrdinal :: Int }+ deriving (Show,Ord,Eq,Enum,Ix,Num)++-- | look up a 'CaptureID' in the 'CaptureNames' dictionary+findCaptureID :: CaptureID -> CaptureNames -> Int+findCaptureID (IsCaptureOrdinal o) _ = getCaptureOrdinal o+findCaptureID (IsCaptureName n) hms =+ getCaptureOrdinal $ fromMaybe oops $ HMS.lookup n hms+ where+ oops = error $ unlines $+ ("lookupCaptureID: " ++ T.unpack t ++ " not found in:") :+ [ " "++T.unpack (getCaptureName nm) | nm <- HMS.keys hms ]+ t = getCaptureName n
+ Text/RE/ZeInternals/Types/LineNo.hs view
@@ -0,0 +1,21 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++module Text.RE.ZeInternals.Types.LineNo where+++-- | our line numbers are of the proper zero-based kind+newtype LineNo =+ ZeroBasedLineNo { getZeroBasedLineNo :: Int }+ deriving (Show,Enum)++-- | the first line in a file+firstLine :: LineNo+firstLine = ZeroBasedLineNo 0++-- | extract a conventional 1-based line number+getLineNo :: LineNo -> Int+getLineNo = succ . getZeroBasedLineNo++-- | inject a conventional 1-based line number+lineNo :: Int -> LineNo+lineNo = ZeroBasedLineNo . pred
+ Text/RE/ZeInternals/Types/Match.lhs view
@@ -0,0 +1,194 @@+\begin{code}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE DeriveDataTypeable #-}+\end{code}++\begin{code}+module Text.RE.ZeInternals.Types.Match+ ( Match(..)+ , noMatch+ , emptyMatchArray+ , matched+ , matchedText+ , matchCapture+ , matchCaptures+ , (!$$)+ , captureText+ , (!$$?)+ , captureTextMaybe+ , (!$)+ , capture+ , (!$?)+ , captureMaybe+ , convertMatchText+ ) where+\end{code}++\begin{code}+import Data.Array+import Data.Maybe+import Data.Typeable+import Text.Regex.Base+import Text.RE.ZeInternals.Types.Capture+import Text.RE.ZeInternals.Types.CaptureID++infixl 9 !$, !$$+\end{code}++\begin{code}+-- | the result of matching a RE to a text once, listing the text that+-- was matched and the named captures in the RE and all of the substrings+-- matched, with the text captured by the whole RE; a complete failure+-- to match will be represented with an empty array (with bounds (0,-1))+data Match a =+ Match+ { matchSource :: !a -- ^ the whole source text+ , captureNames :: !CaptureNames -- ^ the RE's capture names+ , matchArray :: !(Array CaptureOrdinal (Capture a))+ -- ^ 0..n-1 captures,+ -- starting with the+ -- text matched by the+ -- whole RE+ }+ deriving (Show,Eq,Typeable)+\end{code}++\begin{code}+-- | Construct a Match that does not match anything.+noMatch :: a -> Match a+noMatch t = Match t noCaptureNames emptyMatchArray++-- | an empty array of Capture+emptyMatchArray :: Array CaptureOrdinal (Capture a)+emptyMatchArray = listArray (CaptureOrdinal 0,CaptureOrdinal $ -1) []+\end{code}++\begin{code}+instance Functor Match where+ fmap f Match{..} =+ Match+ { matchSource = f matchSource+ , captureNames = captureNames+ , matchArray = fmap (fmap f) matchArray+ }+\end{code}++\begin{code}+-- | tests whether the RE matched the source text at all+matched :: Match a -> Bool+matched = isJust . matchCapture++-- | tests whether the RE matched the source text at all+matchedText :: Match a -> Maybe a+matchedText = fmap capturedText . matchCapture++-- | the top-level capture if the source text matched the RE,+-- Nothing otherwise+matchCapture :: Match a -> Maybe (Capture a)+matchCapture = fmap fst . matchCaptures++-- | the top-level capture and the sub captures if the text matched+-- the RE, Nothing otherwise+matchCaptures :: Match a -> Maybe (Capture a,[Capture a])+matchCaptures Match{..} = case rangeSize (bounds matchArray) == 0 of+ True -> Nothing+ False -> Just (matchArray!0,drop 1 $ elems matchArray)++-- | an alternative for captureText+(!$$) :: Match a -> CaptureID -> a+(!$$) = flip captureText++-- | look up the text of the nth capture, 0 being the match of the whole+-- RE against the source text, 1, the first bracketed sub-expression to+-- be matched and so on+captureText :: CaptureID -> Match a -> a+captureText cid mtch = capturedText $ capture cid mtch++-- | an alternative for captureTextMaybe+(!$$?) :: Match a -> CaptureID -> Maybe a+(!$$?) = flip captureTextMaybe++-- | look up the text of the nth capture (0 being the match of the+-- whole), returning Nothing if the Match doesn't contain the capture+captureTextMaybe :: CaptureID -> Match a -> Maybe a+captureTextMaybe cid mtch = do+ cap <- mtch !$? cid+ case hasCaptured cap of+ True -> Just $ capturedText cap+ False -> Nothing++-- | an alternative for capture+(!$) :: Match a -> CaptureID -> Capture a+(!$) = flip capture++-- | look up the nth capture, 0 being the match of the whole RE against+-- the source text, 1, the first bracketed sub-expression to be matched+-- and so on+capture :: CaptureID -> Match a -> Capture a+capture cid mtch = fromMaybe oops $ mtch !$? cid+ where+ oops = error $ "capture: out of bounds (" ++ show cid ++ ")"++-- | an alternative for capture captureMaybe+(!$?) :: Match a -> CaptureID -> Maybe (Capture a)+(!$?) = flip captureMaybe++-- | look up the nth capture, 0 being the match of the whole RE against+-- the source text, 1, the first bracketed sub-expression to be matched+-- and so on, returning Nothing if there is no such capture, or if the+-- capture failed to capture anything (being in a failed alternate)+captureMaybe :: CaptureID -> Match a -> Maybe (Capture a)+captureMaybe cid mtch@Match{..} = do+ cap <- case bounds matchArray `inRange` CaptureOrdinal i of+ True -> Just $ matchArray ! CaptureOrdinal i+ False -> Nothing+ case hasCaptured cap of+ True -> Just cap+ False -> Nothing+ where+ i = lookupCaptureID cid mtch++lookupCaptureID :: CaptureID -> Match a -> Int+lookupCaptureID cid Match{..} = findCaptureID cid captureNames+\end{code}+++\begin{code}+-- | this instance hooks 'Match' into regex-base: regex consumers need+-- not worry about any of this+instance+ ( RegexContext regex source (AllTextSubmatches (Array Int) (source,(Int,Int)))+ , RegexLike regex source+ ) =>+ RegexContext regex source (Match source) where+ match r s = convertMatchText s $ getAllTextSubmatches $ match r s+ matchM r s = do+ y <- matchM r s+ return $ convertMatchText s $ getAllTextSubmatches y+\end{code}++\begin{code}+-- | convert a regex-base native MatchText into a regex Match type+convertMatchText :: source -> MatchText source -> Match source+convertMatchText hay arr =+ Match+ { matchSource = hay+ , captureNames = noCaptureNames+ , matchArray =+ ixmap (CaptureOrdinal lo,CaptureOrdinal hi) getCaptureOrdinal $+ fmap f arr+ }+ where+ (lo,hi) = bounds arr++ f (ndl,(off,len)) =+ Capture+ { captureSource = hay+ , capturedText = ndl+ , captureOffset = off+ , captureLength = len+ }+\end{code}
+ Text/RE/ZeInternals/Types/Matches.lhs view
@@ -0,0 +1,80 @@+\begin{code}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE DeriveDataTypeable #-}+\end{code}++\begin{code}+module Text.RE.ZeInternals.Types.Matches+ ( Matches(..)+ , anyMatches+ , countMatches+ , matches+ , mainCaptures+ ) where+\end{code}++\begin{code}+import Data.Typeable+import Text.Regex.Base+import Text.RE.ZeInternals.Types.Capture+import Text.RE.ZeInternals.Types.CaptureID+import Text.RE.ZeInternals.Types.Match+\end{code}+++\begin{code}+-- | the result type to use when every match is needed, not just the+-- first match of the RE against the source+data Matches a =+ Matches+ { matchesSource :: !a -- ^ the source text being matched+ , allMatches :: ![Match a] -- ^ all 'Match' instances found, left to right+ }+ deriving (Show,Eq,Typeable)+\end{code}++\begin{code}+instance Functor Matches where+ fmap f Matches{..} =+ Matches+ { matchesSource = f matchesSource+ , allMatches = map (fmap f) allMatches+ }+\end{code}++\begin{code}+-- | tests whether the RE matched the source text at all+anyMatches :: Matches a -> Bool+anyMatches = not . null . allMatches++-- | count the matches+countMatches :: Matches a -> Int+countMatches = length . allMatches++-- | list the Matches+matches :: Matches a -> [a]+matches = map capturedText . mainCaptures++-- | extract the main capture from each match+mainCaptures :: Matches a -> [Capture a]+mainCaptures ac = [ capture c0 cs | cs<-allMatches ac ]+ where+ c0 = IsCaptureOrdinal $ CaptureOrdinal 0+\end{code}++\begin{code}+-- | this instance hooks 'Matches' into regex-base: regex consumers need+-- not worry about any of this+instance+ ( RegexContext regex source [MatchText source]+ , RegexLike regex source+ ) =>+ RegexContext regex source (Matches source) where+ match r s = Matches s $ map (convertMatchText s) $ match r s+ matchM r s = do+ y <- matchM r s+ return $ Matches s $ map (convertMatchText s) y+\end{code}
+ Text/RE/ZeInternals/Types/SearchReplace.hs view
@@ -0,0 +1,15 @@++module Text.RE.ZeInternals.Types.SearchReplace+ ( SearchReplace(..)+ ) where++-- | contains a compiled RE and replacement template+data SearchReplace re s =+ SearchReplace+ { getSearch :: !re -- ^ the RE+ , getTemplate :: !s -- ^ the replacement template+ }+ deriving (Show)++instance Functor (SearchReplace re) where+ fmap f (SearchReplace re x) = SearchReplace re (f x)
changelog view
@@ -1,5 +1,10 @@ -*-change-log-*- +0.11.0.0 Chris Dornan <chris.dornan@irisconnect.co.uk> 2017-03-29+ * Simplify API (#97)+ * Rename Location to RELocation (#98)+ * Rename the MacrosDescriptor Fields #99+ 0.10.0.3 Chris Dornan <chris.dornan@irisconnect.co.uk> 2017-03-28 * Update to LTS-8.6 (#95) * Improve Haddocks for Text.RE.{TDFA,PCRE} (#94)
regex.cabal view
@@ -1,5 +1,5 @@ Name: regex-Version: 0.10.0.3+Version: 0.11.0.0 Synopsis: Toolkit for regex-base Description: A Regular Expression Toolkit for regex-base with Compile-time checking of RE syntax, data types for@@ -31,7 +31,7 @@ Source-Repository this Type: git Location: https://github.com/iconnect/regex.git- Tag: 0.10.0.3+ Tag: 0.11.0.0 @@ -41,49 +41,48 @@ Exposed-Modules: Text.RE- Text.RE.Internal.AddCaptureNames- Text.RE.Internal.EscapeREString- Text.RE.Internal.NamedCaptures- Text.RE.Internal.PreludeMacros- Text.RE.SearchReplace+ Text.RE.IsRegex+ Text.RE.Replace Text.RE.Summa Text.RE.TDFA Text.RE.TDFA.ByteString Text.RE.TDFA.ByteString.Lazy- Text.RE.TDFA.RE Text.RE.TDFA.Sequence Text.RE.TDFA.String Text.RE.TDFA.Text Text.RE.TDFA.Text.Lazy Text.RE.TestBench- Text.RE.TestBench.Parsers Text.RE.Tools Text.RE.Tools.Edit Text.RE.Tools.Grep Text.RE.Tools.Lex Text.RE.Tools.Sed- Text.RE.Types- Text.RE.Types.Capture- Text.RE.Types.CaptureID- Text.RE.Types.IsRegex- Text.RE.Types.LineNo- Text.RE.Types.Match- Text.RE.Types.Matches- Text.RE.Types.REOptions- Text.RE.Types.Replace- Text.RE.Types.SearchReplace+ Text.RE.ZeInternals.AddCaptureNames+ Text.RE.ZeInternals.EscapeREString+ Text.RE.ZeInternals.NamedCaptures+ Text.RE.ZeInternals.PreludeMacros+ Text.RE.ZeInternals.Replace+ Text.RE.ZeInternals.TDFA+ Text.RE.ZeInternals.TestBench+ Text.RE.ZeInternals.Types.Capture+ Text.RE.ZeInternals.Types.CaptureID+ Text.RE.ZeInternals.Types.LineNo+ Text.RE.ZeInternals.Types.Match+ Text.RE.ZeInternals.Types.Matches+ Text.RE.REOptions+ Text.RE.ZeInternals.Types.SearchReplace Other-Modules:- Text.RE.Internal.QQ- Text.RE.Internal.SearchReplace- Text.RE.Internal.SearchReplace.TDFA- Text.RE.Internal.SearchReplace.TDFA.ByteString- Text.RE.Internal.SearchReplace.TDFA.ByteString.Lazy- Text.RE.Internal.SearchReplace.TDFA.Sequence- Text.RE.Internal.SearchReplace.TDFA.String- Text.RE.Internal.SearchReplace.TDFA.Text- Text.RE.Internal.SearchReplace.TDFA.Text.Lazy- Text.RE.Internal.SearchReplace.TDFAEdPrime+ Text.RE.ZeInternals.QQ+ Text.RE.ZeInternals.SearchReplace+ Text.RE.ZeInternals.SearchReplace.TDFA+ Text.RE.ZeInternals.SearchReplace.TDFA.ByteString+ Text.RE.ZeInternals.SearchReplace.TDFA.ByteString.Lazy+ Text.RE.ZeInternals.SearchReplace.TDFA.Sequence+ Text.RE.ZeInternals.SearchReplace.TDFA.String+ Text.RE.ZeInternals.SearchReplace.TDFA.Text+ Text.RE.ZeInternals.SearchReplace.TDFA.Text.Lazy+ Text.RE.ZeInternals.SearchReplace.TDFAEdPrime Default-Language: Haskell2010