[project @ 2005-01-27 14:19:50 by simonpj]
[ghc-base.git] / Text / Regex / Posix.hsc
index 9cc06f7..ee22088 100644 (file)
@@ -6,13 +6,19 @@
 -- 
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
--- Portability :  non-portable (needs POSIX regexps)
+-- Portability :  portable
 --
 -- Interface to the POSIX regular expression library.
 --
 -----------------------------------------------------------------------------
 
 -- ToDo: should have an interface using PackedStrings.
+#ifndef __NHC__
+#include "ghcconfig.h"
+#else
+#define HAVE_REGEX_H 1
+#define HAVE_REGCOMP 1
+#endif
 
 module Text.Regex.Posix (
        -- * The @Regex@ type
@@ -37,13 +43,27 @@ module Text.Regex.Posix (
   ) where
 
 #include <sys/types.h>
+
+#if HAVE_REGEX_H && HAVE_REGCOMP
 #include "regex.h"
+#else
+#include "regex/regex.h"
+
+-- CFILES stuff is Hugs only
+{-# CFILES cbits/regex/reallocf.c #-}
+{-# CFILES cbits/regex/regcomp.c #-}
+{-# CFILES cbits/regex/regerror.c #-}
+{-# CFILES cbits/regex/regexec.c #-}
+{-# CFILES cbits/regex/regfree.c #-}
+#endif
 
 import Prelude
 
 import Foreign
 import Foreign.C
 
+type CRegex    = ()
+
 -- | A compiled regular expression
 newtype Regex = Regex (ForeignPtr CRegex)
 
@@ -60,9 +80,9 @@ regcomp pattern flags = do
   r <- withCString pattern $ \cstr ->
         withForeignPtr regex_fptr $ \p ->
            c_regcomp p cstr (fromIntegral flags)
-  addForeignPtrFinalizer regex_fptr ptr_regfree
   if (r == 0)
-     then return (Regex regex_fptr)
+     then do addForeignPtrFinalizer ptr_regfree regex_fptr
+            return (Regex regex_fptr)
      else error "Text.Regex.Posix.regcomp: error in pattern" -- ToDo
 
 -- -----------------------------------------------------------------------------
@@ -93,13 +113,13 @@ regexec (Regex regex_fptr) str = do
 
         if (r /= 0) then return Nothing else do 
 
-        (before,match,after) <- matched_parts str p_match
+          (before,match,after) <- matched_parts str p_match
 
-        sub_strs <- 
-         mapM (unpack str) $ take nsub_int $ tail $
-            iterate (`plusPtr` (#const sizeof(regmatch_t))) p_match
+          sub_strs <- 
+           mapM (unpack str) $ take nsub_int $ tail $
+              iterate (`plusPtr` (#const sizeof(regmatch_t))) p_match
 
-        return (Just (before, match, after, sub_strs))
+          return (Just (before, match, after, sub_strs))
 
 matched_parts :: String -> Ptr CRegMatch -> IO (String, String, String)
 matched_parts string p_match = do
@@ -117,7 +137,7 @@ unpack string p_match = do
   -- the subexpression may not have matched at all, perhaps because it
   -- was optional.  In this case, the offsets are set to -1.
   if (start == -1) then return "" else do
-  return (take (fromIntegral (end-start)) (drop (fromIntegral start) string))
+    return (take (fromIntegral (end-start)) (drop (fromIntegral start) string))
 
 -- -----------------------------------------------------------------------------
 -- The POSIX regex C interface
@@ -154,9 +174,9 @@ unpack string p_match = do
        REG_ERANGE, \
        REG_ESPACE
 
-type CRegex    = ()
 type CRegMatch = ()
 
+#ifdef __GLASGOW_HASKELL__
 foreign import ccall unsafe "regcomp"
   c_regcomp :: Ptr CRegex -> CString -> CInt -> IO CInt
 
@@ -166,3 +186,23 @@ foreign import ccall  unsafe "&regfree"
 foreign import ccall unsafe "regexec"
   c_regexec :: Ptr CRegex -> CString -> CSize
            -> Ptr CRegMatch -> CInt -> IO CInt
+#else
+-- For NHC and (we think) Hugs, we have to hackily put
+-- the regex.h include in the name of the C function to
+-- import.  (GHC does this by interpreting the
+-- "-#include regex.h" OPTIONS pragma that hsc2hs generates.
+-- The trouble with the hacky solution is that sometimes
+-- we want regex.h and sometimes regex/regex.h.  I'm not
+-- sure if the hack will work for NHC and Hugs on all 
+-- platforms
+
+foreign import ccall unsafe "regex.h regcomp"
+  c_regcomp :: Ptr CRegex -> CString -> CInt -> IO CInt
+
+foreign import ccall  unsafe "regex.h &regfree"
+  ptr_regfree :: FunPtr (Ptr CRegex -> IO ())
+
+foreign import ccall unsafe "regex.h regexec"
+  c_regexec :: Ptr CRegex -> CString -> CSize
+           -> Ptr CRegMatch -> CInt -> IO CInt
+#endif