/* * */ #include "cdf.h" /* * Global configuration variables. These are set based on command-line * arguments, and read-only beyond that point. */ static bool ARG_REVERSE_CDF = false; static bool ARG_FP_INPUT = false; static bool ARG_UINT_INPUT = false; static bool ARG_HELP = false; static int parse_options(int argc, char*const* argv) { int arg_index = 0; int arg; bool error = false; while ((arg = getopt(argc, argv, "frhu")) != -1) { switch (arg) { case 'f': ARG_FP_INPUT = true; break; case 'r': ARG_REVERSE_CDF = true; break; case 'u': ARG_UINT_INPUT = true; case 'h': ARG_HELP = true; break; case '?': if (isprint(optopt)) { fprintf(stderr, "Unknown option `-%c`.\n", optopt); } else { fprintf(stderr, "Unknown option character `\\x%x`.\n", optopt); } error = true; break; default: error = true; break; } } if (ARG_UINT_INPUT && ARG_FP_INPUT) { fprintf(stderr, "Error: the -u and -f flags are mutually exclusive.\n"); error = true; } if (!error) { arg_index = optind; } return arg_index; } static void help() { fprintf(stderr, "Usage:\ncdf [-f|-u] [-r] [filename]\n"); } static DistRecord *expand_array(DistRecord *records, size_t *capacity) { (*capacity) *= 2; DistRecord *new = realloc(records, (*capacity*sizeof(DistRecord))); if (!new) { fprintf(stderr, "ERROR: Memory allocation failed\n"); return nullptr; } return new; } static int read_data_int(DistRecord **records, size_t capacity, FILE *file) { size_t reccnt = 0; while (fscanf(file, "%ld %ld\n", &(*records + reccnt)->count, &(*records + reccnt)->data.i) != EOF) { reccnt++; if (reccnt == capacity) { if (!(*records = expand_array(*records, &capacity))) { return -1; } } } return reccnt; } static int read_data_fp(DistRecord **records, size_t capacity, FILE *file) { size_t reccnt = 0; while (fscanf(file, "%ld %lf\n", &(*records + reccnt)->count, &(*records + reccnt)->data.d) != EOF) { reccnt++; if (reccnt == capacity) { if (!(*records = expand_array(*records, &capacity))) { return -1; } } } return reccnt; } static int read_data_uint(DistRecord **records, size_t capacity, FILE *file) { size_t reccnt = 0; while (fscanf(file, "%ld %ld\n", &(*records + reccnt)->count, &(*records + reccnt)->data.u) != EOF) { reccnt++; if (reccnt == capacity) { if (!(*records = expand_array(*records, &capacity))) { return -1; } } } return reccnt; } static int print_data_fp(DistRecord *records, long double *freqs, size_t cnt) { if (ARG_REVERSE_CDF) { long double total_freq = 1.0; for (size_t i=0; i