/** ** Data preparation for diagnostic interfaces ** ** Copyright 2009-2011 Gary Wuertz gary@issiweb.com ** Copyright 2011 BenEleventh Consulting manolson@beneleventh.com ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . ** */ #include #include #include #include #include /** * Something borrowed...... */ #define APP_BUFF_SIZE 1024 #define NDSIZECOLLECT 0x1000000 typedef unsigned int U_INT; struct pparams { int cmd; // command to execute int options; // debug options char *outpath; // output file; FILE *input; // input file FILE *output; // output file U_INT limit; // limit delta U_INT repeat; // repeat values U_INT value; // inject value U_INT bsize; // Buffer size double xs; // X scale }; /** * For bin output */ #define X_BINS 512 #define Y_BINS 2048 /** * Divide data into bins */ #define X_FACTOR (1.0 * X_BINS)/(1.0 * p->bsize) #define Y_FACTOR (0.5 * Y_BINS)/(1.0 * 0x7fffffff) /* * Scale bins back to values x = 1M, y=4.0G */ #define X_SCALE (p->xs/X_BINS) #define Y_SCALE (4.0/Y_BINS) static int inject_output(struct pparams *p); static void matrix_output(struct pparams *p); static void sequence_output(struct pparams *p); static void usage(int nopts, struct option *long_options, const char **cmds); /** * Data Prep */ int main(int argc, char **argv) { static const char* cmds[] = { "b", "buffer", "1", "buffer size (k): default 1024", "f", "file", "1", "output file name: default is '-' (stdout)", "i", "inject", "1", "inject 0=2up, 1=1up, 2=raw 1up", "o", "output", "1", "[bin|delta|inject|raw|xor|wrap] data", "r", "repeat", "1", "repeat inject sequence", "s", "start", "1", "start value inject sequence", "u", "upper", "1", "inject sequence upper bound", "v", "verbose", "1", "verbose reporting", "h", "help", "0", "This help" }; char *outputs[] = {"bin","delta","inject","raw","xor","wrap",NULL}; static int nopts = sizeof(cmds)/(4*sizeof(char *)); struct option long_options[nopts+1]; char short_options[1+nopts*2]; struct pparams params; FILE *f; U_INT i, j, n; int c; char *s; for(i=j=0;j<(nopts*4);j+=4) { long_options[i].name = cmds[j+1]; long_options[i].has_arg = atoi(cmds[j+2]); long_options[i].flag = NULL; long_options[i].val = cmds[j][0]; strcat(short_options,cmds[j]); if (long_options[i].has_arg!=0) strcat(short_options,":"); i += 1; } memset(&long_options[i], 0, sizeof(struct option)); memset(¶ms, 0, sizeof(struct pparams)); params.outpath = "-"; params.bsize = NDSIZECOLLECT; params.xs = 1.0; do { c = getopt_long (argc, argv, short_options, long_options, NULL); switch(c) { case 'b': params.bsize = atoi(optarg); params.xs = params.bsize; while(params.xs >= 10.0) params.xs /= 10.0; break; case 'f': params.outpath = optarg; break; case 'i': params.options = atoi(optarg); break; case 'o': n = strlen(optarg); for(i=0;outputs[i]!=NULL;i++) if (!strncmp(optarg, outputs[i], n)) { params.cmd = optarg[0]; break; } break; case 'r': params.repeat = atoi(optarg); break; case 's': params.value = atoi(optarg); break; case 'u': params.limit = atoi(optarg); break; case 'v': params.cmd = atoi(optarg); break; case '?': case 'h': usage(nopts, long_options, cmds); case -1: break; } } while (c!=-1); if (0==params.cmd || optind != (argc-1)) usage(nopts, long_options, cmds); if (!strcmp(argv[1],"-")) params.input = stdin; else { params.input = fopen(argv[optind], "rb"); if (NULL == params.input) { fprintf(stderr, "Unable to open input %s\n", argv[optind]); exit(2); } } if (!strcmp(params.outpath, "-")) params.output = stdout; else { params.output = fopen(params.outpath, "wb"); if (NULL == params.output) { fprintf(stderr, "Unable to open %s\n", params.outpath); exit(3); } fprintf(stdout, "writing to %s\n", params.outpath); } switch(params.cmd) { case 'i': while(inject_output(¶ms)>0) ; break; case 'b': matrix_output(¶ms); break; case 'd': case 'r': case 'x': case 'w': sequence_output(¶ms); break; } if (params.output != stdout) fclose(params.output); return 0; } /** * Create injection data - input file is log10 sequence data - can be repeated */ static int inject_output(struct pparams *p) { U_INT buf[APP_BUFF_SIZE]; char ibuf[80], *s; U_INT i, j; double n, delta; int rv = 1; n = 0; for(i=0;ivalue; s = fgets(ibuf, 80, p->input); if (NULL == s && p->repeat != 0) { p->repeat -= 1; rewind(p->input); s = fgets(ibuf, 80, p->input); } if (NULL != s) { if (p->options!=0) delta = strtod(ibuf, NULL); else { n = strtod(ibuf, &s); delta = strtod(s, NULL); } if (p->limit != 0 && delta > p->limit) delta -= p->limit; if (p->options == 2) p->value = (U_INT) delta; else p->value += (U_INT)pow(10.0,delta); } else rv = 0; } if (i != fwrite(buf, sizeof(U_INT), i, p->output)) { printf("Write error\n"); rv = -1; } return rv; } /** * Create matrix data file */ static void matrix_output(struct pparams *p) { U_INT buf[APP_BUFF_SIZE]; U_INT **matrix; FILE *f = p->input; int i, n, sz, x, y; matrix = (U_INT **) malloc(sizeof(U_INT **) * X_BINS); if (NULL == matrix) { fprintf(stderr, "Unable to allocate cols\n"); return; } sz = sizeof(U_INT *) * Y_BINS; for (i = 0;i< X_BINS;i++) { matrix[i] = (U_INT *)malloc(sz); if (NULL == matrix[i]) { fprintf(stderr, "Unable to allocate row\n"); return; } memset(matrix[i], 0, sz); } n = 0; while(1) { sz = fread(buf, sizeof(U_INT), APP_BUFF_SIZE, f); if (sz < 1) break; for(i=0;ibsize; } } for(x=0;xoutput,"%g\t%g\t%u\n", x*X_SCALE, y*Y_SCALE, matrix[x][y]); } /** * Create sequence data file */ static void sequence_output(struct pparams *p) { U_INT buf[APP_BUFF_SIZE]; FILE *f = p->input; int i, m, n, sz; U_INT delta, cur, prev; U_INT plus, minus; m = p->cmd=='r'? 1 : 0; n = 0; plus = minus = 0; while(1) { sz = fread(buf, sizeof(U_INT), APP_BUFF_SIZE, f); if (sz < 1) break; for(i=0;icmd) { case 'd': if (cur < prev) delta = prev - cur; else delta = cur - prev; fprintf(p->output,"%g\t%g\n", n * 10.0/1024.0, log10(delta)); break; case 'x': fprintf(p->output,"%g\t%g\n", n * 10.0/1024.0, log10(cur^prev)); break; case 'r': fprintf(p->output,"%g\t%g\n", n * 10.0/1024.0, 1.0 * cur); break; case 'w': if (cur < prev) { if (p->options & 1) fprintf(p->output,"rollover %d\n", n); minus++; } else plus++; break; } n += 1; n %= p->bsize; } } if (p->cmd=='w') fprintf(p->output,"Rollover %u/%u = %g\n", minus, plus, minus*100/(double)(minus+plus)); } /** * usage */ static void usage(int nopts, struct option *long_options, const char **cmds) { int i; fprintf(stderr, "\nUsage: %s [options] \n\n", "data_prep"); fprintf(stderr, "Prepare diagnostic data from \n\n"); fprintf(stderr, " Options:\n"); for(i=0;long_options[i].val != 0;i++) { fprintf(stderr," --%-10s, -%c %s %s\n", long_options[i].name, long_options[i].val, long_options[i].has_arg? "[]":" ",cmds[4*i+3]); } fprintf(stderr, "\n"); exit(1); }