From 1ef526c695df4b37aa184867fb5b62c93118aa02 Mon Sep 17 00:00:00 2001 From: Joel Kronqvist Date: Sun, 24 Mar 2024 10:00:19 +0200 Subject: Refactored configuration parsing to a separate file and added unit tests to it --- stdu.c | 152 ++++------------------------------------------------------------- 1 file changed, 8 insertions(+), 144 deletions(-) (limited to 'stdu.c') diff --git a/stdu.c b/stdu.c index 43038a8..f7f5511 100644 --- a/stdu.c +++ b/stdu.c @@ -6,144 +6,11 @@ #include #include "intmath.h" +#include "config-parser.h" int tests_run = 0; int tests_failed = 0; -struct Config { - int precision; - bool human_readable; -}; -typedef struct Config Config; -struct Result { - bool success; - void* result; -}; -typedef struct Result Result; - -Result parse_config(int argc, char* argv[]) { - Result res; - res.success = false; - Config tmp; - tmp.precision = 0; - tmp.human_readable = false; - - size_t i = 1; - char* argument; - char* precision = NULL; - while (i < argc) { - argument = argv[i]; - int comp1 = strcmp(argument, "--precision") == 0; - if ( - comp1 || strncmp(argument, "-p", 2) == 0 - ) { - if (precision != NULL) { - char* error_msg = malloc(44); - snprintf( - error_msg, - 44, - "precision can't be specified multiple times" - ); - res.result = error_msg; - return res; - } - i++; - if (strlen(argument) != 2 && !comp1) { - precision = argument + 2; - continue; - } - if (i == argc) { - char* error_msg = malloc(57); - snprintf( - error_msg, - 57, - "`%s` should be followed by an integer argument", - argument - ); - res.result = error_msg; - return res; - } - precision = argv[i]; - } else if ( - strcmp(argument, "--human-readable") == 0 - || strcmp(argument, "-h") == 0 - ) { - if (tmp.human_readable != false) { - char* error_msg = malloc(52); - snprintf( - error_msg, - 52, - "human readability can't be specified multiple times" - ); - res.result = error_msg; - return res; - } - tmp.human_readable = true; - } else { - size_t msg_size = 21 + strlen(argument); - char* error_msg = malloc(msg_size); - snprintf( - error_msg, - msg_size, - "unknown argument: `%s`", - argument - ); - res.result = error_msg; - return res; - } - - i++; - } - - if (precision != NULL) { - char* endptr; - errno = 0; - tmp.precision = (int) strtol(precision, &endptr, 10); - if (errno != 0) { - char* error_msg = malloc(64); - char* errno_str = strerror(errno); - snprintf( - error_msg, - 64, - "invalid precision: %s", - errno_str - ); - free(errno_str); - res.result = error_msg; - return res; - } - if (*endptr != '\0') { - char* error_msg = malloc(53); - snprintf( - error_msg, - 53, - "the precision may not contain non-numeric characters", - precision - ); - res.result = error_msg; - return res; - } - if (tmp.precision <= 0) { - char* error_msg = malloc(50); - snprintf( - error_msg, - 50, - "the precision can't be less than or equal to zero" - ); - res.result = error_msg; - return res; - } - } - - Config* conf = malloc(sizeof(int) + sizeof(bool)); - conf->precision = tmp.precision; - conf->human_readable = tmp.human_readable; - - res.success = true; - res.result = conf; - return res; -} - int main (int argc, char* argv[]) { Result res = parse_config(argc, argv); if (res.success == false) { @@ -157,14 +24,11 @@ int main (int argc, char* argv[]) { } Config* conf = (Config*) res.result; - int precision = conf->precision; - bool human_readable = conf->human_readable; - printf("precision: %d\n", precision); - if (human_readable) printf("human readable\n"); + if (conf->human_readable) printf("human readable\n"); unsigned int base = 10; - if (human_readable && precision == 0) { - precision = 1; + if (conf->human_readable && conf->precision == 0) { + conf->precision = 1; base = 1024; } @@ -172,10 +36,10 @@ int main (int argc, char* argv[]) { size_t bufsize = 1; unsigned int bytes_read = 0; size_t new_read_bytes = 0; - if (precision != 0) { + if (conf->precision != 0) { blocksize = exp_notated_to_int(int_ceiled_exponent_notation_base( bytes_read + 1, - precision, + conf->precision, base)) - bytes_read; bufsize = 1024; @@ -214,10 +78,10 @@ int main (int argc, char* argv[]) { /* resizing buffer and blocksize to read as much as possible * at once */ - if (precision == 0) continue; + if (conf->precision == 0) continue; blocksize = exp_notated_to_int(int_ceiled_exponent_notation_base( bytes_read + 1, - precision, + conf->precision, base)) - bytes_read; if (blocksize > bufsize) { -- cgit v1.2.3