2006-04-06 [mones] 2.1.0cvs7
[claws.git] / src / codeconv.c
index fbac9bcdbce4ae87e8b24b086d124914a817fb72..3bdb47d9b5f983b34583d3a415a590e6264e9bc2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2006 Hiroyuki Yamamoto and the Sylpheed-Claws team
  *
  * 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
@@ -34,8 +34,6 @@
 #  include <locale.h>
 #endif
 
-#include <iconv.h>
-
 #include "codeconv.h"
 #include "unmime.h"
 #include "base64.h"
 #include "utils.h"
 #include "prefs_common.h"
 
+/* For unknown reasons the inconv.m4 macro undefs that macro if no
+   const is needed.  This would break the code below so we define it. */
+#ifndef ICONV_CONST
+#define ICONV_CONST
+#endif
+
 typedef enum
 {
        JIS_ASCII,
@@ -529,72 +533,6 @@ static void conv_unreadable_8bit(gchar *str)
        }
 }
 
-#define NCV    '\0'
-
-void conv_mb_alnum(gchar *str)
-{
-       static guchar char_tbl[] = {
-               /* 0xa0 - 0xaf */
-               NCV, ' ', NCV, NCV, ',', '.', NCV, ':',
-               ';', '?', '!', NCV, NCV, NCV, NCV, NCV,
-               /* 0xb0 - 0xbf */
-               NCV, NCV, NCV, NCV, NCV, NCV, NCV, NCV,
-               NCV, NCV, NCV, NCV, NCV, NCV, NCV, NCV,
-               /* 0xc0 - 0xcf */
-               NCV, NCV, NCV, NCV, NCV, NCV, NCV, NCV,
-               NCV, NCV, '(', ')', NCV, NCV, '[', ']',
-               /* 0xd0 - 0xdf */
-               '{', '}', NCV, NCV, NCV, NCV, NCV, NCV,
-               NCV, NCV, NCV, NCV, '+', '-', NCV, NCV,
-               /* 0xe0 - 0xef */
-               NCV, '=', NCV, '<', '>', NCV, NCV, NCV,
-               NCV, NCV, NCV, NCV, NCV, NCV, NCV, NCV
-       };
-
-       register guchar *p = str;
-       register gint len;
-
-       len = strlen(str);
-
-       while (len > 1) {
-               if (*p == 0xa3) {
-                       register guchar ch = *(p + 1);
-
-                       if (ch >= 0xb0 && ch <= 0xfa) {
-                               /* [a-zA-Z] */
-                               *p = ch & 0x7f;
-                               p++;
-                               len--;
-                               memmove(p, p + 1, len);
-                               len--;
-                       } else  {
-                               p += 2;
-                               len -= 2;
-                       }
-               } else if (*p == 0xa1) {
-                       register guchar ch = *(p + 1);
-
-                       if (ch >= 0xa0 && ch <= 0xef &&
-                           NCV != char_tbl[ch - 0xa0]) {
-                               *p = char_tbl[ch - 0xa0];
-                               p++;
-                               len--;
-                               memmove(p, p + 1, len);
-                               len--;
-                       } else {
-                               p += 2;
-                               len -= 2;
-                       }
-               } else if (iseuckanji(*p)) {
-                       p += 2;
-                       len -= 2;
-               } else {
-                       p++;
-                       len--;
-               }
-       }
-}
-
 CharSet conv_guess_ja_encoding(const gchar *str)
 {
        const guchar *p = str;
@@ -677,16 +615,30 @@ void conv_localetodisp(gchar *outbuf, gint outlen, const gchar *inbuf)
 {
        gchar *tmpstr;
 
+       codeconv_set_strict(TRUE);
        tmpstr = conv_iconv_strdup(inbuf, conv_get_locale_charset_str(),
                                   CS_INTERNAL);
+       codeconv_set_strict(FALSE);
        if (tmpstr && g_utf8_validate(tmpstr, -1, NULL)) {
                strncpy2(outbuf, tmpstr, outlen);
                g_free(tmpstr);
+               return;
        } else if (tmpstr && !g_utf8_validate(tmpstr, -1, NULL)) {
+               g_free(tmpstr);
+               codeconv_set_strict(TRUE);
+               tmpstr = conv_iconv_strdup(inbuf, 
+                               conv_get_locale_charset_str_no_utf8(),
+                               CS_INTERNAL);
+               codeconv_set_strict(FALSE);
+       }
+       if (tmpstr && g_utf8_validate(tmpstr, -1, NULL)) {
+               strncpy2(outbuf, tmpstr, outlen);
+               g_free(tmpstr);
+               return;
+       } else {
                g_free(tmpstr);
                conv_utf8todisp(outbuf, outlen, inbuf);
-       } else
-               conv_utf8todisp(outbuf, outlen, inbuf);
+       }
 }
 
 static void conv_noconv(gchar *outbuf, gint outlen, const gchar *inbuf)
@@ -1324,6 +1276,9 @@ static CharSet conv_get_locale_charset_no_utf8(void)
        gchar *tmp;
        gint i;
 
+       if (prefs_common.broken_are_utf8)
+               return conv_get_locale_charset();
+
        if (cur_charset != -1)
                return cur_charset;
 
@@ -1668,9 +1623,14 @@ void conv_encode_header_full(gchar *dest, gint len, const gchar *src,
                                out_str = conv_codeset_strdup
                                        (part_str, cur_encoding, out_encoding);
                                if (!out_str) {
-                                       g_warning("conv_encode_header(): code conversion failed\n");
-                                       conv_unreadable_8bit(part_str);
-                                       out_str = g_strdup(part_str);
+                                       if (strict_mode) {
+                                               *dest = '\0';
+                                               return;
+                                       } else {
+                                               g_warning("conv_encode_header(): code conversion failed\n");
+                                               conv_unreadable_8bit(part_str);
+                                               out_str = g_strdup(part_str);
+                                       }
                                }
                                out_str_len = strlen(out_str);