Hi, * Rocco Rutte wrote:
Thoughts?
I was told iconvlist() is only implemented by libiconv, not glibc so that Linux users won't really benefit. Thus I've updated the patch to use mutt_iconv_open() to see if iconv_open() knows about the charset.
Thoughts? Rocco
diff --git a/charset.c b/charset.c --- a/charset.c +++ b/charset.c @@ -629,3 +629,59 @@ void fgetconv_close (FGETCONV **_fc) iconv_close (fc->cd); FREE (_fc); /* __FREE_CHECKED__ */ } + +#ifdef HAVE_ICONV_LIST + +struct iconvlist_data +{ + const char *name; + int found; +}; + +static int check_charset (unsigned int cnt, const char * const *names, void *data) +{ + struct iconvlist_data *d = (struct iconvlist_data *)data; + unsigned int i; + + for (i = 0; !d->found && i < cnt; i++) + if (ascii_strcasecmp (names[i], d->name) == 0) + d->found = 1; + return d->found; +} + +#endif /* HAVE_ICONV_LIST */ + +int mutt_check_charset (const char *s, int strict) +{ + int i; +#if HAVE_ICONV_LIST + struct iconvlist_data data; +#else + iconv_t cd; +#endif + + if (!strict) + for (i = 0; PreferredMIMENames[i].key; i++) + { + if (ascii_strcasecmp (PreferredMIMENames[i].key, s) == 0 || + ascii_strcasecmp (PreferredMIMENames[i].pref, s) == 0) + return 1; + } + +#if HAVE_ICONV_LIST + data.name = s; + data.found = 0; + iconvlist (check_charset, &data); + if (data.found) + return 1; +#else + if ((cd = mutt_iconv_open (s, s, 0)) != (iconv_t)(-1)) + { + iconv_close (cd); + return 1; + } else + return -1; +#endif + + return 0; +} diff --git a/charset.h b/charset.h --- a/charset.h +++ b/charset.h @@ -56,4 +56,11 @@ char *mutt_get_default_charset (); */ #define M_ICONV_HOOK_FROM 1 /* apply charset-hooks to fromcode */ +/* Check if given character set is valid (either officially assigned by + * known to local iconv() implementation). If strict is non-zero, check + * against iconv() only. Returns 1 if known and 0 otherwise. + * Uses mutt_iconv_open() if iconvlist() is missing. + */ +int mutt_check_charset (const char *s, int strict); + #endif /* _CHARSET_H */ diff --git a/configure.ac b/configure.ac --- a/configure.ac +++ b/configure.ac @@ -982,6 +982,35 @@ AC_CHECK_HEADERS(iconv.h, [Define if <iconv.h> defines iconv_t.])], AC_MSG_RESULT(no))]) +AC_CACHE_CHECK([for iconvlist()], mutt_cv_iconv_list, + mutt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_TRY_RUN([ +#include <iconv.h> + +static int count = 0; + +static int test_iconvlist (unsigned int c, const char **n, void *d) +{ + count += c; + return 0; +} + +int main() +{ + iconvlist (test_iconvlist, 0); + return count > 0 ? 0 : 1; +} + ], + mutt_cv_iconv_list=yes, + mutt_cv_iconv_list=no, + mutt_cv_iconv_list=yes) + LIBS="$mutt_save_LIBS") +if test "$mutt_cv_iconv_list" = yes; then + AC_DEFINE(HAVE_ICONV_LIST,1, [Define if you have the iconvlist() function.]) +fi + + dnl (1) Some implementations of iconv won't convert from UTF-8 to UTF-8. dnl (2) In glibc-2.1.2 and earlier there is a bug that messes up ob and dnl obl when args 2 and 3 are 0 (fixed in glibc-2.1.3). diff --git a/main.c b/main.c --- a/main.c +++ b/main.c @@ -435,6 +435,12 @@ static void show_version (void) "+ICONV_NONTRANS " #else "-ICONV_NONTRANS " +#endif + +#ifdef HAVE_ICONV_LIST + "+ICONV_LIST " +#else + "-ICONV_LIST " #endif #if HAVE_LIBIDN