--- ray/src/cal/rsplit.c 2019/07/05 00:20:57 1.1 +++ ray/src/cal/rsplit.c 2019/08/14 21:00:14 1.10 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rsplit.c,v 1.1 2019/07/05 00:20:57 greg Exp $"; +static const char RCSid[] = "$Id: rsplit.c,v 1.10 2019/08/14 21:00:14 greg Exp $"; #endif /* * rsplit.c - split input into multiple output streams @@ -7,32 +7,30 @@ static const char RCSid[] = "$Id: rsplit.c,v 1.1 2019/ * 7/4/19 Greg Ward */ -#include -#include -#include #include +#include "rtio.h" #include "platform.h" +#include "paths.h" #include "resolu.h" -#include "rtio.h" #define DOHEADER 1 #define DORESOLU 2 #define MAXFILE 512 /* maximum number of files */ -FILE *output[MAXFILE]; -int bytsiz[MAXFILE]; -short hdrflags[MAXFILE]; -const char *format[MAXFILE]; -int termc[MAXFILE]; -int nfiles = 0; +static int swapped = 0; /* input is byte-swapped */ -int outheader = 0; /* output header to each stream? */ +static FILE *output[MAXFILE]; +static int bytsiz[MAXFILE]; +static short hdrflags[MAXFILE]; +static const char *format[MAXFILE]; +static int termc[MAXFILE]; +static int nfiles = 0; -RESOLU ourres = {PIXSTANDARD, 0, 0}; +static RESOLU ourres = {PIXSTANDARD, 0, 0}; -char buf[16384]; +static char buf[16384]; /* input buffer used in scanOK() */ /* process header line */ @@ -40,7 +38,7 @@ static int headline(char *s, void *p) { extern const char FMTSTR[]; - int i = nfiles; + int i; if (strstr(s, FMTSTR) == s) return(0); /* don't copy format */ @@ -50,6 +48,11 @@ headline(char *s, void *p) return(0); if (!strncmp(s, "NCOMP=", 6)) return(0); + if ((i = isbigendian(s)) >= 0) { + swapped = (nativebigendian() != i); + return(0); + } + i = nfiles; while (i--) /* else copy line to output streams */ if (hdrflags[i] & DOHEADER) fputs(s, output[i]); @@ -80,9 +83,8 @@ scanOK(int termc) int main(int argc, char *argv[]) { - int inpheader = 0; - int inpres = 0; - int outres = 0; + int inpflags = 0; + int needres = 0; int force = 0; int append = 0; long outcnt = 0; @@ -98,39 +100,31 @@ main(int argc, char *argv[]) switch (argv[i][1]) { case 't': curterm = argv[i][2]; + if (!curterm) curterm = '\n'; break; case 'i': switch (argv[i][2]) { case 'h': - inpheader = !inpheader; + inpflags ^= DOHEADER; break; case 'H': - inpres = !inpres; + inpflags ^= DORESOLU; break; default: goto badopt; } break; case 'f': - ++force; - append = 0; + force = !force; break; case 'a': - if (outheader | outres) { - fputs(argv[0], stderr); - fputs(": -a option incompatible with -oh and -oH\n", - stderr); - return(1); - } - append = 1; + append = !append; break; case 'x': ourres.xr = atoi(argv[++i]); - outres = 1; break; case 'y': ourres.yr = atoi(argv[++i]); - outres = 1; break; case 'o': switch (argv[i][2]) { @@ -165,7 +159,7 @@ main(int argc, char *argv[]) break; case 'a': curfmt = "ascii"; - curbytes = argv[i][3] ? -1 : 0; + curbytes = -1; break; default: goto badopt; @@ -178,13 +172,10 @@ main(int argc, char *argv[]) fputs(": output size too big\n", stderr); return(1); } - if (curbytes > 0) { - curterm = '\0'; - ++bininp; - } + bininp += (curbytes > 0); break; case '\0': - outres |= (curflags & DORESOLU); + needres |= (curflags & DORESOLU); termc[nfiles] = curterm; hdrflags[nfiles] = curflags; output[nfiles] = stdout; @@ -200,7 +191,7 @@ main(int argc, char *argv[]) return(1); } } else if (argv[i][0] == '!') { - outres |= (curflags & DORESOLU); + needres |= (curflags & DORESOLU); termc[nfiles] = curterm; hdrflags[nfiles] = curflags; if ((output[nfiles] = popen(argv[i]+1, "w")) == NULL) { @@ -213,7 +204,13 @@ main(int argc, char *argv[]) format[nfiles] = curfmt; bytsiz[nfiles++] = curbytes; } else { - outres |= (curflags & DORESOLU); + if (append & (curflags != 0)) { + fputs(argv[0], stderr); + fputs(": -a option incompatible with -oh and -oH\n", + stderr); + return(1); + } + needres |= (curflags & DORESOLU); termc[nfiles] = curterm; hdrflags[nfiles] = curflags; if (!append & !force && access(argv[i], F_OK) == 0) { @@ -252,20 +249,20 @@ main(int argc, char *argv[]) flockfile(output[i]); #endif /* load/copy header */ - if (inpheader && getheader(stdin, headline, NULL) < 0) { + if (inpflags & DOHEADER && getheader(stdin, headline, NULL) < 0) { fputs(argv[0], stderr); fputs(": cannot get header from standard input\n", stderr); return(1); } /* handle resolution string */ - if (inpres && !fgetsresolu(&ourres, stdin)) { + if (inpflags & DORESOLU && !fgetsresolu(&ourres, stdin)) { fputs(argv[0], stderr); fputs(": cannot get resolution string from standard input\n", stderr); return(1); } - if (outres && (ourres.xr <= 0) | (ourres.yr <= 0)) { + if (needres && (ourres.xr <= 0) | (ourres.yr <= 0)) { fputs(argv[0], stderr); fputs(": -oH option requires -iH or -x and -y options\n", stderr); return(1); @@ -281,11 +278,19 @@ main(int argc, char *argv[]) } for (i = 0; i < nfiles; i++) { /* complete headers */ if (hdrflags[i] & DOHEADER) { - if (!inpheader) + if (!(inpflags & DOHEADER)) newheader("RADIANCE", output[i]); printargs(argc, argv, output[i]); - if (format[i] != NULL) + if (format[i] != NULL) { + extern const char BIGEND[]; + if ((format[i][0] == 'f') | + (format[i][0] == 'd')) { + fputs(BIGEND, output[i]); + fputs(nativebigendian() ^ swapped ? + "1\n" : "0\n", output[i]); + } fputformat(format[i], output[i]); + } fputc('\n', output[i]); } if (hdrflags[i] & DORESOLU) @@ -296,24 +301,47 @@ main(int argc, char *argv[]) if (bytsiz[i] > 0) { /* binary output */ if (getbinary(buf, bytsiz[i], 1, stdin) < 1) break; - putbinary(buf, bytsiz[i], 1, output[i]); + if (putbinary(buf, bytsiz[i], 1, output[i]) < 1) + break; } else if (bytsiz[i] < 0) { /* N-field output */ int n = -bytsiz[i]; while (n--) { if (!scanOK(termc[i])) break; - fputs(buf, output[i]); + if (fputs(buf, output[i]) == EOF) + break; } if (n >= 0) /* fell short? */ break; + if (termc[i] != '\n') /* add EOL if none */ + fputc('\n', output[i]); } else { /* 1-field output */ if (!scanOK(termc[i])) break; - fputs(buf, output[i]); + if (fputs(buf, output[i]) == EOF) + break; + if (termc[i] != '\n') /* add EOL if none */ + fputc('\n', output[i]); } + /* skip input EOL? */ + if (!bininp && termc[nfiles-1] != '\n') { + int c = getchar(); + if ((c != '\n') & (c != EOF)) + ungetc(c, stdin); + } } if (i < nfiles) break; } while (--outcnt); + /* check ending */ + if (fflush(NULL) == EOF) { + fputs(argv[0], stderr); + fputs(": write error on one or more outputs\n", stderr); + return(1); + } + if (outcnt > 0) { + fputs(argv[0], stderr); + fputs(": warning: premature EOD\n", stderr); + } return(0); }