From a793df3e2a07c65f36fb2f5f43d2c51ab0c47bf2 Mon Sep 17 00:00:00 2001 From: Joel Kronqvist Date: Wed, 10 Apr 2024 16:54:50 +0300 Subject: Added help message & fixed blocksize bug The bug was caused by integer overflow with too large precisions. --- config-parser.c | 29 +++++++++++++---------------- config-parser.h | 1 + intmath.c | 12 ++++++++++++ intmath.h | 1 + stdu.c | 21 +++++++++++++++++++++ 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/config-parser.c b/config-parser.c index 5e403f8..075ef47 100644 --- a/config-parser.c +++ b/config-parser.c @@ -17,6 +17,7 @@ Result parse_config(int argc, char* argv[]) { Config tmp; tmp.precision = 0; tmp.human_readable = false; + tmp.help = false; size_t i = 1; char* argument; @@ -25,6 +26,16 @@ Result parse_config(int argc, char* argv[]) { argument = argv[i]; int comp1 = strcmp(argument, "--precision") == 0; if ( + strcmp(argument, "--help") == 0 + || strcmp(argument, "-?") == 0 + ) { + tmp.help = true; + } else if ( + strcmp(argument, "--human-readable") == 0 + || strcmp(argument, "-h") == 0 + ) { + tmp.human_readable = true; + } else if ( comp1 || strncmp(argument, "-p", 2) == 0 ) { if (precision != NULL) { @@ -54,21 +65,6 @@ Result parse_config(int argc, char* argv[]) { 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); @@ -126,8 +122,9 @@ Result parse_config(int argc, char* argv[]) { } Config* conf = malloc(sizeof(int) + sizeof(bool)); - conf->precision = tmp.precision; + conf->help = tmp.help; conf->human_readable = tmp.human_readable; + conf->precision = tmp.precision; res.success = true; res.result = conf; diff --git a/config-parser.h b/config-parser.h index 1026a98..08aa934 100644 --- a/config-parser.h +++ b/config-parser.h @@ -2,6 +2,7 @@ struct Config { int precision; bool human_readable; + bool help; }; typedef struct Config Config; struct Result { diff --git a/intmath.c b/intmath.c index 9e1f3ed..a4738b9 100644 --- a/intmath.c +++ b/intmath.c @@ -14,6 +14,18 @@ int int_pown(unsigned int base, unsigned int exp) { return res; } +int int_logn(unsigned int base, unsigned int a) { + unsigned int exp = 1; + int res = (int) base; + int lastres = res - 1; + while ((res < a) && (lastres < res)) { + lastres = res; + res *= base; + exp++; + } + return exp; +} + unsigned long long ull_pown(unsigned int base, unsigned int exp) { unsigned long long res = 1; while (exp > 0) { diff --git a/intmath.h b/intmath.h index 5d0b56b..b86ce72 100644 --- a/intmath.h +++ b/intmath.h @@ -1,5 +1,6 @@ int int_pown(unsigned int base, unsigned int exp); unsigned long long ull_pown(unsigned int base, unsigned int exp); +int int_logn(unsigned int base, unsigned int a); int int_pow10(unsigned int exp); int int_floor(int x, int precision); int int_ceil(int x, int precision); diff --git a/stdu.c b/stdu.c index 64f19a5..466d2f5 100644 --- a/stdu.c +++ b/stdu.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "intmath.h" #include "formatting.h" @@ -26,6 +27,17 @@ int main (int argc, char* argv[]) { Config* conf = (Config*) res.result; + if (conf->help) { + printf( +"Usage: stdu [-h] [-p n]\n\ +Print amount of data piped to stdin.\n\ +--help | -?: print this help message\n\ +--human-readable | -h: output in a human readable format\n\ +--precision n | -p n | -pn: output with n significant digits\n " + ); + return 0; + } + unsigned int base = 10; if (conf->human_readable && conf->precision == 0) { conf->precision = 1; @@ -38,6 +50,15 @@ int main (int argc, char* argv[]) { unsigned long long bytes_read = 0; size_t new_read_bytes = 0; if (conf->precision != 0) { + int max_precision = int_logn(base, (unsigned int) INT_MAX); + if (conf->precision > max_precision) { + fprintf( + stderr, + "Overflow error: precision may not be greater than %d\n", + max_precision + ); + return 1; + } blocksize = exp_notated_to_ull(ull_ceiled_exponent_notation_base( bytes_read + 1, conf->precision, -- cgit v1.2.3