X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=charset.cpkg;h=a58b013b53abd4271b8d441adacafcd0a807b6d0;hp=2c8f507cf8ccc1b8ca81d7ec303b2d8e3ce4a4b1;hb=07066d3ea19865d08c4a8fd98b5e87eeace810da;hpb=94c83f42e786ffbebb2ea3defcd6df95efe116f0 diff --git a/charset.cpkg b/charset.cpkg index 2c8f507..a58b013 100644 --- a/charset.cpkg +++ b/charset.cpkg @@ -27,7 +27,7 @@ #include -#ifdef HAVE_LANGINFO_CODESET +#ifdef HAVE_LANGINFO_H # include #endif @@ -38,10 +38,38 @@ #endif @import "lib-lua/base.cpkg" +int Charset_is_utf8 = 0; +wchar_t CharsetReplacement = '?'; + static rx_t *charset_hooks = NULL; static rx_t *iconv_hooks = NULL; -@package MCharset { +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 @@ -64,7 +92,10 @@ static rx_t *iconv_hooks = NULL; ** .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 @@ -95,51 +126,21 @@ static rx_t *iconv_hooks = NULL; void charset_hook(rx_t local, const string_t alias) { rx_set_template(local, alias); - rx_list_append(&charset_hooks, local); + rx_list_add2(&charset_hooks, &local); RETURN(); }; void iconv_hook(rx_t local, const string_t alias) { rx_set_template(local, alias); - rx_list_append(&iconv_hooks, local); + rx_list_add2(&iconv_hooks, &local); RETURN(); }; }; -int Charset_is_utf8 = 0; -wchar_t CharsetReplacement = '?'; - - /****************************************************************************/ /* 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) { @@ -206,8 +207,8 @@ int charset_is_us_ascii(const char *s) /* Like iconv_open, but canonicalises the charsets */ iconv_t mutt_iconv_open(const char *tocode, const char *fromcode, int flags) { - char to1[STRING]; - char from1[STRING]; + char to1[STRING], to2[STRING]; + char from1[STRING], from2[STRING]; char tmp[STRING]; iconv_t cd; @@ -225,121 +226,41 @@ iconv_t mutt_iconv_open(const char *tocode, const char *fromcode, int flags) charset_canonicalize(from1, sizeof(from1), fromcode); } + m_strcat(to1, sizeof(to1), "//TRANSLIT"); if ((cd = iconv_open(to1, from1)) != MUTT_ICONV_ERROR) return cd; - { - char to2[STRING]; - char from2[STRING]; - - if (rx_list_match2(iconv_hooks, to1, to2, sizeof(to2)) - && rx_list_match2(iconv_hooks, from1, from2, sizeof(from2))) - return iconv_open(to2, from2); + if (rx_list_match2(iconv_hooks, to1, to2, sizeof(to2)) + && rx_list_match2(iconv_hooks, from1, from2, sizeof(from2))) { + m_strcat(to2, sizeof(to2), "//TRANSLIT"); + return iconv_open(to2, from2); } + return MUTT_ICONV_ERROR; } -/* Like iconv, but keeps going even when the input is invalid - If you're supplying inrepls, the source charset should be stateless; - if you're supplying an outrepl, the target charset should be. */ -/* XXX: MC: I do not understand what it does yet */ -ssize_t mutt_iconv(iconv_t cd, - const char **inbuf, ssize_t *inbytesleft, - char **outbuf, ssize_t *outbytesleft, - const char **inrepls, const char *outrepl) -{ - ssize_t ret = 0, ret1; - const char *ib = *inbuf; - ssize_t ibl = *inbytesleft; - char *ob = *outbuf; - ssize_t obl = *outbytesleft; - - for (;;) { - ret1 = my_iconv(cd, &ib, &ibl, &ob, &obl); - if (ret1 != -1) - ret += ret1; - - if (ibl && obl && errno == EILSEQ) { - if (inrepls) { - /* Try replacing the input */ - const char **t; - - for (t = inrepls; *t; t++) { - const char *ib1 = *t; - ssize_t ibl1 = m_strlen(*t); - char *ob1 = ob; - ssize_t obl1 = obl; - - my_iconv(cd, &ib1, &ibl1, &ob1, &obl1); - if (!ibl1) { - ++ib, --ibl; - ob = ob1, obl = obl1; - ++ret; - break; - } - } - if (*t) - continue; - } - /* Replace the output */ - if (!outrepl) - outrepl = "?"; - my_iconv(cd, 0, 0, &ob, &obl); - if (obl) { - ssize_t n = m_strlen(outrepl); - - if (n > obl) { - outrepl = "?"; - n = 1; - } - memcpy(ob, outrepl, n); - ++ib, --ibl; - ob += n, obl -= n; - ++ret; - my_iconv(cd, 0, 0, 0, 0); /* for good measure */ - continue; - } - } - *inbuf = ib, *inbytesleft = ibl; - *outbuf = ob, *outbytesleft = obl; - return ret; - } -} - /* Convert a string */ int mutt_convert_string(char **ps, const char *from, const char *to, int flags) { iconv_t cd; - const char *repls[] = { "\357\277\275", "?", 0 }; - if (m_strisempty(*ps)) return 0; cd = mutt_iconv_open(to, from, flags); if (cd != MUTT_ICONV_ERROR) { - const char **inrepls = NULL; - const char *outrepl = NULL; const char *ib; char *buf, *ob; ssize_t ibl, obl; - if (charset_is_utf8(to)) - outrepl = "\357\277\275"; - else - if (charset_is_utf8(from)) - inrepls = repls; - else - outrepl = "?"; - ibl = m_strlen(*ps) + 1; ib = *ps; obl = MB_LEN_MAX * ibl; ob = buf = p_new(char, obl + 1); - mutt_iconv(cd, &ib, &ibl, &ob, &obl, inrepls, outrepl); + mutt_iconv(cd, &ib, &ibl, &ob, &obl); iconv_close(cd); *ob = '\0'; @@ -367,9 +288,9 @@ static ssize_t convert_string(const char *f, ssize_t flen, obl = 4 * flen + 1; ob = buf = p_new(char, obl); - n = my_iconv(cd, &f, &flen, &ob, &obl); + n = mutt_iconv(cd, &f, &flen, &ob, &obl); - if (n < 0 || my_iconv(cd, 0, 0, &ob, &obl) < 0) { + if (n < 0 || mutt_iconv(cd, 0, 0, &ob, &obl) < 0) { e = errno; p_delete(&buf); iconv_close(cd); @@ -386,7 +307,7 @@ static ssize_t convert_string(const char *f, ssize_t flen, 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; @@ -405,7 +326,7 @@ int mutt_convert_nonmime_string(char **ps) 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; @@ -431,14 +352,11 @@ struct fgetconv_t { char *ob; char *ib; ssize_t ibl; - const char **inrepls; }; fgetconv_t * fgetconv_open(FILE *file, const char *from, const char *to, int flags) { - static const char *repls[] = { "\357\277\275", "?", 0 }; - struct fgetconv_t *fc = p_new(struct fgetconv_t, 1); fc->file = file; @@ -450,7 +368,6 @@ fgetconv_open(FILE *file, const char *from, const char *to, int flags) fc->p = fc->ob = fc->bufo; fc->ib = fc->bufi; fc->ibl = 0; - fc->inrepls = repls + charset_is_utf8(to); } return fc; } @@ -460,7 +377,7 @@ void fgetconv_close(fgetconv_t **fcp) struct fgetconv_t *fc = *fcp; if (fc->cd != MUTT_ICONV_ERROR) - iconv_close (fc->cd); + iconv_close(fc->cd); p_delete(fcp); } @@ -483,7 +400,7 @@ int fgetconv(fgetconv_t *fc) if (fc->ibl) { ssize_t obl = ssizeof(fc->bufo); - my_iconv(fc->cd, (const char **)&fc->ib, &fc->ibl, &fc->ob, &obl); + mutt_iconv(fc->cd, (const char **)&fc->ib, &fc->ibl, &fc->ob, &obl); if (fc->p < fc->ob) return (unsigned char)*(fc->p)++; } @@ -509,8 +426,7 @@ int fgetconv(fgetconv_t *fc) if (fc->ibl) { ssize_t obl = ssizeof(fc->bufo); - mutt_iconv(fc->cd, (const char **)&fc->ib, &fc->ibl, &fc->ob, &obl, - fc->inrepls, 0); + mutt_iconv(fc->cd, (const char **)&fc->ib, &fc->ibl, &fc->ob, &obl); if (fc->p < fc->ob) { return (unsigned char)*(fc->p)++; }