Use libcharset instead of nl_langinfo(CODESET) if possible.
authorpho@cielonegro.org <unknown>
Wed, 19 May 2010 01:31:12 +0000 (01:31 +0000)
committerpho@cielonegro.org <unknown>
Wed, 19 May 2010 01:31:12 +0000 (01:31 +0000)
nl_langinfo(CODESET) doesn't always return standardized variations of the encoding names. Use libcharset if possible, which is shipped together with GNU libiconv.

libraries/base/GHC/IO/Encoding/Iconv.hs
libraries/base/cbits/PrelIOUtils.c
libraries/base/configure.ac

index 4de9cfe..fd35fc6 100644 (file)
@@ -92,14 +92,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.
index b910c28..f43f5d8 100644 (file)
@@ -24,13 +24,27 @@ void debugBelch2(const char*s, char *t)
     debugBelch(s,t);
 }
 
-// Use a C wrapper for this because we avoid hsc2hs in base
-#if HAVE_LANGINFO_H
-#include <langinfo.h>
-char *localeEncoding (void)
+#if defined(HAVE_LIBCHARSET)
+#  include <libcharset.h>
+#elif defined(HAVE_LANGINFO_H)
+#  include <langinfo.h>
+#endif
+
+const char* localeEncoding(void)
 {
+#if defined(HAVE_LIBCHARSET)
+    return locale_charset();
+
+#elif defined(HAVE_LANGINFO_H)
     return nl_langinfo(CODESET);
-}
+
+#else
+#warning Depending on the unportable behavior of GNU iconv due to absence of both libcharset and langinfo.h
+    /* GNU iconv accepts "" to mean the current locale's
+     * encoding. Warning: This isn't portable.
+     */
+    return "";
 #endif
+}
 
 #endif /* __GLASGOW_HASKELL__ */
index 26cd890..e4ab28b 100644 (file)
@@ -136,6 +136,17 @@ FP_SEARCH_LIBS_PROTO(iconv,
                              AC_MSG_ERROR([iconv is required on non-Windows platforms]);;
                       esac])
 
+# If possible, we use libcharset instead of nl_langinfo(CODESET) to
+# determine the current locale's character encoding.
+FP_SEARCH_LIBS_PROTO(
+    [locale_charset],
+    [#include <libcharset.h>],
+    [const char* charset = locale_charset();],
+    [charset],
+    [AC_DEFINE([HAVE_LIBCHARSET], [1], [Define to 1 if you have libcharset.])
+     EXTRA_LIBS="$EXTRA_LIBS $ac_lib"])
+
+
 AC_SUBST(EXTRA_LIBS)
 AC_CONFIG_FILES([base.buildinfo])