--- ray/src/cal/rcalc.c 2003/11/05 19:03:03 1.9 +++ ray/src/cal/rcalc.c 2004/10/11 10:02:15 1.14 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rcalc.c,v 1.9 2003/11/05 19:03:03 greg Exp $"; +static const char RCSid[] = "$Id: rcalc.c,v 1.14 2004/10/11 10:02:15 greg Exp $"; #endif /* * rcalc.c - record calculator program. @@ -8,14 +8,17 @@ static const char RCSid[] = "$Id: rcalc.c,v 1.9 2003/1 */ #include +#include #include #include #include #include #include "platform.h" -#include "calcomp.h" #include "rterror.h" +#include "rtmisc.h" +#include "rtio.h" +#include "calcomp.h" #define isnum(c) (isdigit(c) || (c)=='-' || (c)=='.' \ || (c)=='+' || (c)=='e' || (c)=='E') @@ -54,6 +57,7 @@ struct field { /* record format struc #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), resetinp(void); static void putrec(void), putout(void), nbsynch(void); static int getrec(void); @@ -66,6 +70,7 @@ 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); +static double l_in(char *); struct field *inpfmt = NULL; /* input record format */ struct field *outfmt = NULL; /* output record structure */ @@ -73,6 +78,7 @@ struct strvar *svhead = NULL; /* string variables */ int blnkeq = 1; /* blanks compare equal? */ 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 nbicols = 0; /* number of binary input columns */ @@ -109,6 +115,7 @@ char *argv[] biggerlib(); #endif varset("PI", ':', 3.14159265358979323846); + funset("in", 1, '=', &l_in); for (i = 1; i < argc && argv[i][0] == '-'; i++) switch (argv[i][1]) { @@ -118,6 +125,9 @@ char *argv[] case 'l': igneol = !igneol; break; + case 'p': + passive = !passive; + break; case 't': sepchar = argv[i][2]; break; @@ -195,7 +205,7 @@ char *argv[] 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"); +eputs(" [-b][-l][-n][-p][-w][-u][-tS][-s svar=sval][-e expr][-f source][-i infmt][-o outfmt] [file]\n"); quit(1); } @@ -215,6 +225,7 @@ eputs(" [-b][-l][-n][-w][-u][-tS][-s svar=sval][-e exp execute(argv[i]); quit(0); + return 0; /* pro forma return */ } @@ -230,7 +241,7 @@ nbsynch(void) /* non-blank starting sync } -int +static int getinputrec( /* get next input record */ FILE *fp ) @@ -298,6 +309,38 @@ putout(void) /* produce an output recor } +static double +l_in(char *funame) /* function call for $channel */ +{ + int n; + register char *cp; + /* get argument as integer */ + n = (int)(argument(1) + .5); + if (n != 0) /* return channel value */ + return(chanvalue(n)); + /* determine number of channels */ + if (noinput || inpfmt != NULL) + return(0); + if (nbicols > 0) + return(nbicols); + if (nbicols < 0) + return(-nbicols); + cp = inpbuf; /* need to count */ + for (n = 0; *cp; ) + if (blnkeq && isspace(sepchar)) { + while (isspace(*cp)) + cp++; + n += *cp != '\0'; + while (*cp && !isspace(*cp)) + cp++; + } else { + n += *cp != '\n'; + while (*cp && *cp++ != sepchar) + ; + } + return(n); +} + double chanvalue( /* return value for column n */ int n @@ -411,7 +454,7 @@ int output eputs(": cannot open\n"); quit(1); } - res = read(fd, inpbuf+1, INBSIZ-1); + res = read(fd, inpbuf+2, INBSIZ-2); if (res <= 0 || res >= INBSIZ-1) { eputs(spec); if (res < 0) @@ -423,7 +466,7 @@ int output quit(1); } close(fd); - (inptr=inpbuf+1)[res] = '\0'; + (inptr=inpbuf+2)[res] = '\0'; } f = &fmt; /* get fields */ while ((res = readfield(&inptr)) != F_NUL) { @@ -585,33 +628,32 @@ clearrec(void) /* clear input record variables */ static int -getrec(void) /* get next record from file */ +getrec(void) /* get next record from file */ { int eatline; register struct field *f; - + while (ipb.chr != EOF) { eatline = !igneol && ipb.chr != '\n'; if (blnkeq) /* beware of nbsynch() */ while (isblnk(ipb.chr)) - scaninp(); + resetinp(); clearrec(); /* start with fresh record */ for (f = inpfmt; f != NULL; f = f->next) if (getfield(f) == -1) break; if (f == NULL) { - advinp(); + advinp(); /* got one! */ return(1); } - resetinp(); + resetinp(); /* eat false start */ if (eatline) { /* eat rest of line */ while (ipb.chr != '\n') { if (ipb.chr == EOF) return(0); - scaninp(); + resetinp(); } - scaninp(); - advinp(); + resetinp(); } } return(0); @@ -808,6 +850,8 @@ resetinp(void) /* rewind position ipb.beg = ipb.end; ipb.pos = ipb.beg; ipb.chr = *ipb.pos; + if (passive) /* transmit unmatched character? */ + fputc(ipb.chr, stdout); if (++ipb.beg >= &inpbuf[INBSIZ]) ipb.beg = inpbuf; scaninp();