module Bio.Util.Regex ( Regex, regComp, regMatch )where
import Control.Applicative
import Control.Monad
import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.Marshal.Alloc
import Foreign.C.String
import Foreign.C.Types
import System.IO.Unsafe
newtype Regex = Regex (ForeignPtr Regex)
regComp :: String -> Regex
regComp re = unsafePerformIO $ do
fp <- mallocForeignPtrBytes (64)
withForeignPtr fp $ \p -> do
withCString re $ \pre -> do
ec <- regcomp p pre (1 + 8)
when (ec /= 0) $ do
sz <- regerror ec p nullPtr 0
allocaBytes (fromIntegral sz) $ \err -> do
_ <- regerror ec p err sz
peekCString err >>= error . (++) "regexec: "
addForeignPtrFinalizer regfree fp
return $ Regex fp
regMatch :: Regex -> String -> Bool
regMatch (Regex fp) str =
unsafePerformIO $
withForeignPtr fp $ \p ->
withCString str $ \s ->
(==) 0 <$> regexec p s 0 nullPtr 0
foreign import ccall unsafe regcomp :: Ptr Regex -> CString -> CInt -> IO CInt
foreign import ccall unsafe regexec :: Ptr Regex -> CString -> CSize -> Ptr () -> CInt -> IO CInt
foreign import ccall unsafe regerror :: CInt -> Ptr Regex -> CString -> CSize -> IO CSize
foreign import ccall unsafe "®free" regfree :: FunPtr (Ptr Regex -> IO ())