home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / pr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-05-05  |  5.8 KB  |  423 lines

  1. /*
  2.  *   print file with headings
  3.  *  2+head+2+page[56]+5
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <signal.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10.  
  11. int    ncol    = 1;
  12. char    *header;
  13. int    col;
  14. int    icol;
  15. FILE    *file;
  16. char    *bufp;
  17. #define    BUFS    6720
  18. char    buffer[BUFS];    /* for multi-column output */
  19. char    obuf[BUFSIZ];
  20. #define    FF    014
  21. int    line;
  22. char    *colp[72];
  23. int    nofile;
  24. char    isclosed[10];
  25. FILE    *ifile[10];
  26. char    **lastarg;
  27. int    peekc;
  28. int    fpage;
  29. int    page;
  30. int    colw;
  31. int    nspace;
  32. int    width    = 72;
  33. int    length    = 66;
  34. int    plength = 61;
  35. int    margin    = 10;
  36. int    ntflg;
  37. int    mflg;
  38. int    tabc;
  39. char    *tty;
  40. int    mode;
  41. char    *ttyname();
  42. char    *ctime();
  43.  
  44. main(argc, argv)
  45. char **argv;
  46. {
  47.     int nfdone;
  48.     int onintr();
  49.  
  50.     setbuf(stdout, obuf);
  51.     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  52.         signal(SIGINT, onintr);
  53.     lastarg = &argv[argc-1];
  54.     fixtty();
  55.     for (nfdone=0; argc>1; argc--) {
  56.         argv++;
  57.         if (**argv == '-') {
  58.             switch (*++*argv) {
  59.             case 'h':
  60.                 if (argc>=2) {
  61.                     header = *++argv;
  62.                     argc--;
  63.                 }
  64.                 continue;
  65.  
  66.             case 't':
  67.                 ntflg++;
  68.                 continue;
  69.  
  70.             case 'l':
  71.                 length = atoi(++*argv);
  72.                 continue;
  73.  
  74.             case 'w':
  75.                 width = atoi(++*argv);
  76.                 continue;
  77.  
  78.             case 's':
  79.                 if (*++*argv)
  80.                     tabc = **argv;
  81.                 else
  82.                     tabc = '\t';
  83.                 continue;
  84.  
  85.             case 'm':
  86.                 mflg++;
  87.                 continue;
  88.  
  89.             default:
  90.                 ncol = atoi(*argv);
  91.                 continue;
  92.             }
  93.         } else if (**argv == '+') {
  94.             fpage = atoi(++*argv);
  95.         } else {
  96.             print(*argv, argv);
  97.             nfdone++;
  98.             if (mflg)
  99.                 break;
  100.         }
  101.     }
  102.     if (nfdone==0)
  103.         print((char *)0, (char **)0);
  104.     done();
  105. }
  106.  
  107. done()
  108. {
  109.  
  110.     if (tty)
  111.         chmod(tty, mode);
  112.     exit(0);
  113. }
  114.  
  115. onintr()
  116. {
  117.  
  118.     if (tty)
  119.         chmod(tty, mode);
  120.     _exit(1);
  121. }
  122.  
  123. fixtty()
  124. {
  125.     struct stat sbuf;
  126.  
  127.     tty = ttyname(1);
  128.     if (tty == 0)
  129.         return;
  130.     stat(tty, &sbuf);
  131.     mode = sbuf.st_mode&0777;
  132.     chmod(tty, 0600);
  133. }
  134.  
  135. print(fp, argp)
  136. char *fp;
  137. char **argp;
  138. {
  139.     extern char *sprintf();
  140.     struct stat sbuf;
  141.     register sncol;
  142.     register char *sheader;
  143.     register char *cbuf;
  144.     char linebuf[150], *cp;
  145.  
  146.     if (ntflg)
  147.         margin = 0;
  148.     else
  149.         margin = 10;
  150.     if (length <= margin)
  151.         length = 66;
  152.     if (width <= 0)
  153.         width = 72;
  154.     if (ncol>72 || ncol>width) {
  155.         fprintf(stderr, "pr: No room for columns.\n");
  156.         done();
  157.     }
  158.     if (mflg) {
  159.         mopen(argp);
  160.         ncol = nofile;
  161.     }
  162.     colw = width/ncol;
  163.     sncol = ncol;
  164.     sheader = header;
  165.     plength = length-5;
  166.     if (ntflg)
  167.         plength = length;
  168.     if (--ncol<0)
  169.         ncol = 0;
  170.     if (mflg)
  171.         fp = 0;
  172.     if (fp) {
  173.         if((file=fopen(fp, "r"))==NULL) {
  174.             if (tty==NULL)
  175.                 fprintf(stderr, "pr: can't open %s\n", fp);
  176.             ncol = sncol;
  177.             header = sheader;
  178.             return;
  179.         }
  180.         stat(fp, &sbuf);
  181.     } else {
  182.         file = stdin;
  183.         time(&sbuf.st_mtime);
  184.     }
  185.     if (header == 0)
  186.         header = fp?fp:"";
  187.     cbuf = ctime(&sbuf.st_mtime);
  188.     cbuf[16] = '\0';
  189.     cbuf[24] = '\0';
  190.     page = 1;
  191.     icol = 0;
  192.     colp[ncol] = bufp = buffer;
  193.     if (mflg==0)
  194.         nexbuf();
  195.     while (mflg&&nofile || (!mflg)&&tpgetc(ncol)>0) {
  196.         if (mflg==0) {
  197.             colp[ncol]--;
  198.             if (colp[ncol] < buffer)
  199.                 colp[ncol] = &buffer[BUFS];
  200.         }
  201.         line = 0;
  202.         if (ntflg==0) {
  203.             sprintf(linebuf, "\n\n%s %s  %s Page %d\n\n\n",
  204.                 cbuf+4, cbuf+20, header, page);
  205.             for(cp=linebuf;*cp;) put(*cp++);
  206.         }
  207.         putpage();
  208.         if (ntflg==0)
  209.             while(line<length)
  210.                 put('\n');
  211.         page++;
  212.     }
  213.     fclose(file);
  214.     ncol = sncol;
  215.     header = sheader;
  216. }
  217.  
  218. mopen(ap)
  219. char **ap;
  220. {
  221.     register char **p, *p1;
  222.  
  223.     p = ap;
  224.     while((p1 = *p) && p++ <= lastarg) {
  225.         if((ifile[nofile]=fopen(p1, "r")) == NULL){
  226.             isclosed[nofile] = 1;
  227.             nofile--;
  228.         }
  229.         else
  230.             isclosed[nofile] = 0;
  231.         if(++nofile>=10) {
  232.             fprintf(stderr, "pr: Too many args\n");
  233.             done();
  234.         }
  235.     }
  236. }
  237.  
  238. putpage()
  239. {
  240.     register int lastcol, i, c;
  241.     int j;
  242.  
  243.     if (ncol==0) {
  244.         while (line<plength) {
  245.             while((c = tpgetc(0)) && c!='\n' && c!=FF)
  246.                 putcp(c);
  247.             putcp('\n');
  248.             line++;
  249.             if (c==FF)
  250.                 break;
  251.         }
  252.         return;
  253.     }
  254.     colp[0] = colp[ncol];
  255.     if (mflg==0) for (i=1; i<=ncol; i++) {
  256.         colp[i] = colp[i-1];
  257.         for (j = margin; j<length; j++)
  258.             while((c=tpgetc(i))!='\n')
  259.                 if (c==0)
  260.                     break;
  261.     }
  262.     while (line<plength) {
  263.         lastcol = colw;
  264.         for (i=0; i<ncol; i++) {
  265.             while ((c=pgetc(i)) && c!='\n')
  266.                 if (col<lastcol || tabc!=0)
  267.                     put(c);
  268.             if (c==0)
  269.                 continue;
  270.             if (tabc)
  271.                 put(tabc);
  272.             else while (col<lastcol)
  273.                 put(' ');
  274.             lastcol += colw;
  275.         }
  276.         while ((c = pgetc(ncol)) && c!='\n')
  277.             put(c);
  278.         put('\n');
  279.     }
  280. }
  281.  
  282. nexbuf()
  283. {
  284.     register int n;
  285.     register char *rbufp;
  286.  
  287.     rbufp = bufp;
  288.     n = &buffer[BUFS] - rbufp;
  289.     if (n>512)
  290.         n = 512;
  291.     if(feof(file) ||
  292.        (n=fread(rbufp,1,n,file)) <= 0){
  293.         fclose(file);
  294.         *rbufp = 0376;
  295.     }
  296.     else {
  297.         rbufp += n;
  298.         if (rbufp >= &buffer[BUFS])
  299.             rbufp = buffer;
  300.         *rbufp = 0375;
  301.     }
  302.     bufp = rbufp;
  303. }
  304.  
  305. tpgetc(ai)
  306. {
  307.     register char **p;
  308.     register int c, i;
  309.  
  310.     i = ai;
  311.     if (mflg) {
  312.         if((c=getc(ifile[i])) == EOF) {
  313.             if (isclosed[i]==0) {
  314.                 isclosed[i] = 1;
  315.                 if (--nofile <= 0)
  316.                     return(0);
  317.             }
  318.             return('\n');
  319.         }
  320.         if (c==FF && ncol>0)
  321.             c = '\n';
  322.         return(c);
  323.     }
  324. loop:
  325.     c = **(p = &colp[i]) & 0377;
  326.     if (c == 0375) {
  327.         nexbuf();
  328.         c = **p & 0377;
  329.     }
  330.     if (c == 0376)
  331.         return(0);
  332.     (*p)++;
  333.     if (*p >= &buffer[BUFS])
  334.         *p = buffer;
  335.     if (c==0)
  336.         goto loop;
  337.     return(c);
  338. }
  339.  
  340. pgetc(i)
  341. {
  342.     register int c;
  343.  
  344.     if (peekc) {
  345.         c = peekc;
  346.         peekc = 0;
  347.     } else
  348.         c = tpgetc(i);
  349.     if (tabc)
  350.         return(c);
  351.     switch (c) {
  352.  
  353.     case '\t':
  354.         icol++;
  355.         if ((icol&07) != 0)
  356.             peekc = '\t';
  357.         return(' ');
  358.  
  359.     case '\n':
  360.         icol = 0;
  361.         break;
  362.  
  363.     case 010:
  364.     case 033:
  365.         icol--;
  366.         break;
  367.     }
  368.     if (c >= ' ')
  369.         icol++;
  370.     return(c);
  371. }
  372. put(ac)
  373. {
  374.     register int ns, c;
  375.  
  376.     c = ac;
  377.     if (tabc) {
  378.         putcp(c);
  379.         if (c=='\n')
  380.             line++;
  381.         return;
  382.     }
  383.     switch (c) {
  384.  
  385.     case ' ':
  386.         nspace++;
  387.         col++;
  388.         return;
  389.  
  390.     case '\n':
  391.         col = 0;
  392.         nspace = 0;
  393.         line++;
  394.         break;
  395.  
  396.     case 010:
  397.     case 033:
  398.         if (--col<0)
  399.             col = 0;
  400.         if (--nspace<0)
  401.             nspace = 0;
  402.  
  403.     }
  404.     while(nspace) {
  405.         if (nspace>2 && col > (ns=((col-nspace)|07))) {
  406.             nspace = col-ns-1;
  407.             putcp('\t');
  408.         } else {
  409.             nspace--;
  410.             putcp(' ');
  411.         }
  412.     }
  413.     if (c >= ' ')
  414.         col++;
  415.     putcp(c);
  416. }
  417.  
  418. putcp(c)
  419. {
  420.     if (page >= fpage)
  421.         putchar(c);
  422. }
  423.