packages feed

regex-pcre 0.82 → 0.91

raw patch · 9 files changed

+339/−513 lines, 9 filesdep ~regex-basesetup-changed

Dependency ranges changed: regex-base

Files

Setup.hs view
@@ -3,11 +3,9 @@ -- I usually compile this with "ghc --make -o setup Setup.hs"  import Distribution.Simple(defaultMain)--warning = "\nThis is a message from the regex-pcre author.\n\-          \You may need to edit regex-pcre.cabal to have\n\-          \Include-Dirs: and Extra-Lib-Dirs point to where\n\-          \the regex.h and libpcre can be found.\n\n"--main = do putStr warning+main = do putStrLn msg           defaultMain++msg = "regex-pcre needs to compile against the libpcre libary from http://www.pcre.org/\n\+      \You might also need to edit the end of the regex-pcre.cabal file to point at\n\+      \the directories where libpcre 'include' and 'lib' have been installed.\n"
Text/Regex/PCRE.hs view
@@ -5,7 +5,7 @@ you should do so with qualified imports, perhaps renamed for convenience. -You will need to have libpcre, from <http://www.pcre.org/>, to use+You will need to have libpcre, from www.pcre.org, to use this module.  The haskell must be compiled with -DHAVE_PCRE_H and linked with pcre.  This is the default in the cabal file. @@ -34,14 +34,19 @@ exported by this module and medium- and low-level interfaces that returns error using Either structures. -}--module Text.Regex.PCRE(+{- Copyright   :  (c) Chris Kuklewicz 2007 -}+module Text.Regex.PCRE(getVersion_Text_Regex_PCRE+  ,module Text.Regex.Base   -- ** Wrap, for '=~' and '=~~', types and constants-   module Text.Regex.PCRE.Wrap+  ,module Text.Regex.PCRE.Wrap   -- ** String, instances only   ,module Text.Regex.PCRE.String+  -- ** Seq Char, instances only+  ,module Text.Regex.PCRE.Sequence   -- ** ByteString, instances only-  ,module Text.Regex.PCRE.ByteString) where+  ,module Text.Regex.PCRE.ByteString+  -- ** Lazy ByteString, instances only+  ,module Text.Regex.PCRE.ByteString.Lazy) where  import Text.Regex.PCRE.Wrap(Regex, CompOption(CompOption), ExecOption(ExecOption), (=~), (=~~),   unusedOffset, getNumSubs, configUTF8, getVersion,@@ -52,4 +57,14 @@   execBlank, execAnchored, execNotBOL, execNotEOL, execNotEmpty,   execNoUTF8Check, execPartial) import Text.Regex.PCRE.String()+import Text.Regex.PCRE.Sequence() import Text.Regex.PCRE.ByteString()+import Text.Regex.PCRE.ByteString.Lazy()+import Data.Version(Version(..))+import Text.Regex.Base++getVersion_Text_Regex_PCRE :: Version+getVersion_Text_Regex_PCRE =+  Version { versionBranch = [0,91]+          , versionTags = ["unstable"]+          }
Text/Regex/PCRE/ByteString.hs view
@@ -3,6 +3,7 @@ This exports instances of the high level API and the medium level API of 'compile','execute', and 'regexec'. -}+{- Copyright   :  (c) Chris Kuklewicz 2007 -} module Text.Regex.PCRE.ByteString(   -- ** Types   Regex,@@ -47,12 +48,11 @@ import Text.Regex.PCRE.Wrap -- all import Data.Array(Array,listArray) import Data.ByteString(ByteString)-import qualified Data.ByteString as B(empty,useAsCString,last,null,take,drop,pack)+import qualified Data.ByteString as B(empty,useAsCString,last,take,drop) import qualified Data.ByteString.Base as B(unsafeUseAsCString,unsafeUseAsCStringLen) import System.IO.Unsafe(unsafePerformIO) import Text.Regex.Base.RegexLike(RegexContext(..),RegexMaker(..),RegexLike(..),MatchOffset,MatchLength) import Text.Regex.Base.Impl(polymatch,polymatchM)-import Foreign(nullPtr) import Foreign.C.String(CStringLen)  instance RegexContext Regex ByteString ByteString where@@ -63,26 +63,23 @@ unwrap x = case x of Left err -> fail ("Text.Regex.PCRE.ByteString died: "++ show err)                      Right v -> return v -{-# INLINE asCStringLen #-} asCStringLen :: ByteString -> (CStringLen -> IO a) -> IO a-asCStringLen s op = B.unsafeUseAsCStringLen s checked-  where checked cs@(ptr,_) | ptr == nullPtr = B.unsafeUseAsCStringLen myEmpty (op . trim)-                           | otherwise = op cs-        myEmpty = B.pack [0]-        trim (ptr,_) = (ptr,0)+asCStringLen = B.unsafeUseAsCStringLen  instance RegexMaker Regex CompOption ExecOption ByteString where   makeRegexOpts c e pattern = unsafePerformIO $     compile c e pattern >>= unwrap+  makeRegexOptsM c e pattern = either (fail.show) return $ unsafePerformIO $+    compile c e pattern  instance RegexLike Regex ByteString where   matchTest regex bs = unsafePerformIO $     asCStringLen bs (wrapTest 0 regex) >>= unwrap   matchOnce regex bs = unsafePerformIO $     execute regex bs >>= unwrap-  matchAll regex bs = unsafePerformIO $+  matchAll regex bs = unsafePerformIO $      asCStringLen bs (wrapMatchAll regex) >>= unwrap-  matchCount regex bs = unsafePerformIO $+  matchCount regex bs = unsafePerformIO $      asCStringLen bs (wrapCount regex) >>= unwrap  -- ---------------------------------------------------------------------@@ -93,9 +90,9 @@         -> ByteString  -- ^ The regular expression to compile         -> IO (Either (MatchOffset,String) Regex) -- ^ Returns: the compiled regular expression compile c e pattern = do-  let asCString bs = if (not (B.null bs)) && (0==B.last bs)-                       then B.unsafeUseAsCString bs-                       else B.useAsCString bs+  let asCString = if (0==B.last pattern)+                    then B.unsafeUseAsCString+                    else B.useAsCString   asCString pattern (wrapCompile c e)  -- ---------------------------------------------------------------------@@ -113,7 +110,7 @@   maybeStartEnd <- asCStringLen bs (wrapMatch 0 regex)   case maybeStartEnd of     Right Nothing -> return (Right Nothing)-    Right (Just parts) ->+    Right (Just parts) ->        return . Right . Just . listArray (0,pred (length parts))       . map (\(s,e)->(fromIntegral s, fromIntegral (e-s))) $ parts     Left err -> return (Left err)@@ -125,7 +122,7 @@   let getSub (start,stop) | start == unusedOffset = B.empty                           | otherwise = B.take (stop-start) . B.drop start $ bs       matchedParts [] = (B.empty,B.empty,bs,[]) -- no information-      matchedParts (matchedStartStop@(start,stop):subStartStop) =+      matchedParts (matchedStartStop@(start,stop):subStartStop) =          (B.take start bs         ,getSub matchedStartStop         ,B.drop stop bs
+ Text/Regex/PCRE/ByteString/Lazy.hs view
@@ -0,0 +1,132 @@+{-# OPTIONS_GHC -fglasgow-exts -fno-warn-orphans #-}+{-|+This exports instances of the high level API and the medium level+API of 'compile','execute', and 'regexec'.+-}+{- Copyright   :  (c) Chris Kuklewicz 2007 -}+module Text.Regex.PCRE.ByteString.Lazy(+  -- ** Types+  Regex,+  MatchOffset,+  MatchLength,+  CompOption(CompOption),+  ExecOption(ExecOption),+  ReturnCode,+  WrapError,+  -- ** Miscellaneous+  unusedOffset,+  getVersion,+  -- ** Medium level API functions+  compile,+  execute,+  regexec,+  -- ** CompOption flags+  compBlank,+  compAnchored,+  compAutoCallout,+  compCaseless,+  compDollarEndOnly,+  compDotAll,+  compExtended,+  compExtra,+  compFirstLine,+  compMultiline,+  compNoAutoCapture,+  compUngreedy,+  compUTF8,+  compNoUTF8Check,+  -- ** ExecOption flags+  execBlank,+  execAnchored,+  execNotBOL,+  execNotEOL,+  execNotEmpty,+  execNoUTF8Check,+  execPartial+  ) where++import Text.Regex.PCRE.Wrap -- all+import Data.Array(Array)+import qualified Data.ByteString.Lazy as L(ByteString,toChunks,fromChunks,last,snoc)+import qualified Data.ByteString as B(ByteString,concat)+import qualified Data.ByteString.Base as B(unsafeUseAsCString,unsafeUseAsCStringLen)+import System.IO.Unsafe(unsafePerformIO)+import Text.Regex.Base.RegexLike(RegexContext(..),RegexMaker(..),RegexLike(..),MatchOffset,MatchLength)+import Text.Regex.Base.Impl(polymatch,polymatchM)+import qualified Text.Regex.PCRE.ByteString as BS(execute,regexec)+import Foreign.C.String(CString,CStringLen)++instance RegexContext Regex L.ByteString L.ByteString where+  match = polymatch+  matchM = polymatchM++{-# INLINE fromLazy #-}+fromLazy :: L.ByteString -> B.ByteString+fromLazy = B.concat . L.toChunks++{-# INLINE toLazy #-}+toLazy :: B.ByteString -> L.ByteString+toLazy = L.fromChunks . return++unwrap :: (Show e) => Either e v -> IO v+unwrap x = case x of Left err -> fail ("Text.Regex.PCRE.ByteString.Lazy died: "++ show err)+                     Right v -> return v++{-# INLINE asCString #-}+asCString :: L.ByteString -> (CString -> IO a) -> IO a+asCString s = if (0==L.last s)+                then B.unsafeUseAsCString (fromLazy s)+                else B.unsafeUseAsCString (fromLazy (L.snoc s 0))++{-# INLINE asCStringLen #-}+asCStringLen :: L.ByteString -> (CStringLen -> IO a) -> IO a+asCStringLen s = B.unsafeUseAsCStringLen (fromLazy s)++instance RegexMaker Regex CompOption ExecOption L.ByteString where+  makeRegexOpts c e pattern = unsafePerformIO $+    compile c e pattern >>= unwrap+  makeRegexOptsM c e pattern = either (fail.show) return $ unsafePerformIO $+    compile c e pattern++instance RegexLike Regex L.ByteString where+  matchTest regex bs = unsafePerformIO $+    asCStringLen bs (wrapTest 0 regex) >>= unwrap+  matchOnce regex bs = unsafePerformIO $+    execute regex bs >>= unwrap+  matchAll regex bs = unsafePerformIO $ +    asCStringLen bs (wrapMatchAll regex) >>= unwrap+  matchCount regex bs = unsafePerformIO $ +    asCStringLen bs (wrapCount regex) >>= unwrap++-- ---------------------------------------------------------------------+-- | Compiles a regular expression+--+compile :: CompOption  -- ^ (summed together)+        -> ExecOption  -- ^ (summed together)+        -> L.ByteString  -- ^ The regular expression to compile+        -> IO (Either (MatchOffset,String) Regex) -- ^ Returns: the compiled regular expression+compile c e pattern = do+  asCString pattern (wrapCompile c e)++-- ---------------------------------------------------------------------+-- | Matches a regular expression against a buffer, returning the buffer+-- indicies of the match, and any submatches+--+-- | Matches a regular expression against a string+execute :: Regex      -- ^ Compiled regular expression+        -> L.ByteString -- ^ String to match against+        -> IO (Either WrapError (Maybe (Array Int (MatchOffset,MatchLength))))+                -- ^ Returns: 'Nothing' if the regex did not match the+                -- string, or:+                --   'Just' an array of (offset,length) pairs where index 0 is whole match, and the rest are the captured subexpressions.+execute regex bs = BS.execute regex (fromLazy bs)++regexec :: Regex      -- ^ Compiled regular expression+        -> L.ByteString -- ^ String to match against+        -> IO (Either WrapError (Maybe (L.ByteString, L.ByteString, L.ByteString, [L.ByteString])))+regexec regex bs = do+  x <- BS.regexec regex (fromLazy bs)+  return $ case x of+             Left e -> Left e+             Right Nothing -> Right Nothing+             Right (Just (a,b,c,ds)) -> Right (Just (toLazy a,toLazy b,toLazy c,map toLazy ds))
+ Text/Regex/PCRE/Sequence.hs view
@@ -0,0 +1,150 @@+{-# OPTIONS_GHC -fglasgow-exts -fno-warn-orphans -fbang-patterns #-}+{-|+This exports instances of the high level API and the medium level+API of 'compile','execute', and 'regexec'.+-}+{- Copyright   :  (c) Chris Kuklewicz 2007 -}+module Text.Regex.PCRE.Sequence(+  -- ** Types+  Regex,+  MatchOffset,+  MatchLength,+  CompOption(CompOption),+  ExecOption(ExecOption),+  ReturnCode,+  WrapError,+  -- ** Miscellaneous+  unusedOffset,+  getVersion,+  -- ** Medium level API functions+  compile,+  execute,+  regexec,+  -- ** Constants for CompOption+  compBlank,+  compAnchored,+  compAutoCallout,+  compCaseless,+  compDollarEndOnly,+  compDotAll,+  compExtended,+  compExtra,+  compFirstLine,+  compMultiline,+  compNoAutoCapture,+  compUngreedy,+  compUTF8,+  compNoUTF8Check,+  -- ** Constants for ExecOption+  execBlank,+  execAnchored,+  execNotBOL,+  execNotEOL,+  execNotEmpty,+  execNoUTF8Check,+  execPartial+  ) where++import Text.Regex.PCRE.Wrap -- all+--import Foreign.C.String(withCStringLen,withCString)+import Data.Array(Array,listArray)+import System.IO.Unsafe(unsafePerformIO)+import Text.Regex.Base.RegexLike(RegexMaker(..),RegexLike(..),RegexContext(..),MatchLength,MatchOffset,Extract(..))+import Text.Regex.Base.Impl(polymatch,polymatchM)+import Data.Sequence as S hiding (length)+import qualified Data.Sequence as S (length)+import Foreign.C.String+import Foreign.Marshal.Array+import Foreign.Marshal.Alloc+import Foreign.Storable++instance RegexContext Regex (Seq Char) (Seq Char) where+  match = polymatch+  matchM = polymatchM++unwrap :: (Show e) => Either e v -> IO v+unwrap x = case x of Left err -> fail ("Text.Regex.PCRE.Sequence died: "++ show err)+                     Right v -> return v++instance RegexMaker Regex CompOption ExecOption (Seq Char) where+  makeRegexOpts c e pattern = unsafePerformIO $+    compile c e pattern >>= unwrap+  makeRegexOptsM c e pattern = either (fail.show) return $ unsafePerformIO $+    compile c e pattern++instance RegexLike Regex (Seq Char) where+  matchTest regex str = unsafePerformIO $+    withSeq str (wrapTest 0 regex) >>= unwrap+  matchOnce regex str = unsafePerformIO $+    execute regex str >>= unwrap+  matchAll regex str = unsafePerformIO $ +    withSeq str (wrapMatchAll regex) >>= unwrap+  matchCount regex str = unsafePerformIO $ +    withSeq str (wrapCount regex) >>= unwrap++-- | Compiles a regular expression+compile :: CompOption -- ^ Flags (summed together)+        -> ExecOption -- ^ Flags (summed together)+        -> (Seq Char)     -- ^ The regular expression to compile+        -> IO (Either (MatchOffset,String) Regex) -- ^ Returns: an error string and offset or the compiled regular expression+compile c e pattern = withSeq0 pattern (wrapCompile c e)++-- | Matches a regular expression against a string+execute :: Regex      -- ^ Compiled regular expression+        -> (Seq Char)     -- ^ (Seq Char) to match against+        -> IO (Either WrapError (Maybe (Array Int (MatchOffset,MatchLength))))+                -- ^ Returns: 'Nothing' if the regex did not match the+                -- string, or:+                --   'Just' an array of (offset,length) pairs where index 0 is whole match, and the rest are the captured subexpressions.+execute regex str = do+  maybeStartEnd <- withSeq str (wrapMatch 0 regex)+  case maybeStartEnd of+    Right Nothing -> return (Right Nothing)+--  Right (Just []) -> fail "got [] back!" -- should never happen+    Right (Just parts) -> +      return . Right . Just . listArray (0,pred (length parts))+      . map (\(s,e)->(fromIntegral s, fromIntegral (e-s))) $ parts+    Left err -> return (Left err)++-- | execute match and extract substrings rather than just offsets+regexec  :: Regex      -- ^ compiled regular expression+         -> (Seq Char)     -- ^ string to match+         -> IO (Either WrapError (Maybe ((Seq Char), (Seq Char),(Seq Char), [(Seq Char)])))+                      -- ^ Returns: Nothing if no match, else+                      --   (text before match, text after match, array of matches with 0 being the whole match)+regexec regex str = do+  let getSub (start,stop) | start == unusedOffset = S.empty+                          | otherwise = extract (start,stop-start) str+      matchedParts [] = (S.empty,S.empty,str,[]) -- no information+      matchedParts (matchedStartStop@(start,stop):subStartStop) = +        (before start str+        ,getSub matchedStartStop+        ,after stop str+        ,map getSub subStartStop)+  maybeStartEnd <- withSeq str (wrapMatch 0 regex)+  case maybeStartEnd of+    Right Nothing -> return (Right Nothing)+--  Right (Just []) -> fail "got [] back!" -- should never happen+    Right (Just parts) -> return . Right . Just . matchedParts $ parts+    Left err -> return (Left err)++withSeq :: Seq Char -> (CStringLen -> IO a) -> IO a+withSeq s f =+  let -- Ensure null at end of s+      len = S.length s+      pokes !p !a = case viewl a of+                      EmptyL -> return ()+                      c :< a' -> poke p (castCharToCChar c) >> pokes (advancePtr p 1) a'+  in allocaBytes (S.length s) (\ptr -> pokes ptr s >> f (ptr,len))++withSeq0 :: Seq Char -> (CString -> IO a) -> IO a+withSeq0 s f =+  let -- Ensure null at end of s+      s' = case viewr s of                -- bang !s'+             EmptyR -> singleton '\0'+             _ :> '\0' -> s+             _ -> s |> '\0'+      pokes p a = case viewl a of         -- bang pokes !p !a+                    EmptyL -> return ()+                    c :< a' -> poke p (castCharToCChar c) >> pokes (advancePtr p 1) a'+  in allocaBytes (S.length s') (\ptr -> pokes ptr s' >> f ptr)
Text/Regex/PCRE/String.hs view
@@ -3,6 +3,7 @@ This exports instances of the high level API and the medium level API of 'compile','execute', and 'regexec'. -}+{- Copyright   :  (c) Chris Kuklewicz 2007 -} module Text.Regex.PCRE.String(   -- ** Types   Regex,@@ -62,6 +63,8 @@ instance RegexMaker Regex CompOption ExecOption String where   makeRegexOpts c e pattern = unsafePerformIO $     compile c e pattern >>= unwrap+  makeRegexOptsM c e pattern = either (fail.show) return $ unsafePerformIO $+    compile c e pattern  instance RegexLike Regex String where   matchTest regex str = unsafePerformIO $
− Text/Regex/PCRE/Wrap.hs
@@ -1,464 +0,0 @@-{-# OPTIONS_GHC -optc-D__GLASGOW_HASKELL__=606 #-}-{-# OPTIONS_GHC -optc-DHAVE_PCRE_H #-}-{-# INCLUDE <sys/types.h> #-}-{-# INCLUDE <pcre.h> #-}-{-# LINE 1 "Text/Regex/PCRE/Wrap.hsc" #-}-{-# OPTIONS_GHC  -fglasgow-exts -fffi #-}-{-# LINE 2 "Text/Regex/PCRE/Wrap.hsc" #-}--- | This will fail or error only if allocation fails or a nullPtr is passed in.--- TODO :: Consider wrapMatchAll using list of start/end offsets and not MatchArray------ The exported symbols are the same whether HAVE_PCRE_H is defined,--- but when if it is not defined then @getVersion == Nothing@ and all--- other exported values will call error or fail.-module Text.Regex.PCRE.Wrap(-  -- ** High-level interface-  Regex,-  CompOption(CompOption),-  ExecOption(ExecOption),-  (=~),-  (=~~),--  -- ** Low-level interface-  StartOffset,-  EndOffset,-  ReturnCode(ReturnCode),-  WrapError,-  wrapCompile,-  wrapTest,-  wrapMatch,-  wrapMatchAll,-  wrapCount,--  -- ** Miscellaneous-  getVersion,-  configUTF8,-  getNumSubs,-  unusedOffset,--  -- ** CompOption values-  compBlank,-  compAnchored,-  compAutoCallout,-  compCaseless,-  compDollarEndOnly,-  compDotAll,-  compExtended,-  compExtra,-  compFirstLine,-  compMultiline,-  compNoAutoCapture,-  compUngreedy,-  compUTF8,-  compNoUTF8Check,--  -- ** ExecOption values-  execBlank,-  execAnchored,-  execNotBOL,-  execNotEOL,-  execNotEmpty,-  execNoUTF8Check,-  execPartial,--  -- ** ReturnCode values-  retOk,-  retNoMatch,-  retNull,-  retBadOption,-  retBadMagic,-  retUnknownNode,-  retNoMemory,-  retNoSubstring-  ) where---{-# LINE 70 "Text/Regex/PCRE/Wrap.hsc" #-}-import Control.Monad(when)-import Data.Array(Array,accumArray)-import Data.Bits(Bits((.|.))) -- ((.&.),(.|.),complement))-import Foreign(unsafePerformIO-              ,Ptr,ForeignPtr,FinalizerPtr -- ,FunPtr-              ,alloca,allocaBytes,nullPtr-              ,peek,peekElemOff-              ,newForeignPtr,withForeignPtr)-import Foreign.C(CInt,CChar)-import Foreign.C.String(CString,CStringLen,peekCString)-import Text.Regex.Base.RegexLike(RegexOptions(..),RegexMaker(..),RegexContext(..),MatchArray,MatchOffset)--{-# LINE 89 "Text/Regex/PCRE/Wrap.hsc" #-}----- | return version of pcre used or Nothing if pcre is not available.-getVersion :: Maybe String--type PCRE = ()-type StartOffset = MatchOffset-type EndOffset = MatchOffset-type WrapError = (ReturnCode,String)--newtype CompOption = CompOption CInt deriving (Eq,Show,Num,Bits)-newtype ExecOption = ExecOption CInt deriving (Eq,Show,Num,Bits)-newtype ReturnCode = ReturnCode CInt deriving (Eq,Show)---- | A compiled regular expression-data Regex = Regex (ForeignPtr PCRE) CompOption ExecOption--compBlank :: CompOption-execBlank :: ExecOption-unusedOffset :: MatchOffset-retOk :: ReturnCode--wrapCompile :: CompOption -- ^ Flags (summed together)-            -> ExecOption -- ^ Flags (summed together)-            -> CString  -- ^ The regular expression to compile-            -> IO (Either (MatchOffset,String) Regex) -- ^ Returns: an error offset and string or the compiled regular expression-wrapTest :: StartOffset -- ^ Starting index in CStringLen-         -> Regex       -- ^ Compiled regular expression-         -> CStringLen  -- ^ String to match against and length in bytes-         -> IO (Either WrapError Bool)-wrapMatch :: StartOffset -- ^ Starting index in CStringLen-          -> Regex       -- ^ Compiled regular expression-          -> CStringLen  -- ^ String to match against and length in bytes-          -> IO (Either WrapError (Maybe [(StartOffset,EndOffset)]))-                -- ^ Returns: 'Right Nothing' if the regex did not match the-                -- string, or:-                --   'Right Just' an array of (offset,length) pairs where index 0 is whole match, and the rest are the captured subexpressions, or:-                --   'Left ReturnCode' if there is some strange error-wrapMatchAll :: Regex -> CStringLen -> IO (Either WrapError [ MatchArray ])-wrapCount :: Regex -> CStringLen -> IO (Either WrapError Int)--getNumSubs :: Regex -> Int-configUTF8 :: Bool--(=~)  :: (RegexMaker Regex CompOption ExecOption source,RegexContext Regex source1 target)-      => source1 -> source -> target-(=~~) :: (RegexMaker Regex CompOption ExecOption source,RegexContext Regex source1 target,Monad m)-      => source1 -> source -> m target---{-# LINE 139 "Text/Regex/PCRE/Wrap.hsc" #-}--{-# LINE 140 "Text/Regex/PCRE/Wrap.hsc" #-}--{-# LINE 141 "Text/Regex/PCRE/Wrap.hsc" #-}--instance RegexOptions Regex CompOption ExecOption where-  blankCompOpt = compBlank-  blankExecOpt = execBlank-  defaultCompOpt = compMultiline-  defaultExecOpt = execBlank-  setExecOpts e' (Regex r c _) = Regex r c e'-  getExecOpts (Regex _ _ e) = e---- (=~) :: (RegexMaker Regex CompOption ExecOption source,RegexContext Regex source1 target) => source1 -> source -> target-(=~) x r = let q :: Regex-               q = makeRegex r-           in match q x---- (=~~) ::(RegexMaker Regex CompOption ExecOption source,RegexContext Regex source1 target,Monad m) => source1 -> source -> m target-(=~~) x r = let q :: Regex-                q = makeRegex r-            in matchM q x--type PCRE_Extra = ()--fi :: (Integral i,Num n ) => i -> n-fi x = fromIntegral x--compBlank = CompOption 0-execBlank = ExecOption 0-unusedOffset = (-1)-retOk = ReturnCode 0--retNeededMoreSpace :: ReturnCode-retNeededMoreSpace = ReturnCode 0--newtype InfoWhat = InfoWhat CInt deriving (Eq,Show)-newtype ConfigWhat = ConfigWhat CInt deriving (Eq,Show)--nullTest' :: Ptr a -> String -> IO (Either (MatchOffset,String) b) -> IO (Either (MatchOffset,String) b)-{-# INLINE nullTest' #-}-nullTest' ptr msg io = do-  if nullPtr == ptr-    then return (Left (0,"Ptr parameter was nullPtr in Text.Regex.PCRE.Wrap."++msg)) -    else io--nullTest :: Ptr a -> String -> IO (Either WrapError b) -> IO (Either WrapError b)-{-# INLINE nullTest #-}-nullTest ptr msg io = do-  if nullPtr == ptr-    then return (Left (retOk,"Ptr parameter was nullPtr in Text.Regex.PCRE.Wrap."++msg)) -    else io--wrapRC :: ReturnCode -> IO (Either WrapError b)-{-# INLINE wrapRC #-}-wrapRC r = return (Left (r,"Error in Text.Regex.PCRE.Wrap: "++show r))---- | Compiles a regular expression-wrapCompile flags e pattern = do- nullTest' pattern "wrapCompile pattern" $ do-  alloca $ \errOffset -> alloca $ \errPtr -> do-   nullTest' errPtr "wrapCompile errPtr" $ do-    pcre_ptr <- c_pcre_compile pattern flags errPtr errOffset nullPtr-    if pcre_ptr == nullPtr-      then do-        -- No need to use c_ptr_free in the error case (e.g. pcredemo.c)-        offset <- peek errOffset-        string <- peekCString =<< peek errPtr-        return (Left (fi offset,string))-      else do regex <- newForeignPtr c_ptr_free pcre_ptr-              return . Right $ Regex regex flags e--getNumSubs (Regex pcre_fptr _ _) = fi . unsafePerformIO $ withForeignPtr pcre_fptr getNumSubs'--getNumSubs' :: Ptr PCRE -> IO CInt-{-# INLINE getNumSubs' #-}-getNumSubs' pcre_ptr =-  alloca $ \st -> do -- (st :: Ptr CInt)-    when (st == nullPtr) (fail "Text.Regex.PCRE.Wrap.getNumSubs' could not allocate a CInt!!!")-    c_pcre_fullinfo pcre_ptr nullPtr pcreInfoCapturecount st-    peek st--wrapTest startOffset (Regex pcre_fptr _ flags) (cstr,len) = do- nullTest cstr "wrapTest cstr" $ do-  withForeignPtr pcre_fptr $ \pcre_ptr -> do-    r@(ReturnCode r') <- c_pcre_exec pcre_ptr nullPtr cstr (fi len) (fi startOffset) flags nullPtr 0-    if r == retNoMatch-      then return (Right False)-      else if r' < 0-             then wrapRC r-             else return (Right True)---- | Matches a regular expression against a string------ Should never return (Right (Just []))-wrapMatch startOffset (Regex pcre_fptr _ flags) (cstr,len) = do- nullTest cstr "wrapMatch cstr" $ do-  withForeignPtr pcre_fptr $ \pcre_ptr -> do-    nsub <- getNumSubs' pcre_ptr-    let nsub_int :: Int-        nsub_int = fi nsub-        ovec_size :: CInt-        ovec_size = ((nsub + 1) * 3) -- "man pcreapi" for explanation-        ovec_bytes :: Int-        ovec_bytes = (fi ovec_size) * (4)-{-# LINE 242 "Text/Regex/PCRE/Wrap.hsc" #-}-    allocaBytes ovec_bytes $ \ovec -> do-     nullTest ovec "wrapMatch ovec" $ do-      r@(ReturnCode r') <- c_pcre_exec pcre_ptr nullPtr cstr (fi len) (fi startOffset) flags ovec ovec_size-      if r == retNoMatch-        then return (Right Nothing)-        else if r' < 0-          then wrapRC r-          else do-            let pairsSet :: Int-                pairsSet = if r == retNeededMoreSpace -- if r == ReturnCode 0-                             then nsub_int + 1 -- should not happen-                             else fi r' -- implies pairsSet > 0-                extraPairs :: [(Int,Int)]-                extraPairs = replicate (nsub_int + 1 - pairsSet)-                                       (unusedOffset,unusedOffset)-            pairs <- return . toPairs =<< mapM (peekElemOff ovec) [0 .. ((pairsSet*2)-1)]-            return . Right . Just $ (pairs ++ extraPairs)---- | wrapMatchAll is an improvement over wrapMatch since it only--- allocates memory with allocaBytes once at the start.--- --- -wrapMatchAll (Regex pcre_fptr _ flags) (cstr,len) = do- nullTest cstr "wrapMatchAll cstr" $ do-  withForeignPtr pcre_fptr $ \regex -> do-    nsub <- getNumSubs' regex-    let nsub_int :: Int-        nsub_int = fi nsub-        ovec_size :: CInt-        ovec_size = ((nsub + 1) * 3) -- "man pcreapi" for explanation-        ovec_bytes :: Int-        ovec_bytes = (fi ovec_size) * (4)-{-# LINE 274 "Text/Regex/PCRE/Wrap.hsc" #-}-        clen = fi len-        flags' = (execNotEmpty .|. execAnchored .|. flags)-    allocaBytes ovec_bytes $ \ovec ->-     nullTest ovec "wrapMatchAll ovec" $-      let loop acc flags_in_use pos = do-            r@(ReturnCode r') <- c_pcre_exec regex nullPtr cstr clen (fi pos) flags_in_use ovec ovec_size-            if r == retNoMatch-              then return (Right (acc []))-              else if r' < 0-                     then wrapRC r-                     else do-                       let pairsSet = if r == retNeededMoreSpace then nsub_int+1 else fi r'-                       pairs <- return . toPairs =<< mapM (peekElemOff ovec) [0 .. ((pairsSet*2)-1)]-                       let acc' = acc . (toMatchArray nsub_int pairs:)-                       case pairs of-                         [] -> return (Right (acc' []))-                         ((s,e):_) | s==e -> if s == len -                                               then return (Right (acc' []))-                                               else loop acc' flags' e-                                   | otherwise -> loop acc' flags e-      in loop id flags 0-toMatchArray :: Int -> [(Int,Int)] -> Array Int (Int,Int)-toMatchArray n pairs = accumArray (\_ (s,e) -> (s,(e-s))) (-1,0) (0,n) (zip [0..] pairs)--toPairs :: [CInt] -> [(Int,Int)]-toPairs [] = []-toPairs (a:b:rest) = (fi a,fi b):toPairs rest-toPairs [_] = error "Should not have just one element in WrapPCRE.wrapMatchAll.toPairs"--wrapCount (Regex pcre_fptr _ flags) (cstr,len) = do- nullTest cstr "wrapCount cstr" $ do-  withForeignPtr pcre_fptr $ \pcre_ptr -> do-    nsub <- getNumSubs' pcre_ptr-    let ovec_size :: CInt-        ovec_size = ((nsub + 1) * 3) -- "man pcreapi" for explanation-        ovec_bytes :: Int-        ovec_bytes = (fi ovec_size) * (4)-{-# LINE 311 "Text/Regex/PCRE/Wrap.hsc" #-}-        clen = fi len-    allocaBytes ovec_bytes $ \ovec ->-     nullTest ovec "wrapCount ovec" $-      let act pos = c_pcre_exec pcre_ptr nullPtr cstr clen (fi pos) flags ovec ovec_size-          loop acc pos | acc `seq` pos `seq` False = undefined-                       | otherwise  = do-            r@(ReturnCode r') <- act pos-            if r == retNoMatch-              then return (Right acc)-              else if r' < 0-                then wrapRC r-                else do-                  pairs <- return . toPairs =<< mapM (peekElemOff ovec) [0,1]-                  case pairs of-                    [] -> return (Right (succ acc))-                    ((s,e):_) | s==e -> return (Right (succ acc))-                              | otherwise -> loop (succ acc) e-      in loop 0 0--getVersion = unsafePerformIO $ do-  version <- c_pcre_version-  if version == nullPtr-    then return (Just "pcre_version was null")-    else return . Just =<< peekCString version--configUTF8 = unsafePerformIO $-  alloca $ \ptrVal -> do -- (ptrVal :: Ptr CInt)-    when (ptrVal == nullPtr) (fail "Text.Regex.PCRE.Wrap.configUTF8 could not alloca CInt!!!")-    c_pcre_config pcreConfigUtf8 ptrVal-    val <- peek ptrVal-    case val of-      (1 :: CInt) -> return True-      0 -> return False-      _ -> return False -- should not happen--foreign import ccall unsafe "pcre.h pcre_compile"-  c_pcre_compile :: CString -> CompOption -> Ptr CString -> Ptr CInt -> CString -> IO (Ptr PCRE)-foreign import ccall unsafe "&free"-  c_ptr_free :: FinalizerPtr a -- FunPtr (Ptr a -> IO ())-foreign import ccall unsafe "pcre.h pcre_exec"-  c_pcre_exec :: Ptr PCRE -> Ptr PCRE_Extra -> CString -> CInt -> CInt -> ExecOption -> Ptr CInt -> CInt -> IO ReturnCode-foreign import ccall unsafe "pcre.h pcre_fullinfo"-  c_pcre_fullinfo :: Ptr PCRE -> Ptr PCRE_Extra -> InfoWhat -> Ptr a -> IO CInt-foreign import ccall unsafe "pcre.h pcre_version"-  c_pcre_version :: IO (Ptr CChar)-foreign import ccall unsafe "pcre.h pcre_config"-  c_pcre_config :: ConfigWhat -> Ptr a -> IO CInt---compAnchored  :: CompOption-compAnchored  = CompOption 16-compAutoCallout  :: CompOption-compAutoCallout  = CompOption 16384-compCaseless  :: CompOption-compCaseless  = CompOption 1-compDollarEndOnly  :: CompOption-compDollarEndOnly  = CompOption 32-compDotAll  :: CompOption-compDotAll  = CompOption 4-compExtended  :: CompOption-compExtended  = CompOption 8-compExtra  :: CompOption-compExtra  = CompOption 64-compFirstLine  :: CompOption-compFirstLine  = CompOption 262144-compMultiline  :: CompOption-compMultiline  = CompOption 2-compNoAutoCapture  :: CompOption-compNoAutoCapture  = CompOption 4096-compUngreedy  :: CompOption-compUngreedy  = CompOption 512-compUTF8  :: CompOption-compUTF8  = CompOption 2048-compNoUTF8Check  :: CompOption-compNoUTF8Check  = CompOption 8192--{-# LINE 374 "Text/Regex/PCRE/Wrap.hsc" #-}--execAnchored  :: ExecOption-execAnchored  = ExecOption 16-execNotBOL  :: ExecOption-execNotBOL  = ExecOption 128-execNotEOL  :: ExecOption-execNotEOL  = ExecOption 256-execNotEmpty  :: ExecOption-execNotEmpty  = ExecOption 1024-execNoUTF8Check  :: ExecOption-execNoUTF8Check  = ExecOption 8192-execPartial  :: ExecOption-execPartial  = ExecOption 32768--{-# LINE 382 "Text/Regex/PCRE/Wrap.hsc" #-}--retNoMatch  :: ReturnCode-retNoMatch  = ReturnCode (-1)-retNull  :: ReturnCode-retNull  = ReturnCode (-2)-retBadOption  :: ReturnCode-retBadOption  = ReturnCode (-3)-retBadMagic  :: ReturnCode-retBadMagic  = ReturnCode (-4)-retUnknownNode  :: ReturnCode-retUnknownNode  = ReturnCode (-5)-retNoMemory  :: ReturnCode-retNoMemory  = ReturnCode (-6)-retNoSubstring  :: ReturnCode-retNoSubstring  = ReturnCode (-7)--{-# LINE 391 "Text/Regex/PCRE/Wrap.hsc" #-}---- Comment out most of these to avoid unused binding warnings---- PCRE_INFO_FIRSTCHAR is deprecated, use PCRE_INFO_FIRSTBYTE instead.-pcreInfoCapturecount :: InfoWhat-pcreInfoCapturecount = InfoWhat 2--{-# LINE 397 "Text/Regex/PCRE/Wrap.hsc" #-}-{--  PCRE_INFO_BACKREFMAX, \-  PCRE_INFO_DEFAULT_TABLES, \-  PCRE_INFO_FIRSTBYTE, \-  PCRE_INFO_FIRSTCHAR, \-  PCRE_INFO_FIRSTTABLE, \-  PCRE_INFO_LASTLITERAL, \-  PCRE_INFO_NAMECOUNT, \-  PCRE_INFO_NAMEENTRYSIZE, \-  PCRE_INFO_NAMETABLE, \-  PCRE_INFO_OPTIONS, \-  PCRE_INFO_SIZE, \-  PCRE_INFO_STUDYSIZE--}-pcreConfigUtf8 :: ConfigWhat-pcreConfigUtf8 = ConfigWhat 0--{-# LINE 413 "Text/Regex/PCRE/Wrap.hsc" #-}-{--  PCRE_CONFIG_UNICODE_PROPERTIES, \-  PCRE_CONFIG_NEWLINE, \-  PCRE_CONFIG_LINK_SIZE, \-  PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, \-  PCRE_CONFIG_MATCH_LIMIT, \-  PCRE_CONFIG_MATCH_LIMIT_RECURSION, \-  PCRE_CONFIG_STACKRECURSE--}---{-# LINE 489 "Text/Regex/PCRE/Wrap.hsc" #-}
Text/Regex/PCRE/Wrap.hsc view
@@ -1,10 +1,12 @@ {-# OPTIONS_GHC  -fglasgow-exts -fffi #-}+-- The exported symbols are the same whether HAVE_PCRE_H is defined,+-- but when if it is not defined then 'getVersion == Nothing' and all+-- other exported values will call error or fail.+ -- | This will fail or error only if allocation fails or a nullPtr is passed in. -- TODO :: Consider wrapMatchAll using list of start/end offsets and not MatchArray ----- The exported symbols are the same whether HAVE_PCRE_H is defined,--- but when if it is not defined then @getVersion == Nothing@ and all--- other exported values will call error or fail.+{- Copyright   :  (c) Chris Kuklewicz 2007 -} module Text.Regex.PCRE.Wrap(   -- ** High-level interface   Regex,@@ -153,9 +155,8 @@            in match q x  -- (=~~) ::(RegexMaker Regex CompOption ExecOption source,RegexContext Regex source1 target,Monad m) => source1 -> source -> m target-(=~~) x r = let q :: Regex-                q = makeRegex r-            in matchM q x+(=~~) x r = do (q :: Regex) <-  makeRegexM r+               matchM q x  type PCRE_Extra = () 
regex-pcre.cabal view
@@ -1,10 +1,5 @@--- ****************************************************************--- To fix for cabal < 1.1.4 comment out the Extra-Source-Files line--- You may need to edit the Extra-Lib-Dirs entry near the bottom to find libpcre--- You may need to edit the Include-Dirs entry at the bottom to find regex.h--- **************************************************************** Name:                   regex-pcre-Version:                0.82+Version:                0.91 -- Cabal-Version:       >=1.1.4 License:                BSD3 License-File:           LICENSE@@ -13,37 +8,36 @@ Maintainer:             TextRegexLazy@personal.mightyreason.com Stability:              Seems to work, passes a few tests Homepage:               http://sourceforge.net/projects/lazy-regex--- Package-URL:+Package-URL:            http://darcs.haskell.org/packages/regex-unstable/regex-pcre/ Synopsis:               Replaces/Enhances Text.Regex-Description:            The PCRE backend to accompany regex-base+Description:            The PCRE backend to accompany regex-base, see www.pcre.org Category:               Text Tested-With:            GHC--- The base >=0 2.0 is for the upcoming GHC 6.6-Build-Depends:        base >= 2.0, regex-base--- Build-Depends:          regex-base, base, fps >= 0.7+Build-Depends:          base >= 2.0, regex-base >= 0.80 -- Data-Files: -- Extra-Source-Files: -- Extra-Tmp-Files: Exposed-Modules:        Text.Regex.PCRE                         Text.Regex.PCRE.Wrap                         Text.Regex.PCRE.String+                        Text.Regex.PCRE.Sequence                         Text.Regex.PCRE.ByteString+                        Text.Regex.PCRE.ByteString.Lazy Buildable:              True -- Other-Modules:--- be backward compatible until 6.4.2 is futher deployed -- HS-Source-Dirs:         "." Extensions:             MultiParamTypeClasses, FunctionalDependencies -- GHC-Options:            -Wall -Werror GHC-Options:            -Wall -Werror -O2 -- GHC-Options:            -Wall -ddump-minimal-imports--- GHC-Prog-Options:+-- GHC-Prof-Options:  -- Hugs-Options: -- NHC-Options:--- Includes: -- C-Sources:+-- Includes: -- LD-Options: -- Frameworks: CC-Options:             -DHAVE_PCRE_H Extra-Libraries:        pcre---Extra-Lib-Dirs:         /opt/local/lib---Include-Dirs:           /opt/local/include+-- Include-Dirs:           /opt/local/include+-- Extra-Lib-Dirs:         /opt/local/lib