]> diplodocus.org Git - nmh/commitdiff
Added support for %{charset} display string escape to mhshow(1).
authorDavid Levine <levinedl@acm.org>
Sun, 16 Feb 2014 19:12:39 +0000 (13:12 -0600)
committerDavid Levine <levinedl@acm.org>
Sun, 16 Feb 2014 19:12:39 +0000 (13:12 -0600)
docs/pending-release-notes
man/mhshow.man
test/mhshow/test-textcharset
uip/mhshowsbr.c

index 419569b..7187a49 100644 (file)
@@ -77,6 +77,7 @@ NEW FEATURES
 - If nmh was configured with iconv(3) support, mhshow will convert, if
   necessary, the charset of text/plain content to match the user's
   locale setting.
 - If nmh was configured with iconv(3) support, mhshow will convert, if
   necessary, the charset of text/plain content to match the user's
   locale setting.
+- Added support for %{charset} display string escape to mhshow(1).
 
 -----------------
 OBSOLETE FEATURES
 
 -----------------
 OBSOLETE FEATURES
index 7cb76cf..2237bdd 100644 (file)
@@ -1,4 +1,4 @@
-.TH MHSHOW %manext1% "February 9, 2014" "%nmhversion%"
+.TH MHSHOW %manext1% "February 16, 2014" "%nmhversion%"
 .\"
 .\" %nmhwarning%
 .\"
 .\"
 .\" %nmhwarning%
 .\"
@@ -224,16 +224,17 @@ The display string may contain the following escapes:
 .PP
 .RS 5
 .nf
 .PP
 .RS 5
 .nf
-.ta \w'%F  'u
-%a     Insert parameters from Content-Type field
-%e     exclusive execution
-%f     Insert filename containing content
-%F     %e, %f, and stdin is terminal not content
-%l     display listing prior to displaying content
-%p     %l, and ask for confirmation
-%s     Insert content subtype
-%d     Insert content description
-%%     Insert the character %
+.ta \w'%F      'u
+%a        Insert parameters from Content-Type field
+%{charset} Insert the charset value from the Content-Type field
+%e        exclusive execution
+%f        Insert filename containing content
+%F        %e, %f, and stdin is terminal not content
+%l        display listing prior to displaying content
+%p        %l, and ask for confirmation
+%s        Insert content subtype
+%d        Insert content description
+%%        Insert the character %
 .fi
 .RE
 .PP
 .fi
 .RE
 .PP
index c55f95b..4768808 100755 (executable)
@@ -25,6 +25,7 @@ LC_ALL=en_US.UTF-8; export LC_ALL
 expected="$MH_TEST_DIR"/$$.expected
 actual="$MH_TEST_DIR"/$$.actual
 
 expected="$MH_TEST_DIR"/$$.expected
 actual="$MH_TEST_DIR"/$$.actual
 
+# check charset conversion
 msgfile=`mhpath new`
 cat >"$msgfile" <<EOF
 From: foo@example.edu
 msgfile=`mhpath new`
 cat >"$msgfile" <<EOF
 From: foo@example.edu
@@ -53,4 +54,165 @@ EOF
 run_prog mhshow -nopause last >"$actual" 2>&1
 check "$expected" "$actual"
 
 run_prog mhshow -nopause last >"$actual" 2>&1
 check "$expected" "$actual"
 
+cat >>"$MH" <<'EOF'
+mhshow-show-text/plain: echo %{charset}
+EOF
+
+# check expansion of %{charset} by itself
+msgfile=`mhpath new`
+cat >"$msgfile" <<EOF
+From: foo@example.edu
+To: bar@example.edu
+Subject: test display with %{charset} expansion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=windows-1252
+Content-Transfer-Encoding: quoted-printable
+Date: Sun, 18 Dec 2005 00:52:39 +0100
+
+4 =F7 2 =3D 2
+EOF
+
+cat >"$expected" <<EOF
+Date:    Sun, 18 Dec 2005 00:52:39 +0100
+To:      bar@example.edu
+From:    foo@example.edu
+Subject: test display with %{charset} expansion
+
+MIME-Version: 1.0
+
+windows-1252
+EOF
+
+run_prog mhshow -nopause last >"$actual" 2>&1
+check "$expected" "$actual"
+
+# check expansion of empty %{charset} by itself
+msgfile=`mhpath new`
+cat >"$msgfile" <<EOF
+From: foo@example.edu
+To: bar@example.edu
+Subject: test display with empty %{charset} expansion
+MIME-Version: 1.0
+Content-Type: text/plain
+Content-Transfer-Encoding: quoted-printable
+Date: Sun, 18 Dec 2005 00:52:39 +0100
+
+4 =F7 2 =3D 2
+EOF
+
+cat >"$expected" <<EOF
+Date:    Sun, 18 Dec 2005 00:52:39 +0100
+To:      bar@example.edu
+From:    foo@example.edu
+Subject: test display with empty %{charset} expansion
+
+MIME-Version: 1.0
+
+
+EOF
+
+run_prog mhshow -nopause last >"$actual" 2>&1
+check "$expected" "$actual"
+
+grep -v 'mhshow-show-text/plain:' "$MH" >"$MH.new"
+mv -f "$MH.new" "$MH"
+cat >>"$MH" <<'EOF'
+mhshow-show-text/plain: echo `ap -format '%(void(lit %{charset}))%<(nonnull)-I %(putstr)%>' 0`
+EOF
+
+# check expansion of embedded %{charset} with no text following
+cat >"$expected" <<EOF
+Date:    Sun, 18 Dec 2005 00:52:39 +0100
+To:      bar@example.edu
+From:    foo@example.edu
+Subject: test display with %{charset} expansion
+
+MIME-Version: 1.0
+
+-I windows-1252
+EOF
+
+run_prog mhshow -nopause prev >"$actual" 2>&1
+check "$expected" "$actual"
+
+# check expansion of empty embedded %{charset} with no text following
+cat >"$expected" <<EOF
+Date:    Sun, 18 Dec 2005 00:52:39 +0100
+To:      bar@example.edu
+From:    foo@example.edu
+Subject: test display with empty %{charset} expansion
+
+MIME-Version: 1.0
+
+
+EOF
+
+run_prog mhshow -nopause last >"$actual" 2>&1
+check "$expected" "$actual"
+
+sed -e 's%\(mhshow-show-text/plain:.*\)%\1 file%' "$MH" >"$MH.new"
+mv -f "$MH.new" "$MH"
+
+# check expansion of embedded %{charset} with text following
+cat >"$expected" <<EOF
+Date:    Sun, 18 Dec 2005 00:52:39 +0100
+To:      bar@example.edu
+From:    foo@example.edu
+Subject: test display with %{charset} expansion
+
+MIME-Version: 1.0
+
+-I windows-1252 file
+EOF
+
+run_prog mhshow -nopause prev >"$actual" 2>&1
+check "$expected" "$actual"
+
+# check expansion of empty embedded %{charset} with text following
+cat >"$expected" <<EOF
+Date:    Sun, 18 Dec 2005 00:52:39 +0100
+To:      bar@example.edu
+From:    foo@example.edu
+Subject: test display with empty %{charset} expansion
+
+MIME-Version: 1.0
+
+file
+EOF
+
+run_prog mhshow -nopause last >"$actual" 2>&1
+check "$expected" "$actual"
+
+sed -e 's/%{charset}/%{unknown}/' "$MH" >"$MH.new"
+mv -f "$MH.new" "$MH"
+
+# check expansion of unknown parameter
+msgfile=`mhpath new`
+cat >"$msgfile" <<EOF
+From: foo@example.edu
+To: bar@example.edu
+Subject: test display with unknown C-T parameter expansion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=windows-1252
+Content-Transfer-Encoding: quoted-printable
+Date: Sun, 18 Dec 2005 00:52:39 +0100
+
+4 =F7 2 =3D 2
+EOF
+
+cat >"$expected" <<EOF
+Date:    Sun, 18 Dec 2005 00:52:39 +0100
+To:      bar@example.edu
+From:    foo@example.edu
+Subject: test display with unknown C-T parameter expansion
+
+MIME-Version: 1.0
+
+-I %{unknown} file
+EOF
+
+run_prog mhshow -nopause last >"$actual" 2>&1
+check "$expected" "$actual"
+
+
 exit $failed
 exit $failed
index 0a97017..1309056 100644 (file)
@@ -73,6 +73,7 @@ static int show_external (CT, int, int);
 static int parse_display_string (CT, char *, int *, int *, int *, int *, char *,
                                  char *, size_t, int multipart);
 static int convert_content_charset (CT, char **);
 static int parse_display_string (CT, char *, int *, int *, int *, int *, char *,
                                  char *, size_t, int multipart);
 static int convert_content_charset (CT, char **);
+static int parameter_value (CI, const char *, const char *, const char **);
 static void intrser (int);
 
 
 static void intrser (int);
 
 
@@ -833,40 +834,40 @@ parse_display_string (CT ct, char *cp, int *xstdin, int *xlist, int *xpause,
                /* and fall... */
 
            case 'f':
                /* and fall... */
 
            case 'f':
-                if (multipart) {
-                    /* insert filename(s) containing content */
-                    struct multipart *m = (struct multipart *) ct->c_ctparams;
-                    struct part *part;
-                    char *s = "";
-                    CT p;
-
-                    for (part = m->mp_parts; part; part = part->mp_next) {
-                        p = part->mp_part;
-
-                        snprintf (bp, buflen, "%s'%s'", s, p->c_storage);
-                        len = strlen (bp);
-                        bp += len;
-                        buflen -= len;
-                        s = " ";
-                    }
-                    /* set our starting pointer back to bp, to avoid
-                     * requoting the filenames we just added
-                     */
-                    pp = bp;
-                } else {
-                    /* insert filename containing content */
-                    snprintf (bp, buflen, "'%s'", file);
-                    /* since we've quoted the file argument, set things up
-                     * to look past it, to avoid problems with the quoting
-                     * logic below.  (I know, I should figure out what's
-                     * broken with the quoting logic, but..)
-                     */
-                    len = strlen(bp);
-                    buflen -= len;
-                    bp += len;
-                    pp = bp;
-                }
-                break;
+               if (multipart) {
+                   /* insert filename(s) containing content */
+                   struct multipart *m = (struct multipart *) ct->c_ctparams;
+                   struct part *part;
+                   char *s = "";
+                   CT p;
+
+                   for (part = m->mp_parts; part; part = part->mp_next) {
+                       p = part->mp_part;
+
+                       snprintf (bp, buflen, "%s'%s'", s, p->c_storage);
+                       len = strlen (bp);
+                       bp += len;
+                       buflen -= len;
+                       s = " ";
+                   }
+                   /* set our starting pointer back to bp, to avoid
+                    * requoting the filenames we just added
+                    */
+                   pp = bp;
+               } else {
+                   /* insert filename containing content */
+                   snprintf (bp, buflen, "'%s'", file);
+                   /* since we've quoted the file argument, set things up
+                    * to look past it, to avoid problems with the quoting
+                    * logic below.  (I know, I should figure out what's
+                    * broken with the quoting logic, but..)
+                    */
+                   len = strlen(bp);
+                   buflen -= len;
+                   bp += len;
+                   pp = bp;
+               }
+               break;
 
            case 'p':
                /* %l, and pause prior to displaying content */
 
            case 'p':
                /* %l, and pause prior to displaying content */
@@ -887,6 +888,52 @@ parse_display_string (CT ct, char *cp, int *xstdin, int *xlist, int *xpause,
                /* insert character % */
                goto raw;
 
                /* insert character % */
                goto raw;
 
+           case '{' : {
+               static const char param[] = "charset";
+               const char *value;
+               const int found = parameter_value (ci, param, cp, &value);
+
+               if (found == OK) {
+                   /* Because it'll get incremented in the next iteration,
+                      just increment by 1 for the '{'. */
+                   cp += strlen(param) + 1;
+
+                   /* cp points to the param and it's set in the
+                      Content-Type header. */
+                   strncpy (bp, value, buflen);
+                   break;
+               } else if (found == 1) {
+                   /* cp points to the param and it's not set in the
+                      Content-Type header, so skip it. */
+                   cp += strlen(param) + 1;
+
+                   if (*cp == '\0') {
+                       break;
+                   } else {
+                       if (*(cp + 1) == '\0') {
+                           break;
+                       } else {
+                           ++cp;
+                           /* Increment cp again so that the last
+                              character of the %{} token isn't output
+                              after falling thru below. */
+                           ++cp;
+                       }
+                   }
+               } else {
+                   /* cp points to an unrecognized parameter.  Output
+                      it as-is, starting here with the "%{". */
+                   *bp++ = '%';
+                   *bp++ = '{';
+                   *bp = '\0';
+                   buflen -= 2;
+                   break;
+               }
+
+               /* No parameter was found, so fall thru to default to
+                  output the rest of the text as-is. */
+           }
+
            default:
                *bp++ = *--cp;
                *bp = '\0';
            default:
                *bp++ = *--cp;
                *bp = '\0';
@@ -1132,6 +1179,37 @@ convert_content_charset (CT ct, char **file) {
 }
 
 
 }
 
 
+/*
+ * Return values:
+ *   NOTOK if cp doesn't point to {param}
+ *   OK    if cp points to {param} and that attribute exists, and returns
+ *         its value
+ *   1     if cp points to {param} and that attribute doesn't exist
+ */
+int
+parameter_value (CI ci, const char *param, const char *cp, const char **value) {
+    int found = NOTOK;
+    char *braced_param = concat ("{", param, "}", NULL);
+
+    if (! strncasecmp(cp, braced_param, strlen (braced_param))) {
+        char **ap, **ep;
+
+        found = 1;
+
+        for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ++ap, ++ep) {
+            if (!strcasecmp (*ap, param)) {
+                found = OK;
+                *value = *ep;
+                break;
+            }
+        }
+    }
+
+    free (braced_param);
+    return found;
+}
+
+
 static void
 intrser (int i)
 {
 static void
 intrser (int i)
 {