From b56d2e60a1141e9fc23d795b5b7222921670a285 Mon Sep 17 00:00:00 2001 From: "pho@cielonegro.org" Date: Wed, 19 May 2010 01:31:12 +0000 Subject: [PATCH] Use libcharset instead of nl_langinfo(CODESET) if possible. nl_langinfo(CODESET) doesn't always return standardized variations of the encoding names. Use libcharset if possible, which is shipped together with GNU libiconv. --- GHC/IO/Encoding/Iconv.hs | 9 +++------ cbits/PrelIOUtils.c | 24 +++++++++++++++++++----- configure.ac | 11 +++++++++++ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/GHC/IO/Encoding/Iconv.hs b/GHC/IO/Encoding/Iconv.hs index 4de9cfe..fd35fc6 100644 --- a/GHC/IO/Encoding/Iconv.hs +++ b/GHC/IO/Encoding/Iconv.hs @@ -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. diff --git a/cbits/PrelIOUtils.c b/cbits/PrelIOUtils.c index b910c28..f43f5d8 100644 --- a/cbits/PrelIOUtils.c +++ b/cbits/PrelIOUtils.c @@ -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 -char *localeEncoding (void) +#if defined(HAVE_LIBCHARSET) +# include +#elif defined(HAVE_LANGINFO_H) +# include +#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__ */ diff --git a/configure.ac b/configure.ac index 26cd890..e4ab28b 100644 --- a/configure.ac +++ b/configure.ac @@ -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 ], + [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]) -- 1.7.10.4