1: /* Copyright (c) 1983 Regents of the University of California */
2:
3: #ifndef lint
4: static char sccsid[] = "@(#)lam.c 4.4 (Berkeley) 4/5/86";
5: #endif not lint
6:
7: /*
8: * lam - laminate files
9: * Author: John Kunze, Office of Comp. Affairs, 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 = (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);
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: gatherline(ip)
129: struct openfile *ip;
130: {
131: char s[BUFSIZ];
132: register int c;
133: register char *p;
134: register char *lp = linep;
135: char *end = s + BUFSIZ;
136:
137: if (ip->eof) {
138: p = ip->sepstring;
139: while (*p)
140: *lp++ = *p++;
141: if (ip->pad) {
142: sprintf(lp, ip->format, "");
143: lp += strlen(lp);
144: }
145: return(lp);
146: }
147: for (p = s; (c = fgetc(ip->fp)) != EOF && p < end; p++)
148: if ((*p = c) == ip->eol)
149: break;
150: *p = '\0';
151: p = ip->sepstring;
152: while (*p)
153: *lp++ = *p++;
154: sprintf(lp, ip->format, s);
155: lp += strlen(lp);
156: if (c == EOF) {
157: ip->eof = 1;
158: if (ip->fp == stdin)
159: fclose(stdin);
160: morefiles--;
161: }
162: return(lp);
163: }
164:
165: error(msg, s)
166: char *msg;
167: char *s;
168: {
169: char buf[BUFSIZ];
170:
171: setbuf(stderr, buf);
172: fprintf(stderr, "lam: ");
173: fprintf(stderr, msg, s);
174: fprintf(stderr, "\nUsage: lam [ -[fp] min.max ] [ -s sepstring ] [ -t c ] file ...\n");
175: if (strncmp("lam - ", msg, 6) == 0)
176: fprintf(stderr, "Options:\n\t%s\t%s\t%s\t%s\t%s",
177: "-f min.max field widths for file fragments\n",
178: "-p min.max like -f, but pad missing fragments\n",
179: "-s sepstring fragment separator\n",
180: "-t c input line terminator is c, no \\n after output lines\n",
181: "Capitalized options affect more than one file.\n");
182: exit(1);
183: }
Defined functions
main
defined in line
32;
never used
Defined variables
buf
defined in line
28; used 3 times
input
defined in line
24; used 2 times
line
defined in line
29; used 2 times
linep
defined in line
30; used 3 times
sccsid
defined in line
4;
never used
Defined struct's
Defined macros