]> diplodocus.org Git - nmh/commitdiff
implement -prefer, for multipart/alternative preferences
authorPaul Fox <pgf@foxharp.boston.ma.us>
Wed, 4 Feb 2015 02:55:41 +0000 (21:55 -0500)
committerPaul Fox <pgf@foxharp.boston.ma.us>
Wed, 4 Feb 2015 20:00:05 +0000 (15:00 -0500)
h/mhparse.h
uip/mhlist.c
uip/mhparse.c
uip/mhshow.c
uip/mhstore.c

index c3b0b9f..d1c9442 100644 (file)
@@ -6,7 +6,7 @@
 
 #define        NPARTS  50
 #define        NTYPES  20
-#define        NPARMS  10
+#define        NPREFS  20
 
 /*
  * Abstract type for header fields
index 3e98b87..3465523 100644 (file)
@@ -32,6 +32,7 @@
     X("file file", 0, FILESW) \
     X("part number", 0, PARTSW) \
     X("type content", 0, TYPESW) \
+    X("prefer content", 0, PREFERSW) \
     X("rcache policy", 0, RCACHESW) \
     X("wcache policy", 0, WCACHESW) \
     X("changecur", 0, CHGSW) \
@@ -62,6 +63,11 @@ extern char *parts[NPARTS + 1];
 extern char *types[NTYPES + 1];
 extern int userrs;
 
+/* mhparse.c */
+extern char *preferred_types[];
+extern  char *preferred_subtypes[];
+extern int npreferred;
+
 /*
  * This is currently needed to keep mhparse happy.
  * This needs to be changed.
@@ -186,6 +192,18 @@ do_cache:
                types[ntype++] = cp;
                continue;
 
+           case PREFERSW:
+               if (!(cp = *argp++) || *cp == '-')
+                   adios (NULL, "missing argument to %s", argp[-2]);
+               if (npreferred >= NPREFS)
+                   adios (NULL, "too many preferred types (starting with %s), %d max",
+                          cp, NPREFS);
+               preferred_types[npreferred] = cp;
+               cp = strchr(cp, '/');
+               if (cp) *cp++ = '\0';
+               preferred_subtypes[npreferred++] = cp;
+               continue;
+
            case FILESW:
                if (!(cp = *argp++) || (*cp == '-' && cp[1]))
                    adios (NULL, "missing argument to %s", argp[-2]);
index 9f63678..00fa61b 100644 (file)
@@ -43,6 +43,12 @@ int bogus_mp_content;
 int suppress_extraneous_trailing_semicolon_warning;
 int extraneous_trailing_semicolon;
 
+/* list of preferred type/subtype pairs, for -prefer */
+char *preferred_types[NPREFS],
+     *preferred_subtypes[NPREFS];
+int npreferred;
+
+
 /*
  * Structures for TEXT messages
  */
@@ -121,6 +127,7 @@ static int InitGeneric (CT);
 static int InitText (CT);
 static int InitMultiPart (CT);
 static void reverse_parts (CT);
+static void prefer_parts(CT ct);
 static int InitMessage (CT);
 static int InitApplication (CT);
 static int init_encoding (CT, OpenCEFunc);
@@ -1223,8 +1230,10 @@ end_part:
 
 last_part:
     /* reverse the order of the parts for multipart/alternative */
-    if (ct->c_subtype == MULTI_ALTERNATE)
+    if (ct->c_subtype == MULTI_ALTERNATE) {
        reverse_parts (ct);
+       prefer_parts (ct);
+    }
 
     /*
      * label all subparts with part number, and
@@ -1270,9 +1279,15 @@ last_part:
 
 
 /*
- * reverse the order of the parts of a multipart/alternative
+ * reverse the order of the parts of a multipart/alternative,
+ * presumably to put the "most favored" alternative first, for
+ * ease of choosing/displaying it later on.  from a mail message on
+ * nmh-workers, from kenh:
+ *  "Stock" MH 6.8.5 did not have a reverse_parts() function, but I
+ *  see code in mhn that did the same thing...  Acccording to the RCS
+ *  logs, that code was around from the initial checkin of mhn.c by
+ *  John Romine in 1992, which is as far back as we have."
  */
-
 static void
 reverse_parts (CT ct)
 {
@@ -1289,6 +1304,60 @@ reverse_parts (CT ct)
     }
 }
 
+static void
+move_preferred_part (CT ct, char *type, char *subtype)
+{
+    struct multipart *m = (struct multipart *) ct->c_ctparams;
+    struct part *part, *next, *prev, *head, *nhead, *ntail;
+    struct part h, n;
+    CI ci;
+
+    /* move the matching part(s) to the head of the list:  walk the
+     * list of parts, move matching parts to a new list (maintaining
+     * their order), and finally, concatenate the old list onto the
+     * new.
+     */
+
+    head = &h;
+    nhead = &n;
+
+    head->mp_next = m->mp_parts;
+    nhead->mp_next = NULL;
+    ntail = nhead;
+
+    prev = head;
+    part = head->mp_next;
+    while (part != NULL) {
+       ci = &part->mp_part->c_ctinfo;
+       if (!strcasecmp(ci->ci_type, type) &&
+               (!subtype || !strcasecmp(ci->ci_subtype, subtype))) {
+           prev->mp_next = part->mp_next;
+           part->mp_next = NULL;
+           ntail->mp_next = part;
+           ntail = part;
+           part = prev->mp_next;
+       } else {
+           prev = part;
+           part = prev->mp_next;
+       }
+    }
+    ntail->mp_next = head->mp_next;
+    m->mp_parts = nhead->mp_next;
+
+}
+
+/*
+ * move parts that match the user's preferences (-prefer) to the head
+ * of the line.  process preferences in reverse so first one given
+ * ends up first in line
+ */
+static void
+prefer_parts(CT ct)
+{
+    int i;
+    for (i = npreferred-1; i >= 0; i--)
+       move_preferred_part(ct, preferred_types[i], preferred_subtypes[i]);
+}
 
 
 
index 63f4fcb..c834376 100644 (file)
@@ -34,6 +34,7 @@
     X("markform formfile", 0, MARKFORMSW) \
     X("part number", 0, PARTSW) \
     X("type content", 0, TYPESW) \
+    X("prefer content", 0, PREFERSW) \
     X("rcache policy", 0, RCACHESW) \
     X("wcache policy", 0, WCACHESW) \
     X("version", 0, VERSIONSW) \
@@ -77,6 +78,11 @@ extern char *parts[NPARTS + 1];
 extern char *types[NTYPES + 1];
 extern int userrs;
 
+/* mhparse.c */
+extern char *preferred_types[];
+extern  char *preferred_subtypes[];
+extern int npreferred;
+
 int debugsw = 0;
 int verbosw = 0;
 
@@ -203,6 +209,18 @@ do_cache:
                types[ntype++] = cp;
                continue;
 
+           case PREFERSW:
+               if (!(cp = *argp++) || *cp == '-')
+                   adios (NULL, "missing argument to %s", argp[-2]);
+               if (npreferred >= NPREFS)
+                   adios (NULL, "too many preferred types (starting with %s), %d max",
+                          cp, NPREFS);
+               preferred_types[npreferred] = cp;
+               cp = strchr(cp, '/');
+               if (cp) *cp++ = '\0';
+               preferred_subtypes[npreferred++] = cp;
+               continue;
+
            case FILESW:
                if (!(cp = *argp++) || (*cp == '-' && cp[1]))
                    adios (NULL, "missing argument to %s", argp[-2]);
index 65d0b34..a348103 100644 (file)
@@ -29,6 +29,7 @@
     X("outfile outfile", 0, OUTFILESW) \
     X("part number", 0, PARTSW) \
     X("type content", 0, TYPESW) \
+    X("prefer content", 0, PREFERSW) \
     X("rcache policy", 0, RCACHESW) \
     X("wcache policy", 0, WCACHESW) \
     X("version", 0, VERSIONSW) \
@@ -58,6 +59,11 @@ extern char *parts[NPARTS + 1];
 extern char *types[NTYPES + 1];
 extern int userrs;
 
+/* mhparse.c */
+extern char *preferred_types[];
+extern  char *preferred_subtypes[];
+extern int npreferred;
+
 #define        quitser pipeser
 
 /* mhparse.c */
@@ -175,6 +181,18 @@ do_cache:
                types[ntype++] = cp;
                continue;
 
+           case PREFERSW:
+               if (!(cp = *argp++) || *cp == '-')
+                   adios (NULL, "missing argument to %s", argp[-2]);
+               if (npreferred >= NPREFS)
+                   adios (NULL, "too many preferred types (starting with %s), %d max",
+                          cp, NPREFS);
+               preferred_types[npreferred] = cp;
+               cp = strchr(cp, '/');
+               if (cp) *cp++ = '\0';
+               preferred_subtypes[npreferred++] = cp;
+               continue;
+
            case FILESW:
                if (!(cp = *argp++) || (*cp == '-' && cp[1]))
                    adios (NULL, "missing argument to %s", argp[-2]);