| 1 | #ifndef lint | 
| 2 | static const char       RCSid[] = "$Id: total.c,v 1.1 2003/02/22 02:07:20 greg Exp $"; | 
| 3 | #endif | 
| 4 | /* | 
| 5 | *  total.c - program to reduce columns of data. | 
| 6 | * | 
| 7 | *      5/18/88 | 
| 8 | */ | 
| 9 |  | 
| 10 | #include  <stdio.h> | 
| 11 | #include  <stdlib.h> | 
| 12 | #include  <ctype.h> | 
| 13 | #include  <math.h> | 
| 14 |  | 
| 15 | #define  MAXCOL         256             /* maximum number of columns */ | 
| 16 |  | 
| 17 | #define  ADD            0               /* add numbers */ | 
| 18 | #define  MULT           1               /* multiply numbers */ | 
| 19 | #define  MAX            2               /* maximum */ | 
| 20 | #define  MIN            3               /* minimum */ | 
| 21 |  | 
| 22 | double  init_val[] = {0., 1., -1e12, 1e12};     /* initial values */ | 
| 23 |  | 
| 24 | int  func = ADD;                        /* default function */ | 
| 25 | double  power = 0.0;                    /* power for sum */ | 
| 26 | int  mean = 0;                          /* compute mean */ | 
| 27 | int  count = 0;                         /* number to sum */ | 
| 28 | int  tabc = '\t';                       /* default separator */ | 
| 29 | int  subtotal = 0;                      /* produce subtotals? */ | 
| 30 |  | 
| 31 | static int execute(char *fname); | 
| 32 |  | 
| 33 | int | 
| 34 | main( | 
| 35 | int  argc, | 
| 36 | char  *argv[] | 
| 37 | ) | 
| 38 | { | 
| 39 | int  status; | 
| 40 | int  a; | 
| 41 |  | 
| 42 | for (a = 1; a < argc; a++) | 
| 43 | if (argv[a][0] == '-') | 
| 44 | if (argv[a][1] >= '0' && argv[a][1] <= '9') | 
| 45 | count = atoi(argv[a]+1); | 
| 46 | else | 
| 47 | switch (argv[a][1]) { | 
| 48 | case 'm': | 
| 49 | mean = !mean; | 
| 50 | break; | 
| 51 | case 'p': | 
| 52 | func = MULT; | 
| 53 | break; | 
| 54 | case 's': | 
| 55 | func = ADD; | 
| 56 | power = atof(argv[a]+2); | 
| 57 | break; | 
| 58 | case 'u': | 
| 59 | func = MAX; | 
| 60 | break; | 
| 61 | case 'l': | 
| 62 | func = MIN; | 
| 63 | break; | 
| 64 | case 't': | 
| 65 | tabc = argv[a][2]; | 
| 66 | break; | 
| 67 | case 'r': | 
| 68 | subtotal = !subtotal; | 
| 69 | break; | 
| 70 | default: | 
| 71 | fprintf(stderr, | 
| 72 | "Usage: %s [-m][-sE|p|u|l][-tC][-count [-r]] [file..]\n", | 
| 73 | argv[0]); | 
| 74 | exit(1); | 
| 75 | } | 
| 76 | else | 
| 77 | break; | 
| 78 | if (mean) { | 
| 79 | if (func == MAX) { | 
| 80 | fprintf(stderr, "%s: average maximum?!\n", argv[0]); | 
| 81 | exit(1); | 
| 82 | } | 
| 83 | if (func == MIN) { | 
| 84 | fprintf(stderr, "%s: average minimum?!\n", argv[0]); | 
| 85 | exit(1); | 
| 86 | } | 
| 87 | } | 
| 88 | status = 0; | 
| 89 | if (a >= argc) | 
| 90 | status = execute(NULL) == -1 ? 1 : status; | 
| 91 | else | 
| 92 | for ( ; a < argc; a++) | 
| 93 | status = execute(argv[a]) == -1 ? 2 : status; | 
| 94 | exit(status); | 
| 95 | } | 
| 96 |  | 
| 97 |  | 
| 98 | static int | 
| 99 | execute(                        /* compute result */ | 
| 100 | char  *fname | 
| 101 | ) | 
| 102 | { | 
| 103 | double  result[MAXCOL]; | 
| 104 | char  buf[16*MAXCOL]; | 
| 105 | register char  *cp, *num; | 
| 106 | register int  n; | 
| 107 | double  d; | 
| 108 | int  ncol; | 
| 109 | long  nlin, ltotal; | 
| 110 | FILE  *fp; | 
| 111 | /* open file */ | 
| 112 | if (fname == NULL) | 
| 113 | fp = stdin; | 
| 114 | else if ((fp = fopen(fname, "r")) == NULL) { | 
| 115 | fprintf(stderr, "%s: cannot open\n", fname); | 
| 116 | return(-1); | 
| 117 | } | 
| 118 | ltotal = 0; | 
| 119 | while (!feof(fp)) { | 
| 120 | if (ltotal == 0)                        /* initialize */ | 
| 121 | if (func == MULT)       /* special case */ | 
| 122 | for (n = 0; n < MAXCOL; n++) | 
| 123 | result[n] = 0.0; | 
| 124 | else | 
| 125 | for (n = 0; n < MAXCOL; n++) | 
| 126 | result[n] = init_val[func]; | 
| 127 | ncol = 0; | 
| 128 | for (nlin = 0; (count <= 0 || nlin < count) && | 
| 129 | (cp = fgets(buf, sizeof(buf), fp)) != NULL; | 
| 130 | nlin++) { | 
| 131 | /* compute */ | 
| 132 | for (n = 0; n < MAXCOL; n++) { | 
| 133 | while (isspace(*cp)) | 
| 134 | cp++; | 
| 135 | if (!*cp) | 
| 136 | break; | 
| 137 | num = cp; | 
| 138 | while (*cp && !(isspace(tabc)?isspace(*cp):*cp==tabc)) | 
| 139 | cp++; | 
| 140 | if (*cp) | 
| 141 | *cp++ = '\0'; | 
| 142 | if (!*num || isspace(*num)) | 
| 143 | d = init_val[func]; | 
| 144 | else | 
| 145 | d = atof(num); | 
| 146 | switch (func) { | 
| 147 | case ADD: | 
| 148 | if (d == 0.0) | 
| 149 | break; | 
| 150 | if (power != 0.0) | 
| 151 | result[n] += pow(fabs(d),power); | 
| 152 | else | 
| 153 | result[n] += d; | 
| 154 | break; | 
| 155 | case MULT: | 
| 156 | if (d == 0.0) | 
| 157 | break; | 
| 158 | result[n] += log(fabs(d)); | 
| 159 | break; | 
| 160 | case MAX: | 
| 161 | if (d > result[n]) | 
| 162 | result[n] = d; | 
| 163 | break; | 
| 164 | case MIN: | 
| 165 | if (d < result[n]) | 
| 166 | result[n] = d; | 
| 167 | break; | 
| 168 | } | 
| 169 | } | 
| 170 | if (n > ncol) | 
| 171 | ncol = n; | 
| 172 | } | 
| 173 | if (nlin == 0) | 
| 174 | break; | 
| 175 | /* compute and print */ | 
| 176 | ltotal += nlin; | 
| 177 | for (n = 0; n < ncol; n++) { | 
| 178 | d = result[n]; | 
| 179 | if (mean) { | 
| 180 | d /= (double)ltotal; | 
| 181 | if (func == ADD && power != 0.0 && d != 0.0) | 
| 182 | d = pow(d, 1.0/power); | 
| 183 | } | 
| 184 | if (func == MULT) | 
| 185 | d = exp(d); | 
| 186 | printf("%.9g%c", d, tabc); | 
| 187 | } | 
| 188 | putchar('\n'); | 
| 189 | if (!subtotal) | 
| 190 | ltotal = 0; | 
| 191 | } | 
| 192 | /* close file */ | 
| 193 | return(fclose(fp)); | 
| 194 | } |