]> granicus.if.org Git - mutt/commitdiff
Add charset alias support and fix various errors in the
authorThomas Roessler <roessler@does-not-exist.org>
Tue, 15 Sep 1998 16:00:57 +0000 (16:00 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Tue, 15 Sep 1998 16:00:57 +0000 (16:00 +0000)
character set code.

charset.c
charset.h
charsets/Makefile.in
charsets/gen_charsets
charsets/parse_i18n.c
handler.c

index dd12df09a03f3754c929b04c5f1bee0c97a4f839..0de70c9c00c18eb3db5a87adedc0b5ecc281fa15 100644 (file)
--- a/charset.c
+++ b/charset.c
 
 static HASH *Translations = NULL;
 static HASH *Charsets = NULL;
+static HASH *CharsetAliases = NULL;
 
 static CHARSET *mutt_new_charset(void)
 {
   CHARSET *chs;
   
   chs       = safe_malloc(sizeof(CHARSET));
-  chs->name = NULL;
   chs->map  = NULL;
   
   return chs;
@@ -43,7 +43,6 @@ static void mutt_free_charset(CHARSET **chsp)
 {
   CHARSET *chs = *chsp;
   
-  safe_free((void **) &chs->name);
   safe_free((void **) &chs->map);
   safe_free((void **) chsp);
 }
@@ -77,8 +76,7 @@ static CHARSET *load_charset(const char *name)
   int i;
 
   chs = mutt_new_charset();
-  chs->name = safe_strdup(name);
-  
+
   snprintf(path, sizeof(path), "%s/charsets/%s", SHAREDIR, name);
   if((fp = fopen(path, "r")) == NULL)
     goto bail;
@@ -89,7 +87,7 @@ static CHARSET *load_charset(const char *name)
   if(strcmp(buffer, CHARSET_MAGIC) != 0)
     goto bail;
 
-  chs->map  = safe_malloc(sizeof(UNICODE_MAP));
+  chs->map  = safe_malloc(sizeof(CHARSET_MAP));
   
   for(i = 0; i < 256; i++)
   {
@@ -106,30 +104,64 @@ static CHARSET *load_charset(const char *name)
   return chs;
 }
 
+static HASH *load_charset_aliases(void)
+{
+  FILE *fp;
+  char buffer[LONG_STRING];
+  char *t;
+  HASH *charset_aliases;
+  
+  sprintf(buffer, "%s/charsets/charsets.alias", SHAREDIR);
+  if(!(fp = fopen(buffer, "r")))
+     return NULL;
+
+  charset_aliases = hash_create(256);
+  
+  while(fgets(buffer, sizeof(buffer), fp))
+  {
+    if((t = strchr(buffer, '\n')))
+      *t = '\0';
+
+    if(!(t = strchr(buffer, ' ')))
+      continue;
+    
+    *t++ = '\0';
+    hash_insert(charset_aliases, safe_strdup(buffer), safe_strdup(t), 1);
+  }
+  fclose(fp);
+  return charset_aliases;
+}
+
 static void init_charsets()
 {
   if(Charsets) return;
 
-  Charsets     = hash_create(128);
-  Translations = hash_create(256);
+  Charsets       = hash_create(128);
+  Translations   = hash_create(256);
+  CharsetAliases = load_charset_aliases();
 }
 
 CHARSET *mutt_get_charset(const char *name)
 {
   CHARSET *charset;
   char buffer[SHORT_STRING];
+  char *real_charset;
   
   init_charsets();
   canonical_charset(buffer, sizeof(buffer), name);
-  if(!(charset = hash_find(Charsets, buffer)))
+
+  if(!CharsetAliases || !(real_charset = hash_find(CharsetAliases, buffer)))
+    real_charset = buffer;
+
+  if(!(charset = hash_find(Charsets, real_charset)))
   {
-    charset = load_charset(buffer);
-    hash_insert(Charsets, buffer, charset, 0);
+    charset = load_charset(real_charset);
+    hash_insert(Charsets, safe_strdup(real_charset), charset, 1);
   }
   return charset;
 }
 
-static int translate_char(UNICODE_MAP *to, int ch)
+static int translate_char(CHARSET_MAP *to, int ch)
 {
   int i;
 
@@ -142,10 +174,10 @@ static int translate_char(UNICODE_MAP *to, int ch)
   return '?';
 }
 
-UNICODE_MAP *build_translation(UNICODE_MAP *from, UNICODE_MAP *to)
+CHARSET_MAP *build_translation(CHARSET_MAP *from, CHARSET_MAP *to)
 {
   int i;
-  UNICODE_MAP *map = safe_malloc(sizeof(UNICODE_MAP));
+  CHARSET_MAP *map = safe_malloc(sizeof(CHARSET_MAP));
 
   for(i = 0; i < 256; i++)
     (*map)[i] = translate_char(to, (*from)[i]);
@@ -153,24 +185,30 @@ UNICODE_MAP *build_translation(UNICODE_MAP *from, UNICODE_MAP *to)
   return map;
 }
 
-UNICODE_MAP *mutt_get_translation(const char *_from, const char *_to)
+CHARSET_MAP *mutt_get_translation(const char *_from, const char *_to)
 {
-  char from[SHORT_STRING];
-  char to[SHORT_STRING];
+  char from_canon[SHORT_STRING];
+  char to_canon[SHORT_STRING];
   char key[SHORT_STRING];
+  char *from, *to;
   CHARSET *from_cs, *to_cs;
-  UNICODE_MAP *map;
+  CHARSET_MAP *map;
 
   if(!_from || !_to)
     return NULL;
   
   init_charsets();
 
-  canonical_charset(from, sizeof(from), _from);
-  canonical_charset(to, sizeof(to), _to);
+  canonical_charset(from_canon, sizeof(from_canon), _from);
+  canonical_charset(to_canon, sizeof(to_canon), _to);
+
+  if(!CharsetAliases || !(from = hash_find(CharsetAliases, from_canon)))
+    from = from_canon;
+  if(!CharsetAliases || !(to = hash_find(CharsetAliases, to_canon)))
+    to = to_canon;
   
   /* quick check for the identity mapping */
-  if((*from == *to) && !strcmp(from, to))
+  if((from == to) || ((*from == *to) && !strcmp(from, to)))
     return NULL;
   
   snprintf(key, sizeof(key), "%s %s", from, to);
@@ -183,20 +221,20 @@ UNICODE_MAP *mutt_get_translation(const char *_from, const char *_to)
       return NULL;
     
     map = build_translation(from_cs->map, to_cs->map);
-    hash_insert(Translations, key, map, 0);
+    hash_insert(Translations, safe_strdup(key), map, 1);
   }
   return map;
 }
 
-int mutt_display_char(int ch, UNICODE_MAP *map)
+unsigned char mutt_display_char(unsigned char ch, CHARSET_MAP *map)
 {
-  if (!map || (ch <= 0) || (ch > 255))
+  if (!map || !ch)
     return ch;
-
-  return (*map)[ch];
+  
+  return (unsigned char) (*map)[ch];
 }
 
-int mutt_display_string(char *str, UNICODE_MAP *map)
+int mutt_display_string(char *str, CHARSET_MAP *map)
 {
   if(!map)
     return -1;
index 88d53913f5a8fc100bae69316fb181f0c9ee15c6..aa29f78be7f6fe8bb519cbc103b78e968bec3575 100644 (file)
--- a/charset.h
+++ b/charset.h
 
 #ifndef _GEN_CHARSETS
 
-typedef int UNICODE_MAP[256];
+typedef int CHARSET_MAP[256];
 
 typedef struct 
 {
-  char *name;
-  UNICODE_MAP *map;
+  CHARSET_MAP *map;
 } CHARSET;
-
-CHARSET *mutt_get_charset(const char *);
-UNICODE_MAP *mutt_get_translation(const char *, const char *);
-int mutt_display_char(int, UNICODE_MAP *);
-int mutt_display_string(char *, UNICODE_MAP *);
+  
+CHARSET     *mutt_get_charset(const char *);
+CHARSET_MAP *mutt_get_translation(const char *, const char *);
+unsigned char mutt_display_char(unsigned char, CHARSET_MAP *);
+int mutt_display_string(char *, CHARSET_MAP *);
 
 #endif
 
index 689cf751c2dfcdff48d250f2858c794c34a50f1b..11da4bed1f557fd721319d4384e77b8288037a87 100644 (file)
@@ -36,7 +36,7 @@ distclean: clean
        -rm -f Makefile
 
 veryclean:
-       -rm -f `cat charsets.list` charsets.list
+       -rm -f `cat charsets.list` charsets.list charsets.alias
 
 charmaps: parse_i18n
        ( cd $(srcdir) && ./gen_charsets )
@@ -45,4 +45,4 @@ install: charsets.list
        $(srcdir)/../mkinstalldirs $(sharedir)/charsets
        ( cd $(srcdir) && $(INSTALL) \
                -m 644 `cat charsets.list` $(sharedir)/charsets )
-
+       $(INSTALL) -m 644 charsets.alias $(sharedir)/charsets
index 4ab05ab706099fdb9af1960f949c1ed34b38778c..00fae06f0f9c1d457ff8ae6ea7312c93f97ccb1b 100755 (executable)
@@ -4,8 +4,11 @@ dirs="/usr/local/lib/nls /usr/lib/nls /usr/local/share/nls /usr/share/nls"
 dirs="$dirs /usr/local/lib/i18n /usr/lib/i18n /usr/local/share/i18n"
 dirs="$dirs /usr/share/i18n"
 
-rm -f ./charsets.list
+rm -f ./charsets.list ./charsets.alias ./charsets.$$
 
 for d in $dirs ; do
-  [ -d $d/charmaps ] && ./parse_i18n ./ $d/charmaps/* >> ./charsets.list
+  [ -d $d/charmaps ] && ./parse_i18n ./ $d/charmaps/* >> ./charsets.$$
 done
+
+awk '$1 == "charset" { printf ("%s\n", $2); }' ./charsets.$$ > charsets.list
+awk '$1 == "alias"   { printf ("%s %s\n", $2, $3); }' ./charsets.$$ > charsets.alias
index a832558917bc8eee6a49f5ec9ec71234db73f048..02eaba794b0460b8eda420c7a788b6a6f168fbf3 100644 (file)
@@ -31,12 +31,19 @@ static char *basedir = NULL;
 
 typedef int MAP[256];
 
+typedef struct alias
+{
+  char *charset;
+  struct alias *next;
+} ALIAS;
+
 typedef struct
 {
   char *charset;
   char escape_char;
   char comment_char;
   short is_valid;
+  ALIAS *aliases;
   MAP map;
 } CHARMAP;
 
@@ -100,6 +107,8 @@ static CHARMAP *charmap_new(void)
   m->escape_char = '\\';
   m->comment_char = '#';
   m->is_valid = 0;
+
+  m->aliases = NULL;
   
   for(i = 0; i < 256; i++)
     m->map[i] = -1;
@@ -109,15 +118,35 @@ static CHARMAP *charmap_new(void)
 
 static void charmap_free(CHARMAP **cp)
 {
+  ALIAS *p, *q;
+  
   if(!cp || !*cp)
     return ;
   
+  for(p = (*cp)->aliases; p; p = q)
+  {
+    q = p->next;
+    safe_free((void **) &p->charset);
+    safe_free((void **) &p);
+  }
+  
   safe_free((void **) &(*cp)->charset);
   safe_free((void **) cp);
   
   return;
 }
 
+static void add_alias(CHARMAP *m, const char *alias)
+{
+  ALIAS *aptr;
+
+  aptr = safe_malloc(sizeof(ALIAS));
+  aptr->charset = safe_strdup(alias);
+  canonical_charset(aptr->charset, strlen(aptr->charset) + 1, aptr->charset);
+  aptr->next = m->aliases;
+  m->aliases = aptr;
+}
+
 static CHARMAP *parse_charmap_header(FILE *fp, const char *prefix)
 {
   char buffer[1024];
@@ -139,7 +168,14 @@ static CHARMAP *parse_charmap_header(FILE *fp, const char *prefix)
       break;
 
     if(*buffer == m->comment_char)
+    {
+      if((t = strtok(buffer + 1, "\t ")) && !strcasecmp(t, "alias"))
+      {
+       while((t = strtok(NULL, "\t, ")))
+         add_alias(m, t);
+      }
       continue;
+    }
     
     if(!(t = strtok(buffer, "\t ")))
       continue;
@@ -282,6 +318,7 @@ int main(int argc, const char *argv[])
 {
   FILE *fp;
   CHARMAP *m;
+  ALIAS *aptr;
   int i;
   char buffer[1024];
   
@@ -310,8 +347,15 @@ int main(int argc, const char *argv[])
       
       if((fp = fopen(buffer, "w")))
       {
-       printf("%s\n", m->charset);
        write_charmap(fp, m);
+       
+       printf("charset %s\n", m->charset);
+       for(aptr = m->aliases; aptr; aptr = aptr->next)
+       {
+         if(strcmp(aptr->charset, m->charset))
+           printf("alias %s %s\n", aptr->charset, m->charset);
+       }
+       
        fclose(fp);
       }
       else
index 86e8f64502182281e980e642f88577f151152b3e..417ede45c7e6627c3c25bc0f63603404d29bf3dd 100644 (file)
--- a/handler.c
+++ b/handler.c
@@ -72,7 +72,7 @@ void mutt_decode_xbit (STATE *s, BODY *b, int istext)
   
   if (istext)
   {
-    UNICODE_MAP *map;
+    CHARSET_MAP *map;
     
     map = mutt_get_translation(mutt_get_parameter("charset", b->parameter), Charset);
 
@@ -97,7 +97,7 @@ void mutt_decode_xbit (STATE *s, BODY *b, int istext)
        }
        
       }
-      state_putc(mutt_display_char(c, map), s);
+      state_putc(mutt_display_char((unsigned char) c, map), s);
       if(c == '\n')
        lbreak = 1;
     }
@@ -122,7 +122,7 @@ void mutt_decode_quoted (STATE *s, BODY *b, int istext)
 {
   long len = b->length;
   int ch, lbreak = 1;
-  UNICODE_MAP *map = mutt_get_translation(mutt_get_parameter("charset", b->parameter), Charset);
+  CHARSET_MAP *map = mutt_get_translation(mutt_get_parameter("charset", b->parameter), Charset);
 
   while (len > 0)
   {
@@ -190,7 +190,7 @@ void mutt_decode_quoted (STATE *s, BODY *b, int istext)
     }
 
     if(ch != EOF)
-      state_putc(istext ? mutt_display_char(ch, map) : ch, s);
+      state_putc(istext ? mutt_display_char((unsigned char) ch, map) : ch, s);
 
     if(ch == '\n')
       lbreak = 1;
@@ -202,7 +202,7 @@ void mutt_decode_base64 (STATE *s, BODY *b, int istext)
   long len = b->length;
   char buf[5];
   int c1, c2, c3, c4, ch, cr = 0, i;
-  UNICODE_MAP *map = mutt_get_translation(mutt_get_parameter("charset", b->parameter), Charset);
+  CHARSET_MAP *map = mutt_get_translation(mutt_get_parameter("charset", b->parameter), Charset);
 
   buf[4] = 0;
 
@@ -231,7 +231,7 @@ void mutt_decode_base64 (STATE *s, BODY *b, int istext)
       cr = 1;
     else
     {
-      state_putc(istext ? mutt_display_char(ch, map) : ch, s);
+      state_putc(istext ? mutt_display_char((unsigned char) ch, map) : ch, s);
       if (ch == '\n' && s->prefix) state_puts (s->prefix, s);
     }
 
@@ -248,7 +248,7 @@ void mutt_decode_base64 (STATE *s, BODY *b, int istext)
       cr = 1;
     else
     {
-      state_putc(istext ? mutt_display_char(ch, map) : ch, s);
+      state_putc(istext ? mutt_display_char((unsigned char)ch, map) : ch, s);
       if (ch == '\n' && s->prefix)
        state_puts (s->prefix, s);
     }
@@ -265,7 +265,7 @@ void mutt_decode_base64 (STATE *s, BODY *b, int istext)
       cr = 1;
     else
     {
-      state_putc(istext ? mutt_display_char(ch, map) : ch, s);
+      state_putc(istext ? mutt_display_char((unsigned char) ch, map) : ch, s);
       if (ch == '\n' && s->prefix)
        state_puts (s->prefix, s);
     }