home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume18 / mush6.4 / part03 / sort.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-12  |  5.7 KB  |  214 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.     SIGRET (*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", cmd_help);
  32.         }
  33.     }
  34.     if (msg_cnt <= 1) {
  35.     print("Not enough messages to sort.\n");
  36.     return -1;
  37.     }
  38.     turnon(glob_flags, IGN_SIGS);
  39.     on_intr();
  40.  
  41.     if (list && ison(glob_flags, IS_PIPE)) {
  42.     for (n = 0; n < msg_cnt; n++)
  43.         if (msg_bit(list, n)) {
  44.         if (offset < 0)
  45.             offset = n;
  46.         range++;
  47.         } else if (offset >= 0)
  48.         break;
  49.     } else
  50.     offset = 0, range = msg_cnt;
  51.  
  52.     if (range < 2)
  53.     print("Range not broad enough to sort anything\n");
  54.     else {
  55.     Debug("Sorting %d messages starting at message %d\n", range, offset+1);
  56.  
  57.     if (setjmp(sortbuf) == 0)
  58.         qsort((char *)&msg[offset], range, sizeof (struct msg), how);
  59.     else
  60.         print("WARNING: Sorting interrupted: unpredictable order.\n");
  61.     turnon(glob_flags, DO_UPDATE);
  62.     }
  63.     turnoff(glob_flags, IGN_SIGS);
  64.     off_intr();
  65.     /* Break pipes because message lists are invalid */
  66.     return 0 - in_pipe();
  67. }
  68.  
  69. #ifdef MYQSORT
  70. qsort(base, len, siz, compar)
  71. register struct msg *base;
  72. int (*compar)();
  73. {
  74.      register int i, swapping;
  75.      struct msg temp;
  76.  
  77.      do  {
  78.      swapping = 0;
  79.      for (i = 0; i < len-1; ++i) {
  80.          if (compar(base+i, base+i+1) > 0) {
  81.          temp = base[i];
  82.          base[i] = base[i+1];
  83.          base[i+1] = temp;
  84.          swapping = 1;
  85.          }
  86.      }
  87.      } while (swapping);
  88. }
  89. #endif /* MYSORT */
  90.  
  91. status_cmp(msg1, msg2)
  92. register struct msg *msg1, *msg2;
  93. {
  94.     if (ison(glob_flags, WAS_INTR))
  95.     longjmp(sortbuf, 1);
  96.     if (msg1 < msg || msg2 < msg) {
  97.     wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  98.     return 0;
  99.     }
  100.     if (msg1->m_flags == msg2->m_flags)
  101.         return 0;
  102.     if (ison(msg1->m_flags, DELETE) && isoff(msg2->m_flags, DELETE))
  103.     return order;
  104.     if (isoff(msg1->m_flags, DELETE) && ison(msg2->m_flags, DELETE))
  105.     return -order;
  106.     if (isoff(msg1->m_flags, OLD) && ison(msg2->m_flags, OLD))
  107.     return -order;
  108.     if (ison(msg1->m_flags, OLD) && isoff(msg2->m_flags, OLD))
  109.     return order;
  110.     if (ison(msg1->m_flags, UNREAD) && isoff(msg2->m_flags, UNREAD))
  111.     return -order;
  112.     if (isoff(msg1->m_flags, UNREAD) && ison(msg2->m_flags, UNREAD))
  113.     return order;
  114.     if (ison(msg1->m_flags,PRESERVE) && isoff(msg2->m_flags,PRESERVE))
  115.     return -order;
  116.     if (isoff(msg1->m_flags,PRESERVE) && ison(msg2->m_flags,PRESERVE))
  117.     return order;
  118.     if (ison(msg1->m_flags,REPLIED) && isoff(msg2->m_flags,REPLIED))
  119.     return -order;
  120.     if (isoff(msg1->m_flags,REPLIED) && ison(msg2->m_flags,REPLIED))
  121.     return order;
  122.     if (ison(msg1->m_flags,SAVED) && isoff(msg2->m_flags,SAVED))
  123.     return -order;
  124.     if (isoff(msg1->m_flags,SAVED) && ison(msg2->m_flags,SAVED))
  125.     return order;
  126.  
  127.     return order;
  128. }
  129.  
  130. author_cmp(msg1, msg2)
  131. register struct msg *msg1, *msg2;
  132. {
  133.     char buf1[HDRSIZ], buf2[HDRSIZ];
  134.  
  135.     if (ison(glob_flags, WAS_INTR))
  136.     longjmp(sortbuf, 1);
  137.     if (msg1 < msg || msg2 < msg) {
  138.     wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  139.     return 0;
  140.     }
  141.     (void) reply_to(msg1 - msg, 0, buf1); /* "0" for "author only" */
  142.     (void) reply_to(msg2 - msg, 0, buf2);
  143.     Debug("author: msg %d: %s, msg %d: %s\n", msg1-msg, buf1, msg2-msg, buf2);
  144.     if (ignore_case)
  145.     return lcase_strncmp(buf1, buf2, -1) * order;
  146.     return strcmp(buf1, buf2) * order;
  147. }
  148.  
  149. /*
  150.  * Subject comparison ignoring Re:  subject_to() appends an Re: if there is
  151.  * any subject whatsoever.
  152.  */
  153. subject_cmp(msg1, msg2)
  154. register struct msg *msg1, *msg2;
  155. {
  156.     char buf1[HDRSIZ], buf2[HDRSIZ];
  157.  
  158.     if (ison(glob_flags, WAS_INTR))
  159.     longjmp(sortbuf, 1);
  160.     if (msg1 < msg || msg2 < msg) {
  161.     wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  162.     return 0;
  163.     }
  164.     (void) subject_to(msg1 - msg, buf1);
  165.     (void) subject_to(msg2 - msg, buf2);
  166.     Debug("subjects: (%d): \"%s\" (%d): \"%s\"\n", msg1-msg,buf1,msg2-msg,buf2);
  167.     if (ignore_case)
  168.     return lcase_strncmp(buf1, buf2, -1) * order;
  169.     return strcmp(buf1, buf2) * order;
  170. }
  171.  
  172. /*
  173.  * compare subject strings from two messages.
  174.  * If Re is appended, so be it -- if user wants to ignore Re: use 'R' flag.
  175.  */
  176. subj_with_re(msg1, msg2)
  177. register struct msg *msg1, *msg2;
  178. {
  179.     char buf1[HDRSIZ], buf2[HDRSIZ], *p;
  180.  
  181.     if (ison(glob_flags, WAS_INTR))
  182.     longjmp(sortbuf, 1);
  183.     if (msg1 < msg || msg2 < msg) {
  184.     wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  185.     return 0;
  186.     }
  187.     if (!(p = header_field(msg1 - msg, "subject")))
  188.     p = "";
  189.     (void) strcpy(buf1, p);
  190.     if (!(p = header_field(msg2 - msg, "subject")))
  191.     p = "";
  192.     (void) strcpy(buf2, p);
  193.     Debug("subjects: (%d): \"%s\" (%d): \"%s\"\n",
  194.     msg1-msg, buf1, msg2-msg, buf2);
  195.     if (ignore_case)
  196.     return lcase_strncmp(buf1, buf2, -1) * order;
  197.     return strcmp(buf1, buf2) * order;
  198. }
  199.  
  200. date_cmp(msg1, msg2)
  201. register struct msg *msg1, *msg2;
  202. {
  203.     if (ison(glob_flags, WAS_INTR))
  204.     longjmp(sortbuf, 1);
  205.     if (msg1 < msg || msg2 < msg) {
  206.     wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
  207.     return 0;
  208.     }
  209.     if (ison(glob_flags, DATE_RECV))
  210.     return strcmp(msg1->m_date_recv, msg2->m_date_recv) * order;
  211.     else
  212.     return strcmp(msg1->m_date_sent, msg2->m_date_sent) * order;
  213. }
  214.