diff -upr hugs98-Dec2003.orig/fptools/libraries/base/Foreign/C/String.hs hugs98-Dec2003/fptools/libraries/base/Foreign/C/String.hs
--- hugs98-Dec2003.orig/fptools/libraries/base/Foreign/C/String.hs	2003-10-21 22:24:31.000000000 +0900
+++ hugs98-Dec2003/fptools/libraries/base/Foreign/C/String.hs	2004-04-13 00:22:08.000000000 +0900
@@ -38,8 +38,14 @@ module Foreign.C.String (   -- represent
   castCharToCChar,   -- :: Char -> CChar
   castCCharToChar,   -- :: CChar -> Char
 
+#ifdef __HUGS__
+  charIsRepresentable
+#endif
   ) where
 
+#ifdef __HUGS__
+import Foreign.Marshal
+#endif
 import Foreign.Marshal.Array
 import Foreign.C.Types
 import Foreign.Ptr
@@ -73,8 +79,10 @@ type CStringLen = (CString, Int)	-- stri
 --
 -- * the following routines apply the default conversion when converting the
 --   C-land character encoding into the Haskell-land character encoding
+#ifndef __HUGS__
 --
 --   ** NOTE: The current implementation doesn't handle conversions yet! **
+#endif
 --
 -- * the routines using an explicit length tolerate NUL characters in the
 --   middle of a string
@@ -84,8 +92,18 @@ type CStringLen = (CString, Int)	-- stri
 --
 peekCString    :: CString -> IO String
 #ifndef __GLASGOW_HASKELL__
+#ifndef __HUGS__
 peekCString cp  = do cs <- peekArray0 nUL cp; return (cCharsToChars cs)
 #else
+peekCString cp =
+    alloca (\p -> do poke p cp; loop p)
+    where loop p = do c <- primExtractChar p
+		      if c == '\0'
+			 then return []
+			 else do cs <- loop p
+				 return (c : cs)
+#endif
+#else
 peekCString cp = do
   l <- lengthArray0 nUL cp
   if l <= 0 then return "" else loop "" (l-1)
@@ -100,7 +118,20 @@ peekCString cp = do
 --
 peekCStringLen           :: CStringLen -> IO String
 #ifndef __GLASGOW_HASKELL__
-peekCStringLen (cp, len)  = do cs <- peekArray len cp; return (cCharsToChars cs)
+#ifndef __HUGS__
+peekCStringLen (cp, len)  = do cs <- peekArray len cp; return (cCharsToChars cs)
+#else
+-- FIXME: might read beyond len.
+peekCStringLen (cp, len) =
+    alloca (\p -> do poke p cp; loop (cp `plusPtr` len) p)
+    where loop end p =
+              do cp <- peek p
+                 if cp < end
+                     then do c <- primExtractChar p
+                             cs <- loop end p
+                             return (c : cs)
+                     else return []
+#endif
 #else
 peekCStringLen (cp, len) 
   | len <= 0  = return "" -- being (too?) nice.
@@ -123,8 +154,12 @@ peekCStringLen (cp, len) 
 --
 newCString :: String -> IO CString
 #ifndef __GLASGOW_HASKELL__
+#ifndef __HUGS__
 newCString  = newArray0 nUL . charsToCChars
 #else
+newCString  = fmap fst . newCStringLen . (++"\0")
+#endif
+#else
 newCString str = do
   ptr <- mallocArray0 (length str)
   let
@@ -141,9 +176,16 @@ newCString str = do
 --
 newCStringLen     :: String -> IO CStringLen
 #ifndef __GLASGOW_HASKELL__
+#ifndef __HUGS__
 newCStringLen str  = do a <- newArray (charsToCChars str)
 			return (pairLength str a)
 #else
+newCStringLen str =
+    do p <- mallocArray ((length str + 1) * primMaxCharEncoding)
+       len <- addChars p str
+       return (p,len)
+#endif
+#else
 newCStringLen str = do
   ptr <- mallocArray0 len
   let
@@ -164,8 +206,12 @@ newCStringLen str = do
 --
 withCString :: String -> (CString -> IO a) -> IO a
 #ifndef __GLASGOW_HASKELL__
+#ifndef __HUGS__
 withCString  = withArray0 nUL . charsToCChars
 #else
+withCString str act = withCStringLen (str++"\0") (act . fst)
+#endif
+#else
 withCString str f =
   allocaArray0 (length str) $ \ptr ->
       let
@@ -185,8 +231,15 @@ withCString str f =
 --
 withCStringLen         :: String -> (CStringLen -> IO a) -> IO a
 #ifndef __GLASGOW_HASKELL__
+#ifndef __HUGS__
 withCStringLen str act  = withArray (charsToCChars str) $ act . pairLength str
 #else
+withCStringLen str act =
+    do allocaArray ((length str) * primMaxCharEncoding)
+                   (\p -> do len <- addChars p str 
+                             act (p,len))
+#endif
+#else
 withCStringLen str f =
   allocaArray len $ \ptr ->
       let
@@ -207,6 +260,7 @@ withCStringLen str f =
 nUL :: CChar
 nUL  = 0
 
+#ifndef __HUGS__
 -- pair a C string with the length of the given Haskell string
 --
 pairLength :: String -> CString -> CStringLen
@@ -221,9 +275,28 @@ cCharsToChars xs  = map castCCharToChar 
 --
 charsToCChars :: [Char] -> [CChar]
 charsToCChars xs  = map castCharToCChar xs
+#endif
 
 castCCharToChar :: CChar -> Char
 castCCharToChar ch = unsafeChr (fromIntegral (fromIntegral ch :: Word8))
 
 castCharToCChar :: Char -> CChar
 castCharToCChar ch = fromIntegral (ord ch)
+
+#ifdef __HUGS__
+charIsRepresentable :: Char -> IO Bool
+charIsRepresentable = return.primIsRepresentable
+primitive primIsRepresentable :: Char -> Bool
+
+primitive primMaxCharEncoding :: Int
+primitive primAddChar :: Char -> Ptr CString -> IO ()
+primitive primExtractChar :: Ptr CString -> IO Char
+
+addChars :: Ptr CChar -> String -> IO Int
+addChars buffer str =
+    alloca (\p -> 
+            do poke p buffer
+               mapM_ (\c -> primAddChar c p) str
+               end <- peek p
+               return (end `minusPtr` buffer))
+#endif
diff -upr hugs98-Dec2003.orig/src/builtin.c hugs98-Dec2003/src/builtin.c
--- hugs98-Dec2003.orig/src/builtin.c	2003-12-02 21:15:49.000000000 +0900
+++ hugs98-Dec2003/src/builtin.c	2004-04-12 18:21:08.000000000 +0900
@@ -335,6 +335,10 @@ PROTO_PRIM(primToLower);
 PROTO_PRIM(primToTitle);
 PROTO_PRIM(primUniGenCat);
 #endif
+PROTO_PRIM(primIsRepresentable);
+PROTO_PRIM(primMaxCharEncoding);
+PROTO_PRIM(primAddChar);
+PROTO_PRIM(primExtractChar);
 
 #if TREX
 PROTO_PRIM(primRecExt);
@@ -552,6 +556,10 @@ static struct primitive builtinPrimTable
   {"toTitle",		1, primToTitle},
   {"primUniGenCat",	1, primUniGenCat},
 #endif
+  {"primMaxCharEncoding",	0, primMaxCharEncoding},
+  {"primIsRepresentable",	1, primIsRepresentable},
+  {"primAddChar",		2+IOArity, primAddChar},
+  {"primExtractChar",		1+IOArity, primExtractChar},
 
 #if TREX
   {"recExt",            3, primRecExt},
@@ -1467,6 +1475,26 @@ Char2Char(primToTitle,toTitle(x))
 Char2Int(primUniGenCat,uni_gencat(x))
 #endif
 
+CAFInt(primMaxCharEncoding,MAX_CHAR_ENCODING)
+Char2Bool(primIsRepresentable,charIsRepresentable(x))
+
+primFun(primAddChar) {
+    Char c;
+    char** p;
+    CharArg(c,2+IOArity);
+    PtrArg(p,1+IOArity);
+    AddChar(c,*p);
+    IOReturn(nameUnit);
+}
+
+primFun(primExtractChar) {
+    Char c;
+    char** p;
+    PtrArg(p,1+IOArity);
+    c = ExtractChar(*p);
+    IOReturn(mkChar(c));
+}
+
 /* --------------------------------------------------------------------------
  * Extensible records: (Gaster and Jones, 1996)
  * ------------------------------------------------------------------------*/
