Annotation of src/usr.bin/lam/lam.c, Revision 1.1.1.1
1.1 deraadt 1: /* $NetBSD: lam.c,v 1.2 1994/11/14 20:27:42 jtc Exp $ */
2:
3: /*-
4: * Copyright (c) 1993
5: * The Regents of the University of California. All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by the University of
18: * California, Berkeley and its contributors.
19: * 4. Neither the name of the University nor the names of its contributors
20: * may be used to endorse or promote products derived from this software
21: * without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33: * SUCH DAMAGE.
34: */
35:
36: #ifndef lint
37: static char copyright[] =
38: "@(#) Copyright (c) 1993\n\
39: The Regents of the University of California. All rights reserved.\n";
40: #endif /* not lint */
41:
42: #ifndef lint
43: #if 0
44: static char sccsid[] = "@(#)lam.c 8.1 (Berkeley) 6/6/93";
45: #endif
46: static char rcsid[] = "$NetBSD: lam.c,v 1.2 1994/11/14 20:27:42 jtc Exp $";
47: #endif /* not lint */
48:
49: /*
50: * lam - laminate files
51: * Author: John Kunze, UCB
52: */
53:
54: #include <stdio.h>
55: #include <stdlib.h>
56: #include <string.h>
57:
58: #define MAXOFILES 20
59: #define BIGBUFSIZ 5 * BUFSIZ
60:
61: struct openfile { /* open file structure */
62: FILE *fp; /* file pointer */
63: short eof; /* eof flag */
64: short pad; /* pad flag for missing columns */
65: char eol; /* end of line character */
66: char *sepstring; /* string to print before each line */
67: char *format; /* printf(3) style string spec. */
68: } input[MAXOFILES];
69:
70: int morefiles; /* set by getargs(), changed by gatherline() */
71: int nofinalnl; /* normally append \n to each output line */
72: char line[BIGBUFSIZ];
73: char *linep;
74:
75: void error __P((char *, char *));
76: char *gatherline __P((struct openfile *));
77: void getargs __P((char *[]));
78: char *pad __P((struct openfile *));
79:
80: int
81: main(argc, argv)
82: int argc;
83: char *argv[];
84: {
85: register struct openfile *ip;
86:
87: getargs(argv);
88: if (!morefiles)
89: error("lam - laminate files", "");
90: for (;;) {
91: linep = line;
92: for (ip = input; ip->fp != NULL; ip++)
93: linep = gatherline(ip);
94: if (!morefiles)
95: exit(0);
96: fputs(line, stdout);
97: fputs(ip->sepstring, stdout);
98: if (!nofinalnl)
99: putchar('\n');
100: }
101: }
102:
103: void
104: getargs(av)
105: char *av[];
106: {
107: register struct openfile *ip = input;
108: register char *p;
109: register char *c;
110: static char fmtbuf[BUFSIZ];
111: char *fmtp = fmtbuf;
112: int P, S, F, T;
113:
114: P = S = F = T = 0; /* capitalized options */
115: while ((p = *++av) != NULL) {
116: if (*p != '-' || !p[1]) {
117: morefiles++;
118: if (*p == '-')
119: ip->fp = stdin;
120: else if ((ip->fp = fopen(p, "r")) == NULL) {
121: perror(p);
122: exit(1);
123: }
124: ip->pad = P;
125: if (!ip->sepstring)
126: ip->sepstring = (S ? (ip-1)->sepstring : "");
127: if (!ip->format)
128: ip->format = ((P || F) ? (ip-1)->format : "%s");
129: if (!ip->eol)
130: ip->eol = (T ? (ip-1)->eol : '\n');
131: ip++;
132: continue;
133: }
134: switch (*(c = ++p) | 040) {
135: case 's':
136: if (*++p || (p = *++av))
137: ip->sepstring = p;
138: else
139: error("Need string after -%s", c);
140: S = (*c == 'S' ? 1 : 0);
141: break;
142: case 't':
143: if (*++p || (p = *++av))
144: ip->eol = *p;
145: else
146: error("Need character after -%s", c);
147: T = (*c == 'T' ? 1 : 0);
148: nofinalnl = 1;
149: break;
150: case 'p':
151: ip->pad = 1;
152: P = (*c == 'P' ? 1 : 0);
153: case 'f':
154: F = (*c == 'F' ? 1 : 0);
155: if (*++p || (p = *++av)) {
156: fmtp += strlen(fmtp) + 1;
157: if (fmtp > fmtbuf + BUFSIZ)
158: error("No more format space", "");
159: sprintf(fmtp, "%%%ss", p);
160: ip->format = fmtp;
161: }
162: else
163: error("Need string after -%s", c);
164: break;
165: default:
166: error("What do you mean by -%s?", c);
167: break;
168: }
169: }
170: ip->fp = NULL;
171: if (!ip->sepstring)
172: ip->sepstring = "";
173: }
174:
175: char *
176: pad(ip)
177: struct openfile *ip;
178: {
179: register char *p = ip->sepstring;
180: register char *lp = linep;
181:
182: while (*p)
183: *lp++ = *p++;
184: if (ip->pad) {
185: sprintf(lp, ip->format, "");
186: lp += strlen(lp);
187: }
188: return (lp);
189: }
190:
191: char *
192: gatherline(ip)
193: struct openfile *ip;
194: {
195: char s[BUFSIZ];
196: register int c;
197: register char *p;
198: register char *lp = linep;
199: char *end = s + BUFSIZ;
200:
201: if (ip->eof)
202: return (pad(ip));
203: for (p = s; (c = fgetc(ip->fp)) != EOF && p < end; p++)
204: if ((*p = c) == ip->eol)
205: break;
206: *p = '\0';
207: if (c == EOF) {
208: ip->eof = 1;
209: if (ip->fp == stdin)
210: fclose(stdin);
211: morefiles--;
212: return (pad(ip));
213: }
214: p = ip->sepstring;
215: while (*p)
216: *lp++ = *p++;
217: sprintf(lp, ip->format, s);
218: lp += strlen(lp);
219: return (lp);
220: }
221:
222: void
223: error(msg, s)
224: char *msg, *s;
225: {
226: fprintf(stderr, "lam: ");
227: fprintf(stderr, msg, s);
228: fprintf(stderr,
229: "\nUsage: lam [ -[fp] min.max ] [ -s sepstring ] [ -t c ] file ...\n");
230: if (strncmp("lam - ", msg, 6) == 0)
231: fprintf(stderr, "Options:\n\t%s\t%s\t%s\t%s\t%s",
232: "-f min.max field widths for file fragments\n",
233: "-p min.max like -f, but pad missing fragments\n",
234: "-s sepstring fragment separator\n",
235: "-t c input line terminator is c, no \\n after output lines\n",
236: "Capitalized options affect more than one file.\n");
237: exit(1);
238: }