home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / mush6.0 / part02 / sort.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-04-12  |  5.4 KB  |  209 lines

  1. /* sort.c 2.0    (c) copyright 1986 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4. /* #define MYQSORT */
  5.  
  6. static int order, ignore_case;
  7. static jmp_buf sortbuf;
  8.  
  9. sort(argc, argv, list)
  10. register int argc;
  11. register char *argv[], list[];
  12. {
  13.     int status_cmp(), author_cmp(), date_cmp(), subject_cmp(), subj_with_re();
  14.     int (*oldint)(), (*oldquit)();
  15.     int (*how)() = status_cmp;
  16.     int n, offset = -1, range = 0;
  17.  
  18.     order = 1, ignore_case = FALSE;
  19.  
  20.     while (argc && *++argv) {
  21.     n = 0;
  22.     while (argv[0][n])
  23.         switch(argv[0][n++]) {
  24.         case '-': order = -1;
  25.         when 'd': how = date_cmp;
  26.         when 'a': how = author_cmp;
  27.         when 's': how = subject_cmp;
  28.         when 'R': how = subj_with_re;
  29.         when 'S': how = status_cmp;
  30.         when 'i': ignore_case = TRUE;
  31.         otherwise: return help(0, "sort_help", cmd_help);
  32.         }
  33.     }
  34.     if (msg_cnt <= 1) {
  35.     print("Not enough messages to sort.\n");
  36.     return -1;
  37.     }
  38.     on_intr();
  39.  
  40.     if (list && ison(glob_flags, IS_PIPE)) {
  41.     for (n = 0; n < msg_cnt; n++)
  42.         if (msg_bit(list, n)) {
  43.         if (offset < 0)
  44.             offset = n;
  45.         range++;
  46.         } else if (offset >= 0)
  47.         break;
  48.     } else
  49.     offset = 0, range = msg_cnt;
  50.  
  51.     if (range < 2)
  52.     print("Range not broad enough to sort anything\n");
  53.     else {
  54.     Debug("Sorting %d messages starting at message %d\n", range, offset+1);
  55.  
  56.     if (setjmp(sortbuf) == 0)
  57.         qsort((char *)&msg[offset], range, sizeof (struct msg), how);
  58.     else
  59.         print("WARNING: Sorting interrupted: unpredictable order.\n");
  60.     turnon(glob_flags, DO_UPDATE);
  61.     }
  62.     off_intr();
  63.     return -1;
  64. }
  65.  
  66. #ifdef MYQSORT
  67. qsort(base, len, siz, compar)
  68. register struct msg *base;
  69. int (*compar)();
  70. {
  71.      register int i, swapping;
  72.      struct msg temp;
  73.  
  74.      do  {
  75.      swapping = 0;
  76.      for (i = 0; i < len-1; ++i) {
  77.          if (compar(base+i, base+i+1) > 0) {
  78.          temp = base[i];
  79.          base[i] = base[i+1];
  80.          base[i+1] = temp;
  81.          swapping = 1;
  82.          }
  83.      }
  84.      } while (swapping);
  85. }
  86. #endif /* MYSORT */
  87.  
  88. status_cmp(msg1, msg2)
  89. register struct msg *msg1, *msg2;
  90. {
  91.     if (ison(glob_flags, WAS_INTR))
  92.     longjmp(sortbuf, 1);
  93.     if (msg1 < msg || msg2 < msg) {
  94.     wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  95.     return 0;
  96.     }
  97.     if (msg1->m_flags == msg2->m_flags)
  98.         return 0;
  99.     if (ison(msg1->m_flags, DELETE) && isoff(msg2->m_flags, DELETE))
  100.     return order;
  101.     if (isoff(msg1->m_flags, DELETE) && ison(msg2->m_flags, DELETE))
  102.     return -order;
  103.     if (isoff(msg1->m_flags, OLD) && ison(msg2->m_flags, OLD))
  104.     return -order;
  105.     if (ison(msg1->m_flags, OLD) && isoff(msg2->m_flags, OLD))
  106.     return order;
  107.     if (ison(msg1->m_flags, UNREAD) && isoff(msg2->m_flags, UNREAD))
  108.     return -order;
  109.     if (isoff(msg1->m_flags, UNREAD) && ison(msg2->m_flags, UNREAD))
  110.     return order;
  111.     if (ison(msg1->m_flags,PRESERVE) && isoff(msg2->m_flags,PRESERVE))
  112.     return -order;
  113.     if (isoff(msg1->m_flags,PRESERVE) && ison(msg2->m_flags,PRESERVE))
  114.     return order;
  115.     if (ison(msg1->m_flags,REPLIED) && isoff(msg2->m_flags,REPLIED))
  116.     return -order;
  117.     if (isoff(msg1->m_flags,REPLIED) && ison(msg2->m_flags,REPLIED))
  118.     return order;
  119.  
  120.     return order;
  121. }
  122.  
  123. author_cmp(msg1, msg2)
  124. register struct msg *msg1, *msg2;
  125. {
  126.     char buf1[BUFSIZ], buf2[BUFSIZ];
  127.  
  128.     if (ison(glob_flags, WAS_INTR))
  129.     longjmp(sortbuf, 1);
  130.     if (msg1 < msg || msg2 < msg) {
  131.     wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  132.     return 0;
  133.     }
  134.     (void) reply_to(msg1 - msg, 0, buf1); /* "0" for "author only" */
  135.     (void) reply_to(msg2 - msg, 0, buf2);
  136.     Debug("author: msg %d: %s, msg %d: %s\n", msg1-msg, buf1, msg2-msg, buf2);
  137.     if (ignore_case)
  138.     return lcase_strcmp(buf1, buf2) * order;
  139.     return strcmp(buf1, buf2) * order;
  140. }
  141.  
  142. /*
  143.  * Subject comparison ignoring Re:  subject_to() appends an Re: if there is
  144.  * any subject whatsoever.
  145.  */
  146. subject_cmp(msg1, msg2)
  147. register struct msg *msg1, *msg2;
  148. {
  149.     char buf1[BUFSIZ], buf2[BUFSIZ];
  150.  
  151.     if (ison(glob_flags, WAS_INTR))
  152.     longjmp(sortbuf, 1);
  153.     if (msg1 < msg || msg2 < msg) {
  154.     wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  155.     return 0;
  156.     }
  157.     (void) subject_to(msg1 - msg, buf1);
  158.     (void) subject_to(msg2 - msg, buf2);
  159.     Debug("subjects: (%d): \"%s\" (%d): \"%s\"\n", msg1-msg,buf1,msg2-msg,buf2);
  160.     if (ignore_case)
  161.     return lcase_strcmp(buf1, buf2) * order;
  162.     return strcmp(buf1, buf2) * order;
  163. }
  164.  
  165. /*
  166.  * compare subject strings from two messages.
  167.  * If Re is appended, so be it -- if user wants to ignore Re: use 'R' flag.
  168.  */
  169. subj_with_re(msg1, msg2)
  170. register struct msg *msg1, *msg2;
  171. {
  172.     char buf1[BUFSIZ], buf2[BUFSIZ], *p;
  173.  
  174.     if (ison(glob_flags, WAS_INTR))
  175.     longjmp(sortbuf, 1);
  176.     if (msg1 < msg || msg2 < msg) {
  177.     wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  178.     return 0;
  179.     }
  180.     if (!(p = header_field(msg1 - msg, "subject")))
  181.     p = "";
  182.     (void) strcpy(buf1, p);
  183.     if (!(p = header_field(msg2 - msg, "subject")))
  184.     p = "";
  185.     (void) strcpy(buf2, p);
  186.     Debug("subjects: (%d): \"%s\" (%d): \"%s\"\n",
  187.     msg1-msg, buf1, msg2-msg, buf2);
  188.     if (ignore_case)
  189.     return lcase_strcmp(buf1, buf2) * order;
  190.     return strcmp(buf1, buf2) * order;
  191. }
  192.  
  193. date_cmp(msg1, msg2)
  194. register struct msg *msg1, *msg2;
  195. {
  196.     char buf1[11], buf2[11];
  197.  
  198.     if (ison(glob_flags, WAS_INTR))
  199.     longjmp(sortbuf, 1);
  200.     if (msg1 < msg || msg2 < msg) {
  201.     wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  202.     return 0;
  203.     }
  204.     (void) strcpy(buf1, msg_date(msg1-msg));
  205.     (void) strcpy(buf2, msg_date(msg2-msg));
  206.     Debug("dates: msg %d: %s, msg %d: %s\n", msg1-msg, buf1, msg2-msg, buf2);
  207.     return strcmp(buf1, buf2) * order;
  208. }
  209.