--- ray/src/cal/total.c 2005/06/02 04:47:27 1.4 +++ ray/src/cal/total.c 2016/03/24 19:00:54 1.12 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: total.c,v 1.4 2005/06/02 04:47:27 greg Exp $"; +static const char RCSid[] = "$Id: total.c,v 1.12 2016/03/24 19:00:54 greg Exp $"; #endif /* * total.c - program to reduce columns of data. @@ -13,7 +13,7 @@ static const char RCSid[] = "$Id: total.c,v 1.4 2005/0 #include #include "platform.h" -#define MAXCOL 256 /* maximum number of columns */ +#define MAXCOL 8192 /* maximum number of columns */ #define ADD 0 /* add numbers */ #define MULT 1 /* multiply numbers */ @@ -22,6 +22,9 @@ static const char RCSid[] = "$Id: total.c,v 1.4 2005/0 double init_val[] = {0., 1., -1e12, 1e12}; /* initial values */ +long incnt = 0; /* limit number of input records? */ +long outcnt = 0; /* limit number of output records? */ + int func = ADD; /* default function */ double power = 0.0; /* power for sum */ int mean = 0; /* compute mean */ @@ -30,6 +33,7 @@ int nbicols = 0; /* number of binary input columns int bocols = 0; /* produce binary output columns */ int tabc = '\t'; /* default separator */ int subtotal = 0; /* produce subtotals? */ +int nrecsout = 0; /* number of records produced */ static int execute(char *fname); @@ -72,6 +76,9 @@ char *argv[] break; case 'i': switch (argv[a][2]) { + case 'n': + incnt = atol(argv[++a]); + break; case 'a': nbicols = 0; break; @@ -105,6 +112,9 @@ char *argv[] break; case 'o': switch (argv[a][2]) { + case 'n': + outcnt = atol(argv[++a]); + break; case 'a': bocols = 0; break; @@ -143,7 +153,7 @@ char *argv[] if (a >= argc) status = execute(NULL) == -1 ? 1 : status; else - for ( ; a < argc; a++) + for ( ; a < argc && (outcnt <= 0 || nrecsout < outcnt); a++) status = execute(argv[a]) == -1 ? 2 : status; exit(status); } @@ -213,8 +223,10 @@ putrecord( /* write out results record */ return; } /* ASCII output */ - while (n-- > 0) - fprintf(fp, "%.9g%c", *field++, tabc); + while (n-- > 0) { + fprintf(fp, "%.9g", *field++); + if (n) fputc(tabc, fp); + } fputc('\n', fp); } @@ -226,8 +238,9 @@ char *fname { double inpval[MAXCOL]; double tally[MAXCOL]; + short rsign[MAXCOL]; double result[MAXCOL]; - register int n; + int n; int nread, ncol; long nlin, ltotal; FILE *fp; @@ -240,18 +253,25 @@ char *fname } if (nbicols) SET_FILE_BINARY(fp); +#ifdef getc_unlocked /* avoid lock/unlock overhead */ + flockfile(fp); +#endif + ltotal = 0; while (!feof(fp)) { if (ltotal == 0) { /* initialize */ if (func == MULT) /* special case */ - for (n = 0; n < MAXCOL; n++) + for (n = 0; n < MAXCOL; n++) { tally[n] = 0.0; + rsign[n] = 1; + } else for (n = 0; n < MAXCOL; n++) tally[n] = init_val[func]; } ncol = 0; for (nlin = 0; (count <= 0 || nlin < count) && + (incnt <= 0 || nlin < incnt) && (nread = getrecord(inpval, fp)) > 0; nlin++) { /* compute */ @@ -267,8 +287,13 @@ char *fname break; case MULT: if (inpval[n] == 0.0) - break; - tally[n] += log(fabs(inpval[n])); + rsign[n] = 0; + else if (inpval[n] < 0.0) { + rsign[n] = -rsign[n]; + inpval[n] = -inpval[n]; + } + if (rsign[n]) + tally[n] += log(inpval[n]); break; case MAX: if (inpval[n] > tally[n]) @@ -294,11 +319,16 @@ char *fname result[n] = pow(result[n], 1.0/power); } if (func == MULT) - result[n] = exp(tally[n]); + result[n] = rsign[n] * exp(result[n]); } putrecord(result, ncol, stdout); + ++nrecsout; + if (outcnt > 0 && nrecsout >= outcnt) + break; if (!subtotal) ltotal = 0; + if (incnt > 0 && nlin >= incnt) + break; } /* close input */ return(fclose(fp));