--- ray/src/cal/rsplit.c 2020/03/31 16:39:01 1.12 +++ ray/src/cal/rsplit.c 2020/04/05 15:07:09 1.15 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rsplit.c,v 1.12 2020/03/31 16:39:01 greg Exp $"; +static const char RCSid[] = "$Id: rsplit.c,v 1.15 2020/04/05 15:07:09 greg Exp $"; #endif /* * rsplit.c - split input into multiple output streams @@ -96,13 +96,16 @@ main(int argc, char *argv[]) int append = 0; long outcnt = 0; int bininp = 0; + int nstdoutcomp = 0; int curterm = '\n'; int curncomp = 1; int curbytes = 0; int curflags = 0; const char *curfmt = "ascii"; - int i; + short outndx[MAXFILE]; + int i; + memset(outndx, 0, sizeof(outndx)); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { @@ -181,16 +184,20 @@ main(int argc, char *argv[]) } bininp += (curbytes > 0); break; - case '\0': - needres |= (curflags & DORESOLU); - termc[nfiles] = curterm; - hdrflags[nfiles] = curflags; + case '\0': /* stdout */ + if (!nstdoutcomp) { /* first use? */ + needres |= (curflags & DORESOLU); + hdrflags[nfiles] = curflags; + } output[nfiles] = stdout; if (curbytes > 0) SET_FILE_BINARY(output[nfiles]); + termc[nfiles] = curterm; format[nfiles] = curfmt; - ncomp[nfiles] = curncomp; - bytsiz[nfiles++] = curbytes; + nstdoutcomp += + ncomp[nfiles] = curncomp; + bytsiz[nfiles] = curbytes; + outndx[nfiles++] = i; break; badopt:; default: @@ -198,10 +205,17 @@ main(int argc, char *argv[]) fputs(": bad option\n", stderr); return(1); } + } else if (argv[i][0] == '.' && !argv[i][1]) { + output[nfiles] = NULL; /* discard data */ + termc[nfiles] = curterm; + format[nfiles] = curfmt; + ncomp[nfiles] = curncomp; + bytsiz[nfiles] = curbytes; + outndx[nfiles++] = i; } else if (argv[i][0] == '!') { needres |= (curflags & DORESOLU); - termc[nfiles] = curterm; hdrflags[nfiles] = curflags; + termc[nfiles] = curterm; if ((output[nfiles] = popen(argv[i]+1, "w")) == NULL) { fputs(argv[i], stderr); fputs(": cannot start command\n", stderr); @@ -211,8 +225,18 @@ main(int argc, char *argv[]) SET_FILE_BINARY(output[nfiles]); format[nfiles] = curfmt; ncomp[nfiles] = curncomp; - bytsiz[nfiles++] = curbytes; + bytsiz[nfiles] = curbytes; + outndx[nfiles++] = i; } else { + int j = nfiles; + while (j--) /* check duplicates */ + if (!strcmp(argv[i], argv[outndx[j]])) { + fputs(argv[0], stderr); + fputs(": duplicate output: ", stderr); + fputs(argv[i], stderr); + fputc('\n', stderr); + return(1); + } if (append & (curflags != 0)) { fputs(argv[0], stderr); fputs(": -a option incompatible with -oh and -oH\n", @@ -220,8 +244,8 @@ main(int argc, char *argv[]) return(1); } needres |= (curflags & DORESOLU); - termc[nfiles] = curterm; hdrflags[nfiles] = curflags; + termc[nfiles] = curterm; if (!append & !force && access(argv[i], F_OK) == 0) { fputs(argv[i], stderr); fputs(": file exists -- use -f to overwrite\n", @@ -238,7 +262,8 @@ main(int argc, char *argv[]) SET_FILE_BINARY(output[nfiles]); format[nfiles] = curfmt; ncomp[nfiles] = curncomp; - bytsiz[nfiles++] = curbytes; + bytsiz[nfiles] = curbytes; + outndx[nfiles++] = i; } if (nfiles >= MAXFILE) { fputs(argv[0], stderr); @@ -256,20 +281,20 @@ main(int argc, char *argv[]) #ifdef getc_unlocked /* avoid lock/unlock overhead */ flockfile(stdin); for (i = nfiles; i--; ) - flockfile(output[i]); + if (output[i] != NULL) + ftrylockfile(output[i]); #endif /* load/copy header */ if (inpflags & DOHEADER && getheader(stdin, headline, NULL) < 0) { fputs(argv[0], stderr); - fputs(": cannot get header from standard input\n", + fputs(": cannot read header from standard input\n", stderr); return(1); } /* handle resolution string */ if (inpflags & DORESOLU && !fgetsresolu(&ourres, stdin)) { fputs(argv[0], stderr); - fputs(": cannot get resolution string from standard input\n", - stderr); + fputs(": bad resolution string on standard input\n", stderr); return(1); } if (needres && (ourres.xr <= 0) | (ourres.yr <= 0)) { @@ -291,11 +316,11 @@ main(int argc, char *argv[]) if (!(inpflags & DOHEADER)) newheader("RADIANCE", output[i]); printargs(argc, argv, output[i]); - fprintf(output[i], "NCOMP=%d\n", ncomp[i]); + fprintf(output[i], "NCOMP=%d\n", output[i]==stdout ? + nstdoutcomp : ncomp[i]); if (format[i] != NULL) { extern const char BIGEND[]; - if ((format[i][0] == 'f') | - (format[i][0] == 'd')) { + if (bytsiz[i] > 1) { fputs(BIGEND, output[i]); fputs(nativebigendian() ^ swapped ? "1\n" : "0\n", output[i]); @@ -313,7 +338,8 @@ main(int argc, char *argv[]) if (getbinary(buf, bytsiz[i], ncomp[i], stdin) < ncomp[i]) break; - if (putbinary(buf, bytsiz[i], ncomp[i], + if (output[i] != NULL && + putbinary(buf, bytsiz[i], ncomp[i], output[i]) < ncomp[i]) break; } else if (ncomp[i] > 1) { /* N-field output */ @@ -321,20 +347,24 @@ main(int argc, char *argv[]) while (n--) { if (!scanOK(termc[i])) break; - if (fputs(buf, output[i]) == EOF) + if (output[i] != NULL && + fputs(buf, output[i]) == EOF) break; } if (n >= 0) /* fell short? */ break; - if (termc[i] != '\n') /* add EOL if none */ + if ((output[i] != NULL) & /* add EOL if none */ + (termc[i] != '\n')) fputc('\n', output[i]); } else { /* 1-field output */ if (!scanOK(termc[i])) break; - if (fputs(buf, output[i]) == EOF) - break; - if (termc[i] != '\n') /* add EOL if none */ - fputc('\n', output[i]); + if (output[i] != NULL) { + if (fputs(buf, output[i]) == EOF) + break; + if (termc[i] != '\n') /* add EOL? */ + fputc('\n', output[i]); + } } /* skip input EOL? */ if (!bininp && termc[nfiles-1] != '\n') {