--- ray/src/cal/rcalc.c 2022/03/11 22:50:13 1.32 +++ ray/src/cal/rcalc.c 2022/03/13 16:11:48 1.36 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rcalc.c,v 1.32 2022/03/11 22:50:13 greg Exp $"; +static const char RCSid[] = "$Id: rcalc.c,v 1.36 2022/03/13 16:11:48 greg Exp $"; #endif /* * rcalc.c - record calculator program. @@ -22,40 +22,40 @@ static const char RCSid[] = "$Id: rcalc.c,v 1.32 2022/ #define isblnk(c) (igneol ? isspace(c) : ((c)==' ')|((c)=='\t')) -#define INBSIZ 16384 /* longest record */ -#define MAXCOL 32 /* number of columns recorded */ +#define INBSIZ 16384 /* longest record */ +#define MAXCOL 32 /* number of columns recorded */ - /* field type specifications */ -#define F_NUL 0 /* empty */ -#define F_TYP 0x7000 /* mask for type */ -#define F_WID 0x0fff /* mask for width */ -#define T_LIT 0x1000 /* string literal */ -#define T_STR 0x2000 /* string variable */ -#define T_NUM 0x3000 /* numeric value */ + /* field type specifications */ +#define F_NUL 0 /* empty */ +#define F_TYP 0x7000 /* mask for type */ +#define F_WID 0x0fff /* mask for width */ +#define T_LIT 0x1000 /* string literal */ +#define T_STR 0x2000 /* string variable */ +#define T_NUM 0x3000 /* numeric value */ -struct strvar { /* string variable */ +struct strvar { /* string variable */ char *name; char *val; char *preset; struct strvar *next; }; -struct field { /* record format structure */ - int type; /* type of field (& width) */ +struct field { /* record format structure */ + int type; /* type of field (& width) */ union { - char *sl; /* string literal */ - struct strvar *sv; /* string variable */ - char *nv; /* numeric variable */ - EPNODE *ne; /* numeric expression */ - } f; /* field contents */ - struct field *next; /* next field in record */ + char *sl; /* string literal */ + struct strvar *sv; /* string variable */ + char *nv; /* numeric variable */ + EPNODE *ne; /* numeric expression */ + } f; /* field contents */ + struct field *next; /* next field in record */ }; #define savqstr(s) strcpy(emalloc(strlen(s)+1),s) #define freqstr(s) efree(s) static int getinputrec(FILE *fp); -static void scaninp(void), advinp(void), passinp(void), skipinp(void); +static void scaninp(void), skipinp(void), advinp(int skip); static void putrec(void), putout(void), nbsynch(void); static int getrec(void); static void execute(char *file); @@ -93,12 +93,12 @@ int nowarn = 0; /* non-fatal diagnostic output */ int unbuff = 0; /* unbuffered output (flush each record) */ struct { - FILE *fin; /* input file */ - int chr; /* next character */ - char *beg; /* home position */ - char *pos; /* scan position */ - char *end; /* read position */ -} ipb; /* circular lookahead buffer */ + FILE *fin; /* input file */ + int chr; /* next character */ + char *beg; /* home position */ + char *pos; /* scan position */ + char *end; /* read position */ +} ipb; /* circular lookahead buffer */ int @@ -240,7 +240,7 @@ eputs(" [-b][-l][-n][-p|-P][-w][-u][-tS][-s svar=sval] #ifdef getc_unlocked /* avoid lock/unlock overhead */ flockfile(stdout); #endif - if (noinput) { /* produce a single output record */ + if (noinput) { /* produce a single output record */ if (i < argc) { eputs(argv[0]); eputs(": file argument(s) incompatible with -n\n"); @@ -255,12 +255,12 @@ eputs(" [-b][-l][-n][-p|-P][-w][-u][-tS][-s svar=sval] eputs(": options -p and -P require -i and -o formats\n"); quit(1); } - if (blnkeq) /* for efficiency */ + if (blnkeq) /* for efficiency */ nbsynch(); - if (i == argc) /* from stdin */ + if (i == argc) /* from stdin */ execute(NULL); - else /* from one or more files */ + else /* from one or more files */ for ( ; i < argc; i++) execute(argv[i]); @@ -270,7 +270,7 @@ eputs(" [-b][-l][-n][-p|-P][-w][-u][-tS][-s svar=sval] static void -nbsynch(void) /* non-blank starting synch character */ +nbsynch(void) /* non-blank starting synch character */ { if (inpfmt == NULL || (inpfmt->type & F_TYP) != T_LIT) return; @@ -305,16 +305,19 @@ FILE *fp static void -execute( /* process a file */ +execute( /* process a file */ char *file ) { - 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; + static char condVN[] = "cond"; + static char recnoVN[] = "recno"; + static char outnoVN[] = "outno"; + const int conditional = vardefined(condVN); + const int set_recno = (varlookup(recnoVN) != NULL); + const int set_outno = (varlookup(outnoVN) != NULL); + long nrecs = 0; + long nout = 0; + FILE *fp; if (file == NULL) fp = stdin; @@ -328,26 +331,29 @@ char *file #ifdef getc_unlocked /* avoid lock/unlock overhead */ flockfile(fp); #endif + if (conditional == ':') { + eputs(condVN); + eputs(": defined as constant\n"); + quit(1); + } if (inpfmt != NULL) initinp(fp); while (inpfmt != NULL ? getrec() : getinputrec(fp)) { ++nrecs; if (set_recno) - varset("recno", '=', (double)nrecs); + varset(recnoVN, '=', (double)nrecs); if (set_outno) - varset("outno", '=', (double)(nout+1)); + varset(outnoVN, '=', (double)(nout+1)); colflg = 0; eclock++; - if (!conditional || varvalue("cond") > 0.0) { + if (!conditional || varvalue(condVN) > 0.0) { + if (inpfmt != NULL) + advinp(0); putout(); ++nout; - advinp(); } else if (inpfmt != NULL) { - if (passive < 0) - passinp(); - else - advinp(); + advinp(1); } if (incnt && nrecs >= incnt) break; @@ -407,7 +413,7 @@ l_in(char *funame) /* function call for $channel */ } double -chanvalue( /* return value for column n */ +chanvalue( /* return value for column n */ int n ) { @@ -446,7 +452,7 @@ int n while (*cp && *cp++ != sepchar) ; - while (isspace(*cp)) /* some atof()'s don't like tabs */ + while (isspace(*cp)) /* some atof()'s don't like tabs */ cp++; if (n <= MAXCOL) { @@ -458,7 +464,7 @@ int n void -chanset( /* output column n */ +chanset( /* output column n */ int n, double v ) @@ -474,7 +480,7 @@ double v void -bchanset( /* output binary channel n */ +bchanset( /* output binary channel n */ int n, double v ) @@ -504,7 +510,7 @@ double v static void -readfmt( /* read record format */ +readfmt( /* read record format */ char *spec, int output ) @@ -518,9 +524,9 @@ int output for (inptr = spec; *inptr; inptr++) if (*inptr == '$') break; - if (*inptr) /* inline */ + if (*inptr) /* inline */ inptr = spec; - else { /* from file */ + else { /* from file */ if ((fd = open(spec, 0)) == -1) { eputs(spec); eputs(": cannot open\n"); @@ -540,7 +546,7 @@ int output close(fd); (inptr=inpbuf+2)[res] = '\0'; } - f = &fmt; /* get fields */ + f = &fmt; /* get fields */ while ((res = readfield(&inptr)) != F_NUL) { f->next = (struct field *)emalloc(sizeof(struct field)); f = f->next; @@ -572,7 +578,7 @@ int output static int -readfield( /* get next field in format */ +readfield( /* get next field in format */ char **pp ) { @@ -639,7 +645,7 @@ char **pp struct strvar * -getsvar( /* get string variable */ +getsvar( /* get string variable */ char *svname ) { @@ -658,7 +664,7 @@ char *svname static void -svpreset( /* preset a string variable */ +svpreset( /* preset a string variable */ char *eqn ) { @@ -734,11 +740,11 @@ getrec(void) /* get next record from file */ static int -getfield( /* get next field */ +getfield( /* get next field */ struct field *f ) { - static char buf[RMAXWORD+1]; /* no recursion! */ + static char buf[RMAXWORD+1]; /* no recursion! */ int delim, inword; double d; char *np; @@ -890,7 +896,7 @@ putrec(void) /* output a record */ static void -initinp(FILE *fp) /* prepare lookahead buffer */ +initinp(FILE *fp) /* prepare lookahead buffer */ { ipb.fin = fp; @@ -908,7 +914,7 @@ scaninp(void) /* scan next character */ return; if (++ipb.pos >= &inpbuf[INBSIZ]) ipb.pos = inpbuf; - if (ipb.pos == ipb.end) { /* new character */ + if (ipb.pos == ipb.end) { /* new character */ if ((ipb.chr = getc(ipb.fin)) != EOF) { *ipb.end = ipb.chr; if (++ipb.end >= &inpbuf[INBSIZ]) @@ -922,39 +928,37 @@ scaninp(void) /* scan next character */ static void -advinp(void) /* move home to current position */ +skipinp(void) /* rewind position and advance 1 */ { - ipb.beg = ipb.pos; + if (ipb.beg == NULL) /* can't fully rewind? */ + ipb.beg = ipb.end; + ipb.pos = ipb.beg; + ipb.chr = *ipb.pos; + if (passive) /* transmit unmatched character? */ + putchar(ipb.chr); + if (++ipb.beg >= &inpbuf[INBSIZ]) + ipb.beg = inpbuf; + scaninp(); } static void -passinp(void) /* pass beginning to current position */ +advinp(int skip) /* advance home to current position */ { - if (!passive | (ipb.beg == NULL)) { - advinp(); + if (!skip | (passive >= 0)) { + ipb.beg = ipb.pos; /* no need to copy input */ return; } - while (ipb.beg != ipb.pos) { /* transfer buffer unaltered */ + if (ipb.beg == NULL) { /* buffer overflowed a bit? */ + wputs("buffer overflow\n"); + puts("\n*** MISSING DATA ***"); + ipb.beg = ipb.end; + } + while (ipb.beg != ipb.pos) { /* copy buffer to current */ putchar(*ipb.beg); if (++ipb.beg >= &inpbuf[INBSIZ]) ipb.beg = inpbuf; } -} - - -static void -skipinp(void) /* rewind position and advance 1 */ -{ - if (ipb.beg == NULL) /* full */ - ipb.beg = ipb.end; - ipb.pos = ipb.beg; - ipb.chr = *ipb.pos; - if (passive) /* transmit unmatched character? */ - putchar(ipb.chr); - if (++ipb.beg >= &inpbuf[INBSIZ]) - ipb.beg = inpbuf; - scaninp(); }