home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / c / snippets / pr.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  9KB  |  274 lines

  1. /*
  2.       This program is similar to a program of the same name found on UNIX.
  3.       It prints the files named in the command tail with headings
  4.       except as modified below.
  5.  
  6.       usage: pr [-i -ln -on -pname -tn -wn] file1[ file2 ... filen]
  7.       where:      -i     = accept files from stdin
  8.                   -ln    = set lines per page to n
  9.                   -on    = set page offset to n
  10.                   -pname = output to file <name>
  11.                   -tn    = set tabs to n cols
  12.                   -wn    = set page width to n
  13.  
  14.       note: the expr 'PAGE(mesg)' found in col 1 will cause a formfeed
  15.                   and the 'mesg' to be included in the title line on this and
  16.                   each subsequent page until EOF or another PAGE.
  17. */
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <time.h>
  23. #include "getopts.h"                            /* Also in SNIPPETS     */
  24.  
  25. #define TAB_DEFAULT 4
  26. #define PAGE_LENGTH 60
  27. #define PAGE_OFFSET 0
  28. #define PAGE_WIDTH      80
  29. #define MAX_ARGS    70
  30. #define MAX_FILES 64
  31. #define PATH_LENGTH 63
  32. #define PAGE(head)
  33.  
  34.  
  35. int       page_length = PAGE_LENGTH;
  36. int       page_offset = PAGE_OFFSET;
  37. int       page_width  = PAGE_WIDTH;
  38. int       tab_width   = TAB_DEFAULT;
  39. Boolean_T read_stdin  = FALSE;
  40.  
  41. char      print_name[FILENAME_MAX] = "PRN";
  42. char      filenames[MAX_FILES] [FILENAME_MAX];
  43.  
  44. struct Option_Tag options[] = {
  45.       {'I',  Boolean_Tag, &read_stdin  },       /* Valid options        */
  46.       {'i',  Boolean_Tag, &read_stdin  },
  47.       {'L',  Word_Tag,    &page_length },
  48.       {'l',  Word_Tag,    &page_length },
  49.       {'O',  Word_Tag,    &page_offset },
  50.       {'o',  Word_Tag,    &page_offset },
  51.       {'T',  Word_Tag,    &tab_width   },
  52.       {'t',  Word_Tag,    &tab_width   },
  53.       {'W',  Word_Tag,    &page_width  },
  54.       {'w',  Word_Tag,    &page_width  },
  55.       {'P',  String_Tag,   print_name  },
  56.       {'p',  String_Tag,   print_name  },
  57.       {'\0', ERROR,        NULL  }              /* Terminating record   */
  58. };
  59.  
  60. char title[80];
  61. char Date[20];
  62. char Time[20];
  63. int  ln, pn;
  64.  
  65. PAGE (MAIN)
  66. main(int argc, char *argv[])  /* copy file to printer */
  67. {
  68.       FILE *file, *lp;
  69.       int fi;
  70.       int pn;
  71.       char *cp;
  72.  
  73.       if (argc < 2) /* No args so tell 'em how it works */
  74.       {
  75.             fprintf(stderr,
  76.             "usage:\n\npr %s %s\n\n",
  77.             "[-i] [-lnn] [-onn] [-p<name>] [-tn] [-wnn]",
  78.             "[file1[ file2 ... filen]]");
  79.             fprintf(stderr,
  80.             "where: i = read 'stdin' for filenames to print\n");
  81.             fprintf(stderr,
  82.             "       l = lines-per-page and nn <= 120\n");
  83.             fprintf(stderr,
  84.             "       o = page offset    and nn <= 120\n");
  85.             fprintf(stderr,
  86.             "       p = print redirection and\n");
  87.             fprintf(stderr,
  88.             "           <name> = pathname or devicename\n");
  89.             fprintf(stderr,
  90.             "       t = spaces-per-tab and n  <= 8\n");
  91.             fprintf(stderr,
  92.             "       w = page width     and nn <= 160\n\n");
  93.             fprintf(stderr,
  94.             "Notes: PAGE(<title text of any length>) in col 1 of text file\n");
  95.             fprintf(stderr,
  96.             "       and <title text...> the title you want.\n\n");
  97.             fprintf(stderr,
  98.             "       C pgms should include the following macro:\n\n");
  99.             fprintf(stderr,
  100.             "            #define PAGE(title)\n\n");
  101.             fprintf(stderr,
  102.             "       < and > not required and should not be used\n\n");
  103.             exit(0);
  104.       }
  105.       
  106.       if (ERROR == getopts(argc, argv))
  107.             return 1;
  108.       
  109.       if ((page_length <= 0) || (page_length > 120))
  110.             page_length = PAGE_LENGTH;
  111.  
  112.       if ((tab_width <= 0) || (tab_width > 8))
  113.             tab_width = TAB_DEFAULT;
  114.  
  115.       if ((page_offset < 0) || (page_offset > 120))
  116.             page_offset = PAGE_OFFSET;
  117.  
  118.       if ((page_width <= 0) || (page_width > 160))
  119.             page_width = PAGE_WIDTH;
  120.  
  121.       for (fi = 0, pn = 1; pn < xargc; ++fi, ++pn)
  122.       {
  123.             if (fi < MAX_FILES)
  124.                   strcpy(filenames[fi], xargv[pn]);
  125.             else
  126.             {
  127.                   fprintf(stderr, "pr: "
  128.                         "Exceeded maximum file capacity\n");
  129.                   break;
  130.             }
  131.       }
  132.  
  133.       if ((lp = fopen(print_name, "w")) == 0)
  134.       {
  135.             fprintf(stderr, "pr: Unable to open %s as output\n", print_name);
  136.             exit(1);
  137.       }
  138.  
  139.       if (read_stdin)
  140.       {
  141.             for(;;)
  142.             {
  143.                   if (fi == MAX_FILES)
  144.                   {
  145.                         fputs("pr: Exceeded maximum file capacity\n",
  146.                               stderr);
  147.                         break;
  148.                   }
  149.                   cp = fgets(filenames [fi], FILENAME_MAX, stdin);
  150.                   if (!cp)
  151.                         break;
  152.                   else  fi++;
  153.             }
  154.       }
  155.       /* now print each file */
  156.  
  157.       for (pn = 0; pn < fi; pn++)
  158.             prt(filenames [pn], lp);  /* print the file */
  159. }
  160. PAGE (NEW PAGE)
  161.  
  162. new_page (char *fnp, FILE *lp)
  163. {
  164.       if (ln < 3)
  165.             return;
  166.       ++pn;
  167.       if (pn > 1)
  168.             fputc('\f', lp);
  169.       fprintf(lp, "%s    %s %s    PAGE %d:  %s\n\n",
  170.                    fnp, Date, Time, pn, title);
  171.       ln = 2;
  172. }
  173.  
  174. PAGE (PRINT FILE)
  175. prt (char fnp[], FILE *lp)
  176. {
  177.       FILE *inp_file;
  178.       int i, j, col;
  179.       char line [256], *st, *et, *sp;
  180.       time_t now;
  181.       struct tm *tnow;
  182.  
  183.       inp_file = fopen(fnp, "r");
  184.       if (!inp_file)
  185.       {
  186.             fprintf(stderr, "pr: unable to open %s\n", fnp);
  187.             return;
  188.       }
  189.       else
  190.             fprintf(stderr, "pr: printing %s\n", fnp);
  191.  
  192.       pn = 0;
  193.       ln = 999;
  194.       now  = time(&now);
  195.       tnow = localtime(&now);
  196.       strftime(Date, 19, "%a %d %b %Y", tnow);
  197.       strftime(Time, 19, "%I:%M %PM", tnow);
  198.       *title = '\0';
  199.  
  200.       while (fgets(line, 256, inp_file))
  201.       {
  202.             if (strncmp(line, "PAGE", 4) == 0)
  203.             {
  204.                   if (NULL != (st = strchr(line, '(')))
  205.                   {
  206.                         et = strchr(line, ')');
  207.                         strncpy(title, st + 1, (et) ? et - st - 1 : 160);
  208.                   }
  209.                   ln = 999;
  210.             }
  211.  
  212.             if (ln > page_length)
  213.                   new_page(fnp, lp);
  214.  
  215.             if (page_offset)
  216.                   indent(lp);
  217.  
  218.             for (col = (page_offset) ? page_offset : 1, sp = &line[0];
  219.                    *sp; sp++)
  220.             {
  221.                   switch (*sp)
  222.                   {
  223.                   case '\t':  /* tab character */
  224.                         do
  225.                         {
  226.                               fputc(' ', lp);
  227.                               col++;
  228.                               if (col > page_width)
  229.                               {
  230.                                     fputc('\n', lp);
  231.                                     col = (page_offset) ? page_offset : 1;
  232.                                     ln++;
  233.                                     if (ln > page_length)
  234.                                           new_page(fnp, lp);
  235.                                     if (page_offset)
  236.                                           indent(lp);
  237.                                     break;
  238.                               }
  239.                         } while ((col - 1) % tab_width);
  240.                         break;
  241.  
  242.                   case '\f':  /* form feed character */
  243.                         new_page(fnp, lp);
  244.                         break;
  245.  
  246.                   default:
  247.                         fputc(*sp, lp);
  248.                         ++col;
  249.                         if (col > page_width)
  250.                         {
  251.                               fputc('\n', lp);
  252.                               col = (page_offset) ? page_offset - 1 : 0;
  253.                               ln++;
  254.                               if (ln > page_length)
  255.                                     new_page(fnp, lp);
  256.                               if (page_offset)
  257.                                     indent(lp);
  258.                         }
  259.                   }
  260.             } /* of line print (for) */
  261.             ++ln;
  262.       } /* of while not eof */
  263.       fclose(inp_file);
  264.       fputc(014, lp);
  265. } /* of print */
  266.  
  267. indent(FILE *lp)
  268. {
  269.       int i;
  270.  
  271.       for(i = 1; i < page_offset; i++)
  272.             fputc(' ', lp);
  273. }
  274.