--- ray/src/cal/rcalc.c 2004/10/11 10:02:15 1.14 +++ ray/src/cal/rcalc.c 2013/12/19 16:38:12 1.22 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rcalc.c,v 1.14 2004/10/11 10:02:15 greg Exp $"; +static const char RCSid[] = "$Id: rcalc.c,v 1.22 2013/12/19 16:38:12 greg Exp $"; #endif /* * rcalc.c - record calculator program. @@ -8,9 +8,6 @@ static const char RCSid[] = "$Id: rcalc.c,v 1.14 2004/ */ #include -#include -#include -#include #include #include @@ -25,7 +22,7 @@ static const char RCSid[] = "$Id: rcalc.c,v 1.14 2004/ #define isblnk(c) (igneol ? isspace(c) : (c)==' '||(c)=='\t') -#define INBSIZ 4096 /* longest record */ +#define INBSIZ 16384 /* longest record */ #define MAXCOL 32 /* number of columns recorded */ /* field type specifications */ @@ -81,8 +78,9 @@ int igneol = 0; /* ignore end of line? int passive = 0; /* passive mode (transmit unmatched input) */ char sepchar = '\t'; /* input/output separator */ int noinput = 0; /* no input records? */ +int itype = 'a'; /* input type (a/f/F/d/D) */ int nbicols = 0; /* number of binary input columns */ -int bocols = 0; /* produce binary output columns */ +int otype = 'a'; /* output format (a/f/F/d/D) */ char inpbuf[INBSIZ]; /* input buffer */ double colval[MAXCOL]; /* input column values */ unsigned long colflg = 0; /* column retrieved flags */ @@ -106,6 +104,7 @@ int argc, char *argv[] ) { + char *fpath; int i; esupport |= E_VARIABLE|E_FUNCTION|E_INCHAN|E_OUTCHAN|E_RCONST; @@ -135,7 +134,15 @@ char *argv[] svpreset(argv[++i]); break; case 'f': - fcompile(argv[++i]); + fpath = getpath(argv[++i], getrlibpath(), 0); + if (fpath == NULL) { + eputs(argv[0]); + eputs(": cannot find file '"); + eputs(argv[i]); + eputs("'\n"); + quit(1); + } + fcompile(fpath); break; case 'e': scompile(argv[++i], NULL, 0); @@ -146,13 +153,17 @@ char *argv[] case 'i': switch (argv[i][2]) { case '\0': + itype = 'a'; nbicols = 0; readfmt(argv[++i], 0); break; case 'a': + itype = 'a'; nbicols = 0; break; case 'd': + case 'D': + itype = argv[i][2]; if (isdigit(argv[i][3])) nbicols = atoi(argv[i]+3); else @@ -164,11 +175,13 @@ char *argv[] } break; case 'f': + case 'F': + itype = argv[i][2]; if (isdigit(argv[i][3])) - nbicols = -atoi(argv[i]+3); + nbicols = atoi(argv[i]+3); else - nbicols = -1; - if (-nbicols*sizeof(float) > INBSIZ) { + nbicols = 1; + if (nbicols*sizeof(float) > INBSIZ) { eputs(argv[0]); eputs(": too many input columns\n"); quit(1); @@ -181,18 +194,20 @@ char *argv[] case 'o': switch (argv[i][2]) { case '\0': - bocols = 0; + otype = 'a'; readfmt(argv[++i], 1); break; case 'a': - bocols = 0; + otype = 'a'; break; case 'd': - bocols = 1; - break; + case 'D': case 'f': - bocols = -1; + case 'F': + otype = argv[i][2]; break; + default: + goto userr; } break; case 'w': @@ -208,12 +223,20 @@ char *argv[] eputs(" [-b][-l][-n][-p][-w][-u][-tS][-s svar=sval][-e expr][-f source][-i infmt][-o outfmt] [file]\n"); quit(1); } - + if (otype != 'a') + SET_FILE_BINARY(stdout); if (noinput) { /* produce a single output record */ + if (i < argc) { + eputs(argv[0]); + eputs(": file argument(s) incompatible with -n\n"); + quit(1); + } eclock++; putout(); quit(0); } + if (itype != 'a') + SET_FILE_BINARY(stdin); if (blnkeq) /* for efficiency */ nbsynch(); @@ -248,12 +271,20 @@ FILE *fp { if (inpfmt != NULL) return(getrec()); - if (nbicols > 0) - return(fread(inpbuf, sizeof(double), - nbicols, fp) == nbicols); - if (nbicols < 0) - return(fread(inpbuf, sizeof(float), - -nbicols, fp) == -nbicols); + if (tolower(itype) == 'd') { + if (fread(inpbuf, sizeof(double), nbicols, fp) != nbicols) + return(0); + if (itype == 'D') + swap64(inpbuf, nbicols); + return(1); + } + if (tolower(itype) == 'f') { + if (fread(inpbuf, sizeof(float), nbicols, fp) != nbicols) + return(0); + if (itype == 'F') + swap32(inpbuf, nbicols); + return(1); + } return(fgets(inpbuf, INBSIZ, fp) != NULL); } @@ -280,11 +311,12 @@ char *file while (getinputrec(fp)) { varset("recno", '=', (double)++nrecs); + varset("outno", '=', (double)(nout+1)); colflg = 0; eclock++; if (!conditional || varvalue("cond") > 0.0) { - varset("outno", '=', (double)++nout); putout(); + ++nout; } } fclose(fp); @@ -298,11 +330,11 @@ putout(void) /* produce an output recor colpos = 0; if (outfmt != NULL) putrec(); - else if (bocols) - chanout(bchanset); - else + else if (otype == 'a') chanout(chanset); - if (colpos && !bocols) + else + chanout(bchanset); + if (colpos && otype == 'a') putchar('\n'); if (unbuff) fflush(stdout); @@ -321,10 +353,8 @@ l_in(char *funame) /* function call for $channel */ /* determine number of channels */ if (noinput || inpfmt != NULL) return(0); - if (nbicols > 0) + if (nbicols) return(nbicols); - if (nbicols < 0) - return(-nbicols); cp = inpbuf; /* need to count */ for (n = 0; *cp; ) if (blnkeq && isspace(sepchar)) { @@ -357,15 +387,13 @@ int n eputs("illegal channel number\n"); quit(1); } - if (nbicols > 0) { + if (nbicols) { if (n > nbicols) return(0.0); - cp = inpbuf + (n-1)*sizeof(double); - return(*(double *)cp); - } - if (nbicols < 0) { - if (n > -nbicols) - return(0.0); + if (tolower(itype) == 'd') { + cp = inpbuf + (n-1)*sizeof(double); + return(*(double *)cp); + } cp = inpbuf + (n-1)*sizeof(float); return(*(float *)cp); } @@ -417,16 +445,25 @@ double v ) { static char zerobuf[sizeof(double)]; + float fval = v; while (++colpos < n) fwrite(zerobuf, - bocols>0 ? sizeof(double) : sizeof(float), + tolower(otype)=='d' ? sizeof(double) : sizeof(float), 1, stdout); - if (bocols > 0) + switch (otype) { + case 'D': + swap64((char *)&v, 1); + /* fall through */ + case 'd': fwrite(&v, sizeof(double), 1, stdout); - else { - float fval = v; + break; + case 'F': + swap32((char *)&fval, 1); + /* fall through */ + case 'f': fwrite(&fval, sizeof(float), 1, stdout); + break; } } @@ -634,10 +671,13 @@ getrec(void) /* get next record from file */ register struct field *f; while (ipb.chr != EOF) { - eatline = !igneol && ipb.chr != '\n'; - if (blnkeq) /* beware of nbsynch() */ + if (blnkeq) { /* beware of nbsynch() */ while (isblnk(ipb.chr)) resetinp(); + if (ipb.chr == EOF) + return(0); + } + eatline = (!igneol && ipb.chr != '\n'); clearrec(); /* start with fresh record */ for (f = inpfmt; f != NULL; f = f->next) if (getfield(f) == -1)