Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ matrix:
# For the Stack builds we can pass in arbitrary Stack arguments via the ARGS
# variable, such as using --stack-yaml to point to a different file.

# Linux/stack/hackage release

- env: BUILD=release-stack GHCVER=8.0.1 STACK_YAML=stack-8.0.yaml
compiler: ": #stack 8.0.1"
addons: {apt: {packages: [libgmp-dev]}}

# Linux/stack

- env: BUILD=stack GHCVER=7.10.3 STACK_YAML=stack-7.10.yaml
Expand Down Expand Up @@ -121,7 +127,7 @@ install:
- |
set -ex
case "$BUILD" in
stack)
release-stack|stack)
stack --no-terminal --install-ghc $ARGS test --coverage --bench --only-dependencies
;;
cabal)
Expand All @@ -140,6 +146,30 @@ script:
- |
set -ex
case "$BUILD" in
release-stack)
lpn=regex-$(cat lib/version.txt)
epn=regex-examples-$(cat lib/version.txt)
ltb=releases/${lpn}.tar.gz
etb=releases/${epn}.tar.gz
if [ -f ${ltb} ]; then
echo "installing ${lpn}"
tar xzf ${ltb}
cp ${STACK_YAML} ${lpn}
cd ${lpn}
stack --no-terminal $ARGS install --bench --coverage --no-run-benchmarks --haddock --no-haddock-deps
echo "testing ${epn}"
cd ..
tar xzf ${etb}
sed -e "s/extra-deps: \\[\\]/extra-deps: [${lpn}]/" ${STACK_YAML} > ${epn}/${STACK_YAML}
cd ${epn}
stack --no-terminal $ARGS test --bench --coverage --no-run-benchmarks --haddock --no-haddock-deps
cd ..
else
echo "***"
echo "*** no Hackage release to test"
echo "***"
fi
;;
stack)
stack --no-terminal $ARGS test --bench --coverage --no-run-benchmarks --haddock --no-haddock-deps
;;
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ two packages:
- [X] 2017-02-21 v0.2.0.3 Tweak README/index layout
- [X] 2017-02-22 v0.2.0.4 [Repair re-gen-modules-test for Windows](https://github.com/iconnect/regex/issues/47)
- [X] 2017-02-26 v0.3.0.0 [API adjustments](https://github.com/iconnect/regex/milestone/2)
- [ ] 2017-03-05 v0.5.0.0 [Ready for review: tutorials and examples finalized](https://github.com/iconnect/regex/milestone/6)
- [X] 2017-03-05 v0.5.0.0 [Ready for review: API, tutorials and examples finalized](https://github.com/iconnect/regex/milestone/6)
- [ ] 2017-03-20 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)

Expand Down
6 changes: 4 additions & 2 deletions Text/RE/Capture.lhs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE DeriveDataTypeable #-}
\end{code}

\begin{code}
Expand Down Expand Up @@ -40,6 +41,7 @@ module Text.RE.Capture
\begin{code}
import Data.Array
import Data.Maybe
import Data.Typeable
import Text.Regex.Base
import Text.RE.CaptureID

Expand All @@ -56,7 +58,7 @@ data Matches a =
{ matchesSource :: !a -- ^ the source text being matched
, allMatches :: ![Match a] -- ^ all captures found, left to right
}
deriving (Show,Eq)
deriving (Show,Eq,Typeable)
\end{code}

\begin{code}
Expand All @@ -74,7 +76,7 @@ data Match a =
-- text matched by the
-- whole RE
}
deriving (Show,Eq)
deriving (Show,Eq,Typeable)
\end{code}

\begin{code}
Expand Down
58 changes: 58 additions & 0 deletions Text/RE/Internal/AddCaptureNames.hs
Original file line number Diff line number Diff line change
@@ -1,11 +1,69 @@
{-# 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 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"
12 changes: 9 additions & 3 deletions Text/RE/PCRE/ByteString.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
Expand Down Expand Up @@ -25,7 +26,9 @@ module Text.RE.PCRE.ByteString
, module Text.RE.PCRE.RE
) where

import Prelude.Compat
import qualified Data.ByteString as B
import Data.Typeable
import Text.Regex.Base
import Text.RE
import Text.RE.Internal.AddCaptureNames
Expand All @@ -46,23 +49,26 @@ import qualified Text.Regex.PCRE as PCRE
(?=~) bs rex = addCaptureNamesToMatch (reCaptureNames rex) $ match (reRegex rex) bs

-- | the regex-base polymorphic match operator
(=~) :: ( RegexContext PCRE.Regex B.ByteString a
(=~) :: ( Typeable a
, RegexContext PCRE.Regex B.ByteString a
, RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String
)
=> B.ByteString
-> RE
-> a
(=~) bs rex = match (reRegex rex) bs
(=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs

-- | the regex-base monadic, polymorphic match operator
(=~~) :: ( Monad m
, Functor m
, Typeable a
, RegexContext PCRE.Regex B.ByteString a
, RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String
)
=> B.ByteString
-> RE
-> m a
(=~~) bs rex = matchM (reRegex rex) bs
(=~~) bs rex = addCaptureNames (reCaptureNames rex) <$> matchM (reRegex rex) bs

instance IsRegex RE B.ByteString where
matchOnce = flip (?=~)
Expand Down
12 changes: 9 additions & 3 deletions Text/RE/PCRE/ByteString/Lazy.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
Expand Down Expand Up @@ -25,7 +26,9 @@ module Text.RE.PCRE.ByteString.Lazy
, module Text.RE.PCRE.RE
) where

import Prelude.Compat
import qualified Data.ByteString.Lazy as LBS
import Data.Typeable
import Text.Regex.Base
import Text.RE
import Text.RE.Internal.AddCaptureNames
Expand All @@ -46,23 +49,26 @@ import qualified Text.Regex.PCRE as PCRE
(?=~) bs rex = addCaptureNamesToMatch (reCaptureNames rex) $ match (reRegex rex) bs

-- | the regex-base polymorphic match operator
(=~) :: ( RegexContext PCRE.Regex LBS.ByteString a
(=~) :: ( Typeable a
, RegexContext PCRE.Regex LBS.ByteString a
, RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String
)
=> LBS.ByteString
-> RE
-> a
(=~) bs rex = match (reRegex rex) bs
(=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs

-- | the regex-base monadic, polymorphic match operator
(=~~) :: ( Monad m
, Functor m
, Typeable a
, RegexContext PCRE.Regex LBS.ByteString a
, RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String
)
=> LBS.ByteString
-> RE
-> m a
(=~~) bs rex = matchM (reRegex rex) bs
(=~~) bs rex = addCaptureNames (reCaptureNames rex) <$> matchM (reRegex rex) bs

instance IsRegex RE LBS.ByteString where
matchOnce = flip (?=~)
Expand Down
12 changes: 9 additions & 3 deletions Text/RE/PCRE/Sequence.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
Expand Down Expand Up @@ -25,7 +26,9 @@ module Text.RE.PCRE.Sequence
, module Text.RE.PCRE.RE
) where

import Prelude.Compat
import qualified Data.Sequence as S
import Data.Typeable
import Text.Regex.Base
import Text.RE
import Text.RE.Internal.AddCaptureNames
Expand All @@ -46,23 +49,26 @@ import qualified Text.Regex.PCRE as PCRE
(?=~) bs rex = addCaptureNamesToMatch (reCaptureNames rex) $ match (reRegex rex) bs

-- | the regex-base polymorphic match operator
(=~) :: ( RegexContext PCRE.Regex (S.Seq Char) a
(=~) :: ( Typeable a
, RegexContext PCRE.Regex (S.Seq Char) a
, RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String
)
=> (S.Seq Char)
-> RE
-> a
(=~) bs rex = match (reRegex rex) bs
(=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs

-- | the regex-base monadic, polymorphic match operator
(=~~) :: ( Monad m
, Functor m
, Typeable a
, RegexContext PCRE.Regex (S.Seq Char) a
, RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String
)
=> (S.Seq Char)
-> RE
-> m a
(=~~) bs rex = matchM (reRegex rex) bs
(=~~) bs rex = addCaptureNames (reCaptureNames rex) <$> matchM (reRegex rex) bs

instance IsRegex RE (S.Seq Char) where
matchOnce = flip (?=~)
Expand Down
12 changes: 9 additions & 3 deletions Text/RE/PCRE/String.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
Expand Down Expand Up @@ -25,7 +26,9 @@ module Text.RE.PCRE.String
, module Text.RE.PCRE.RE
) where

import Prelude.Compat

import Data.Typeable
import Text.Regex.Base
import Text.RE
import Text.RE.Internal.AddCaptureNames
Expand All @@ -46,23 +49,26 @@ import qualified Text.Regex.PCRE as PCRE
(?=~) bs rex = addCaptureNamesToMatch (reCaptureNames rex) $ match (reRegex rex) bs

-- | the regex-base polymorphic match operator
(=~) :: ( RegexContext PCRE.Regex String a
(=~) :: ( Typeable a
, RegexContext PCRE.Regex String a
, RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String
)
=> String
-> RE
-> a
(=~) bs rex = match (reRegex rex) bs
(=~) bs rex = addCaptureNames (reCaptureNames rex) $ match (reRegex rex) bs

-- | the regex-base monadic, polymorphic match operator
(=~~) :: ( Monad m
, Functor m
, Typeable a
, RegexContext PCRE.Regex String a
, RegexMaker PCRE.Regex PCRE.CompOption PCRE.ExecOption String
)
=> String
-> RE
-> m a
(=~~) bs rex = matchM (reRegex rex) bs
(=~~) bs rex = addCaptureNames (reCaptureNames rex) <$> matchM (reRegex rex) bs

instance IsRegex RE String where
matchOnce = flip (?=~)
Expand Down
Loading