X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FIO%2FEncoding%2FIconv.hs;h=0316698f3c85162b063572cfea18d1134f595e66;hb=41e8fba828acbae1751628af50849f5352b27873;hp=554c0538d12d74dcd149ebe1e58e638a40fa1fb6;hpb=207e64ee80ef749dbb46df0fa6a134b19d5a42a5;p=ghc-base.git diff --git a/GHC/IO/Encoding/Iconv.hs b/GHC/IO/Encoding/Iconv.hs index 554c053..0316698 100644 --- a/GHC/IO/Encoding/Iconv.hs +++ b/GHC/IO/Encoding/Iconv.hs @@ -1,4 +1,9 @@ -{-# OPTIONS_GHC -XNoImplicitPrelude #-} +{-# LANGUAGE CPP + , NoImplicitPrelude + , ForeignFunctionInterface + , NondecreasingIndentation + #-} + ----------------------------------------------------------------------------- -- | -- Module : GHC.IO.Encoding.Iconv @@ -25,13 +30,12 @@ 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 @@ -40,27 +44,22 @@ import GHC.IO.Encoding.Types 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 () +c_DEBUG_DUMP :: Bool +c_DEBUG_DUMP = False -#ifdef DEBUG_DUMP - -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 @@ -99,14 +98,11 @@ utf32be = unsafePerformIO (mkTextEncoding "UTF32BE") {-# 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. @@ -127,11 +123,11 @@ foreign import ccall unsafe "localeEncoding" 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 @@ -141,6 +137,7 @@ char_shift | charSize == 2 = 1 mkTextEncoding :: String -> IO TextEncoding mkTextEncoding charset = do return (TextEncoding { + textEncodingName = charset, mkTextDecoder = newIConv charset haskellChar iconvDecode, mkTextEncoder = newIConv haskellChar charset iconvEncode}) @@ -174,6 +171,7 @@ iconvRecode iconv_t 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 @@ -201,11 +199,10 @@ iconvRecode iconv_t 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 @@ -218,8 +215,9 @@ iconvRecode iconv_t -- 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 */