ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/lam.c
Revision: 1.26
Committed: Fri Jun 7 18:19:22 2024 UTC (10 months, 4 weeks ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.25: +43 -35 lines
Log Message:
feature(rsplit,rlam): Modified to allow any number of files up to system limit

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: lam.c,v 1.25 2019/08/13 16:31:35 greg Exp $";
3 #endif
4 /*
5 * lam.c - simple program to laminate files.
6 *
7 * 7/14/88 Greg Ward
8 */
9
10 #include <ctype.h>
11
12 #include "rtio.h"
13 #include "platform.h"
14 #include "paths.h"
15
16 #define MAXLINE 262144 /* maximum input line */
17
18 struct instream { /* structure to hold input stream info */
19 FILE *input; /* input stream */
20 int bytsiz; /* bytes/component if binary */
21 char *tabc; /* data separation string */
22 } *rifile = NULL;
23
24 int nfiles = 0;
25
26 char buf[MAXLINE];
27
28 int
29 main(int argc, char *argv[])
30 {
31 long incnt = 0;
32 int unbuff = 0;
33 int binout = 0;
34 char *curtab = "\t";
35 int curbytes = 0;
36 int puteol;
37 int i;
38
39 rifile = (struct instream *)calloc(argc-1, sizeof(struct instream));
40 if (!rifile) {
41 fputs(argv[0], stderr);
42 fputs(": not enough memory\n", stderr);
43 return(1);
44 }
45 for (i = 1; i < argc; i++) {
46 if (argv[i][0] == '-') {
47 switch (argv[i][1]) {
48 case 't':
49 curtab = argv[i]+2;
50 if (!*curtab) curtab = "\n";
51 break;
52 case 'u':
53 unbuff = !unbuff;
54 break;
55 case 'i':
56 switch (argv[i][2]) {
57 case 'n':
58 incnt = atol(argv[++i]);
59 break;
60 case 'f':
61 case 'F':
62 curbytes = sizeof(float);
63 break;
64 case 'd':
65 case 'D':
66 curbytes = sizeof(double);
67 break;
68 case 'i':
69 case 'I':
70 curbytes = sizeof(int);
71 break;
72 case 'w':
73 case 'W':
74 curbytes = 2;
75 break;
76 case 'b':
77 curbytes = 1;
78 break;
79 case 'a':
80 curbytes = argv[i][3] ? -1 : 0;
81 break;
82 default:
83 goto badopt;
84 }
85 if (isdigit(argv[i][3]))
86 curbytes *= atoi(argv[i]+3);
87 curbytes += (curbytes == -1);
88 if (curbytes > MAXLINE) {
89 fputs(argv[0], stderr);
90 fputs(": input size too big\n", stderr);
91 return(1);
92 }
93 if (curbytes > 0) {
94 curtab = "";
95 ++binout;
96 }
97 break;
98 case '\0':
99 rifile[nfiles].tabc = curtab;
100 rifile[nfiles].input = stdin;
101 if (curbytes > 0)
102 SET_FILE_BINARY(rifile[nfiles].input);
103 rifile[nfiles++].bytsiz = curbytes;
104 break;
105 badopt:;
106 default:
107 fputs(argv[0], stderr);
108 fputs(": bad option\n", stderr);
109 return(1);
110 }
111 } else if (argv[i][0] == '!') {
112 rifile[nfiles].tabc = curtab;
113 if ((rifile[nfiles].input = popen(argv[i]+1, "r")) == NULL) {
114 fputs(argv[i], stderr);
115 fputs(": cannot start command\n", stderr);
116 return(1);
117 }
118 if (curbytes > 0)
119 SET_FILE_BINARY(rifile[nfiles].input);
120 rifile[nfiles++].bytsiz = curbytes;
121 } else {
122 rifile[nfiles].tabc = curtab;
123 if ((rifile[nfiles].input = fopen(argv[i], "r")) == NULL) {
124 fputs(argv[i], stderr);
125 fputs(": cannot open file\n", stderr);
126 return(1);
127 }
128 if (curbytes > 0)
129 SET_FILE_BINARY(rifile[nfiles].input);
130 rifile[nfiles++].bytsiz = curbytes;
131 }
132 }
133 if (!nfiles) {
134 fputs(argv[0], stderr);
135 fputs(": no input streams\n", stderr);
136 return(1);
137 } /* reduce array to size we need */
138 rifile = (struct instream *)realloc(rifile, nfiles*sizeof(struct instream));
139 if (!rifile) {
140 fputs(argv[0], stderr);
141 fputs(": realloc() failed!\n", stderr);
142 return(1);
143 }
144 if (binout) /* binary output? */
145 SET_FILE_BINARY(stdout);
146 #ifdef getc_unlocked /* avoid lock/unlock overhead */
147 for (i = nfiles; i--; )
148 flockfile(rifile[i].input);
149 flockfile(stdout);
150 #endif
151 puteol = 0; /* any ASCII output at all? */
152 for (i = nfiles; i--; )
153 puteol += (rifile[i].bytsiz <= 0);
154 do { /* main loop */
155 for (i = 0; i < nfiles; i++) {
156 if (rifile[i].bytsiz > 0) { /* binary input */
157 if (getbinary(buf, rifile[i].bytsiz, 1, rifile[i].input) < 1)
158 break;
159 if (putbinary(buf, rifile[i].bytsiz, 1, stdout) != 1)
160 break;
161 } else if (rifile[i].bytsiz < 0) { /* multi-line input */
162 int n = -rifile[i].bytsiz;
163 while (n--) {
164 if (fgets(buf, MAXLINE, rifile[i].input) == NULL)
165 break;
166 if ((i > 0) | (n < -rifile[i].bytsiz-1))
167 fputs(rifile[i].tabc, stdout);
168 buf[strlen(buf)-1] = '\0';
169 if (fputs(buf, stdout) == EOF)
170 break;
171 }
172 if (n >= 0) /* fell short? */
173 break;
174 } else { /* single-line input */
175 if (fgets(buf, MAXLINE, rifile[i].input) == NULL)
176 break;
177 if (i)
178 fputs(rifile[i].tabc, stdout);
179 buf[strlen(buf)-1] = '\0';
180 if (fputs(buf, stdout) == EOF)
181 break;
182 }
183 }
184 if (i < nfiles)
185 break;
186 if (puteol)
187 putchar('\n');
188 if (unbuff)
189 fflush(stdout);
190 } while (--incnt);
191 /* check ending */
192 if (fflush(stdout) == EOF) {
193 fputs(argv[0], stderr);
194 fputs(": write error on standard output\n", stderr);
195 return(1);
196 }
197 if (incnt > 0) {
198 fputs(argv[0], stderr);
199 fputs(": warning: premature EOD\n", stderr);
200 }
201 return(0);
202 }