home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d07xx / d0797.lha / PSUtils / psselect.c < prev    next >
C/C++ Source or Header  |  1993-01-10  |  5KB  |  211 lines

  1. /* psselect.c
  2.  * AJCD 27/1/91
  3.  * rearrange pages in conforming PS file for printing in signatures
  4.  *
  5.  * Usage:
  6.  *       psselect [-q] [-e] [-o] [-r] [-p<pages>] [infile [outfile]]
  7.  */
  8.  
  9. #include "psutil.h"
  10.  
  11. void usage()
  12. {
  13.    fprintf(stderr,
  14.        "Usage: %s [-q] [-e] [-o] [-r] [-p<pages>] [infile [outfile]]\n",
  15.        prog);
  16.    fflush(stderr);
  17.    exit(1);
  18. }
  19.  
  20. struct pgrange {
  21.    int first, last;
  22.    struct pgrange *next;
  23. };
  24.  
  25. typedef struct pgrange range;
  26.  
  27. range * makerange(beg, end, next)
  28.      int beg, end;
  29.      range *next;
  30. {
  31.    range *new;
  32.    if ((new = (range *)malloc(sizeof(range))) == NULL) {
  33.       fprintf(stderr, "%s: out of memory\n", prog);
  34.       fflush(stderr);
  35.       exit(1);
  36.    }
  37.    new->first = beg;
  38.    new->last = end;
  39.    new->next = next;
  40.    return (new);
  41. }
  42.  
  43. range * mergerange(beg, end, curr)
  44.      int beg, end;
  45.      range *curr;
  46. {
  47.    if (curr) {
  48.       range *this, *prev;
  49.       for (this=prev=curr; this; prev=this, this=this->next) {
  50.      int lo = (beg < curr->first) ? -1 : (beg > curr->last) ? 1 : 0;
  51.      int hi = (end < curr->first) ? -1 : (end > curr->last) ? 1 : 0;
  52.      if (hi < 0)
  53.         return (makerange(beg, end, curr));
  54.      else if (lo <= 0) { /* beginning of range */
  55.         if (lo < 0)
  56.            this->first = beg;
  57.         if (hi > 0) {
  58.            while (this->next && this->next->first <= end) {
  59.           range *eaten = this->next;
  60.           this->next = eaten->next;
  61.           if (eaten->last > end)
  62.              end = eaten->last;
  63.           free(eaten);
  64.            }
  65.            this->last = end;
  66.         }  /* else range included; no change */
  67.         return (curr);
  68.      }
  69.       }
  70.       prev->next = makerange(beg, end, NULL);
  71.       return (curr);
  72.    } else return (makerange(beg, end, NULL));
  73. }
  74.  
  75.  
  76. range * addrange(str, rp)
  77.      char *str;
  78.      range *rp;
  79. {
  80.    int first=0;
  81.    if (isdigit(*str)) {
  82.       first = atoi(str);
  83.       while (isdigit(*str)) str++;
  84.    }
  85.    switch (*str) {
  86.    case '\0':
  87.       if (first)
  88.      return (mergerange(first, first, rp));
  89.       break;
  90.    case ',':
  91.       if (first)
  92.      return (addrange(str+1, mergerange(first, first, rp)));
  93.       break;
  94.    case '-':
  95.    case ':':
  96.       str++;
  97.       if (isdigit(*str)) {
  98.      int last = atoi(str);
  99.      while (isdigit(*str)) str++;
  100.      if (!first)
  101.         first = 1;
  102.      if (last >= first) 
  103.         switch (*str) {
  104.         case '\0':
  105.            return (mergerange(first, last, rp));
  106.         case ',':
  107.            return (addrange(str+1, mergerange(first, last, rp)));
  108.         }
  109.       } else if (*str == '\0')
  110.      return (mergerange(first, MAXPAGES, rp));
  111.    }
  112.    fprintf(stderr, "%s: invalid page range\n", prog);
  113.    fflush(stderr);
  114.    exit(1);
  115. }
  116.  
  117.  
  118. int selectpage(page, even, odd, rp)
  119.      int page, even, odd;
  120.      range *rp;
  121. {
  122.    if (page&1) {
  123.       if (odd) return (1);
  124.    } else {
  125.       if (even) return (1);
  126.    }
  127.    while (rp) {
  128.       if (page >= rp->first) {
  129.      if (page <= rp->last)
  130.         return (1);
  131.       } else return (0);
  132.       rp = rp->next;
  133.    }
  134.    return (0);
  135. }
  136.  
  137.  
  138. main(argc, argv)
  139.      int argc;
  140.      char *argv[];
  141. {
  142.    int currentpg, maxpage = 0;
  143.    int even = 0, odd = 0, all = 1, reverse = 0;
  144.    range *pagerange = NULL;
  145.  
  146.    infile = stdin;
  147.    outfile = stdout;
  148.    verbose = 1;
  149.    for (prog = *argv++; --argc; argv++) {
  150.       if (argv[0][0] == '-') {
  151.      switch (argv[0][1]) {
  152.      case 'e':
  153.         even = 1; all = 0;
  154.         break;
  155.      case 'o':
  156.         odd = 1; all = 0; 
  157.         break;
  158.      case 'r':
  159.         reverse = 1;
  160.         break;
  161.      case 'p':
  162.         pagerange = addrange(*argv+2, pagerange); all = 0;
  163.         break;
  164.      case 'q':
  165.         verbose = 0;
  166.         break;
  167.      default:
  168.         usage();
  169.      }
  170.       } else if (infile == stdin) {
  171.      if ((infile = fopen(*argv, "r")) == NULL) {
  172.         fprintf(stderr, "%s: can't open input file %s\n", prog, *argv);
  173.         fflush(stderr);
  174.         exit(1);
  175.      }
  176.       } else if (outfile == stdout) {
  177.      if ((outfile = fopen(*argv, "w")) == NULL) {
  178.         fprintf(stderr, "%s: can't open output file %s\n", prog, *argv);
  179.         fflush(stderr);
  180.         exit(1);
  181.      }
  182.       } else usage();
  183.    }
  184.    if ((infile=seekable(infile))==NULL) {
  185.       fprintf(stderr, "%s: can't seek input\n", prog);
  186.       fflush(stderr);
  187.       exit(1);
  188.    }
  189.    scanpages();
  190.  
  191.    for (currentpg = 1; currentpg <= pages; currentpg++)
  192.       if (selectpage(currentpg, even || all, odd || all, pagerange))
  193.      maxpage++;
  194.  
  195.    /* select pages */
  196.    writeheader(maxpage);
  197.    writeprolog();
  198.    if (reverse) {
  199.       for (currentpg = pages; currentpg > 0; currentpg--)
  200.      if (selectpage(currentpg, even || all, odd || all, pagerange))
  201.         writepage(currentpg-1);
  202.    } else {
  203.       for (currentpg = 1; currentpg <= pages; currentpg++)
  204.      if (selectpage(currentpg, even || all, odd || all, pagerange))
  205.         writepage(currentpg-1);
  206.    }
  207.    writetrailer();
  208.  
  209.    exit(0);
  210. }
  211.