modern syntax for asgops and inits; sccs keywords
[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
4e408819 4static char sccsid[] = "@(#)lam.c 4.4 (Berkeley) %G%";
1b2380f2
SL
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
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)
80 ip->format = (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)) {
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;
f7616c8e
JK
123 if (!ip->sepstring)
124 ip->sepstring = "";
1b2380f2
SL
125}
126
127char *
128gatherline(ip)
129struct 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++)
c9129d72 148 if ((*p = c) == ip->eol)
1b2380f2
SL
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
165error(msg, s)
166char *msg;
167char *s;
168{
169 char buf[BUFSIZ];
170
171 setbuf(stderr, buf);
172 fprintf(stderr, "lam: ");
173 fprintf(stderr, msg, s);
c9129d72 174 fprintf(stderr, "\nUsage: lam [ -[fp] min.max ] [ -s sepstring ] [ -t c ] file ...\n");
1b2380f2 175 if (strncmp("lam - ", msg, 6) == 0)
c9129d72 176 fprintf(stderr, "Options:\n\t%s\t%s\t%s\t%s\t%s",
1b2380f2
SL
177 "-f min.max field widths for file fragments\n",
178 "-p min.max like -f, but pad missing fragments\n",
c9129d72
JK
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");
1b2380f2
SL
182 exit(1);
183}