home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 154_01 / pr.c < prev    next >
Text File  |  1979-12-31  |  4KB  |  209 lines

  1. /*
  2.     pr.c:  detabbing file printer -
  3.  
  4.         usage:  pr [-l] [-n#] [-t#] [-h] [file1] file2] ...
  5.         options:
  6.                 -l        print with line numbers
  7.                 -n#        print # lines per page (4-line header xtra)
  8.                 -t#        set tab to # spaces (default 4)
  9.                 -h        do not print a page header
  10.         Wildcards, drives, and paths are all processed correctly.
  11.  
  12.         Adapted from Software Tools by Chuck Allison - Apr 1985
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <ctype.h>
  17. #include <time.h>
  18.  
  19. #define MAXLINE 256
  20. #define MAXFILES 150
  21. #define yes 1
  22. #define no 0
  23.  
  24. /* ..set default parameters.. */
  25. int number = no,
  26.     lines_per_page = 55,
  27.     tabspace = 4,
  28.     headers = yes;
  29.  
  30. /* ..date and time definitions.. */
  31. unsigned mon,
  32.     day,
  33.     year,
  34.     hour,
  35.     min,
  36.     sec;
  37.  
  38. char datestr[13],
  39.     timestr[6],
  40.     weekday[4],
  41.     am_pm[3];
  42.  
  43. int tabstops[MAXLINE];
  44.  
  45. main(argc,argv)
  46. int argc;
  47. char *argv[];
  48. {
  49.     FILE *f;
  50.     int i,
  51.         xargc,                /* ..expanded arg count (after options).. */
  52.         maxarg = MAXFILES;    /* ..max allowable args after expanding.. */
  53.     char *s,
  54.         *xargv[MAXFILES];    /* ..arg vector after expanding.. */
  55.  
  56.     /* ..process switches.. */
  57.     for ( ; *(s = *(argv+1)) == '-'; ++argv, --argc)
  58.     {
  59.         while (*++s)
  60.             switch(tolower(*s))
  61.             {
  62.                 case 'l':
  63.                     number = yes;
  64.                     break;
  65.                 case 'n':
  66.                     lines_per_page = atoi(s+1);
  67.                     goto next_arg;
  68.                 case 't':
  69.                     tabspace = atoi(s+1);
  70.                     goto next_arg;
  71.                   case 'h':
  72.                     headers = no;
  73.                     break;
  74.                 default :
  75.                     fprintf(stderr,"unknown switch: -%c\n",*s);
  76.                     exit(1);
  77.             }
  78.         next_arg: /* ..cycle on outer for().. */ ;
  79.     }
  80.  
  81.     /* ..initialize tab settings.. */
  82.     settabs();
  83.  
  84.     /* ..get date and time.. */
  85.     date(&year,&mon,&day,weekday);
  86.     sprintf(datestr,"%3s %2d/%02d/%02d",weekday,mon,day,year%1900);
  87.     time(&hour,&min,&sec);
  88.     strcpy(am_pm , (hour >= 12) ? "pm" : "am");
  89.     hour = (hour == 12) ? hour : hour % 12;
  90.     sprintf(timestr,"%2d:%02d %2s",hour,min,am_pm);
  91.  
  92.     /* ..process files.. */
  93.     if (argc == 1)
  94.         pr(stdin,"");
  95.     else
  96.     {
  97.         /* ..expand filespecs.. */
  98.         xargc = exargs("",argc,argv,xargv,maxarg);
  99.  
  100.         /* ..print each file.. */
  101.         for (i = 0; i < xargc; ++i)
  102.             if ((f = fopen(xargv[i],"r")) != NULL)
  103.             {
  104.                 pr(f,xargv[i]);
  105.                 fclose(f);
  106.             }
  107.             else
  108.                 fprintf(stderr,"can't open: %s\n",xargv[i]);
  109.     }
  110. }
  111.  
  112. pr(fp, name)
  113. FILE *fp;
  114. char *name;
  115. {
  116.     int lineno, pageno, offset;
  117.     char line[MAXLINE];
  118.  
  119.     offset = 0;    /* ..# pages already printed * lines_per_page.. */
  120.     pageno = 1;
  121.     lineno = 1;
  122.     if (headers)
  123.         header(name,pageno);
  124.     else
  125.         printf("\n\n\n\n\n");
  126.  
  127.     while (fgets(line,MAXLINE-1,fp) != NULL)
  128.     {
  129.         if (lineno == 0)
  130.         {
  131.             if (headers)
  132.                 header(name,++pageno);
  133.             else
  134.                 printf("\n\n\n\n\n");
  135.             lineno = 1;
  136.         }
  137.  
  138.         /* ..print line number, if requested.. */
  139.         if (number)
  140.             printf("%8d  ",offset+lineno);
  141.         else
  142.             printf("       ");
  143.         lineno++;
  144.  
  145.         /* ..output detabbed line.. */
  146.         detab(line);
  147.  
  148.         /* ..check for page break.. */
  149.         if (lineno > lines_per_page)
  150.         {
  151.             putchar('\f');
  152.             offset += lines_per_page;
  153.             lineno = 0;
  154.         }
  155.     }
  156.     /* ..form-feed after last partial page.. */
  157.     if (lineno > 0) putchar('\f');
  158. }
  159.  
  160. header(file,page)
  161. char *file;
  162. int page;
  163. {
  164.     int i;
  165.  
  166.     printf("\n    ");
  167.     for (i = 0; i < 75; ++i)
  168.         putchar('-');
  169.     printf("\n    %s                %s       %s",
  170.       file,datestr,timestr);
  171.     for (i = 1; i < 24-strlen(file); ++i)
  172.         putchar(' ');
  173.     printf("Page %4d\n    ",page);
  174.     for (i = 0; i < 75; ++i)
  175.         putchar('-');
  176.     printf("\n\n\n");
  177. }
  178.  
  179. detab(line)
  180. char *line;
  181. {
  182.     int i, col;
  183.  
  184.     col = 1;
  185.  
  186.     /* ..note: line[] has a terminating '\n' per fgets().. */
  187.     for (i = 0; i < strlen(line); ++i)
  188.         if (line[i] == '\t')
  189.             /* ..tab.. */
  190.             do
  191.             {
  192.                 putchar(' ');
  193.                 ++col;
  194.             } while (!tabstops[col]);
  195.         else
  196.         {
  197.             putchar(line[i]);
  198.             ++col;
  199.         }
  200. }
  201.  
  202. settabs()
  203. {
  204.     int i;
  205.  
  206.     for (i = 0; i < MAXLINE; ++i)
  207.         tabstops[i] = (i % tabspace == 1);
  208. }
  209.