{-# OPTIONS_GHC -fno-warn-orphans #-}
module Text.Regex.PCRE.Sequence(
Regex,
MatchOffset,
MatchLength,
CompOption(CompOption),
ExecOption(ExecOption),
ReturnCode,
WrapError,
unusedOffset,
getVersion,
compile,
execute,
regexec,
compBlank,
compAnchored,
compAutoCallout,
compCaseless,
compDollarEndOnly,
compDotAll,
compExtended,
compExtra,
compFirstLine,
compMultiline,
compNoAutoCapture,
compUngreedy,
compUTF8,
compNoUTF8Check,
execBlank,
execAnchored,
execNotBOL,
execNotEOL,
execNotEmpty,
execNoUTF8Check,
execPartial
) where
import Prelude hiding (fail)
import Control.Monad.Fail (MonadFail(fail))
import Text.Regex.PCRE.Wrap
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 :: Regex -> Seq Char -> Seq Char
match = Regex -> Seq Char -> Seq Char
forall a b. RegexLike a b => a -> b -> b
polymatch
matchM :: Regex -> Seq Char -> m (Seq Char)
matchM = Regex -> Seq Char -> m (Seq Char)
forall a b (m :: * -> *).
(RegexLike a b, MonadFail m) =>
a -> b -> m b
polymatchM
unwrap :: (Show e) => Either e v -> IO v
unwrap :: Either e v -> IO v
unwrap Either e v
x = case Either e v
x of Left e
err -> String -> IO v
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Text.Regex.PCRE.Sequence died: "String -> String -> String
forall a. [a] -> [a] -> [a]
++ e -> String
forall a. Show a => a -> String
show e
err)
Right v
v -> v -> IO v
forall (m :: * -> *) a. Monad m => a -> m a
return v
v
instance RegexMaker Regex CompOption ExecOption (Seq Char) where
makeRegexOpts :: CompOption -> ExecOption -> Seq Char -> Regex
makeRegexOpts CompOption
c ExecOption
e Seq Char
pattern = IO Regex -> Regex
forall a. IO a -> a
unsafePerformIO (IO Regex -> Regex) -> IO Regex -> Regex
forall a b. (a -> b) -> a -> b
$
CompOption
-> ExecOption
-> Seq Char
-> IO (Either (MatchOffset, String) Regex)
compile CompOption
c ExecOption
e Seq Char
pattern IO (Either (MatchOffset, String) Regex)
-> (Either (MatchOffset, String) Regex -> IO Regex) -> IO Regex
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either (MatchOffset, String) Regex -> IO Regex
forall e v. Show e => Either e v -> IO v
unwrap
makeRegexOptsM :: CompOption -> ExecOption -> Seq Char -> m Regex
makeRegexOptsM CompOption
c ExecOption
e Seq Char
pattern = ((MatchOffset, String) -> m Regex)
-> (Regex -> m Regex)
-> Either (MatchOffset, String) Regex
-> m Regex
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> m Regex
forall (m :: * -> *) a. MonadFail m => String -> m a
fail(String -> m Regex)
-> ((MatchOffset, String) -> String)
-> (MatchOffset, String)
-> m Regex
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(MatchOffset, String) -> String
forall a. Show a => a -> String
show) Regex -> m Regex
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (MatchOffset, String) Regex -> m Regex)
-> Either (MatchOffset, String) Regex -> m Regex
forall a b. (a -> b) -> a -> b
$ IO (Either (MatchOffset, String) Regex)
-> Either (MatchOffset, String) Regex
forall a. IO a -> a
unsafePerformIO (IO (Either (MatchOffset, String) Regex)
-> Either (MatchOffset, String) Regex)
-> IO (Either (MatchOffset, String) Regex)
-> Either (MatchOffset, String) Regex
forall a b. (a -> b) -> a -> b
$
CompOption
-> ExecOption
-> Seq Char
-> IO (Either (MatchOffset, String) Regex)
compile CompOption
c ExecOption
e Seq Char
pattern
instance RegexLike Regex (Seq Char) where
matchTest :: Regex -> Seq Char -> Bool
matchTest Regex
regex Seq Char
str = IO Bool -> Bool
forall a. IO a -> a
unsafePerformIO (IO Bool -> Bool) -> IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$
Seq Char
-> (CStringLen -> IO (Either WrapError Bool))
-> IO (Either WrapError Bool)
forall a. Seq Char -> (CStringLen -> IO a) -> IO a
withSeq Seq Char
str (MatchOffset -> Regex -> CStringLen -> IO (Either WrapError Bool)
wrapTest MatchOffset
0 Regex
regex) IO (Either WrapError Bool)
-> (Either WrapError Bool -> IO Bool) -> IO Bool
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either WrapError Bool -> IO Bool
forall e v. Show e => Either e v -> IO v
unwrap
matchOnce :: Regex -> Seq Char -> Maybe MatchArray
matchOnce Regex
regex Seq Char
str = IO (Maybe MatchArray) -> Maybe MatchArray
forall a. IO a -> a
unsafePerformIO (IO (Maybe MatchArray) -> Maybe MatchArray)
-> IO (Maybe MatchArray) -> Maybe MatchArray
forall a b. (a -> b) -> a -> b
$
Regex -> Seq Char -> IO (Either WrapError (Maybe MatchArray))
execute Regex
regex Seq Char
str IO (Either WrapError (Maybe MatchArray))
-> (Either WrapError (Maybe MatchArray) -> IO (Maybe MatchArray))
-> IO (Maybe MatchArray)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either WrapError (Maybe MatchArray) -> IO (Maybe MatchArray)
forall e v. Show e => Either e v -> IO v
unwrap
matchAll :: Regex -> Seq Char -> [MatchArray]
matchAll Regex
regex Seq Char
str = IO [MatchArray] -> [MatchArray]
forall a. IO a -> a
unsafePerformIO (IO [MatchArray] -> [MatchArray])
-> IO [MatchArray] -> [MatchArray]
forall a b. (a -> b) -> a -> b
$
Seq Char
-> (CStringLen -> IO (Either WrapError [MatchArray]))
-> IO (Either WrapError [MatchArray])
forall a. Seq Char -> (CStringLen -> IO a) -> IO a
withSeq Seq Char
str (Regex -> CStringLen -> IO (Either WrapError [MatchArray])
wrapMatchAll Regex
regex) IO (Either WrapError [MatchArray])
-> (Either WrapError [MatchArray] -> IO [MatchArray])
-> IO [MatchArray]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either WrapError [MatchArray] -> IO [MatchArray]
forall e v. Show e => Either e v -> IO v
unwrap
matchCount :: Regex -> Seq Char -> MatchOffset
matchCount Regex
regex Seq Char
str = IO MatchOffset -> MatchOffset
forall a. IO a -> a
unsafePerformIO (IO MatchOffset -> MatchOffset) -> IO MatchOffset -> MatchOffset
forall a b. (a -> b) -> a -> b
$
Seq Char
-> (CStringLen -> IO (Either WrapError MatchOffset))
-> IO (Either WrapError MatchOffset)
forall a. Seq Char -> (CStringLen -> IO a) -> IO a
withSeq Seq Char
str (Regex -> CStringLen -> IO (Either WrapError MatchOffset)
wrapCount Regex
regex) IO (Either WrapError MatchOffset)
-> (Either WrapError MatchOffset -> IO MatchOffset)
-> IO MatchOffset
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either WrapError MatchOffset -> IO MatchOffset
forall e v. Show e => Either e v -> IO v
unwrap
compile :: CompOption
-> ExecOption
-> (Seq Char)
-> IO (Either (MatchOffset,String) Regex)
compile :: CompOption
-> ExecOption
-> Seq Char
-> IO (Either (MatchOffset, String) Regex)
compile CompOption
c ExecOption
e Seq Char
pattern = Seq Char
-> (CString -> IO (Either (MatchOffset, String) Regex))
-> IO (Either (MatchOffset, String) Regex)
forall a. Seq Char -> (CString -> IO a) -> IO a
withSeq0 Seq Char
pattern (CompOption
-> ExecOption -> CString -> IO (Either (MatchOffset, String) Regex)
wrapCompile CompOption
c ExecOption
e)
execute :: Regex
-> (Seq Char)
-> IO (Either WrapError (Maybe (Array Int (MatchOffset,MatchLength))))
execute :: Regex -> Seq Char -> IO (Either WrapError (Maybe MatchArray))
execute Regex
regex Seq Char
str = do
Either WrapError (Maybe [(MatchOffset, MatchOffset)])
maybeStartEnd <- Seq Char
-> (CStringLen
-> IO (Either WrapError (Maybe [(MatchOffset, MatchOffset)])))
-> IO (Either WrapError (Maybe [(MatchOffset, MatchOffset)]))
forall a. Seq Char -> (CStringLen -> IO a) -> IO a
withSeq Seq Char
str (MatchOffset
-> Regex
-> CStringLen
-> IO (Either WrapError (Maybe [(MatchOffset, MatchOffset)]))
wrapMatch MatchOffset
0 Regex
regex)
case Either WrapError (Maybe [(MatchOffset, MatchOffset)])
maybeStartEnd of
Right Maybe [(MatchOffset, MatchOffset)]
Nothing -> Either WrapError (Maybe MatchArray)
-> IO (Either WrapError (Maybe MatchArray))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe MatchArray -> Either WrapError (Maybe MatchArray)
forall a b. b -> Either a b
Right Maybe MatchArray
forall a. Maybe a
Nothing)
Right (Just [(MatchOffset, MatchOffset)]
parts) ->
Either WrapError (Maybe MatchArray)
-> IO (Either WrapError (Maybe MatchArray))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either WrapError (Maybe MatchArray)
-> IO (Either WrapError (Maybe MatchArray)))
-> ([(MatchOffset, MatchOffset)]
-> Either WrapError (Maybe MatchArray))
-> [(MatchOffset, MatchOffset)]
-> IO (Either WrapError (Maybe MatchArray))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe MatchArray -> Either WrapError (Maybe MatchArray)
forall a b. b -> Either a b
Right (Maybe MatchArray -> Either WrapError (Maybe MatchArray))
-> ([(MatchOffset, MatchOffset)] -> Maybe MatchArray)
-> [(MatchOffset, MatchOffset)]
-> Either WrapError (Maybe MatchArray)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MatchArray -> Maybe MatchArray
forall a. a -> Maybe a
Just (MatchArray -> Maybe MatchArray)
-> ([(MatchOffset, MatchOffset)] -> MatchArray)
-> [(MatchOffset, MatchOffset)]
-> Maybe MatchArray
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MatchOffset, MatchOffset)
-> [(MatchOffset, MatchOffset)] -> MatchArray
forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (MatchOffset
0,MatchOffset -> MatchOffset
forall a. Enum a => a -> a
pred ([(MatchOffset, MatchOffset)] -> MatchOffset
forall (t :: * -> *) a. Foldable t => t a -> MatchOffset
length [(MatchOffset, MatchOffset)]
parts))
([(MatchOffset, MatchOffset)] -> MatchArray)
-> ([(MatchOffset, MatchOffset)] -> [(MatchOffset, MatchOffset)])
-> [(MatchOffset, MatchOffset)]
-> MatchArray
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((MatchOffset, MatchOffset) -> (MatchOffset, MatchOffset))
-> [(MatchOffset, MatchOffset)] -> [(MatchOffset, MatchOffset)]
forall a b. (a -> b) -> [a] -> [b]
map (\(MatchOffset
s,MatchOffset
e)->(MatchOffset -> MatchOffset
forall a b. (Integral a, Num b) => a -> b
fromIntegral MatchOffset
s, MatchOffset -> MatchOffset
forall a b. (Integral a, Num b) => a -> b
fromIntegral (MatchOffset
eMatchOffset -> MatchOffset -> MatchOffset
forall a. Num a => a -> a -> a
-MatchOffset
s))) ([(MatchOffset, MatchOffset)]
-> IO (Either WrapError (Maybe MatchArray)))
-> [(MatchOffset, MatchOffset)]
-> IO (Either WrapError (Maybe MatchArray))
forall a b. (a -> b) -> a -> b
$ [(MatchOffset, MatchOffset)]
parts
Left WrapError
err -> Either WrapError (Maybe MatchArray)
-> IO (Either WrapError (Maybe MatchArray))
forall (m :: * -> *) a. Monad m => a -> m a
return (WrapError -> Either WrapError (Maybe MatchArray)
forall a b. a -> Either a b
Left WrapError
err)
regexec :: Regex
-> (Seq Char)
-> IO (Either WrapError (Maybe ((Seq Char), (Seq Char),(Seq Char), [(Seq Char)])))
regexec :: Regex
-> Seq Char
-> IO
(Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])))
regexec Regex
regex Seq Char
str = do
let getSub :: (MatchOffset, MatchOffset) -> Seq Char
getSub (MatchOffset
start,MatchOffset
stop) | MatchOffset
start MatchOffset -> MatchOffset -> Bool
forall a. Eq a => a -> a -> Bool
== MatchOffset
unusedOffset = Seq Char
forall a. Seq a
S.empty
| Bool
otherwise = (MatchOffset, MatchOffset) -> Seq Char -> Seq Char
forall source.
Extract source =>
(MatchOffset, MatchOffset) -> source -> source
extract (MatchOffset
start,MatchOffset
stopMatchOffset -> MatchOffset -> MatchOffset
forall a. Num a => a -> a -> a
-MatchOffset
start) Seq Char
str
matchedParts :: [(MatchOffset, MatchOffset)]
-> (Seq Char, Seq Char, Seq Char, [Seq Char])
matchedParts [] = (Seq Char
forall a. Seq a
S.empty,Seq Char
forall a. Seq a
S.empty,Seq Char
str,[])
matchedParts (matchedStartStop :: (MatchOffset, MatchOffset)
matchedStartStop@(MatchOffset
start,MatchOffset
stop):[(MatchOffset, MatchOffset)]
subStartStop) =
(MatchOffset -> Seq Char -> Seq Char
forall source. Extract source => MatchOffset -> source -> source
before MatchOffset
start Seq Char
str
,(MatchOffset, MatchOffset) -> Seq Char
getSub (MatchOffset, MatchOffset)
matchedStartStop
,MatchOffset -> Seq Char -> Seq Char
forall source. Extract source => MatchOffset -> source -> source
after MatchOffset
stop Seq Char
str
,((MatchOffset, MatchOffset) -> Seq Char)
-> [(MatchOffset, MatchOffset)] -> [Seq Char]
forall a b. (a -> b) -> [a] -> [b]
map (MatchOffset, MatchOffset) -> Seq Char
getSub [(MatchOffset, MatchOffset)]
subStartStop)
Either WrapError (Maybe [(MatchOffset, MatchOffset)])
maybeStartEnd <- Seq Char
-> (CStringLen
-> IO (Either WrapError (Maybe [(MatchOffset, MatchOffset)])))
-> IO (Either WrapError (Maybe [(MatchOffset, MatchOffset)]))
forall a. Seq Char -> (CStringLen -> IO a) -> IO a
withSeq Seq Char
str (MatchOffset
-> Regex
-> CStringLen
-> IO (Either WrapError (Maybe [(MatchOffset, MatchOffset)]))
wrapMatch MatchOffset
0 Regex
regex)
case Either WrapError (Maybe [(MatchOffset, MatchOffset)])
maybeStartEnd of
Right Maybe [(MatchOffset, MatchOffset)]
Nothing -> Either WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))
-> IO
(Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])
-> Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))
forall a b. b -> Either a b
Right Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])
forall a. Maybe a
Nothing)
Right (Just [(MatchOffset, MatchOffset)]
parts) -> Either WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))
-> IO
(Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))
-> IO
(Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))))
-> ([(MatchOffset, MatchOffset)]
-> Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])))
-> [(MatchOffset, MatchOffset)]
-> IO
(Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])
-> Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))
forall a b. b -> Either a b
Right (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])
-> Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])))
-> ([(MatchOffset, MatchOffset)]
-> Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))
-> [(MatchOffset, MatchOffset)]
-> Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Seq Char, Seq Char, Seq Char, [Seq Char])
-> Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])
forall a. a -> Maybe a
Just ((Seq Char, Seq Char, Seq Char, [Seq Char])
-> Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))
-> ([(MatchOffset, MatchOffset)]
-> (Seq Char, Seq Char, Seq Char, [Seq Char]))
-> [(MatchOffset, MatchOffset)]
-> Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(MatchOffset, MatchOffset)]
-> (Seq Char, Seq Char, Seq Char, [Seq Char])
matchedParts ([(MatchOffset, MatchOffset)]
-> IO
(Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))))
-> [(MatchOffset, MatchOffset)]
-> IO
(Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])))
forall a b. (a -> b) -> a -> b
$ [(MatchOffset, MatchOffset)]
parts
Left WrapError
err -> Either WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))
-> IO
(Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char])))
forall (m :: * -> *) a. Monad m => a -> m a
return (WrapError
-> Either
WrapError (Maybe (Seq Char, Seq Char, Seq Char, [Seq Char]))
forall a b. a -> Either a b
Left WrapError
err)
withSeq :: Seq Char -> (CStringLen -> IO a) -> IO a
withSeq :: Seq Char -> (CStringLen -> IO a) -> IO a
withSeq Seq Char
s CStringLen -> IO a
f =
let
len :: MatchOffset
len = Seq Char -> MatchOffset
forall a. Seq a -> MatchOffset
S.length Seq Char
s
pokes :: CString -> Seq Char -> IO ()
pokes CString
p Seq Char
a | CString -> Bool -> Bool
seq CString
p (Seq Char -> Bool -> Bool
seq Seq Char
a Bool
False) = IO ()
forall a. HasCallStack => a
undefined
| Bool
otherwise =
case Seq Char -> ViewL Char
forall a. Seq a -> ViewL a
viewl Seq Char
a of
ViewL Char
EmptyL -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Char
c :< Seq Char
a' -> CString -> CChar -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke CString
p (Char -> CChar
castCharToCChar Char
c) IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CString -> Seq Char -> IO ()
pokes (CString -> MatchOffset -> CString
forall a. Storable a => Ptr a -> MatchOffset -> Ptr a
advancePtr CString
p MatchOffset
1) Seq Char
a'
in MatchOffset -> (CString -> IO a) -> IO a
forall a b. MatchOffset -> (Ptr a -> IO b) -> IO b
allocaBytes (Seq Char -> MatchOffset
forall a. Seq a -> MatchOffset
S.length Seq Char
s) (\CString
ptr -> CString -> Seq Char -> IO ()
pokes CString
ptr Seq Char
s IO () -> IO a -> IO a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CStringLen -> IO a
f (CString
ptr,MatchOffset
len))
withSeq0 :: Seq Char -> (CString -> IO a) -> IO a
withSeq0 :: Seq Char -> (CString -> IO a) -> IO a
withSeq0 Seq Char
s CString -> IO a
f =
let
s' :: Seq Char
s' = case Seq Char -> ViewR Char
forall a. Seq a -> ViewR a
viewr Seq Char
s of
ViewR Char
EmptyR -> Char -> Seq Char
forall a. a -> Seq a
singleton Char
'\0'
Seq Char
_ :> Char
'\0' -> Seq Char
s
ViewR Char
_ -> Seq Char
s Seq Char -> Char -> Seq Char
forall a. Seq a -> a -> Seq a
|> Char
'\0'
pokes :: CString -> Seq Char -> IO ()
pokes CString
p Seq Char
a | CString -> Bool -> Bool
seq CString
p (Seq Char -> Bool -> Bool
seq Seq Char
a Bool
False) = IO ()
forall a. HasCallStack => a
undefined
| Bool
otherwise =
case Seq Char -> ViewL Char
forall a. Seq a -> ViewL a
viewl Seq Char
a of
ViewL Char
EmptyL -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Char
c :< Seq Char
a' -> CString -> CChar -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke CString
p (Char -> CChar
castCharToCChar Char
c) IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CString -> Seq Char -> IO ()
pokes (CString -> MatchOffset -> CString
forall a. Storable a => Ptr a -> MatchOffset -> Ptr a
advancePtr CString
p MatchOffset
1) Seq Char
a'
in MatchOffset -> (CString -> IO a) -> IO a
forall a b. MatchOffset -> (Ptr a -> IO b) -> IO b
allocaBytes (Seq Char -> MatchOffset
forall a. Seq a -> MatchOffset
S.length Seq Char
s') (\CString
ptr -> CString -> Seq Char -> IO ()
pokes CString
ptr Seq Char
s' IO () -> IO a -> IO a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CString -> IO a
f CString
ptr)