--- ray/src/cal/rcalc.c 2003/02/28 20:29:01 1.2 +++ ray/src/cal/rcalc.c 2003/11/05 19:03:03 1.9 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rcalc.c,v 1.2 2003/02/28 20:29:01 greg Exp $"; +static const char RCSid[] = "$Id: rcalc.c,v 1.9 2003/11/05 19:03:03 greg Exp $"; #endif /* * rcalc.c - record calculator program. @@ -7,20 +7,16 @@ static const char RCSid[] = "$Id: rcalc.c,v 1.2 2003/0 * 9/11/87 */ -#include - #include - +#include +#include #include - #include +#include "platform.h" #include "calcomp.h" +#include "rterror.h" -#ifdef CPM -#define getc agetc /* text files only, right? */ -#endif - #define isnum(c) (isdigit(c) || (c)=='-' || (c)=='.' \ || (c)=='+' || (c)=='e' || (c)=='E') @@ -58,8 +54,18 @@ struct field { /* record format struc #define savqstr(s) strcpy(emalloc(strlen(s)+1),s) #define freqstr(s) efree(s) -extern char *strcpy(), *emalloc(), *savestr(); -struct strvar *getsvar(); +static void scaninp(void), advinp(void), resetinp(void); +static void putrec(void), putout(void), nbsynch(void); +static int getrec(void); +static void execute(char *file); +static void initinp(FILE *fp); +static void svpreset(char *eqn); +static void readfmt(char *spec, int output); +static int readfield(char **pp); +static int getfield(struct field *f); +static void chanset(int n, double v); +static void bchanset(int n, double v); +static struct strvar* getsvar(char *svname); struct field *inpfmt = NULL; /* input record format */ struct field *outfmt = NULL; /* output record structure */ @@ -69,6 +75,8 @@ int blnkeq = 1; /* blanks compare equa int igneol = 0; /* ignore end of line? */ char sepchar = '\t'; /* input/output separator */ int noinput = 0; /* no input records? */ +int nbicols = 0; /* number of binary input columns */ +int bocols = 0; /* produce binary output columns */ char inpbuf[INBSIZ]; /* input buffer */ double colval[MAXCOL]; /* input column values */ unsigned long colflg = 0; /* column retrieved flags */ @@ -86,9 +94,11 @@ struct { } ipb; /* circular lookahead buffer */ -main(argc, argv) -int argc; -char *argv[]; +int +main( +int argc, +char *argv[] +) { int i; @@ -124,10 +134,56 @@ char *argv[]; noinput = 1; break; case 'i': - readfmt(argv[++i], 0); + switch (argv[i][2]) { + case '\0': + nbicols = 0; + readfmt(argv[++i], 0); + break; + case 'a': + nbicols = 0; + break; + case 'd': + if (isdigit(argv[i][3])) + nbicols = atoi(argv[i]+3); + else + nbicols = 1; + if (nbicols*sizeof(double) > INBSIZ) { + eputs(argv[0]); + eputs(": too many input columns\n"); + quit(1); + } + break; + case 'f': + if (isdigit(argv[i][3])) + nbicols = -atoi(argv[i]+3); + else + nbicols = -1; + if (-nbicols*sizeof(float) > INBSIZ) { + eputs(argv[0]); + eputs(": too many input columns\n"); + quit(1); + } + break; + default: + goto userr; + } break; case 'o': - readfmt(argv[++i], 1); + switch (argv[i][2]) { + case '\0': + bocols = 0; + readfmt(argv[++i], 1); + break; + case 'a': + bocols = 0; + break; + case 'd': + bocols = 1; + break; + case 'f': + bocols = -1; + break; + } break; case 'w': nowarn = !nowarn; @@ -135,7 +191,8 @@ char *argv[]; case 'u': unbuff = !unbuff; break; - default: + default:; + userr: eputs("Usage: "); eputs(argv[0]); eputs(" [-b][-l][-n][-w][-u][-tS][-s svar=sval][-e expr][-f source][-i infmt][-o outfmt] [file]\n"); @@ -161,7 +218,8 @@ eputs(" [-b][-l][-n][-w][-u][-tS][-s svar=sval][-e exp } -nbsynch() /* non-blank starting synch character */ +static void +nbsynch(void) /* non-blank starting synch character */ { if (inpfmt == NULL || (inpfmt->type & F_TYP) != T_LIT) return; @@ -172,9 +230,28 @@ nbsynch() /* non-blank starting synch ch } -execute(file) /* process a file */ -char *file; +int +getinputrec( /* get next input record */ +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); + return(fgets(inpbuf, INBSIZ, fp) != NULL); +} + + +static void +execute( /* process a file */ +char *file +) +{ int conditional = vardefined("cond"); long nrecs = 0; long nout = 0; @@ -189,8 +266,8 @@ char *file; } if (inpfmt != NULL) initinp(fp); - - while (inpfmt != NULL ? getrec() : fgets(inpbuf, INBSIZ, fp) != NULL) { + + while (getinputrec(fp)) { varset("recno", '=', (double)++nrecs); colflg = 0; eclock++; @@ -203,16 +280,18 @@ char *file; } -putout() /* produce an output record */ +static void +putout(void) /* produce an output record */ { - extern int chanset(); colpos = 0; if (outfmt != NULL) putrec(); + else if (bocols) + chanout(bchanset); else chanout(chanset); - if (colpos) + if (colpos && !bocols) putchar('\n'); if (unbuff) fflush(stdout); @@ -220,8 +299,9 @@ putout() /* produce an output record */ double -chanvalue(n) /* return value for column n */ -int n; +chanvalue( /* return value for column n */ +int n +) { int i; register char *cp; @@ -234,6 +314,18 @@ int n; eputs("illegal channel number\n"); quit(1); } + if (nbicols > 0) { + if (n > nbicols) + return(0.0); + cp = inpbuf + (n-1)*sizeof(double); + return(*(double *)cp); + } + if (nbicols < 0) { + if (n > -nbicols) + return(0.0); + cp = inpbuf + (n-1)*sizeof(float); + return(*(float *)cp); + } if (n <= MAXCOL && colflg & 1L<<(n-1)) return(colval[n-1]); @@ -259,9 +351,11 @@ int n; } -chanset(n, v) /* output column n */ -int n; -double v; +void +chanset( /* output column n */ +int n, +double v +) { if (colpos == 0) /* no leading separator */ colpos = 1; @@ -273,10 +367,33 @@ double v; } -readfmt(spec, output) /* read record format */ -char *spec; -int output; +void +bchanset( /* output binary channel n */ +int n, +double v +) { + static char zerobuf[sizeof(double)]; + + while (++colpos < n) + fwrite(zerobuf, + bocols>0 ? sizeof(double) : sizeof(float), + 1, stdout); + if (bocols > 0) + fwrite(&v, sizeof(double), 1, stdout); + else { + float fval = v; + fwrite(&fval, sizeof(float), 1, stdout); + } +} + + +static void +readfmt( /* read record format */ +char *spec, +int output +) +{ int fd; char *inptr; struct field fmt; @@ -339,9 +456,10 @@ int output; } -int -readfield(pp) /* get next field in format */ -register char **pp; +static int +readfield( /* get next field in format */ +register char **pp +) { int type = F_NUL; int width = 0; @@ -406,8 +524,9 @@ register char **pp; struct strvar * -getsvar(svname) /* get string variable */ -char *svname; +getsvar( /* get string variable */ +char *svname +) { register struct strvar *sv; @@ -423,8 +542,10 @@ char *svname; } -svpreset(eqn) /* preset a string variable */ -char *eqn; +static void +svpreset( /* preset a string variable */ +char *eqn +) { register struct strvar *sv; register char *val; @@ -443,7 +564,8 @@ char *eqn; } -clearrec() /* clear input record variables */ +static void +clearrec(void) /* clear input record variables */ { register struct field *f; @@ -462,7 +584,8 @@ clearrec() /* clear input record variables */ } -getrec() /* get next record from file */ +static int +getrec(void) /* get next record from file */ { int eatline; register struct field *f; @@ -495,10 +618,12 @@ getrec() /* get next re } -getfield(f) /* get next field */ -register struct field *f; +static int +getfield( /* get next field */ +register struct field *f +) { - static char buf[MAXWORD+1]; /* no recursion! */ + static char buf[RMAXWORD+1]; /* no recursion! */ int delim, inword; double d; char *np; @@ -531,7 +656,7 @@ register struct field *f; delim = f->next->f.sl[0]; cp = buf; do { - if (ipb.chr == EOF) + if (ipb.chr == EOF || ipb.chr == '\n') inword = 0; else if (blnkeq && delim != EOF) inword = isblnk(delim) ? @@ -543,7 +668,7 @@ register struct field *f; *cp++ = ipb.chr; scaninp(); } - } while (inword && cp < &buf[MAXWORD]); + } while (inword && cp < &buf[RMAXWORD]); *cp = '\0'; if (f->f.sv->val == NULL) f->f.sv->val = savqstr(buf); /* first setting */ @@ -572,7 +697,7 @@ register struct field *f; *cp++ = ipb.chr; scaninp(); } - } while (inword && cp < &buf[MAXWORD]); + } while (inword && cp < &buf[RMAXWORD]); *cp = '\0'; d = np==NULL ? 0. : atof(np); if (!vardefined(f->f.nv)) @@ -582,10 +707,12 @@ register struct field *f; return(-1); /* doesn't match! */ return(0); } + return -1; /* pro forma return */ } -putrec() /* output a record */ +static void +putrec(void) /* output a record */ { char fmt[32]; register int n; @@ -635,8 +762,9 @@ putrec() /* output a re } -initinp(fp) /* prepare lookahead buffer */ -FILE *fp; +static void +initinp(FILE *fp) /* prepare lookahead buffer */ + { ipb.fin = fp; ipb.beg = ipb.end = inpbuf; @@ -646,7 +774,8 @@ FILE *fp; } -scaninp() /* scan next character */ +static void +scaninp(void) /* scan next character */ { if (ipb.chr == EOF) return; @@ -665,13 +794,15 @@ scaninp() /* scan next character } -advinp() /* move home to current position */ +static void +advinp(void) /* move home to current position */ { ipb.beg = ipb.pos; } -resetinp() /* rewind position and advance 1 */ +static void +resetinp(void) /* rewind position and advance 1 */ { if (ipb.beg == NULL) /* full */ ipb.beg = ipb.end; @@ -684,16 +815,14 @@ resetinp() /* rewind position and void -eputs(msg) -char *msg; +eputs(char *msg) { fputs(msg, stderr); } void -wputs(msg) -char *msg; +wputs(char *msg) { if (!nowarn) eputs(msg); @@ -701,8 +830,7 @@ char *msg; void -quit(code) -int code; +quit(int code) { exit(code); }