* src/codeconv.c
[claws.git] / src / codeconv.c
index 1cc342fc051aa4a5b20d2cd9fe77fd3073067a97..566efdda66c98083fac7b7b1bbccaddd4fad32d9 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999,2000 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2001 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -351,14 +351,23 @@ gchar *conv_codeset_strdup(const gchar *inbuf,
                }
        }
 
+       /* don't convert if src and dest codeset are identical */
+       if (src_codeset && dest_codeset &&
+           !strcasecmp(src_codeset, dest_codeset))
+               return g_strdup(inbuf);
+
 #if HAVE_LIBJCONV
        if (src_codeset) {
                codesets = &src_codeset;
                n_codesets = 1;
        } else
                codesets = jconv_info_get_pref_codesets(&n_codesets);
-       if (!dest_codeset)
+       if (!dest_codeset) {
                dest_codeset = conv_get_current_charset_str();
+               /* don't convert if current codeset is US-ASCII */
+               if (!strcasecmp(dest_codeset, CS_US_ASCII))
+                       return g_strdup(inbuf);
+       }
 
        if (jconv_alloc_conv(inbuf, strlen(inbuf), &buf, &len,
                             codesets, n_codesets,
@@ -366,11 +375,11 @@ gchar *conv_codeset_strdup(const gchar *inbuf,
            == 0)
                return buf;
        else
-               return NULL;
+               return g_strdup(inbuf);
 #else /* !HAVE_LIBJCONV */
        if (src_codeset) {
                if (!strcasecmp(src_codeset, CS_EUC_JP) ||
-                   !strcasecmp(src_codeset, "EUCJP"))
+                   !strcasecmp(src_codeset, CS_EUCJP))
                        src_charset = C_EUC_JP;
                else if (!strcasecmp(src_codeset, CS_SHIFT_JIS) ||
                         !strcasecmp(src_codeset, "SHIFT-JIS") ||
@@ -414,17 +423,19 @@ CodeConvFunc conv_get_code_conv_func(const gchar *charset)
                code_conv = conv_jistodisp;
        else if (!strcasecmp(charset, CS_US_ASCII))
                code_conv = conv_ustodisp;
+       else if (!strncasecmp(charset, CS_ISO_8859_1, 10))
+               code_conv = conv_latintodisp;
 #if !HAVE_LIBJCONV
        else if (!strncasecmp(charset, "ISO-8859-", 9))
                code_conv = conv_latintodisp;
-#endif /* !HAVE_LIBJCONV */
+#endif
        else if (!strcasecmp(charset, CS_SHIFT_JIS) ||
                 !strcasecmp(charset, "SHIFT-JIS")  ||
                 !strcasecmp(charset, "SJIS")       ||
                 !strcasecmp(charset, "X-SJIS"))
                code_conv = conv_sjistodisp;
        else if (!strcasecmp(charset, CS_EUC_JP) ||
-                !strcasecmp(charset, "EUCJP"))
+                !strcasecmp(charset, CS_EUCJP))
                code_conv = conv_euctodisp;
        else
                code_conv = conv_noconv;
@@ -437,6 +448,7 @@ static const struct {
        gchar *const name;
 } charsets[] = {
        {C_US_ASCII,            CS_US_ASCII},
+       {C_US_ASCII,            CS_ANSI_X3_4_1968},
        {C_UTF_8,               CS_UTF_8},
        {C_ISO_8859_1,          CS_ISO_8859_1},
        {C_ISO_8859_2,          CS_ISO_8859_2},
@@ -445,6 +457,7 @@ static const struct {
        {C_ISO_8859_7,          CS_ISO_8859_7},
        {C_ISO_8859_8,          CS_ISO_8859_8},
        {C_ISO_8859_9,          CS_ISO_8859_9},
+       {C_ISO_8859_11,         CS_ISO_8859_11},
        {C_ISO_8859_13,         CS_ISO_8859_13},
        {C_ISO_8859_15,         CS_ISO_8859_15},
        {C_BALTIC,              CS_BALTIC},
@@ -455,6 +468,7 @@ static const struct {
        {C_ISO_2022_JP,         CS_ISO_2022_JP},
        {C_ISO_2022_JP_2,       CS_ISO_2022_JP_2},
        {C_EUC_JP,              CS_EUC_JP},
+       {C_EUC_JP,              CS_EUCJP},
        {C_SHIFT_JIS,           CS_SHIFT_JIS},
        {C_ISO_2022_KR,         CS_ISO_2022_KR},
        {C_EUC_KR,              CS_EUC_KR},
@@ -463,6 +477,8 @@ static const struct {
        {C_GB2312,              CS_GB2312},
        {C_EUC_TW,              CS_EUC_TW},
        {C_BIG5,                CS_BIG5},
+       {C_TIS_620,             CS_TIS_620},
+       {C_WINDOWS_874,         CS_WINDOWS_874},
 };
 
 #if !HAVE_LIBJCONV
@@ -513,14 +529,19 @@ static const struct {
        {"iw_IL"        , C_ISO_8859_8},
        {"tr_TR"        , C_ISO_8859_9},
 
+       {"th_TH"        , C_TIS_620},
+       /* {"th_TH"     , C_WINDOWS_874}, */
+       /* {"th_TH"     , C_ISO_8859_11}, */
+
        {"lt_LT.iso88594"       , C_ISO_8859_4},
        {"lt_LT.ISO8859-4"      , C_ISO_8859_4},
        {"lt_LT.ISO_8859-4"     , C_ISO_8859_4},
        {"lt_LT"                , C_ISO_8859_13},
        {"lv_LV"                , C_ISO_8859_13},
 
-       {"C"            , C_US_ASCII},
-       {"POSIX"        , C_US_ASCII},
+       {"C"                    , C_US_ASCII},
+       {"POSIX"                , C_US_ASCII},
+       {"ANSI_X3.4-1968"       , C_US_ASCII},
 };
 #endif /* !HAVE_LIBJCONV */
 
@@ -617,16 +638,12 @@ CharSet conv_get_current_charset(void)
 
 const gchar *conv_get_current_charset_str(void)
 {
-#if HAVE_LIBJCONV
-       return jconv_info_get_current_codeset();
-#else
        static const gchar *codeset = NULL;
 
        if (!codeset)
                codeset = conv_get_charset_str(conv_get_current_charset());
 
        return codeset ? codeset : "US-ASCII";
-#endif
 }
 
 CharSet conv_get_outgoing_charset(void)
@@ -647,7 +664,7 @@ CharSet conv_get_outgoing_charset(void)
        /* skip US-ASCII and UTF-8 */
        pref_codesets = jconv_info_get_pref_codesets(&n_pref_codesets);
        for (i = 0; i < n_pref_codesets; i++) {
-               for (j = 2; j < sizeof(charsets) / sizeof(charsets[0]); j++) {
+               for (j = 3; j < sizeof(charsets) / sizeof(charsets[0]); j++) {
                        if (!strcasecmp(pref_codesets[i], charsets[j].name)) {
                                out_charset = charsets[j].charset;
                                return out_charset;
@@ -697,6 +714,20 @@ const gchar *conv_get_outgoing_charset_str(void)
        return str ? str : "US-ASCII";
 }
 
+const gchar *conv_get_current_locale(void)
+{
+       gchar *cur_locale;
+
+       cur_locale = g_getenv("LC_ALL");
+       if (!cur_locale) cur_locale = g_getenv("LANG");
+       if (!cur_locale) cur_locale = setlocale(LC_CTYPE, NULL);
+
+       debug_print("current locale: %s\n",
+                   cur_locale ? cur_locale : "(none)");
+
+       return cur_locale;
+}
+
 void conv_unmime_header_overwrite(gchar *str)
 {
        gchar *buf;
@@ -706,17 +737,24 @@ void conv_unmime_header_overwrite(gchar *str)
        cur_charset = conv_get_current_charset();
 
 #if HAVE_LIBJCONV
-       Xstrdup_a(buf, str, {return;});
+       Xstrdup_a(buf, str, return);
        outlen = strlen(str) + 1;
        UnMimeHeaderConv(buf, str, outlen);
-       if (cur_charset == C_EUC_JP)
-               conv_unreadable_eucjp(str);
+       if (cur_charset == C_EUC_JP) {
+               gchar *tmp;
+               gint len;
+
+               len = strlen(str) * 2 + 1;
+               Xalloca(tmp, len, return);
+               conv_jistodisp(tmp, len, str);
+               strncpy2(str, tmp, outlen);
+       }
 #else
        if (cur_charset == C_EUC_JP) {
                gchar *tmp;
                gint len;
 
-               Xstrdup_a(buf, str, {return;});
+               Xstrdup_a(buf, str, return);
                outlen = strlen(str) + 1;
                UnMimeHeader(buf);
                len = strlen(buf) * 2 + 1;
@@ -734,26 +772,23 @@ void conv_unmime_header(gchar *outbuf, gint outlen, const gchar *str,
        gchar *buf;
        CharSet cur_charset;
 
-       Xstrdup_a(buf, str, {return;});
        cur_charset = conv_get_current_charset();
+       Xstrdup_a(buf, str, return);
 
 #if HAVE_LIBJCONV
        UnMimeHeaderConv(buf, outbuf, outlen);
-       if (cur_charset == C_EUC_JP)
-               conv_unreadable_eucjp(outbuf);
 #else
        UnMimeHeader(buf);
+       strncpy2(outbuf, buf, outlen);
+#endif
        if (cur_charset == C_EUC_JP) {
-               gchar *tmp;
                gint len;
 
-               len = strlen(buf) * 2 + 1;
-               Xalloca(tmp, len, {strncpy2(outbuf, buf, outlen); return;});
-               conv_jistodisp(tmp, len, buf);
-               strncpy2(outbuf, tmp, outlen);
-       } else
+               len = strlen(outbuf) * 2 + 1;
+               Xalloca(buf, len, return);
+               conv_jistodisp(buf, len, outbuf);
                strncpy2(outbuf, buf, outlen);
-#endif
+       }
 }
 
 #define MAX_ENCLEN     75
@@ -784,7 +819,6 @@ void conv_encode_header(gchar *dest, gint len, const gchar *src,
                strlen(mimehdr_charset) + strlen(mimehdr_enctype);
        mimehdr_begin_len = strlen(mimehdr_init) +
                strlen(mimehdr_charset) + strlen(mimehdr_enctype);
-       /* line_len = 1; */
        line_len = header_len;
        destp = dest;
        *dest = '\0';
@@ -847,8 +881,8 @@ void conv_encode_header(gchar *dest, gint len, const gchar *src,
                                }
                                /* g_free(raw); */
                                src_codeset = conv_get_current_charset_str();
-                               /* printf ("tmp = %s, tlen = %d, mbl\n", 
-                                       tmp, tlen, mbl); */
+                               /* printf ("tmp = %s, tlen = %d, mbl\n",
+                                       tmp, tlen, mbl); */
                                if (jconv_alloc_conv(tmp, tlen + mbl,
                                                     &raw_new, &raw_new_len,
                                                     &src_codeset, 1,
@@ -856,6 +890,7 @@ void conv_encode_header(gchar *dest, gint len, const gchar *src,
                                    != 0) {
                                        g_warning("can't convert\n");
                                        tmpp[0] = '\0';
+                                       wtmpp++;
                                        continue;
                                }
                                if (!str_ascii) {
@@ -877,23 +912,21 @@ void conv_encode_header(gchar *dest, gint len, const gchar *src,
                                                        break;
                                                }
                                        }
-                               } else {
-                                       if ((line_len + tlen + mbl +
-                                            (*(wtmpp + 1) ? 0 : nspc) +
-                                            (line_len > 1 ? 1 : 0))
-                                           > MAX_LINELEN) {
-                                               g_free(raw_new);
-                                               if (1 + tlen + mbl +
-                                                   (*(wtmpp + 1) ? 0 : nspc)
-                                                   >= MAX_LINELEN) {
-                                                       *tmpp = '\0';
-                                                       break;
-                                               }
-                                               *destp++ = '\n';
-                                               *destp++ = ' ';
-                                               line_len = 1;
-                                               continue;
+                               } else if ((line_len + tlen + mbl +
+                                           (*(wtmpp + 1) ? 0 : nspc) +
+                                           (line_len > 1 ? 1 : 0))
+                                          > MAX_LINELEN) {
+                                       g_free(raw_new);
+                                       if (1 + tlen + mbl +
+                                           (*(wtmpp + 1) ? 0 : nspc)
+                                           >= MAX_LINELEN) {
+                                               *tmpp = '\0';
+                                               break;
                                        }
+                                       *destp++ = '\n';
+                                       *destp++ = ' ';
+                                       line_len = 1;
+                                       continue;
                                }
 
                                tmpp += mbl;
@@ -907,10 +940,8 @@ void conv_encode_header(gchar *dest, gint len, const gchar *src,
 
                                wtmpp++;
                        }
-                       /*
-                         g_print("tmp = %s, tlen = %d, mb_seqlen = %d\n",
-                               tmp, tlen, mb_seqlen);
-                       */                              
+                       /* g_print("tmp = %s, tlen = %d, mb_seqlen = %d\n",
+                               tmp, tlen, mb_seqlen); */
 
                        if (tlen == 0 || raw_len == 0) {
                                g_free(tmp);
@@ -965,7 +996,7 @@ void conv_encode_header(gchar *dest, gint len, const gchar *src,
 
        g_free(wsrc);
 
-       /* g_print("dest = %s\n", dest);  */
+       /* g_print("dest = %s\n", dest); */
 }
 #else /* !HAVE_LIBJCONV */
 
@@ -998,7 +1029,6 @@ void conv_encode_header(gchar *dest, gint len, const gchar *src,
                      strlen(mimehdr_charset) + strlen(mimehdr_enctype);
        mimehdr_begin_len = strlen(mimehdr_init) +
                            strlen(mimehdr_charset) + strlen(mimehdr_enctype);
-       /* line_len = 1; */
        line_len = header_len;
        destp = dest;
        *dest = '\0';
@@ -1073,22 +1103,20 @@ void conv_encode_header(gchar *dest, gint len, const gchar *src,
                                                        break;
                                                }
                                        }
-                               } else {
-                                       if ((line_len + tlen + mbl +
-                                            (*(wtmpp + 1) ? 0 : nspc) +
-                                            (line_len > 1 ? 1 : 0))
-                                           > MAX_LINELEN) {
-                                               if (1 + tlen + mbl +
-                                                   (*(wtmpp + 1) ? 0 : nspc)
-                                                   >= MAX_LINELEN) {
-                                                       *tmpp = '\0';
-                                                       break;
-                                               }
-                                               *destp++ = '\n';
-                                               *destp++ = ' ';
-                                               line_len = 1;
-                                               continue;
+                               } else if ((line_len + tlen + mbl +
+                                           (*(wtmpp + 1) ? 0 : nspc) +
+                                           (line_len > 1 ? 1 : 0))
+                                          > MAX_LINELEN) {
+                                       if (1 + tlen + mbl +
+                                           (*(wtmpp + 1) ? 0 : nspc)
+                                           >= MAX_LINELEN) {
+                                               *tmpp = '\0';
+                                               break;
                                        }
+                                       *destp++ = '\n';
+                                       *destp++ = ' ';
+                                       line_len = 1;
+                                       continue;
                                }
 
                                tmpp += mbl;
@@ -1100,8 +1128,7 @@ void conv_encode_header(gchar *dest, gint len, const gchar *src,
                                wtmpp++;
                        }
                        /* g_print("tmp = %s, tlen = %d, mb_seqlen = %d\n",
-                               tmp, tlen, mb_seqlen);
-                       */                              
+                               tmp, tlen, mb_seqlen); */
 
                        if (tlen == 0) {
                                g_free(tmp);