home *** CD-ROM | disk | FTP | other *** search
/ The UNIX CD Bookshelf / OREILLY_TUCB_UNIX_CD.iso / upt / examples / SOURCES / JOT / TOOLS.Z / TOOLS / tools / lam.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-07  |  3.9 KB  |  193 lines

  1. /* Copyright (c) 1983 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char sccsid[] = "@(#)lam.c    4.5    (Berkeley)    5/19/88";
  5. #endif not lint
  6.  
  7. /*
  8.  *    lam - laminate files
  9.  *    Author:  John Kunze, UCB
  10.  */
  11.  
  12. #include <stdio.h>
  13.  
  14. #define    MAXOFILES    20
  15. #define    BIGBUFSIZ    5 * BUFSIZ
  16.  
  17. struct    openfile {        /* open file structure */
  18.     FILE    *fp;        /* file pointer */
  19.     short    eof;        /* eof flag */
  20.     short    pad;        /* pad flag for missing columns */
  21.     char    eol;        /* end of line character */
  22.     char    *sepstring;    /* string to print before each line */
  23.     char    *format;    /* printf(3) style string spec. */
  24. }    input[MAXOFILES];
  25.  
  26. int    morefiles;        /* set by getargs(), changed by gatherline() */
  27. int    nofinalnl;        /* normally append \n to each output line */
  28. char    buf[BUFSIZ];
  29. char    line[BIGBUFSIZ];
  30. char    *linep;
  31.  
  32. main(argc, argv)
  33. int    argc;
  34. char    **argv;
  35. {
  36.     register struct    openfile    *ip;
  37.     char    *gatherline();
  38.  
  39.     setbuf(stdout, buf);
  40.     getargs(argv);
  41.     if (!morefiles)
  42.         error("lam - laminate files", "");
  43.     for (;;) {
  44.         linep = line;
  45.         for (ip = input; ip->fp != NULL; ip++)
  46.             linep = gatherline(ip);
  47.         if (!morefiles)
  48.             exit(0);
  49.         fputs(line, stdout);
  50.         fputs(ip->sepstring, stdout);
  51.         if (!nofinalnl)
  52.             putchar('\n');
  53.     }
  54. }
  55.  
  56. getargs(av)
  57. char    **av;
  58. {
  59.     register struct    openfile    *ip = input;
  60.     register char    *p;
  61.     register char    *c;
  62.     static    char    fmtbuf[BUFSIZ];
  63.     char    *fmtp = fmtbuf;
  64.     int    P, S, F, T;
  65.  
  66.     P = S = F = T = 0;        /* capitalized options */
  67.     while (p = *++av) {
  68.         if (*p != '-' || !p[1]) {
  69.             morefiles++;
  70.             if (*p == '-')
  71.                 ip->fp = stdin;
  72.             else if ((ip->fp = fopen(p, "r")) == NULL) {
  73.                 perror(p);
  74.                 exit(1);
  75.             }
  76.             ip->pad = P;
  77.             if (!ip->sepstring)
  78.                 ip->sepstring = (S ? (ip-1)->sepstring : "");
  79.             if (!ip->format)
  80.                 ip->format = ((P || F) ? (ip-1)->format : "%s");
  81.             if (!ip->eol)
  82.                 ip->eol = (T ? (ip-1)->eol : '\n');
  83.             ip++;
  84.             continue;
  85.         }
  86.         switch (*(c = ++p) | 040) {
  87.         case 's':
  88.             if (*++p || (p = *++av))
  89.                 ip->sepstring = p;
  90.             else
  91.                 error("Need string after -%s", c);
  92.             S = (*c == 'S' ? 1 : 0);
  93.             break;
  94.         case 't':
  95.             if (*++p || (p = *++av))
  96.                 ip->eol = *p;
  97.             else
  98.                 error("Need character after -%s", c);
  99.             T = (*c == 'T' ? 1 : 0);
  100.             nofinalnl = 1;
  101.             break;
  102.         case 'p':
  103.             ip->pad = 1;
  104.             P = (*c == 'P' ? 1 : 0);
  105.         case 'f':
  106.             F = (*c == 'F' ? 1 : 0);
  107.             if (*++p || (p = *++av)) {
  108.                 fmtp += strlen(fmtp) + 1;
  109.                 if (fmtp > fmtbuf + BUFSIZ)
  110.                     error("No more format space", "");
  111.                 sprintf(fmtp, "%%%ss", p);
  112.                 ip->format = fmtp;
  113.             }
  114.             else
  115.                 error("Need string after -%s", c);
  116.             break;
  117.         default:
  118.             error("What do you mean by -%s?", c);
  119.             break;
  120.         }
  121.     }
  122.     ip->fp = NULL;
  123.     if (!ip->sepstring)
  124.         ip->sepstring = "";
  125. }
  126.  
  127. char    *
  128. pad(ip)
  129. struct    openfile    *ip;
  130. {
  131.     register char    *p = ip->sepstring;
  132.     register char    *lp = linep;
  133.  
  134.     while (*p)
  135.         *lp++ = *p++;
  136.     if (ip->pad) {
  137.         sprintf(lp, ip->format, "");
  138.         lp += strlen(lp);
  139.     }
  140.     return(lp);
  141. }
  142.  
  143. char    *
  144. gatherline(ip)
  145. struct    openfile    *ip;
  146. {
  147.     char    s[BUFSIZ];
  148.     register int    c;
  149.     register char    *p;
  150.     register char    *lp = linep;
  151.     char    *end = s + BUFSIZ;
  152.  
  153.     if (ip->eof)
  154.         return(pad(ip));
  155.     for (p = s; (c = fgetc(ip->fp)) != EOF && p < end; p++)
  156.         if ((*p = c) == ip->eol)
  157.             break;
  158.     *p = '\0';
  159.     if (c == EOF) {
  160.         ip->eof = 1;
  161.         if (ip->fp == stdin)
  162.             fclose(stdin);
  163.         morefiles--;
  164.         return(pad(ip));
  165.     }
  166.     p = ip->sepstring;
  167.     while (*p)
  168.         *lp++ = *p++;
  169.     sprintf(lp, ip->format, s);
  170.     lp += strlen(lp);
  171.     return(lp);
  172. }
  173.  
  174. error(msg, s)
  175. char    *msg;
  176. char    *s;
  177. {
  178.     char    buf[BUFSIZ];
  179.  
  180.     setbuf(stderr, buf);
  181.     fprintf(stderr, "lam: ");
  182.     fprintf(stderr, msg, s);
  183.     fprintf(stderr, "\nUsage:  lam [ -[fp] min.max ] [ -s sepstring ] [ -t c ] file ...\n");
  184.     if (strncmp("lam - ", msg, 6) == 0)
  185.         fprintf(stderr, "Options:\n\t%s\t%s\t%s\t%s\t%s",
  186.             "-f min.max    field widths for file fragments\n",
  187.             "-p min.max    like -f, but pad missing fragments\n",
  188.             "-s sepstring    fragment separator\n",
  189.             "-t c        input line terminator is c, no \\n after output lines\n",
  190.             "Capitalized options affect more than one file.\n");
  191.     exit(1);
  192. }
  193.