--- ray/src/cal/rcalc.c 2006/12/23 17:27:45 1.20 +++ ray/src/cal/rcalc.c 2019/05/19 21:15:25 1.29 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rcalc.c,v 1.20 2006/12/23 17:27:45 greg Exp $"; +static const char RCSid[] = "$Id: rcalc.c,v 1.29 2019/05/19 21:15:25 greg Exp $"; #endif /* * rcalc.c - record calculator program. @@ -8,9 +8,6 @@ static const char RCSid[] = "$Id: rcalc.c,v 1.20 2006/ */ #include -#include -#include -#include #include #include @@ -20,10 +17,10 @@ static const char RCSid[] = "$Id: rcalc.c,v 1.20 2006/ #include "rtio.h" #include "calcomp.h" -#define isnum(c) (isdigit(c) || (c)=='-' || (c)=='.' \ - || (c)=='+' || (c)=='e' || (c)=='E') +#define isnum(c) (isdigit(c) || ((c)=='-') | ((c)=='.') \ + | ((c)=='+') | ((c)=='e') | ((c)=='E')) -#define isblnk(c) (igneol ? isspace(c) : (c)==' '||(c)=='\t') +#define isblnk(c) (igneol ? isspace(c) : ((c)==' ')|((c)=='\t')) #define INBSIZ 16384 /* longest record */ #define MAXCOL 32 /* number of columns recorded */ @@ -76,6 +73,9 @@ struct field *inpfmt = NULL; /* input record format struct field *outfmt = NULL; /* output record structure */ struct strvar *svhead = NULL; /* string variables */ +long incnt = 0; /* limit number of input records? */ +long outcnt = 0; /* limit number of output records? */ + int blnkeq = 1; /* blanks compare equal? */ int igneol = 0; /* ignore end of line? */ int passive = 0; /* passive mode (transmit unmatched input) */ @@ -107,6 +107,7 @@ int argc, char *argv[] ) { + char *fpath; int i; esupport |= E_VARIABLE|E_FUNCTION|E_INCHAN|E_OUTCHAN|E_RCONST; @@ -136,7 +137,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); @@ -151,6 +160,9 @@ char *argv[] nbicols = 0; readfmt(argv[++i], 0); break; + case 'n': + incnt = atol(argv[++i]); + break; case 'a': itype = 'a'; nbicols = 0; @@ -191,6 +203,9 @@ char *argv[] otype = 'a'; readfmt(argv[++i], 1); break; + case 'n': + outcnt = atol(argv[++i]); + break; case 'a': otype = 'a'; break; @@ -219,6 +234,9 @@ eputs(" [-b][-l][-n][-p][-w][-u][-tS][-s svar=sval][-e } if (otype != 'a') SET_FILE_BINARY(stdout); +#ifdef getc_unlocked /* avoid lock/unlock overhead */ + flockfile(stdout); +#endif if (noinput) { /* produce a single output record */ if (i < argc) { eputs(argv[0]); @@ -229,9 +247,6 @@ eputs(" [-b][-l][-n][-p][-w][-u][-tS][-s svar=sval][-e putout(); quit(0); } - if (itype != 'a') - SET_FILE_BINARY(stdin); - if (blnkeq) /* for efficiency */ nbsynch(); @@ -265,15 +280,15 @@ FILE *fp { if (inpfmt != NULL) return(getrec()); - if (tolower(itype) == 'd') { - if (fread(inpbuf, sizeof(double), nbicols, fp) != nbicols) + if ((itype == 'd') | (itype == 'D')) { + if (getbinary(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) + if ((itype == 'f') | (itype == 'F')) { + if (getbinary(inpbuf, sizeof(float), nbicols, fp) != nbicols) return(0); if (itype == 'F') swap32(inpbuf, nbicols); @@ -288,7 +303,9 @@ execute( /* process a file */ char *file ) { - int conditional = vardefined("cond"); + const int conditional = vardefined("cond"); + const int set_recno = (varlookup("recno") != NULL); + const int set_outno = (varlookup("outno") != NULL); long nrecs = 0; long nout = 0; FILE *fp; @@ -300,17 +317,30 @@ char *file eputs(": cannot open\n"); quit(1); } + if (itype != 'a') + SET_FILE_BINARY(fp); +#ifdef getc_unlocked /* avoid lock/unlock overhead */ + flockfile(fp); +#endif if (inpfmt != NULL) initinp(fp); while (getinputrec(fp)) { - varset("recno", '=', (double)++nrecs); + ++nrecs; + if (set_recno) + varset("recno", '=', (double)nrecs); + if (set_outno) + varset("outno", '=', (double)(nout+1)); colflg = 0; eclock++; if (!conditional || varvalue("cond") > 0.0) { - varset("outno", '=', (double)++nout); putout(); + ++nout; } + if (incnt && nrecs >= incnt) + break; + if (outcnt && nout >= outcnt) + break; } fclose(fp); } @@ -338,7 +368,7 @@ static double l_in(char *funame) /* function call for $channel */ { int n; - register char *cp; + char *cp; /* get argument as integer */ n = (int)(argument(1) + .5); if (n != 0) /* return channel value */ @@ -370,7 +400,7 @@ int n ) { int i; - register char *cp; + char *cp; if (noinput || inpfmt != NULL) { eputs("no column input\n"); @@ -383,7 +413,7 @@ int n if (nbicols) { if (n > nbicols) return(0.0); - if (tolower(itype) == 'd') { + if ((itype == 'd') | (itype == 'D')) { cp = inpbuf + (n-1)*sizeof(double); return(*(double *)cp); } @@ -438,24 +468,24 @@ double v ) { static char zerobuf[sizeof(double)]; + const int otlen = ((otype == 'd') | (otype == 'D')) ? + sizeof(double) : sizeof(float); float fval = v; while (++colpos < n) - fwrite(zerobuf, - tolower(otype)=='d' ? sizeof(double) : sizeof(float), - 1, stdout); + putbinary(zerobuf, otlen, 1, stdout); switch (otype) { case 'D': swap64((char *)&v, 1); /* fall through */ case 'd': - fwrite(&v, sizeof(double), 1, stdout); + putbinary(&v, sizeof(double), 1, stdout); break; case 'F': swap32((char *)&fval, 1); /* fall through */ case 'f': - fwrite(&fval, sizeof(float), 1, stdout); + putbinary(&fval, sizeof(float), 1, stdout); break; } } @@ -471,7 +501,7 @@ int output char *inptr; struct field fmt; int res; - register struct field *f; + struct field *f; /* check for inline format */ for (inptr = spec; *inptr; inptr++) if (*inptr == '$') @@ -531,12 +561,12 @@ int output static int readfield( /* get next field in format */ -register char **pp +char **pp ) { int type = F_NUL; int width = 0; - register char *cp; + char *cp; cp = inpbuf; while (cp < &inpbuf[INBSIZ-1] && **pp != '\0') { @@ -601,7 +631,7 @@ getsvar( /* get string variabl char *svname ) { - register struct strvar *sv; + struct strvar *sv; for (sv = svhead; sv != NULL; sv = sv->next) if (!strcmp(sv->name, svname)) @@ -620,8 +650,8 @@ svpreset( /* preset a string variab char *eqn ) { - register struct strvar *sv; - register char *val; + struct strvar *sv; + char *val; for (val = eqn; *val != '='; val++) if (!*val) @@ -640,7 +670,7 @@ char *eqn static void clearrec(void) /* clear input record variables */ { - register struct field *f; + struct field *f; for (f = inpfmt; f != NULL; f = f->next) switch (f->type & F_TYP) { @@ -661,7 +691,7 @@ static int getrec(void) /* get next record from file */ { int eatline; - register struct field *f; + struct field *f; while (ipb.chr != EOF) { if (blnkeq) { /* beware of nbsynch() */ @@ -670,7 +700,7 @@ getrec(void) /* get next record from file */ if (ipb.chr == EOF) return(0); } - eatline = (!igneol && ipb.chr != '\n'); + eatline = !igneol & (ipb.chr != '\n'); clearrec(); /* start with fresh record */ for (f = inpfmt; f != NULL; f = f->next) if (getfield(f) == -1) @@ -695,14 +725,14 @@ getrec(void) /* get next record from file */ static int getfield( /* get next field */ -register struct field *f +struct field *f ) { static char buf[RMAXWORD+1]; /* no recursion! */ int delim, inword; double d; char *np; - register char *cp; + char *cp; switch (f->type & F_TYP) { case T_LIT: @@ -731,7 +761,7 @@ register struct field *f delim = f->next->f.sl[0]; cp = buf; do { - if (ipb.chr == EOF || ipb.chr == '\n') + if ((ipb.chr == EOF) | (ipb.chr == '\n')) inword = 0; else if (blnkeq && delim != EOF) inword = isblnk(delim) ? @@ -789,10 +819,11 @@ register struct field *f static void putrec(void) /* output a record */ { - char fmt[32]; - register int n; - register struct field *f; + char fmt[32], typ[16]; + int n; + struct field *f; int adlast, adnext; + double dv, av; adlast = 0; for (f = outfmt; f != NULL; f = f->next) { @@ -823,13 +854,24 @@ putrec(void) /* output break; case T_NUM: n = f->type & F_WID; + dv = evalue(f->f.ne); + av = fabs(dv); + if (n <= 9) + strcpy(typ, "g"); + else + sprintf(typ, ".%de", n-5); + if (av < 1L<<31) { + long iv = (int)(av + .5); + if (iv && fabs(av-iv) <= av*1e-14) + strcpy(typ, ".0f"); + } if (adlast && adnext) - strcpy(fmt, "%g"); + sprintf(fmt, "%%%s", typ); else if (adlast) - sprintf(fmt, "%%-%dg", n); + sprintf(fmt, "%%-%d%s", n, typ); else - sprintf(fmt, "%%%dg", n); - printf(fmt, evalue(f->f.ne)); + sprintf(fmt, "%%%d%s", n, typ); + printf(fmt, dv); adlast = 1; break; }