regex-tdfa 1.3.0 → 1.3.1.0
raw patch · 13 files changed
+423/−134 lines, 13 filesdep +directorydep +textdep −file-embeddep −ghc-primdep ~basedep ~bytestringdep ~containerssetup-changednew-uploaderPVP ok
version bump matches the API change (PVP)
Dependencies added: directory, text
Dependencies removed: file-embed, ghc-prim
Dependency ranges changed: base, bytestring, containers, filepath, mtl, parsec, regex-base, regex-tdfa, semigroups, utf8-string
API changes (from Hackage documentation)
+ Text.Regex.TDFA.NewDFA.Uncons: instance Text.Regex.TDFA.NewDFA.Uncons.Uncons Data.Text.Internal.Lazy.Text
+ Text.Regex.TDFA.NewDFA.Uncons: instance Text.Regex.TDFA.NewDFA.Uncons.Uncons Data.Text.Internal.Text
+ Text.Regex.TDFA.Text: compile :: CompOption -> ExecOption -> Text -> Either String Regex
+ Text.Regex.TDFA.Text: data CompOption
+ Text.Regex.TDFA.Text: data ExecOption
+ Text.Regex.TDFA.Text: data Regex
+ Text.Regex.TDFA.Text: execute :: Regex -> Text -> Either String (Maybe MatchArray)
+ Text.Regex.TDFA.Text: instance Text.Regex.Base.RegexLike.RegexContext Text.Regex.TDFA.Common.Regex Data.Text.Internal.Text Data.Text.Internal.Text
+ Text.Regex.TDFA.Text: instance Text.Regex.Base.RegexLike.RegexLike Text.Regex.TDFA.Common.Regex Data.Text.Internal.Text
+ Text.Regex.TDFA.Text: instance Text.Regex.Base.RegexLike.RegexMaker Text.Regex.TDFA.Common.Regex Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption Data.Text.Internal.Text
+ Text.Regex.TDFA.Text: regexec :: Regex -> Text -> Either String (Maybe (Text, Text, Text, [Text]))
+ Text.Regex.TDFA.Text.Lazy: compile :: CompOption -> ExecOption -> Text -> Either String Regex
+ Text.Regex.TDFA.Text.Lazy: data CompOption
+ Text.Regex.TDFA.Text.Lazy: data ExecOption
+ Text.Regex.TDFA.Text.Lazy: data Regex
+ Text.Regex.TDFA.Text.Lazy: execute :: Regex -> Text -> Either String (Maybe MatchArray)
+ Text.Regex.TDFA.Text.Lazy: instance Text.Regex.Base.RegexLike.RegexContext Text.Regex.TDFA.Common.Regex Data.Text.Internal.Lazy.Text Data.Text.Internal.Lazy.Text
+ Text.Regex.TDFA.Text.Lazy: instance Text.Regex.Base.RegexLike.RegexLike Text.Regex.TDFA.Common.Regex Data.Text.Internal.Lazy.Text
+ Text.Regex.TDFA.Text.Lazy: instance Text.Regex.Base.RegexLike.RegexMaker Text.Regex.TDFA.Common.Regex Text.Regex.TDFA.Common.CompOption Text.Regex.TDFA.Common.ExecOption Data.Text.Internal.Lazy.Text
+ Text.Regex.TDFA.Text.Lazy: regexec :: Regex -> Text -> Either String (Maybe (Text, Text, Text, [Text]))
Files
- CHANGELOG.md +20/−8
- Setup.hs +0/−6
- lib/Data/IntMap/EnumMap2.hs +3/−3
- lib/Text/Regex/TDFA.hs +14/−11
- lib/Text/Regex/TDFA/NewDFA/Engine.hs +3/−3
- lib/Text/Regex/TDFA/NewDFA/Engine_FA.hs +3/−3
- lib/Text/Regex/TDFA/NewDFA/Uncons.hs +12/−0
- lib/Text/Regex/TDFA/TDFA.hs +2/−2
- lib/Text/Regex/TDFA/TNFA.hs +2/−2
- lib/Text/Regex/TDFA/Text.hs +101/−0
- lib/Text/Regex/TDFA/Text/Lazy.hs +109/−0
- regex-tdfa.cabal +119/−62
- test/Main.hs +35/−34
CHANGELOG.md view
@@ -1,38 +1,50 @@+See also http://pvp.haskell.org/faq++## 1.3.1.0++- Merge <http://hackage.haskell.org/package/regex-tdfa-text> into `regex-tdfa`; see <https://github.com/haskell-hvr/regex-tdfa/issues/4>.+- Don't inject `ghc-options: -O2` by default anymore (see #7 for rationale) and introduce `force-O2` cabal flag to control the injection of `ghc-options: -O2`.+ Note that you can conveniently control optimization levels on a per-package granularity via `cabal.project` files; see [cabal's user-guide](https://cabal.readthedocs.io/en/latest/nix-local-build.html#configuring-builds-with-cabal-project) for more details.+ # 1.3.0 -Same as 1.2.3.3.+- Same as 1.2.3.3 release; see <https://github.com/ChrisKuklewicz/regex-tdfa/issues/29>.+- Compatibility with GHC 8.8 and regex-base-0.9.4 (h/t @asr).+- Turned `regex-tdfa-unittest` into a `regex-tdfa` testsuite. -See <https://github.com/ChrisKuklewicz/regex-tdfa/issues/29>.+---- -# 1.2.3.3 (deprecated)+### 1.2.3.3 (deprecated) * Compatibility with GHC 8.8 and regex-base-0.9.4 (h/t @asr). * Turned `regex-tdfa-unittest` into a `regex-tdfa` testsuite. -# 1.2.3.2+### 1.2.3.2 * Significantly improved documentation (h/t William Yao). -# 1.2.3.1+### 1.2.3.1 * Compatibility with `containers-0.6`. -# 1.2.3+## 1.2.3 * Added `Semigroup` instances for some types (h/t Herbert Valerio Riedel). -# 1.2.2+## 1.2.2 * New maintainer. * Now we don't reexport the problematic `Show` instance for functions. -# 1.2.1+## 1.2.1 * Updated dependency versions. # 1.2.0 "Almost ghc-7.8" with the array 0.4 changes for `Data.Array.Unsafe`++---- # 1.1.8
− Setup.hs
@@ -1,6 +0,0 @@-#!/usr/bin/env runhaskell---- I usually compile this with "ghc --make -o setup Setup.hs"--import Distribution.Simple(defaultMain)-main = defaultMain
lib/Data/IntMap/EnumMap2.hs view
@@ -2,7 +2,7 @@ module Data.IntMap.EnumMap2 where -import Data.Foldable(Foldable(..))+import Data.Foldable as F (Foldable(foldMap)) import qualified Data.IntMap as M #if MIN_VERSION_containers(0,6,0) import qualified Data.IntMap.Internal.Debug as MD@@ -27,8 +27,8 @@ instance Ord k => Functor (EnumMap k) where fmap f (EnumMap m) = EnumMap (fmap f m) -instance Ord k => Foldable (EnumMap k) where- foldMap f (EnumMap m) = foldMap f m+instance Ord k => F.Foldable (EnumMap k) where+ foldMap f (EnumMap m) = F.foldMap f m (!) :: (Enum key) => EnumMap key a -> key -> a (!) (EnumMap m) k = (M.!) m (fromEnum k)
lib/Text/Regex/TDFA.hs view
@@ -1,4 +1,8 @@ {-|+Module: Text.Regex.TDFA+Copyright: (c) Chris Kuklewicz 2007-2009+SPDX-License-Identifier: BSD-3-Clause+Maintainer: hvr@gnu.org The "Text.Regex.TDFA" module provides a backend for regular expressions. It provides instances for the classes defined and@@ -7,25 +11,22 @@ qualified imports (with renaming for convenience). This regex-tdfa package implements, correctly, POSIX extended regular-expressions. It is highly unlikely that the regex-posix package on+expressions. It is highly unlikely that the @regex-posix@ package on your operating system is correct, see <http://www.haskell.org/haskellwiki/Regex_Posix> for examples of your OS's bugs. = Importing and using -Add to your package.yaml/cabal file:--> dependencies:-> - regex-tdfa+<https://www.haskell.org/cabal/users-guide/developing-packages.html#pkg-field-build-depends Declare a dependency> on the @regex-tdfa@ library in your @.cabal@ file: -In modules where you need to use regexes:+> build-depends: regex-tdfa ^>= 1.3.1.0 -> import Text.Regex.TDFA+In Haskell modules where you want to use regexes simply @import@ /this/ module: -Note that regex-tdfa does not provide support for @Text@ by default.-If you need this functionality, add <https://hackage.haskell.org/package/regex-tdfa-text regex-tdfa-text>-as a dependency and @import Text.Regex.TDFA.Text ()@.+@+import "Text.Regex.TDFA"+@ = Basics @@ -115,7 +116,7 @@ This package does provide captured parenthesized subexpressions. Depending on the text being searched this package supports Unicode.-The @[Char]@ and @(Seq Char)@ text types support Unicode. The @ByteString@+The @[Char]@, @Text@, @Text.Lazy@, and @(Seq Char)@ text types support Unicode. The @ByteString@ and @ByteString.Lazy@ text types only support ASCII. It is possible to support utf8 encoded @ByteString.Lazy@ by using regex-tdfa and <http://hackage.haskell.org/package/regex-tdfa-utf8 regex-tdfa-utf8>@@ -182,6 +183,8 @@ import Text.Regex.TDFA.String() import Text.Regex.TDFA.ByteString() import Text.Regex.TDFA.ByteString.Lazy()+import Text.Regex.TDFA.Text()+import Text.Regex.TDFA.Text.Lazy() import Text.Regex.TDFA.Sequence() import Text.Regex.TDFA.Common(Regex,CompOption(..),ExecOption(..)) --import Text.Regex.TDFA.Wrap(Regex,CompOption(..),ExecOption(..),(=~),(=~~))
lib/Text/Regex/TDFA/NewDFA/Engine.hs view
@@ -10,7 +10,7 @@ -- #ifdef __GLASGOW_HASKELL__ import GHC.Arr(STArray(..)) import GHC.ST(ST(..))-import GHC.Prim(MutableByteArray#,RealWorld,Int#,sizeofMutableByteArray#,unsafeCoerce#)+import GHC.Exts(MutableByteArray#,RealWorld,Int#,sizeofMutableByteArray#,unsafeCoerce#) {- -- #else import Control.Monad.ST(ST)@@ -26,7 +26,7 @@ import Data.IntMap(IntMap) import qualified Data.IntMap as IMap(null,toList,lookup,insert) import Data.Maybe(catMaybes)-import Data.Monoid(Monoid(..))+import Data.Monoid as Mon(Monoid(..)) import qualified Data.IntSet as ISet(toAscList) import Data.Array.IArray((!)) import Data.List(partition,sort,foldl',sortBy,groupBy)@@ -523,7 +523,7 @@ newMScratch :: (Index,Index) -> S.ST s (MScratch s) newMScratch b_index = do pos's <- newArray b_index Nothing- orbit's <- newArray b_index mempty+ orbit's <- newArray b_index Mon.mempty return (MScratch pos's orbit's) {- COMPOSE A FUNCTION CLOSURE TO COMPARE TAG VALUES -}
lib/Text/Regex/TDFA/NewDFA/Engine_FA.hs view
@@ -10,7 +10,7 @@ -- #ifdef __GLASGOW_HASKELL__ import GHC.Arr(STArray(..)) import GHC.ST(ST(..))-import GHC.Prim(MutableByteArray#,RealWorld,Int#,sizeofMutableByteArray#,unsafeCoerce#)+import GHC.Exts(MutableByteArray#,RealWorld,Int#,sizeofMutableByteArray#,unsafeCoerce#) {- -- #else import Control.Monad.ST(ST)@@ -27,7 +27,7 @@ import Data.IntMap(IntMap) import qualified Data.IntMap as IMap(null,toList,lookup,insert) import Data.Maybe(catMaybes)-import Data.Monoid(Monoid(..))+import Data.Monoid as Mon(Monoid(..)) import qualified Data.IntSet as ISet(toAscList,null) import Data.Array.IArray((!)) import Data.List(sortBy,groupBy)@@ -382,7 +382,7 @@ newMScratch :: (Index,Index) -> S.ST s (MScratch s) newMScratch b_index = do pos's <- newArray b_index Nothing- orbit's <- newArray b_index mempty+ orbit's <- newArray b_index Mon.mempty return (MScratch pos's orbit's) {- COMPOSE A FUNCTION CLOSURE TO COMPARE TAG VALUES -}
lib/Text/Regex/TDFA/NewDFA/Uncons.hs view
@@ -3,6 +3,8 @@ import qualified Data.ByteString.Char8 as SBS(ByteString,uncons) import qualified Data.ByteString.Lazy.Char8 as LBS(ByteString,uncons) import Data.Sequence(Seq,viewl,ViewL(EmptyL,(:<)))+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL class Uncons a where {- INLINE uncons #-}@@ -26,3 +28,13 @@ instance Uncons LBS.ByteString where {- INLINE uncons #-} uncons = LBS.uncons++-- | @since 1.3.1+instance Uncons T.Text where+ {- INLINE uncons #-}+ uncons = T.uncons++-- | @since 1.3.1+instance Uncons TL.Text where+ {- INLINE uncons #-}+ uncons = TL.uncons
lib/Text/Regex/TDFA/TDFA.hs view
@@ -6,7 +6,7 @@ ,examineDFA,nfaToDFA,dfaMap) where --import Control.Arrow((***))-import Data.Monoid(Monoid(..))+import Data.Monoid as Mon(Monoid(..)) import Control.Monad.State(State,MonadState(..),execState) import Data.Array.IArray(Array,(!),bounds,{-assocs-}) import Data.IntMap(IntMap)@@ -424,7 +424,7 @@ newOrbit pos = Orbits { inOrbit = inOrbit' , basePos = pos , ordinal = Nothing- , getOrbits = mempty}+ , getOrbits = Mon.mempty} updateOrbit pos _tag new old | inOrbit old = old { inOrbit = inOrbit' , getOrbits = getOrbits old |> pos } | otherwise = new
lib/Text/Regex/TDFA/TNFA.hs view
@@ -47,7 +47,7 @@ import Data.IntSet.EnumSet2(EnumSet) import qualified Data.IntSet.EnumSet2 as Set(singleton,toList,insert) import Data.Maybe(catMaybes,isNothing)-import Data.Monoid(mempty,mappend)+import Data.Monoid as Mon(Monoid(..)) import qualified Data.Set as S(Set,insert,toAscList,empty) import Text.Regex.TDFA.Common(QT(..),QNFA(..),QTrans,TagTask(..),TagUpdate(..),DoPa(..)@@ -771,7 +771,7 @@ addNewline | multiline compOpt = S.insert '\n' | otherwise = id dotTrans | multiline compOpt = Map.singleton '\n' mempty- | otherwise = mempty+ | otherwise = Mon.mempty {-
+ lib/Text/Regex/TDFA/Text.hs view
@@ -0,0 +1,101 @@+{-|+Module : Text.Regex.TDFA.Text+Copyright : Chris Kuklewicz 2007-2009, shelarcy 2012+License : BSD-style (see the file LICENSE)++This modules provides 'RegexMaker' and 'RegexLike' instances for using+'Text' with the TDFA backend ("Text.Regex.TDFA.NewDFA.Engine" and+"Text.Regex.TDFA.NewDFA.Tester").++This exports instances of the high level API and the medium level+API of 'compile','execute', and 'regexec'.++@since 1.3.1+-}+module Text.Regex.TDFA.Text(+ Regex+ ,CompOption+ ,ExecOption+ ,compile+ ,execute+ ,regexec+ ) where++import Data.Array((!),elems)+import qualified Data.Text as T(Text,unpack)++import Text.Regex.Base(RegexLike(..),RegexMaker(..),Extract(..),MatchArray,RegexContext(..))+import Text.Regex.Base.Impl(polymatch,polymatchM)+import Text.Regex.TDFA.ReadRegex(parseRegex)+import Text.Regex.TDFA.String() -- piggyback on RegexMaker for String+import Text.Regex.TDFA.TDFA(patternToRegex)+import Text.Regex.TDFA.Common(Regex(..),CompOption,ExecOption(captureGroups),Position)++import Data.Maybe(listToMaybe)+import Text.Regex.TDFA.NewDFA.Uncons(Uncons)+import qualified Text.Regex.TDFA.NewDFA.Engine as Engine(execMatch)+import qualified Text.Regex.TDFA.NewDFA.Tester as Tester(matchTest)++-- | @since 1.3.1+instance RegexContext Regex T.Text T.Text where+ match = polymatch+ matchM = polymatchM++-- | @since 1.3.1+instance RegexMaker Regex CompOption ExecOption T.Text where+ makeRegexOptsM c e source = makeRegexOptsM c e (T.unpack source)++-- | @since 1.3.1+{-# SPECIALIZE execMatch :: Regex -> Position -> Char -> T.Text -> [MatchArray] #-}+execMatch :: Uncons text => Regex -> Position -> Char -> text -> [MatchArray]+execMatch = Engine.execMatch++-- | @since 1.3.1+{-# SPECIALIZE myMatchTest :: Regex -> T.Text -> Bool #-}+myMatchTest :: Uncons text => Regex -> text -> Bool+myMatchTest = Tester.matchTest++-- | @since 1.3.1+instance RegexLike Regex T.Text where+ matchOnce r s = listToMaybe (matchAll r s)+ matchAll r s = execMatch r 0 '\n' s+ matchCount r s = length (matchAll r' s)+ where r' = r { regex_execOptions = (regex_execOptions r) {captureGroups = False} }+ matchTest = myMatchTest+ matchOnceText regex source =+ fmap (\ma -> let (o,l) = ma!0+ in (before o source+ ,fmap (\ol -> (extract ol source,ol)) ma+ ,after (o+l) source))+ (matchOnce regex source)+ matchAllText regex source =+ map (fmap (\ol -> (extract ol source,ol)))+ (matchAll regex source)++-- | @since 1.3.1+compile :: CompOption -- ^ Flags (summed together)+ -> ExecOption -- ^ Flags (summed together)+ -> T.Text -- ^ The regular expression to compile+ -> Either String Regex -- ^ Returns: the compiled regular expression+compile compOpt execOpt txt =+ case parseRegex (T.unpack txt) of+ Left err -> Left ("parseRegex for Text.Regex.TDFA.Text failed:"++show err)+ Right pattern -> Right (patternToRegex pattern compOpt execOpt)++-- | @since 1.3.1+execute :: Regex -- ^ Compiled regular expression+ -> T.Text -- ^ Text to match against+ -> Either String (Maybe MatchArray)+execute r txt = Right (matchOnce r txt)++-- | @since 1.3.1+regexec :: Regex -- ^ Compiled regular expression+ -> T.Text -- ^ Text to match against+ -> Either String (Maybe (T.Text, T.Text, T.Text, [T.Text]))+regexec r txt =+ case matchOnceText r txt of+ Nothing -> Right (Nothing)+ Just (pre,mt,post) ->+ let main = fst (mt!0)+ rest = map fst (tail (elems mt)) -- will be []+ in Right (Just (pre,main,post,rest))
+ lib/Text/Regex/TDFA/Text/Lazy.hs view
@@ -0,0 +1,109 @@+{-|+Module : Text.Regex.TDFA.Text.Lazy+Copyright : Chris Kuklewicz 2007-2009, shelarcy 2012+License : BSD-style (see the file LICENSE)++This modules provides 'RegexMaker' and 'RegexLike' instances for using+'Text' with the TDFA backend ("Text.Regex.TDFA.NewDFA.Engine" and+"Text.Regex.TDFA.NewDFA.Tester").++This exports instances of the high level API and the medium level+API of 'compile','execute', and 'regexec'.++@since 1.3.1+-}+module Text.Regex.TDFA.Text.Lazy(+ Regex+ ,CompOption+ ,ExecOption+ ,compile+ ,execute+ ,regexec+ ) where++import Data.Array.IArray(Array,(!),elems)+import qualified Data.Text.Lazy as L(Text,unpack)++import Text.Regex.Base(MatchArray,RegexContext(..),Extract(..),RegexMaker(..),RegexLike(..))+import Text.Regex.Base.Impl(polymatch,polymatchM)+import Text.Regex.TDFA.ReadRegex(parseRegex)+import Text.Regex.TDFA.String() -- piggyback on RegexMaker for String+import Text.Regex.TDFA.TDFA(patternToRegex)+import Text.Regex.TDFA.Common(Regex(..),CompOption,ExecOption(captureGroups),Position)++import Data.Maybe(listToMaybe)+import Text.Regex.TDFA.NewDFA.Uncons(Uncons)+import qualified Text.Regex.TDFA.NewDFA.Engine as Engine(execMatch)+import qualified Text.Regex.TDFA.NewDFA.Tester as Tester(matchTest)++-- | @since 1.3.1+instance RegexContext Regex L.Text L.Text where+ match = polymatch+ matchM = polymatchM++-- | @since 1.3.1+instance RegexMaker Regex CompOption ExecOption L.Text where+ makeRegexOptsM c e source = makeRegexOptsM c e (L.unpack source)++-- | @since 1.3.1+{-# SPECIALIZE execMatch :: Regex -> Position -> Char -> L.Text -> [MatchArray] #-}+execMatch :: Uncons text => Regex -> Position -> Char -> text -> [MatchArray]+execMatch = Engine.execMatch++-- | @since 1.3.1+{-# SPECIALIZE myMatchTest :: Regex -> L.Text -> Bool #-}+myMatchTest :: Uncons text => Regex -> text -> Bool+myMatchTest = Tester.matchTest++-- | @since 1.3.1+instance RegexLike Regex L.Text where+ matchOnce r s = listToMaybe (matchAll r s)+ matchAll r s = execMatch r 0 '\n' s+ matchCount r s = length (matchAll r' s)+ where r' = r { regex_execOptions = (regex_execOptions r) {captureGroups = False} }+ matchTest = myMatchTest+ matchOnceText regex source =+ fmap (\ ma ->+ let (o,l) = ma!0+ in (before o source+ ,fmap (\ ol -> (extract ol source,ol)) ma+ ,after (o+l) source))+ (matchOnce regex source)+ matchAllText regex source =+ let go :: Int -> L.Text -> [Array Int (Int, Int)] -> [Array Int (L.Text, (Int, Int))]+ go i _ _ | i `seq` False = undefined+ go _i _t [] = []+ go i t (x:xs) =+ let (off0,len0) = x!0+ trans pair@(off,len) = (extract (off-i,len) t,pair)+ t' = after (off0+(len0-i)) t+ in fmap trans x : seq t' (go (off0+len0) t' xs)+ in go 0 source (matchAll regex source)++-- | @since 1.3.1+compile :: CompOption -- ^ Flags (summed together)+ -> ExecOption -- ^ Flags (summed together)+ -> L.Text -- ^ The regular expression to compile+ -> Either String Regex -- ^ Returns: the compiled regular expression+compile compOpt execOpt txt =+ case parseRegex (L.unpack txt) of+ Left err -> Left ("parseRegex for Text.Regex.TDFA.Text.Lazy failed:"++show err)+ Right pattern -> Right (patternToRegex pattern compOpt execOpt)++-- | @since 1.3.1+execute :: Regex -- ^ Compiled regular expression+ -> L.Text -- ^ Text to match against+ -> Either String (Maybe MatchArray)+execute r txt = Right (matchOnce r txt)++-- | @since 1.3.1+regexec :: Regex -- ^ Compiled regular expression+ -> L.Text -- ^ Text to match against+ -> Either String (Maybe (L.Text, L.Text, L.Text, [L.Text]))+regexec r txt =+ case matchOnceText r txt of+ Nothing -> Right (Nothing)+ Just (pre,mt,post) ->+ let main = fst (mt!0)+ rest = map fst (tail (elems mt)) -- will be []+ in Right (Just (pre,main,post,rest))
regex-tdfa.cabal view
@@ -1,17 +1,16 @@-Name: regex-tdfa-Version: 1.3.0-License: BSD3-License-File: LICENSE-Copyright: Copyright (c) 2007, Christopher Kuklewicz-Author: Christopher Kuklewicz-Maintainer: Artyom <yom@artyom.me>, Christopher Kuklewicz <TextRegexLazy@personal.mightyreason.com>-Stability: Seems to work, but not POSIX yet-Homepage: https://github.com/ChrisKuklewicz/regex-tdfa-Bug-Reports: https://github.com/ChrisKuklewicz/regex-tdfa/issues-Synopsis: Replaces/Enhances Text.Regex-Description: A new all Haskell "tagged" DFA regex engine, inspired by libtre-Category: Text-Tested-With: GHC==7.6.3+cabal-version: 1.12+name: regex-tdfa+version: 1.3.1.0++build-Type: Simple+license: BSD3+license-file: LICENSE+copyright: Copyright (c) 2007-2009, Christopher Kuklewicz+author: Christopher Kuklewicz+maintainer: hvr@gnu.org+bug-reports: https://github.com/hvr/regex-tdfa/issues+tested-with: GHC==7.4.2+ , GHC==7.6.3 , GHC==7.8.4 , GHC==7.10.3 , GHC==8.0.2@@ -19,32 +18,61 @@ , GHC==8.4.4 , GHC==8.6.5 , GHC==8.8.1-Build-Type: Simple++category: Text+synopsis: Pure Haskell Tagged DFA Backend for "Text.Regex" (regex-base)+description:+ This package provides a pure Haskell \"Tagged\" DFA regex engine for <//hackage.haskell.org/package/regex-base regex-base>. This implementation was inspired by the algorithm (and Master's thesis) behind the regular expression library known as <https://github.com/laurikari/tre/ TRE or libtre>.+ .+ Please consult the "Text.Regex.TDFA" module for API documentation including a tutorial with usage examples;+ see also <https://wiki.haskell.org/Regular_expressions> for general information about regular expression support in Haskell.+ extra-source-files: CHANGELOG.md test/cases/*.txt-Cabal-Version: >= 1.8 source-repository head type: git- location: git://github.com/ChrisKuklewicz/regex-tdfa.git+ location: https://github.com/hvr/regex-tdfa.git -flag devel- description: enable flags that are useful for development+flag force-O2 default: False manual: True+ description:+ Force building @regex-tdfa@ with \"@ghc-options: -O2@\".+ .+ __NOTE__: This flag is mostly provided for legacy use-cases. Nowadays you can conveniently control optimization levels on a per-package granularity via @cabal.project@ files; see <https://cabal.readthedocs.io/en/latest/nix-local-build.html#configuring-builds-with-cabal-project cabal's user-guide> for more details. library hs-source-dirs: lib- Build-Depends: array >= 0.4 && < 0.6- , base >= 4 && < 5- , bytestring >= 0.10 && < 0.11- , containers >= 0.5 && < 0.7- , ghc-prim- , mtl == 2.*- , parsec == 3.*- , regex-base >= 0.93.1 && < 0.95 + exposed-modules: Data.IntMap.CharMap2+ Data.IntMap.EnumMap2+ Data.IntSet.EnumSet2+ Text.Regex.TDFA+ Text.Regex.TDFA.ByteString+ Text.Regex.TDFA.ByteString.Lazy+ Text.Regex.TDFA.Common+ Text.Regex.TDFA.CorePattern+ Text.Regex.TDFA.IntArrTrieSet+ Text.Regex.TDFA.NewDFA.Engine+ Text.Regex.TDFA.NewDFA.Engine_FA+ Text.Regex.TDFA.NewDFA.Engine_NC+ Text.Regex.TDFA.NewDFA.Engine_NC_FA+ Text.Regex.TDFA.NewDFA.Tester+ Text.Regex.TDFA.NewDFA.Uncons+ Text.Regex.TDFA.NewDFA.MakeTest+ Text.Regex.TDFA.Pattern+ Text.Regex.TDFA.ReadRegex+ Text.Regex.TDFA.Sequence+ Text.Regex.TDFA.String+ Text.Regex.TDFA.TDFA+ Text.Regex.TDFA.TNFA+ Text.Regex.TDFA.Text+ Text.Regex.TDFA.Text.Lazy++ other-modules: Paths_regex_tdfa+ -- Support Semigroup instances uniformly -- -- See also@@ -54,46 +82,75 @@ -- add any new dependency that isn't already incurred by -- `regex-tdfa`'s transitive deps if !impl(ghc >= 8.0)- build-depends: fail- , semigroups == 0.18.*+ build-depends: fail == 4.9.*+ , semigroups == 0.18.* || == 0.19.*+ build-depends: array >= 0.4 && < 0.6+ , base >= 4.5 && < 4.14+ , bytestring >= 0.9.2 && < 0.11+ , containers >= 0.4.2 && < 0.7+ , mtl >= 2.1.3 && < 2.3+ , parsec == 3.1.*+ , regex-base == 0.94.*+ , text >= 1.2.3 && < 1.3 - other-modules: Paths_regex_tdfa- Exposed-Modules: Data.IntMap.CharMap2- Data.IntMap.EnumMap2- Data.IntSet.EnumSet2- Text.Regex.TDFA- Text.Regex.TDFA.ByteString- Text.Regex.TDFA.ByteString.Lazy- Text.Regex.TDFA.Common- Text.Regex.TDFA.CorePattern- Text.Regex.TDFA.IntArrTrieSet- Text.Regex.TDFA.NewDFA.Engine- Text.Regex.TDFA.NewDFA.Engine_FA- Text.Regex.TDFA.NewDFA.Engine_NC- Text.Regex.TDFA.NewDFA.Engine_NC_FA- Text.Regex.TDFA.NewDFA.Tester- Text.Regex.TDFA.NewDFA.Uncons- Text.Regex.TDFA.NewDFA.MakeTest- Text.Regex.TDFA.Pattern- Text.Regex.TDFA.ReadRegex- Text.Regex.TDFA.Sequence- Text.Regex.TDFA.String- Text.Regex.TDFA.TDFA- Text.Regex.TDFA.TNFA- Buildable: True- Extensions: MultiParamTypeClasses, FunctionalDependencies, BangPatterns, MagicHash, RecursiveDo, NoMonoPatBinds, ForeignFunctionInterface, UnboxedTuples, TypeOperators, FlexibleContexts, ExistentialQuantification, UnliftedFFITypes, TypeSynonymInstances, FlexibleInstances- GHC-Options: -Wall -funbox-strict-fields -fspec-constr-count=10 -O2 -fno-warn-orphans- if flag(devel)- ghc-prof-options: -auto-all+ default-language: Haskell2010+ default-extensions: BangPatterns+ ExistentialQuantification+ FlexibleContexts+ FlexibleInstances+ ForeignFunctionInterface+ FunctionalDependencies+ MagicHash+ MultiParamTypeClasses+ NoMonoPatBinds+ NondecreasingIndentation+ RecursiveDo+ TypeOperators+ TypeSynonymInstances+ UnboxedTuples+ UnliftedFFITypes+ other-extensions: CPP + ghc-options: -Wall -funbox-strict-fields -fspec-constr-count=10 -fno-warn-orphans++ if flag(force-O2)+ ghc-options: -O2++ test-suite regex-tdfa-unittest type: exitcode-stdio-1.0- build-depends: regex-base >= 0.93.1, base >=4 && < 5, regex-tdfa >= 0.92, bytestring, containers, array, mtl, file-embed, filepath, utf8-string+ hs-source-dirs: test main-is: Main.hs- extensions: FlexibleInstances, FlexibleContexts,Rank2Types- GHC-Options: -Wall -O2 -funbox-strict-fields- if flag(devel)- ghc-prof-options: -auto-all++ -- intra-package dependency+ build-depends: regex-tdfa++ -- dependencies whose version constraints are inherited via intra-package 'regex-tdfa' dependency if !impl(ghc >= 8.0) build-depends: fail+ , semigroups+ build-depends: array+ , base+ , bytestring+ , containers+ , filepath+ , mtl+ , regex-base+ , text++ -- component-specific dependencies not inherited via 'regex-tdfa'+ , directory >= 1.1.0 && < 1.4+ , filepath >= 1.3.0 && < 1.5+ , utf8-string >= 1.0.1 && < 1.1++ default-language: Haskell2010+ default-extensions: FlexibleInstances+ FlexibleContexts+ Rank2Types+ other-extensions: GeneralizedNewtypeDeriving++ ghc-options: -Wall -funbox-strict-fields++ if flag(force-O2)+ ghc-options: -O2
test/Main.hs view
@@ -1,28 +1,25 @@-{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MonoLocalBinds #-} module Main where -import Control.Monad-import Control.Monad.Error()-import Data.Array-import Data.List-import Control.Applicative---import Data.Monoid-import Data.Sequence(Seq)-import Data.String-import Data.Typeable-import Data.Version()-import System.Environment-import Text.Regex.Base-import qualified Data.Foldable as F-import Data.FileEmbed+import Control.Applicative as App+import Control.Monad+import qualified Control.Monad.Fail as Fail+import Data.Array+import qualified Data.ByteString as BS import qualified Data.ByteString.UTF8 as UTF8-import qualified Control.Monad.Fail as Fail-import System.Exit+import Data.List+import Data.String+import Data.Typeable+import Data.Version ()+import System.Directory (getDirectoryContents)+import System.Environment+import System.Exit+import System.FilePath ((</>))+import Text.Regex.Base -import qualified Text.Regex.TDFA.Common as TDFA-import qualified Text.Regex.TDFA as TDFA+import qualified Text.Regex.TDFA as TDFA default(Int) @@ -55,18 +52,18 @@ toTest :: String -> (Int,String,String,String) toTest line = let [n,regex,input,output] = words line- noQ [] = []+ noQ [] = [] noQ ('?':xs) = '-':'1':noQ xs- noQ (x:xs) = x:noQ xs+ noQ (x:xs) = x:noQ xs input' = if input == "NULL" then "" else unN input in (read n,regex,input',noQ output) toTest' :: String -> String -> (String,(Int,String,String,String)) toTest' oldRegex line = let [n,regex,input,output] = words line- noQ [] = []+ noQ [] = [] noQ ('?':xs) = '-':'1':noQ xs- noQ (x:xs) = x:noQ xs+ noQ (x:xs) = x:noQ xs input' = if input == "NULL" then "" else input regex' = if regex == "SAME" then oldRegex else regex in (regex',(read n,regex',input',noQ output))@@ -107,22 +104,26 @@ p ("Actual result : "++show output') return (if n<0 then [] else [n]) -checkFile :: (RType -> RSource -> Result A) -> (String, String) -> IO (String,[Int])+checkFile :: (RType -> RSource -> Result A) -> (FilePath, String) -> IO (FilePath,[Int]) checkFile opM (filepath, contents) = do putStrLn $ "\nUsing Tests from: "++filepath vals <- liftM concat (mapM (checkTest opM) (load' contents)) return (filepath,vals) -checkTests :: (RType -> RSource -> Result A) -> IO [(String, [Int])]-checkTests opM = mapM (checkFile opM) testCases+checkTests :: (RType -> RSource -> Result A) -> [(FilePath,String)] -> IO [(String, [Int])]+checkTests opM testCases = mapM (checkFile opM) testCases -testCases :: [(String, String)]-testCases =- map (\(filename, contents) -> (filename, UTF8.toString contents)) $- $(embedDir =<< makeRelativeToProject "test/cases")+readTestCases :: FilePath -> IO [(String, String)]+readTestCases folder = do+ fns <- filter (isSuffixOf ".txt") <$> getDirectoryContents folder+ when (null fns) $+ fail ("readTestCases: No test-cases found in " ++ show folder)+ forM (sort fns) $ \fn -> do+ bs <- BS.readFile (folder </> fn)+ return (fn, UTF8.toString bs) newtype Result a = Result (Either String a)- deriving (Eq, Show, Functor, Applicative, Monad)+ deriving (Eq, Show, Functor, App.Applicative, Monad) instance Fail.MonadFail Result where fail = Result . Left@@ -137,8 +138,8 @@ unN :: String -> String unN ('\\':'n':xs) = '\n':unN xs-unN (x:xs) = x:unN xs-unN [] = []+unN (x:xs) = x:unN xs+unN [] = [] manual :: [String] -> IO () manual [sIn,rIn] = do@@ -178,7 +179,7 @@ putStrLn $ "With exactly two arguments:" putStrLn $ " The first argument is the text to be searched." putStrLn $ " The second argument is the regular expression pattern to search with."- vals <- checkTests posix+ vals <- checkTests posix =<< readTestCases ("test" </> "cases") if null (concatMap snd vals) then putStrLn "\nWow, all the tests passed!" else do