module Text.Regex.PCRE.Precompile where
import Control.Monad (liftM)
import qualified Data.ByteString.Char8 as B
import Data.ByteString.Unsafe (unsafePackCStringLen, unsafeUseAsCString)
import Foreign.ForeignPtr (withForeignPtr, newForeignPtr_)
import Foreign.Ptr (nullPtr, castPtr)
import Foreign.Marshal (alloca)
import Foreign.Storable (peek)
import Foreign.C.Types (CInt)
import Text.Regex.PCRE.Light
import Text.Regex.PCRE.Light.Base
type CompiledBytes = B.ByteString
precompile :: B.ByteString -> [PCREOption] -> IO (Maybe CompiledBytes)
precompile pat opts = regexToTable $ compile pat opts
regexToTable :: Regex -> IO (Maybe CompiledBytes)
regexToTable (Regex p _) =
withForeignPtr p $ \pcre -> alloca $ \res -> do
success <- c_pcre_fullinfo pcre nullPtr info_size res
len <- return . fromIntegral =<< (peek res :: IO CInt)
if success >= 0
then withForeignPtr p (liftM Just . unsafePackCStringLen . (, len) . castPtr)
else return Nothing
regexFromTable :: CompiledBytes -> IO Regex
regexFromTable bytes = unsafeUseAsCString bytes $ \cstr -> do
ptr <- newForeignPtr_ (castPtr cstr)
return $ Regex ptr bytes