aboutsummaryrefslogtreecommitdiff
path: root/stdu.c
diff options
context:
space:
mode:
authorJoel Kronqvist <joelkronqvist@proton.me>2024-03-24 10:00:19 +0200
committerJoel Kronqvist <joelkronqvist@proton.me>2024-03-24 10:00:19 +0200
commit1ef526c695df4b37aa184867fb5b62c93118aa02 (patch)
treee223eda40193d584f55c9f11e8d511988d7e1136 /stdu.c
parente26279107edf7012e6b9cd558aaa09a8f0ca4764 (diff)
downloadstdu-1ef526c695df4b37aa184867fb5b62c93118aa02.tar.gz
stdu-1ef526c695df4b37aa184867fb5b62c93118aa02.zip
Refactored configuration parsing to a separate file and added unit tests to it
Diffstat (limited to 'stdu.c')
-rw-r--r--stdu.c152
1 files changed, 8 insertions, 144 deletions
diff --git a/stdu.c b/stdu.c
index 43038a8..f7f5511 100644
--- a/stdu.c
+++ b/stdu.c
@@ -6,144 +6,11 @@
#include <stdbool.h>
#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) {