gra-projekt/Implementierung/src/helper.c

113 lines
No EOL
2.9 KiB
C

#include "../lib/helper.h"
int stringToInt(char *string) {
char *leftover = "";
errno = 0;
int x = strtold(string, &leftover);
if (*leftover != '\0' || leftover == string) {
errno = EINVAL;
return -1;
}
if (errno == ERANGE) {
printf("Number is too large or too small!\n");
errno = EINVAL;
return -1;
}
errno = 0;
return x;
}
void help(char *progname) {
fprintf(stdout,
"Usage: %s [options...] <file>\n\
-V, --version <version> use a specific implementation\n\
-B, --benchmark [repetitons] benchmark the execution and optionally repeat it\n\
-T, --test run self-test. If set, no file is needed\n\
-h, --help print this help page\n",
progname);
}
enum argumentParseResult parseArguments(int argc, char **argv,
struct configuration *c) {
if (c == NULL) {
return RESULT_EXIT_FAILURE;
}
c->implementationToUse = 0;
c->doBenchmark = false;
c->benchmarkingCycles = 1;
c->runTests = false;
int opt;
while (1) {
static struct option longOptions[] = {
{"version", required_argument, NULL, 'V'},
{"benchmark", optional_argument, NULL, 'B'},
{"test", optional_argument, NULL, 'T'},
{"help", no_argument, NULL, 'h'},
{NULL}};
int longOptionIndex = 0;
opt = getopt_long(argc, argv, "V:B::Th", longOptions, &longOptionIndex);
if (-1 == opt) break;
switch (opt) {
case 'B':
c->doBenchmark = true;
if (optarg != NULL) {
c->benchmarkingCycles = stringToInt(optarg);
if (errno == 0) break;
fprintf(stderr,
"%s: invalid argument, has to be int -- 'B' got '%s'\n",
argv[0], optarg);
return RESULT_EXIT_FAILURE;
}
break;
case 'V':
c->implementationToUse = stringToInt(optarg);
if (errno == 0) break;
fprintf(stderr, "%s: invalid argument, has to be int -- 'V' got '%s'\n",
argv[0], optarg);
return RESULT_EXIT_FAILURE;
case 'T':
c->runTests = true;
break;
case 'h':
help(argv[0]);
return RESULT_EXIT_SUCCESS;
default:
return RESULT_EXIT_FAILURE;
}
}
if (argc > optind) {
c->filename = argv[optind];
} else if (!c->runTests) {
fprintf(stderr, "%s: missing poisional argument -- 'file'\n", argv[0]);
return RESULT_EXIT_FAILURE;
}
return RESULT_OK;
}
double current_time(void) {
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return t.tv_sec + t.tv_nsec * 1e-9;
}
double run_benchmark(unsigned cycles, md2_hash_func func, size_t len,
uint8_t *buf, uint8_t *out) {
double start = current_time();
for (; cycles > 0; cycles--) {
func(len, buf, out);
}
double end = current_time();
return end - start;
}