]> git.llucax.com Git - software/mutt-debian.git/blobdiff - charset.c
debian/control: Standards-Version moved from 3.9.2.0 to 3.9.2 for cosmetic reasons
[software/mutt-debian.git] / charset.c
index 7cb9da51ce309500e76dd4816b12046485de78dd..fd011a4954a3985335403aaafa4169dcd284e0e8 100644 (file)
--- a/charset.c
+++ b/charset.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.org>
+ * Copyright (C) 1999-2002,2007 Thomas Roessler <roessler@does-not-exist.org>
  *
  *     This program is free software; you can redistribute it
  *     and/or modify it under the terms of the GNU General Public
@@ -142,7 +142,7 @@ PreferredMIMENames[] =
   { "iso-ir-157",      "iso-8859-10"   },
   { "latin6",          "iso-8859-10"   }, /* this is not a bug */
   { "l6",              "iso-8859-10"   },
-  { "csISOLatin6"      "iso-8859-10"   }, 
+  { "csISOLatin6",     "iso-8859-10"   }, 
   
   { "csKOI8r",         "koi8-r"        },
   
@@ -239,36 +239,42 @@ void mutt_set_langinfo_charset (void)
 
 #endif
 
+/* this first ties off any charset extension such as //TRANSLIT,
+   canonicalizes the charset and re-adds the extension */
 void mutt_canonical_charset (char *dest, size_t dlen, const char *name)
 {
   size_t i;
-  char *p;
-  char scratch[LONG_STRING];
+  char *p, *ext;
+  char in[LONG_STRING], scratch[LONG_STRING];
+
+  strfcpy (in, name, sizeof (in));
+  if ((ext = strchr (in, '/')))
+    *ext++ = 0;
 
-  if (!ascii_strcasecmp (name, "utf-8")) 
+  if (!ascii_strcasecmp (in, "utf-8") || !ascii_strcasecmp (in, "utf8"))
   {
     strfcpy (dest, "utf-8", dlen);
-    return;
+    goto out;
   }
 
   /* catch some common iso-8859-something misspellings */
-  if (!ascii_strncasecmp (name, "8859", 4) && name[4] != '-')
-    snprintf (scratch, sizeof (scratch), "iso-8859-%s", name +4);
-  else if (!ascii_strncasecmp (name, "8859-", 5))
-    snprintf (scratch, sizeof (scratch), "iso-8859-%s", name + 5);
-  else if (!ascii_strncasecmp (name, "iso8859", 7) && name[7] != '-')
-    snprintf (scratch, sizeof (scratch), "iso_8859-%s", name + 7);
-  else if (!ascii_strncasecmp (name, "iso8859-", 8))
-    snprintf (scratch, sizeof (scratch), "iso_8859-%s", name + 8);
+  if (!ascii_strncasecmp (in, "8859", 4) && in[4] != '-')
+    snprintf (scratch, sizeof (scratch), "iso-8859-%s", in +4);
+  else if (!ascii_strncasecmp (in, "8859-", 5))
+    snprintf (scratch, sizeof (scratch), "iso-8859-%s", in + 5);
+  else if (!ascii_strncasecmp (in, "iso8859", 7) && in[7] != '-')
+    snprintf (scratch, sizeof (scratch), "iso_8859-%s", in + 7);
+  else if (!ascii_strncasecmp (in, "iso8859-", 8))
+    snprintf (scratch, sizeof (scratch), "iso_8859-%s", in + 8);
   else
-    strfcpy (scratch, NONULL(name), sizeof (scratch));
+    strfcpy (scratch, in, sizeof (scratch));
 
   for (i = 0; PreferredMIMENames[i].key; i++)
     if (!ascii_strcasecmp (scratch, PreferredMIMENames[i].key) ||
        !mutt_strcasecmp (scratch, PreferredMIMENames[i].key))
     {
       strfcpy (dest, PreferredMIMENames[i].pref, dlen);
-      return;
+      goto out;
     }
 
   strfcpy (dest, scratch, dlen);
@@ -276,16 +282,33 @@ void mutt_canonical_charset (char *dest, size_t dlen, const char *name)
   /* for cosmetics' sake, transform to lowercase. */
   for (p = dest; *p; p++)
     *p = ascii_tolower (*p);
+
+out:
+  if (ext && *ext)
+  {
+    safe_strcat (dest, dlen, "/");
+    safe_strcat (dest, dlen, ext);
+  }
 }
 
 int mutt_chscmp (const char *s, const char *chs)
 {
   char buffer[STRING];
+  int a, b;
 
   if (!s) return 0;
 
+  /* charsets may have extensions mutt_canonical_charset()
+     leaves intact; we expect `chs' to originate from mutt
+     code, not user input (i.e. `chs' does _not_ have any
+     extension)
+     we simply check if the shorter string is a prefix for
+     the longer */
   mutt_canonical_charset (buffer, sizeof (buffer), s);
-  return !ascii_strcasecmp (buffer, chs);
+  a = mutt_strlen (buffer);
+  b = mutt_strlen (chs);
+  return !ascii_strncasecmp (a > b ? buffer : chs,
+                            a > b ? chs : buffer, MIN(a,b));
 }
 
 char *mutt_get_default_charset ()
@@ -629,3 +652,28 @@ void fgetconv_close (FGETCONV **_fc)
     iconv_close (fc->cd);
   FREE (_fc);          /* __FREE_CHECKED__ */
 }
+
+int mutt_check_charset (const char *s, int strict)
+{
+  int i;
+  iconv_t cd;
+
+  if (mutt_is_utf8 (s))
+    return 0;
+
+  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 0;
+    }
+
+  if ((cd = mutt_iconv_open (s, s, 0)) != (iconv_t)(-1))
+  {
+    iconv_close (cd);
+    return 0;
+  }
+
+  return -1;
+}