-----------------------------------------------------------------------------

A simple high-level interface to Regex

(c) Simon Marlow 1997-1999

Modified 1999 by Ian Jackson to fix an apparent fatal bug (?!)  and to
provide matchRegexAll.
-----------------------------------------------------------------------------

> module RegexString 
>         ( Regex
>         , mkRegex             -- :: String -> Regex
>         , mkRegexWithOpts     -- :: String -> Bool -> Bool -> Regex

>         , matchRegex          -- :: Regex  -> String -> Maybe [String]
>         , matchRegexAll       -- :: Regex  
>                               -- -> String 
>                               -- -> Maybe ( String   -- before match
>                               --          , String   -- the matched string
>                               --          , String   -- after match
>                               --          , String   -- matched by last grouping
>                               --          , [String] -- $1 .. $n group matches
>                               --          )
> 
>         , searchRegex         -- :: Regex -> String -> Maybe [String]
>         , searchRegexAll      -- :: Regex  
>                               -- -> String 
>                               -- -> Maybe ( String   -- before match
>                               --          , String   -- the matched string
>                               --          , String   -- after match
>                               --          , String   -- matched by last grouping
>                               --          , [String] -- $1 .. $n group matches
>                               --          )
> 
>         ) where

> import Regex
> import PackedString
> import Array
> import GlaExts

> type Regex = PatBuffer
> 
> mkRegex :: String -> Regex
> mkRegex s = unsafePerformIO (
>         re_compile_pattern (packString s) False False)
>
> mkRegexWithOpts :: String -> Bool -> Bool -> Regex
> mkRegexWithOpts s single_line case_sensitive
>       = unsafePerformIO (re_compile_pattern (packString s) 
>                               single_line case_sensitive)
> 
> matchRegex :: Regex -> String -> Maybe [String]
> matchRegex = performRegexOp doMatch matches
> 
> matchRegexAll :: Regex
>               -> String
>               -> Maybe ( String -- $`
>                        , String -- $&
>                        , String -- $'
>                        , String -- $+
>                        , [String] -- $1..
>                        )
> matchRegexAll = performRegexOp doMatch matchesAll
>
> doMatch p str start stop flg = re_match p str start flg
>
> performRegexOp :: (Regex -> PackedString -> Int -> Int -> Bool -> IO (Maybe REmatch))
>                -> (REmatch -> PackedString -> a)
>                -> Regex
>                -> String
>                -> Maybe a
> performRegexOp regexOp interpretBy p s = unsafePerformIO $ do
>         m <- regexOp p str 0 (lengthPS str) True
>         case m of
>                 Nothing -> return Nothing
>                 Just m  -> return (Just (interpretBy m str))
>    where
>         str = packString s
>
> matches (REmatch arr _ _ _ _) s = map (getFromBounds s) (elems arr)
>
> matchesAll rm@(REmatch _ before entire after lastbracket) s =
>         ( g before, g entire, g after, g lastbracket, matches rm s )
>    where
>         g = getFromBounds s
>
> searchRegexAll :: Regex
>                -> String
>                -> Maybe ( String -- $`
>                         , String -- $&
>                         , String -- $'
>                         , String -- $+
>                         , [String] -- $1..
>                         )
> searchRegexAll = performRegexOp re_search matchesAll
> 
> 
> searchRegex :: Regex -> String -> Maybe [String]
> searchRegex = performRegexOp re_search matches

> getFromBounds s (beg,end) = unpackPS (substrPS s beg (end-1))
