home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume39 / psutils / part02 / psselect.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-20  |  5.2 KB  |  229 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. #include "patchlevel.h"
  11.  
  12. void usage()
  13. {
  14.    fprintf(stderr, "%s release %d patchlevel %d\n", prog, RELEASE, PATCHLEVEL);
  15.    fprintf(stderr,
  16.        "Usage: %s [-q] [-e] [-o] [-r] [-p<pages>] [infile [outfile]]\n",
  17.        prog);
  18.    fflush(stderr);
  19.    exit(1);
  20. }
  21.  
  22. struct pgrange {
  23.    int first, last;
  24.    struct pgrange *next;
  25. };
  26.  
  27. typedef struct pgrange range;
  28.  
  29. range * makerange(beg, end, next)
  30.      int beg, end;
  31.      range *next;
  32. {
  33.    range *new;
  34.    if ((new = (range *)malloc(sizeof(range))) == NULL) {
  35.       fprintf(stderr, "%s: out of memory\n", prog);
  36.       fflush(stderr);
  37.       exit(1);
  38.    }
  39.    new->first = beg;
  40.    new->last = end;
  41.    new->next = next;
  42.    return (new);
  43. }
  44.  
  45.  
  46. range * addrange(str, rp)
  47.      char *str;
  48.      range *rp;
  49. {
  50.    int first=0;
  51.    int sign;
  52.    sign = (*str == '_' && ++str) ? -1 : 1;
  53.    if (isdigit(*str)) {
  54.       first = sign*atoi(str);
  55.       while (isdigit(*str)) str++;
  56.    }
  57.    switch (*str) {
  58.    case '\0':
  59.       if (first)
  60.      return (makerange(first, first, rp));
  61.       break;
  62.    case ',':
  63.       if (first)
  64.      return (addrange(str+1, makerange(first, first, rp)));
  65.       break;
  66.    case '-':
  67.    case ':':
  68.       str++;
  69.       sign = (*str == '_' && ++str) ? -1 : 1;
  70.       if (isdigit(*str)) {
  71.      int last = sign*atoi(str);
  72.      while (isdigit(*str)) str++;
  73.      if (!first)
  74.         first = 1;
  75.      if (last >= first) 
  76.         switch (*str) {
  77.         case '\0':
  78.            return (makerange(first, last, rp));
  79.         case ',':
  80.            return (addrange(str+1, makerange(first, last, rp)));
  81.         }
  82.       } else if (*str == '\0')
  83.      return (makerange(first, -1, rp));
  84.       else if (*str == ',')
  85.      return (addrange(str+1, makerange(first, -1, rp)));
  86.    }
  87.    fprintf(stderr, "%s: invalid page range\n", prog);
  88.    fflush(stderr);
  89.    exit(1);
  90. }
  91.  
  92.  
  93. main(argc, argv)
  94.      int argc;
  95.      char *argv[];
  96. {
  97.    int currentpg, maxpage = 0;
  98.    int even = 0, odd = 0, reverse = 0;
  99.    int pass, all;
  100.    range *pagerange = NULL;
  101.  
  102.    infile = stdin;
  103.    outfile = stdout;
  104.    verbose = 1;
  105.    for (prog = *argv++; --argc; argv++) {
  106.       if (argv[0][0] == '-') {
  107.      switch (argv[0][1]) {
  108.      case 'e':    /* even pages */
  109.         even = 1;
  110.         break;
  111.      case 'o':    /* odd pages */
  112.         odd = 1;
  113.         break;
  114.      case 'r':    /* reverse */
  115.         reverse = 1;
  116.         break;
  117.      case 'p':    /* page spec */
  118.         pagerange = addrange(*argv+2, pagerange);
  119.         break;
  120.      case 'q':    /* quiet */
  121.         verbose = 0;
  122.         break;
  123.      case 'v':    /* version */
  124.      default:
  125.         usage();
  126.      }
  127.       } else if (pagerange == NULL && !reverse && !even && !odd) {
  128.      pagerange = addrange(*argv, NULL);
  129.       } else if (infile == stdin) {
  130.      if ((infile = fopen(*argv, "r")) == NULL) {
  131.         fprintf(stderr, "%s: can't open input file %s\n", prog, *argv);
  132.         fflush(stderr);
  133.         exit(1);
  134.      }
  135.       } else if (outfile == stdout) {
  136.      if ((outfile = fopen(*argv, "w")) == NULL) {
  137.         fprintf(stderr, "%s: can't open output file %s\n", prog, *argv);
  138.         fflush(stderr);
  139.         exit(1);
  140.      }
  141.       } else usage();
  142.    }
  143.    if ((infile=seekable(infile))==NULL) {
  144.       fprintf(stderr, "%s: can't seek input\n", prog);
  145.       fflush(stderr);
  146.       exit(1);
  147.    }
  148.    scanpages();
  149.  
  150.    /* reverse page list if not reversing pages (list constructed bottom up) */
  151.    if (!reverse) {
  152.       range *revlist = NULL;
  153.       range *next = NULL;
  154.       while (pagerange) {
  155.      next = pagerange->next;
  156.      pagerange->next = revlist;
  157.      revlist = pagerange;
  158.      pagerange = next;
  159.       }
  160.       pagerange = revlist;
  161.    }
  162.  
  163.    /* select all pages or all in range if odd or even not set */
  164.    all = !(odd || even);
  165.  
  166.    /* count pages on first pass, select pages on second pass */
  167.    for (pass = 0; pass < 2; pass++) {
  168.       if (pass) {                           /* write header on second pass */
  169.      writeheader(maxpage);
  170.      writeprolog("");
  171.       }
  172.       if (pagerange) {
  173.      range *r;
  174.      for (r = pagerange; r; r = r->next) {
  175.         if (pagerange->first < 0) {
  176.            pagerange->first += pages + 1;
  177.            if (pagerange->first < 0)
  178.           pagerange->first = 0;
  179.         }
  180.         if (pagerange->last < 0) {
  181.            pagerange->last += pages + 1;
  182.            if (pagerange->last < 0)
  183.           pagerange->last = 0;
  184.         }
  185.         if (reverse) {
  186.            for (currentpg = r->last; currentpg >= r->first; currentpg--) {
  187.           if (currentpg <= pages &&
  188.               ((currentpg&1) ? (odd || all) : (even || all))) {
  189.              if (pass)
  190.             writepage(currentpg-1);
  191.              else
  192.             maxpage++;
  193.           }
  194.            }
  195.         } else {
  196.            for (currentpg = r->first; currentpg <= r->last; currentpg++) {
  197.           if (currentpg <= pages &&
  198.               ((currentpg&1) ? (odd || all) : (even || all))) {
  199.              if (pass)
  200.             writepage(currentpg-1);
  201.              else
  202.             maxpage++;
  203.           }
  204.            }
  205.         }
  206.      }
  207.       } else if (reverse) {
  208.      for (currentpg = pages; currentpg > 0; currentpg--)
  209.         if ((currentpg&1) ? (odd || all) : (even || all)) {
  210.            if (pass)
  211.           writepage(currentpg-1);
  212.            else
  213.           maxpage++;
  214.         }
  215.       } else {
  216.      for (currentpg = 1; currentpg <= pages; currentpg++)
  217.         if ((currentpg&1) ? (odd || all) : (even || all)) {
  218.            if (pass)
  219.           writepage(currentpg-1);
  220.            else
  221.           maxpage++;
  222.         }
  223.       }
  224.    }
  225.    writetrailer();
  226.  
  227.    exit(0);
  228. }
  229.