No more mhshow-charset-* but instead automatic invocation of iconv(1).
authormarkus schnalke <meillo@marmaro.de>
Sat, 14 Apr 2012 15:35:18 +0000 (17:35 +0200)
committermarkus schnalke <meillo@marmaro.de>
Sat, 14 Apr 2012 15:35:18 +0000 (17:35 +0200)
Unless there is an mhshow-show-* rule, text/plain content types are
automatically piped through iconv(1) if their charset is foreign.
For mhshow-show-* rules, there's a new %c escape, which expands to the
foreign charset. The contents of the files, referenced by %f/%F are still
in foreign encoding. One might want to use `iconv -f %c %f | mycommand'
for custom mhshow-show-* rules.
We depend on iconv(1) now! But this may change to dependence on iconv(3),
soon.
This field is inconsistent and not at all finished, yet.

h/mhparse.h
uip/mhfree.c
uip/mhlistsbr.c
uip/mhparse.c
uip/mhshowsbr.c

index 6778654..cca26e9 100644 (file)
@@ -94,6 +94,7 @@ struct Content {
        struct CTinfo c_ctinfo;      /* parsed elements of Content-Type   */
        int c_type;                  /* internal flag for content type    */
        int c_subtype;               /* internal flag for content subtype */
+       char *c_charset;             /* charset string                    */
 
        /* Content-Transfer-Encoding info (decoded contents) */
        CE c_cefile;                 /* structure holding decoded content */
@@ -112,7 +113,6 @@ struct Content {
        int c_rfc934;                /* rfc934 compatibility flag         */
 
        char *c_showproc;            /* default, if not in profile        */
-       char *c_termproc;            /* for charset madness...            */
        char *c_storeproc;           /* overrides profile entry, if any   */
 
        char *c_storage;             /* write contents (file)             */
index 5fe5b2d..bf3382c 100644 (file)
@@ -78,10 +78,10 @@ free_content(CT ct)
                break;
        }
 
+       if (ct->c_charset)
+               free(ct->c_charset);
        if (ct->c_showproc)
                free(ct->c_showproc);
-       if (ct->c_termproc)
-               free(ct->c_termproc);
        if (ct->c_storeproc)
                free(ct->c_storeproc);
 
index 1777cf4..5dee115 100644 (file)
@@ -255,8 +255,8 @@ list_debug(CT ct)
                         ct->c_type, ct->c_subtype,
                         (unsigned int)(unsigned long) ct->c_ctparams);
 
+       fprintf(stderr, "    charset  \"%s\"\n", empty(ct->c_charset));
        fprintf(stderr, "    showproc  \"%s\"\n", empty(ct->c_showproc));
-       fprintf(stderr, "    termproc  \"%s\"\n", empty(ct->c_termproc));
        fprintf(stderr, "    storeproc \"%s\"\n", empty(ct->c_storeproc));
 
        /* print transfer encoding information */
index cf264c6..dc8e380 100644 (file)
@@ -963,9 +963,7 @@ InitGeneric(CT ct)
 static int
 InitText(CT ct)
 {
-       char buffer[BUFSIZ];
-       char *chset = NULL;
-       char **ap, **ep, *cp;
+       char **ap, **ep;
        struct k2v *kv;
        struct text *t;
        CI ci = &ct->c_ctinfo;
@@ -992,10 +990,11 @@ InitText(CT ct)
 
        /* check if content specified a character set */
        if (*ap) {
+               /* store its name */
+               ct->c_charset = getcpy(norm_charmap(*ep));
                /* match character set or set to CHARSET_UNKNOWN */
                for (kv = Charset; kv->kv_key; kv++) {
                        if (!mh_strcasecmp(*ep, kv->kv_key)) {
-                               chset = *ep;
                                break;
                        }
                }
@@ -1004,20 +1003,6 @@ InitText(CT ct)
                t->tx_charset = CHARSET_UNSPECIFIED;
        }
 
-       /*
-       ** If we can not handle character set natively,
-       ** then check profile for string to modify the
-       ** terminal or display method.
-       **
-       ** termproc is for mhshow, though mhlist -debug prints it, too.
-       */
-       if (chset != NULL && !check_charset(chset, strlen(chset))) {
-               snprintf(buffer, sizeof(buffer), "%s-charset-%s",
-                               invo_name, chset);
-               if ((cp = context_find(buffer)))
-                       ct->c_termproc = getcpy(cp);
-       }
-
        return OK;
 }
 
index adb0da7..fe3afc4 100644 (file)
@@ -335,6 +335,13 @@ show_content_aux(CT ct, int alternate, char *cp, char *cracked)
                                }
                                break;
 
+                       case 'c':
+                               /* insert charset */
+                               if (ct->c_charset) {
+                                       strncpy(bp, ct->c_charset, buflen);
+                               }
+                               break;
+
                        case 'd':
                                /* insert content description */
                                if (ct->c_descr) {
@@ -446,25 +453,6 @@ raw:
                }
        }
 
-       if (buflen <= 0 || (ct->c_termproc &&
-                       (size_t)buflen <= strlen(ct->c_termproc))) {
-               /*
-               ** content_error would provide a more useful error message
-               ** here, except that if we got overrun, it probably would
-               ** too.
-               */
-               fprintf(stderr, "Buffer overflow constructing show command!\n");
-               return NOTOK;
-       }
-
-       /* use charset string to modify display method */
-       if (ct->c_termproc) {
-               char term[BUFSIZ];
-
-               strncpy(term, buffer, sizeof(term));
-               snprintf(buffer, sizeof(buffer), ct->c_termproc, term);
-       }
-
 got_command:
        return show_content_aux2(ct, alternate, cracked, buffer,
                        fd, xlist, xstdin, xtty);
@@ -573,7 +561,12 @@ show_text(CT ct, int alternate)
        ** if it is not a text part of a multipart/alternative
        */
        if (!alternate || ct->c_subtype == TEXT_PLAIN) {
-               snprintf(buffer, sizeof(buffer), "%%p%s '%%F'", defaultpager);
+               if (!check_charset(ct->c_charset, strlen(ct->c_charset))) {
+                       snprintf(buffer, sizeof(buffer), "%%liconv -f '%s'",
+                                       ct->c_charset);
+               } else {
+                       snprintf(buffer, sizeof(buffer), "%%lcat");
+               }
                cp = (ct->c_showproc = getcpy(buffer));
                return show_content_aux(ct, alternate, cp, NULL);
        }
@@ -768,6 +761,13 @@ show_multi_aux(CT ct, int alternate, char *cp)
                                }
                                break;
 
+                       case 'c':
+                               /* insert charset */
+                               if (ct->c_charset) {
+                                       strncpy(bp, ct->c_charset, buflen);
+                               }
+                               break;
+
                        case 'd':
                                /* insert content description */
                                if (ct->c_descr) {
@@ -887,25 +887,6 @@ raw:
                }
        }
 
-       if (buflen <= 0 || (ct->c_termproc &&
-                       (size_t)buflen <= strlen(ct->c_termproc))) {
-               /*
-               ** content_error would provide a more useful error message
-               ** here, except that if we got overrun, it probably would
-               ** too.
-               */
-               fprintf(stderr, "Buffer overflow constructing show command!\n");
-               return NOTOK;
-       }
-
-       /* use charset string to modify display method */
-       if (ct->c_termproc) {
-               char term[BUFSIZ];
-
-               strncpy(term, buffer, sizeof(term));
-               snprintf(buffer, sizeof(buffer), ct->c_termproc, term);
-       }
-
        return show_content_aux2(ct, alternate, NULL, buffer,
                        NOTOK, xlist, 0, xtty);
 }