Commit | Line | Data |
---|---|---|
1b2380f2 SL |
1 | /* Copyright (c) 1983 Regents of the University of California */ |
2 | ||
3 | #ifndef lint | |
4 | static char sccsid[] = "@(#)lam.c 4.1 (Berkeley) %G%"; | |
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 *sepstring; /* string to print before each line */ | |
22 | char *format; /* printf(3) style string spec. */ | |
23 | } input[MAXOFILES]; | |
24 | ||
25 | int P; | |
26 | int S; | |
27 | int F; | |
28 | int morefiles; /* set by getargs(), changed by gatherline() */ | |
29 | char buf[BUFSIZ]; | |
30 | char line[BIGBUFSIZ]; | |
31 | char *linep; | |
32 | ||
33 | main(argc, argv) | |
34 | int argc; | |
35 | char **argv; | |
36 | { | |
37 | register struct openfile *ip; | |
38 | char *gatherline(); | |
39 | ||
40 | setbuf(buf, stdout); | |
41 | getargs(argv); | |
42 | if (!morefiles) | |
43 | error("lam - laminate files", ""); | |
44 | for (;;) { | |
45 | linep = line; | |
46 | for (ip = input; ip->fp != NULL; ip++) | |
47 | linep = gatherline(ip); | |
48 | if (!morefiles) | |
49 | exit(0); | |
50 | fputs(line, stdout); | |
51 | fputs(ip->sepstring, stdout); | |
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 | ||
65 | while (p = *++av) { | |
66 | if (*p != '-' || !p[1]) { | |
67 | morefiles++; | |
68 | if (*p == '-') | |
69 | ip->fp = stdin; | |
70 | else if ((ip->fp = fopen(p, "r")) == NULL) { | |
71 | perror(p); | |
72 | exit(1); | |
73 | } | |
74 | ip->pad = P; | |
75 | if (!ip->sepstring) | |
76 | ip->sepstring = (S ? (ip-1)->sepstring : ""); | |
77 | if (!ip->format) | |
78 | ip->format = (F ? (ip-1)->format : "%s"); | |
79 | ip++; | |
80 | continue; | |
81 | } | |
82 | switch (*(c = ++p) | 040) { | |
83 | case 's': | |
84 | if (*++p || (p = *++av)) | |
85 | ip->sepstring = p; | |
86 | else | |
87 | error("Need string after -%s", c); | |
88 | S = (*c == 'S' ? 1 : 0); | |
89 | break; | |
90 | case 'p': | |
91 | ip->pad = 1; | |
92 | P = (*c == 'P' ? 1 : 0); | |
93 | case 'f': | |
94 | F = (*c == 'F' ? 1 : 0); | |
95 | if (*++p || (p = *++av)) { | |
96 | fmtp += strlen(fmtp); | |
97 | if (fmtp > fmtbuf + BUFSIZ) | |
98 | error("No more format space", ""); | |
99 | sprintf(fmtp, "%%%ss", p); | |
100 | ip->format = fmtp; | |
101 | } | |
102 | else | |
103 | error("Need string after -%s", c); | |
104 | break; | |
105 | default: | |
106 | error("What do you mean by -%s?", c); | |
107 | break; | |
108 | } | |
109 | } | |
110 | ip->fp = NULL; | |
111 | } | |
112 | ||
113 | char * | |
114 | gatherline(ip) | |
115 | struct openfile *ip; | |
116 | { | |
117 | char s[BUFSIZ]; | |
118 | register int c; | |
119 | register char *p; | |
120 | register char *lp = linep; | |
121 | char *end = s + BUFSIZ; | |
122 | ||
123 | if (ip->eof) { | |
124 | p = ip->sepstring; | |
125 | while (*p) | |
126 | *lp++ = *p++; | |
127 | if (ip->pad) { | |
128 | sprintf(lp, ip->format, ""); | |
129 | lp += strlen(lp); | |
130 | } | |
131 | return(lp); | |
132 | } | |
133 | for (p = s; (c = fgetc(ip->fp)) != EOF && p < end; p++) | |
134 | if ((*p = c) == '\n') | |
135 | break; | |
136 | *p = '\0'; | |
137 | p = ip->sepstring; | |
138 | while (*p) | |
139 | *lp++ = *p++; | |
140 | sprintf(lp, ip->format, s); | |
141 | lp += strlen(lp); | |
142 | if (c == EOF) { | |
143 | ip->eof = 1; | |
144 | if (ip->fp == stdin) | |
145 | fclose(stdin); | |
146 | morefiles--; | |
147 | } | |
148 | return(lp); | |
149 | } | |
150 | ||
151 | error(msg, s) | |
152 | char *msg; | |
153 | char *s; | |
154 | { | |
155 | char buf[BUFSIZ]; | |
156 | ||
157 | setbuf(stderr, buf); | |
158 | fprintf(stderr, "lam: "); | |
159 | fprintf(stderr, msg, s); | |
160 | fprintf(stderr, "\nUsage: lam [ -[fp] min.max ] [ -s sepstring ] file ...\n"); | |
161 | if (strncmp("lam - ", msg, 6) == 0) | |
162 | fprintf(stderr, "Options:\n\t%s\t%s\t%s", | |
163 | "-f min.max field widths for file fragments\n", | |
164 | "-p min.max like -f, but pad missing fragments\n", | |
165 | "-s sepstring fragment separator\n"); | |
166 | exit(1); | |
167 | } |