-{-# OPTIONS_GHC -fno-implicit-prelude #-}
+{-# OPTIONS_GHC -XNoImplicitPrelude #-}
-----------------------------------------------------------------------------
-- |
-- Module : GHC.IO.Encoding.Iconv
#endif
) where
+#include "MachDeps.h"
#include "HsBaseConfig.h"
#if !defined(mingw32_HOST_OS)
-#undef DEBUG_DUMP
-
-import Foreign
+import Foreign hiding (unsafePerformIO)
import Foreign.C
import Data.Maybe
import GHC.Base
import GHC.Num
import GHC.Show
import GHC.Real
-#ifdef DEBUG_DUMP
+import System.IO.Unsafe (unsafePerformIO)
import System.Posix.Internals
-#endif
-
-iconv_trace :: String -> IO ()
-#ifdef DEBUG_DUMP
+c_DEBUG_DUMP :: Bool
+c_DEBUG_DUMP = False
-iconv_trace s = puts s
+iconv_trace :: String -> IO ()
+iconv_trace s
+ | c_DEBUG_DUMP = puts s
+ | otherwise = return ()
puts :: String -> IO ()
-puts s = do withCStringLen (s++"\n") $ \(p,len) ->
- c_write 1 p (fromIntegral len)
+puts s = do _ <- withCStringLen (s ++ "\n") $ \(p, len) ->
+ c_write 1 (castPtr p) (fromIntegral len)
return ()
-#else
-
-iconv_trace _ = return ()
-
-#endif
-
-- -----------------------------------------------------------------------------
-- iconv encoders/decoders
{-# NOINLINE localeEncoding #-}
localeEncoding :: TextEncoding
localeEncoding = unsafePerformIO $ do
-#if HAVE_LANGINFO_H
- cstr <- c_localeEncoding -- use nl_langinfo(CODESET) to get the encoding
- -- if we have it
+ -- Use locale_charset() or nl_langinfo(CODESET) to get the encoding
+ -- if we have either of them.
+ cstr <- c_localeEncoding
r <- peekCString cstr
mkTextEncoding r
-#else
- mkTextEncoding "" -- GNU iconv accepts "" to mean the -- locale encoding.
-#endif
-- We hope iconv_t is a storable type. It should be, since it has at least the
-- value -1, which is a possible return value from iconv_open.
haskellChar :: String
#ifdef WORDS_BIGENDIAN
-haskellChar | charSize == 2 = "UTF16BE"
- | otherwise = "UCS-4"
+haskellChar | charSize == 2 = "UTF-16BE"
+ | otherwise = "UTF-32BE"
#else
-haskellChar | charSize == 2 = "UTF16LE"
- | otherwise = "UCS-4LE"
+haskellChar | charSize == 2 = "UTF-16LE"
+ | otherwise = "UTF-32LE"
#endif
char_shift :: Int
mkTextEncoding :: String -> IO TextEncoding
mkTextEncoding charset = do
return (TextEncoding {
+ textEncodingName = charset,
mkTextDecoder = newIConv charset haskellChar iconvDecode,
mkTextEncoder = newIConv haskellChar charset iconvEncode})
input@Buffer{ bufRaw=iraw, bufL=ir, bufR=iw, bufSize=_ } iscale
output@Buffer{ bufRaw=oraw, bufL=_, bufR=ow, bufSize=os } oscale
= do
+ iconv_trace ("haskelChar=" ++ show haskellChar)
iconv_trace ("iconvRecode before, input=" ++ show (summaryBuffer input))
iconv_trace ("iconvRecode before, output=" ++ show (summaryBuffer output))
withRawBuffer iraw $ \ piraw -> do
else do
errno <- getErrno
case errno of
- e | e == eINVAL
- || (e == e2BIG || e == eILSEQ) && new_inleft' /= (iw-ir) -> do
+ e | e == eINVAL || e == e2BIG
+ || e == eILSEQ && new_inleft' /= (iw-ir) -> do
iconv_trace ("iconv ignoring error: " ++ show (errnoToIOError "iconv" e Nothing Nothing))
- -- Output overflow is relatively harmless, unless
- -- we made no progress at all.
+ -- Output overflow is harmless
--
-- Similarly, we ignore EILSEQ unless we converted no
-- characters. Sometimes iconv reports EILSEQ for a
-- the buffer have been drained.
return (new_input, new_output)
- _other ->
- throwErrno "iconvRecoder"
+ e -> do
+ iconv_trace ("iconv returned error: " ++ show (errnoToIOError "iconv" e Nothing Nothing))
+ throwErrno "iconvRecoder"
-- illegal sequence, or some other error
#endif /* !mingw32_HOST_OS */