ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/rsplit.c
Revision: 1.5
Committed: Tue Jul 16 15:59:49 2019 UTC (4 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +2 -1 lines
Log Message:
Made it so -t option sets newline if no character follows

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 1.5 static const char RCSid[] = "$Id: rsplit.c,v 1.4 2019/07/05 15:04:20 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * rsplit.c - split input into multiple output streams
6     *
7     * 7/4/19 Greg Ward
8     */
9    
10     #include <stdlib.h>
11     #include <string.h>
12     #include <stdio.h>
13     #include <ctype.h>
14    
15     #include "platform.h"
16     #include "resolu.h"
17     #include "rtio.h"
18    
19     #define DOHEADER 1
20     #define DORESOLU 2
21    
22     #define MAXFILE 512 /* maximum number of files */
23    
24     FILE *output[MAXFILE];
25     int bytsiz[MAXFILE];
26     short hdrflags[MAXFILE];
27     const char *format[MAXFILE];
28     int termc[MAXFILE];
29     int nfiles = 0;
30    
31     int outheader = 0; /* output header to each stream? */
32    
33     RESOLU ourres = {PIXSTANDARD, 0, 0};
34    
35     char buf[16384];
36    
37    
38     /* process header line */
39     static int
40     headline(char *s, void *p)
41     {
42     extern const char FMTSTR[];
43     int i = nfiles;
44    
45     if (strstr(s, FMTSTR) == s)
46     return(0); /* don't copy format */
47     if (!strncmp(s, "NROWS=", 6))
48     return(0);
49     if (!strncmp(s, "NCOLS=", 6))
50     return(0);
51     if (!strncmp(s, "NCOMP=", 6))
52     return(0);
53     while (i--) /* else copy line to output streams */
54     if (hdrflags[i] & DOHEADER)
55     fputs(s, output[i]);
56     return(1);
57     }
58    
59    
60     /* scan field into buffer up to and including terminating byte */
61     static int
62     scanOK(int termc)
63     {
64     char *cp = buf;
65     int c;
66    
67     while ((c = getchar()) != EOF) {
68     *cp++ = c;
69     if (cp-buf >= sizeof(buf))
70     break;
71     if (c == termc) {
72     *cp = '\0';
73     return(cp-buf);
74     }
75     }
76     return(0);
77     }
78    
79    
80     int
81     main(int argc, char *argv[])
82     {
83     int inpheader = 0;
84     int inpres = 0;
85     int outres = 0;
86     int force = 0;
87     int append = 0;
88     long outcnt = 0;
89     int bininp = 0;
90     int curterm = '\n';
91     int curbytes = 0;
92     int curflags = 0;
93     const char *curfmt = "ascii";
94     int i;
95    
96     for (i = 1; i < argc; i++) {
97     if (argv[i][0] == '-') {
98     switch (argv[i][1]) {
99     case 't':
100     curterm = argv[i][2];
101 greg 1.5 if (!curterm) curterm = '\n';
102 greg 1.1 break;
103     case 'i':
104     switch (argv[i][2]) {
105     case 'h':
106     inpheader = !inpheader;
107     break;
108     case 'H':
109     inpres = !inpres;
110     break;
111     default:
112     goto badopt;
113     }
114     break;
115     case 'f':
116     ++force;
117     append = 0;
118     break;
119     case 'a':
120     if (outheader | outres) {
121     fputs(argv[0], stderr);
122     fputs(": -a option incompatible with -oh and -oH\n",
123     stderr);
124     return(1);
125     }
126     append = 1;
127     break;
128     case 'x':
129     ourres.xr = atoi(argv[++i]);
130     outres = 1;
131     break;
132     case 'y':
133     ourres.yr = atoi(argv[++i]);
134     outres = 1;
135     break;
136     case 'o':
137     switch (argv[i][2]) {
138     case 'n':
139     outcnt = atol(argv[++i]);
140     continue;
141     case 'h':
142     curflags ^= DOHEADER;
143     continue;
144     case 'H':
145     curflags ^= DORESOLU;
146     continue;
147     case 'f':
148     curfmt = "float";
149     curbytes = sizeof(float);
150     break;
151     case 'd':
152     curfmt = "double";
153     curbytes = sizeof(double);
154     break;
155     case 'i':
156     curfmt = "int";
157     curbytes = sizeof(int);
158     break;
159     case 'w':
160     curfmt = "16-bit";
161     curbytes = 2;
162     break;
163     case 'b':
164     curfmt = "byte";
165     curbytes = 1;
166     break;
167     case 'a':
168     curfmt = "ascii";
169     curbytes = argv[i][3] ? -1 : 0;
170     break;
171     default:
172     goto badopt;
173     }
174     if (isdigit(argv[i][3]))
175     curbytes *= atoi(argv[i]+3);
176     curbytes += (curbytes == -1);
177     if (curbytes > (int)sizeof(buf)) {
178     fputs(argv[0], stderr);
179     fputs(": output size too big\n", stderr);
180     return(1);
181     }
182     if (curbytes > 0) {
183     curterm = '\0';
184     ++bininp;
185     }
186     break;
187     case '\0':
188     outres |= (curflags & DORESOLU);
189     termc[nfiles] = curterm;
190     hdrflags[nfiles] = curflags;
191     output[nfiles] = stdout;
192     if (curbytes > 0)
193     SET_FILE_BINARY(output[nfiles]);
194     format[nfiles] = curfmt;
195     bytsiz[nfiles++] = curbytes;
196     break;
197     badopt:;
198     default:
199     fputs(argv[0], stderr);
200     fputs(": bad option\n", stderr);
201     return(1);
202     }
203     } else if (argv[i][0] == '!') {
204     outres |= (curflags & DORESOLU);
205     termc[nfiles] = curterm;
206     hdrflags[nfiles] = curflags;
207     if ((output[nfiles] = popen(argv[i]+1, "w")) == NULL) {
208     fputs(argv[i], stderr);
209     fputs(": cannot start command\n", stderr);
210     return(1);
211     }
212     if (curbytes > 0)
213     SET_FILE_BINARY(output[nfiles]);
214     format[nfiles] = curfmt;
215     bytsiz[nfiles++] = curbytes;
216     } else {
217     outres |= (curflags & DORESOLU);
218     termc[nfiles] = curterm;
219     hdrflags[nfiles] = curflags;
220     if (!append & !force && access(argv[i], F_OK) == 0) {
221     fputs(argv[i], stderr);
222     fputs(": file exists -- use -f to overwrite\n",
223     stderr);
224     return(1);
225     }
226     output[nfiles] = fopen(argv[i], append ? "a" : "w");
227     if (output[nfiles] == NULL) {
228     fputs(argv[i], stderr);
229     fputs(": cannot open for output\n", stderr);
230     return(1);
231     }
232     if (curbytes > 0)
233     SET_FILE_BINARY(output[nfiles]);
234     format[nfiles] = curfmt;
235     bytsiz[nfiles++] = curbytes;
236     }
237     if (nfiles >= MAXFILE) {
238     fputs(argv[0], stderr);
239     fputs(": too many output streams\n", stderr);
240     return(1);
241     }
242     }
243     if (!nfiles) {
244     fputs(argv[0], stderr);
245     fputs(": no output streams\n", stderr);
246     return(1);
247     }
248     if (bininp) /* binary input? */
249     SET_FILE_BINARY(stdin);
250     #ifdef getc_unlocked /* avoid lock/unlock overhead */
251     flockfile(stdin);
252     for (i = nfiles; i--; )
253     flockfile(output[i]);
254     #endif
255     /* load/copy header */
256     if (inpheader && getheader(stdin, headline, NULL) < 0) {
257     fputs(argv[0], stderr);
258     fputs(": cannot get header from standard input\n",
259     stderr);
260     return(1);
261     }
262     /* handle resolution string */
263     if (inpres && !fgetsresolu(&ourres, stdin)) {
264     fputs(argv[0], stderr);
265     fputs(": cannot get resolution string from standard input\n",
266     stderr);
267     return(1);
268     }
269     if (outres && (ourres.xr <= 0) | (ourres.yr <= 0)) {
270     fputs(argv[0], stderr);
271     fputs(": -oH option requires -iH or -x and -y options\n", stderr);
272     return(1);
273     }
274     if ((ourres.xr > 0) & (ourres.yr > 0)) {
275     if (outcnt <= 0) {
276     outcnt = ourres.xr * ourres.yr;
277     } else if (outcnt != ourres.xr*ourres.yr) {
278     fputs(argv[0], stderr);
279     fputs(": warning: -on option does not agree with resolution\n",
280     stderr);
281     }
282     }
283     for (i = 0; i < nfiles; i++) { /* complete headers */
284     if (hdrflags[i] & DOHEADER) {
285     if (!inpheader)
286     newheader("RADIANCE", output[i]);
287     printargs(argc, argv, output[i]);
288     if (format[i] != NULL)
289     fputformat(format[i], output[i]);
290     fputc('\n', output[i]);
291     }
292     if (hdrflags[i] & DORESOLU)
293     fputsresolu(&ourres, output[i]);
294     }
295     do { /* main loop */
296     for (i = 0; i < nfiles; i++) {
297     if (bytsiz[i] > 0) { /* binary output */
298     if (getbinary(buf, bytsiz[i], 1, stdin) < 1)
299     break;
300 greg 1.4 if (putbinary(buf, bytsiz[i], 1, output[i]) != 1)
301     break;
302 greg 1.1 } else if (bytsiz[i] < 0) { /* N-field output */
303     int n = -bytsiz[i];
304     while (n--) {
305     if (!scanOK(termc[i]))
306     break;
307 greg 1.4 if (fputs(buf, output[i]) == EOF)
308     break;
309 greg 1.1 }
310     if (n >= 0) /* fell short? */
311     break;
312 greg 1.4 if (termc[i] != '\n') /* add EOL if none */
313     fputc('\n', output[i]);
314 greg 1.1 } else { /* 1-field output */
315     if (!scanOK(termc[i]))
316     break;
317 greg 1.4 if (fputs(buf, output[i]) == EOF)
318     break;
319     if (termc[i] != '\n') /* add EOL if none */
320     fputc('\n', output[i]);
321 greg 1.1 }
322     }
323     if (i < nfiles)
324     break;
325     } while (--outcnt);
326 greg 1.2 /* check ending */
327 greg 1.3 if (fflush(NULL) == EOF) {
328     fputs(argv[0], stderr);
329     fputs(": write error on one or more outputs\n", stderr);
330     return(1);
331     }
332 greg 1.4 if (outcnt > 0) {
333     fputs(argv[0], stderr);
334     fputs(": warning: premature EOD\n", stderr);
335     }
336 greg 1.1 return(0);
337     }