cleanups, add manual page
[unix-history] / usr / src / usr.bin / lam / lam.c
CommitLineData
1b2380f2
SL
1/* Copyright (c) 1983 Regents of the University of California */
2
3#ifndef lint
45febe78 4static char sccsid[] = "@(#)lam.c 4.5 (Berkeley) %G%";
1b2380f2
SL
5#endif not lint
6
7/*
8 * lam - laminate files
45febe78 9 * Author: John Kunze, UCB
1b2380f2
SL
10 */
11
12#include <stdio.h>
13
14#define MAXOFILES 20
15#define BIGBUFSIZ 5 * BUFSIZ
16
17struct openfile { /* open file structure */
18 FILE *fp; /* file pointer */
19 short eof; /* eof flag */
20 short pad; /* pad flag for missing columns */
c9129d72 21 char eol; /* end of line character */
1b2380f2
SL
22 char *sepstring; /* string to print before each line */
23 char *format; /* printf(3) style string spec. */
24} input[MAXOFILES];
25
1b2380f2 26int morefiles; /* set by getargs(), changed by gatherline() */
c9129d72 27int nofinalnl; /* normally append \n to each output line */
1b2380f2
SL
28char buf[BUFSIZ];
29char line[BIGBUFSIZ];
30char *linep;
31
32main(argc, argv)
33int argc;
34char **argv;
35{
36 register struct openfile *ip;
37 char *gatherline();
38
4e408819 39 setbuf(stdout, buf);
1b2380f2
SL
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);
c9129d72
JK
51 if (!nofinalnl)
52 putchar('\n');
1b2380f2
SL
53 }
54}
55
56getargs(av)
57char **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;
c9129d72 64 int P, S, F, T;
1b2380f2 65
c9129d72 66 P = S = F = T = 0; /* capitalized options */
1b2380f2
SL
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)
45febe78 80 ip->format = ((P || F) ? (ip-1)->format : "%s");
c9129d72
JK
81 if (!ip->eol)
82 ip->eol = (T ? (ip-1)->eol : '\n');
1b2380f2
SL
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;
c9129d72
JK
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;
1b2380f2
SL
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)) {
45febe78 108 fmtp += strlen(fmtp) + 1;
1b2380f2
SL
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;
f7616c8e
JK
123 if (!ip->sepstring)
124 ip->sepstring = "";
1b2380f2
SL
125}
126
45febe78
JK
127char *
128pad(ip)
129struct 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
1b2380f2
SL
143char *
144gatherline(ip)
145struct 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
45febe78
JK
153 if (ip->eof)
154 return(pad(ip));
1b2380f2 155 for (p = s; (c = fgetc(ip->fp)) != EOF && p < end; p++)
c9129d72 156 if ((*p = c) == ip->eol)
1b2380f2
SL
157 break;
158 *p = '\0';
1b2380f2
SL
159 if (c == EOF) {
160 ip->eof = 1;
161 if (ip->fp == stdin)
162 fclose(stdin);
163 morefiles--;
45febe78 164 return(pad(ip));
1b2380f2 165 }
45febe78
JK
166 p = ip->sepstring;
167 while (*p)
168 *lp++ = *p++;
169 sprintf(lp, ip->format, s);
170 lp += strlen(lp);
1b2380f2
SL
171 return(lp);
172}
173
174error(msg, s)
175char *msg;
176char *s;
177{
178 char buf[BUFSIZ];
179
180 setbuf(stderr, buf);
181 fprintf(stderr, "lam: ");
182 fprintf(stderr, msg, s);
c9129d72 183 fprintf(stderr, "\nUsage: lam [ -[fp] min.max ] [ -s sepstring ] [ -t c ] file ...\n");
1b2380f2 184 if (strncmp("lam - ", msg, 6) == 0)
c9129d72 185 fprintf(stderr, "Options:\n\t%s\t%s\t%s\t%s\t%s",
1b2380f2
SL
186 "-f min.max field widths for file fragments\n",
187 "-p min.max like -f, but pad missing fragments\n",
c9129d72
JK
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");
1b2380f2
SL
191 exit(1);
192}