#include <lib-lib/lib-lib.h>
-#ifdef HAVE_LANGINFO_CODESET
+#ifdef HAVE_LANGINFO_H
# include <langinfo.h>
#endif
#endif
@import "lib-lua/base.cpkg"
-@package MCharset {
+int Charset_is_utf8 = 0;
+wchar_t CharsetReplacement = '?';
+
+static rx_t *charset_hooks = NULL;
+static rx_t *iconv_hooks = NULL;
+
+static char *charset_init(void)
+{
+ const char *res = "iso-8859-1";
+#ifdef HAVE_LANGINFO_H
+ char buff[STRING];
+ char buff2[STRING];
+
+ m_strcpy(buff, sizeof(buff), nl_langinfo(CODESET));
+ charset_canonicalize(buff2, sizeof(buff2), buff);
+
+ /* finally, set $charset */
+ if (!m_strisempty(buff2)) {
+ res = buff2;
+ }
+#endif
+ bind_textdomain_codeset(PACKAGE, res);
+ return m_strdup(res);
+}
+
+static void charset_onchange(const char *cset)
+{
+ Charset_is_utf8 = charset_is_utf8(cset);
+ CharsetReplacement = Charset_is_utf8 ? 0xfffd : '?';
+}
+
+@package mod_cset {
/*
** .pp
** This variable is a colon-separated list of character encoding
** .pp
** Character set your terminal uses to display and enter textual data.
*/
- string_t charset = NULL;
+ string_t charset = {
+ .init = charset_init();
+ .onchange = charset_onchange($$);
+ };
/*
** .pp
** instead of or after \fTiso-8859-1\fP.
*/
string_t send_charset = m_strdup("us-ascii:iso-8859-1:utf-8");
-};
-
-int Charset_is_utf8 = 0;
-wchar_t CharsetReplacement = '?';
+ void charset_hook(rx_t local, const string_t alias) {
+ rx_set_template(local, alias);
+ rx_list_add2(&charset_hooks, &local);
+ RETURN();
+ };
+
+ void iconv_hook(rx_t local, const string_t alias) {
+ rx_set_template(local, alias);
+ rx_list_add2(&iconv_hooks, &local);
+ RETURN();
+ };
+};
/****************************************************************************/
/* charset functions */
/****************************************************************************/
-void charset_initialize(void)
-{
-#ifdef HAVE_LANGINFO_CODESET
- char buff[STRING];
- char buff2[STRING];
-
- m_strcpy(buff, sizeof(buff), nl_langinfo(CODESET));
- charset_canonicalize(buff2, sizeof(buff2), buff);
-
- /* finally, set $charset */
- if (!m_strisempty(buff2)) {
- m_strreplace(&MCharset.charset, buff2);
- } else
-#endif
- {
- m_strreplace(&MCharset.charset, "iso-8859-1");
- }
-
- Charset_is_utf8 = !m_strcmp(MCharset.charset, "utf-8");
- CharsetReplacement = Charset_is_utf8 ? 0xfffd : '?';
-
-#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
- bind_textdomain_codeset(PACKAGE, MCharset.charset);
-#endif
-}
-
#include "charset.gperf"
void charset_canonicalize(char *dest, ssize_t dlen, const char *name)
{
/* Like iconv_open, but canonicalises the charsets */
iconv_t mutt_iconv_open(const char *tocode, const char *fromcode, int flags)
{
- char tocode1[STRING];
- char fromcode1[STRING];
- const char *tmp;
-
+ char to1[STRING], to2[STRING];
+ char from1[STRING], from2[STRING];
+ char tmp[STRING];
iconv_t cd;
- if ((flags & M_ICONV_HOOK_TO) && (tmp = mutt_charset_hook(tocode1))) {
- charset_canonicalize(tocode1, sizeof(tocode1), tmp);
+ if ((flags & M_ICONV_HOOK_TO)
+ && rx_list_match2(charset_hooks, tocode, tmp, sizeof(tmp))) {
+ charset_canonicalize(to1, sizeof(to1), tmp);
} else {
- charset_canonicalize(tocode1, sizeof(tocode1), tocode);
+ charset_canonicalize(to1, sizeof(to1), tocode);
}
- if ((flags & M_ICONV_HOOK_FROM) && (tmp = mutt_charset_hook(fromcode1))) {
- charset_canonicalize(fromcode1, sizeof(fromcode1), tmp);
+ if ((flags & M_ICONV_HOOK_FROM)
+ && rx_list_match2(charset_hooks, fromcode, tmp, sizeof(tmp))) {
+ charset_canonicalize(from1, sizeof(from1), tmp);
} else {
- charset_canonicalize(fromcode1, sizeof(fromcode1), fromcode);
+ charset_canonicalize(from1, sizeof(from1), fromcode);
}
- cd = iconv_open(tocode1, fromcode1);
- if (cd != MUTT_ICONV_ERROR)
+ if ((cd = iconv_open(to1, from1)) != MUTT_ICONV_ERROR)
return cd;
- {
- const char *to = mutt_iconv_hook(tocode1);
- const char *from = mutt_iconv_hook(fromcode1);
+ if (rx_list_match2(iconv_hooks, to1, to2, sizeof(to2))
+ && rx_list_match2(iconv_hooks, from1, from2, sizeof(from2)))
+ return iconv_open(to2, from2);
- return to && from ? iconv_open(to, from) : MUTT_ICONV_ERROR;
- }
+ return MUTT_ICONV_ERROR;
}
int mutt_convert_nonmime_string(char **ps)
{
- const char *p = MCharset.assumed_charset;
+ const char *p = mod_cset.assumed_charset;
ssize_t ulen = m_strlen(*ps);
char *u = *ps;
return 0;
while (*p == ':')
- *p++;
+ p++;
q = m_strchrnul(p, ':');
m_strncpy(fromcode, sizeof(fromcode), p, q - p);
p = q;
- if (convert_string(u, ulen, fromcode, MCharset.charset, &s, &slen) >= 0) {
+ if (convert_string(u, ulen, fromcode, mod_cset.charset, &s, &slen) >= 0) {
p_delete(ps);
*ps = s;
return 0;