From: Douglas Bagnall Date: Sat, 13 Aug 2011 12:31:42 +0000 (+0930) Subject: opt: functions to show integer values with kMGTPE suffixes X-Git-Url: https://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=bbdf3ef3c2c14e515388c6146fd00557cee905a1;hp=babb23101ae447aefb65284b8f535f84e6a35008 opt: functions to show integer values with kMGTPE suffixes As with the set_ functions, there are twelve permutations of integer size, base, and signedness. The supported sizes are int, long, and long long. For example, this: char buf1[OPT_SHOW_LEN]; char buf2[OPT_SHOW_LEN]; unsigned i = 1024000; opt_show_uintval_bi(buf1, &i); opt_show_uintval_si(buf2, &i); will put "1000k" in buf1, and "1024k" in buf2. Unlike the opt_set_ functions, these use unsigned arithmetic for unsigned values. (32 bit bug using sizeof(suffixes) instead of strlen(suffixes) fixed by Rusty) --- diff --git a/ccan/opt/helpers.c b/ccan/opt/helpers.c index a27be22f..53fb0158 100644 --- a/ccan/opt/helpers.c +++ b/ccan/opt/helpers.c @@ -370,3 +370,116 @@ char * opt_set_uintval_si(const char *arg, unsigned int *u) { return set_uint_with_suffix(arg, u, 1000); } + +/*static helpers for showing values with kMGTPE suffixes. In this case there + are separate but essentially identical functions for signed and unsigned + values, so that unsigned values greater than LLONG_MAX get suffixes. + */ +static void show_llong_with_suffix(char buf[OPT_SHOW_LEN], long long ll, + const long long base) +{ + const char *suffixes = "kMGTPE"; + int i; + if (ll == 0){ + /*zero is special because everything divides it (you'd get "0E")*/ + snprintf(buf, OPT_SHOW_LEN, "0"); + return; + } + for (i = 0; i < strlen(suffixes); i++){ + long long tmp = ll / base; + if (tmp * base != ll) + break; + ll = tmp; + } + if (i == 0) + snprintf(buf, OPT_SHOW_LEN, "%lld", ll); + else + snprintf(buf, OPT_SHOW_LEN, "%lld%c", ll, suffixes[i - 1]); +} + +static void show_ullong_with_suffix(char buf[OPT_SHOW_LEN], unsigned long long ull, + const unsigned base) +{ + const char *suffixes = "kMGTPE"; + int i; + if (ull == 0){ + /*zero is special because everything divides it (you'd get "0E")*/ + snprintf(buf, OPT_SHOW_LEN, "0"); + return; + } + for (i = 0; i < strlen(suffixes); i++){ + unsigned long long tmp = ull / base; + if (tmp * base != ull) + break; + ull = tmp; + } + if (i == 0) + snprintf(buf, OPT_SHOW_LEN, "%llu", ull); + else + snprintf(buf, OPT_SHOW_LEN, "%llu%c", ull, suffixes[i - 1]); +} + +/* _bi, signed */ +void opt_show_intval_bi(char buf[OPT_SHOW_LEN], const int *x) +{ + show_llong_with_suffix(buf, *x, 1024); +} + +void opt_show_longval_bi(char buf[OPT_SHOW_LEN], const long *x) +{ + show_llong_with_suffix(buf, *x, 1024); +} + +void opt_show_longlongval_bi(char buf[OPT_SHOW_LEN], const long long *x) +{ + show_llong_with_suffix(buf, *x, 1024); +} + +/* _bi, unsigned */ +void opt_show_uintval_bi(char buf[OPT_SHOW_LEN], const unsigned int *x) +{ + show_ullong_with_suffix(buf, (unsigned long long) *x, 1024); +} + +void opt_show_ulongval_bi(char buf[OPT_SHOW_LEN], const unsigned long *x) +{ + show_ullong_with_suffix(buf, (unsigned long long) *x, 1024); +} + +void opt_show_ulonglongval_bi(char buf[OPT_SHOW_LEN], const unsigned long long *x) +{ + show_ullong_with_suffix(buf, (unsigned long long) *x, 1024); +} + +/* _si, signed */ +void opt_show_intval_si(char buf[OPT_SHOW_LEN], const int *x) +{ + show_llong_with_suffix(buf, (long long) *x, 1000); +} + +void opt_show_longval_si(char buf[OPT_SHOW_LEN], const long *x) +{ + show_llong_with_suffix(buf, (long long) *x, 1000); +} + +void opt_show_longlongval_si(char buf[OPT_SHOW_LEN], const long long *x) +{ + show_llong_with_suffix(buf, *x, 1000); +} + +/* _si, unsigned */ +void opt_show_uintval_si(char buf[OPT_SHOW_LEN], const unsigned int *x) +{ + show_ullong_with_suffix(buf, (unsigned long long) *x, 1000); +} + +void opt_show_ulongval_si(char buf[OPT_SHOW_LEN], const unsigned long *x) +{ + show_ullong_with_suffix(buf, (unsigned long long) *x, 1000); +} + +void opt_show_ulonglongval_si(char buf[OPT_SHOW_LEN], const unsigned long long *x) +{ + show_ullong_with_suffix(buf, (unsigned long long) *x, 1000); +} + diff --git a/ccan/opt/opt.h b/ccan/opt/opt.h index 7049fffc..550c342d 100644 --- a/ccan/opt/opt.h +++ b/ccan/opt/opt.h @@ -297,6 +297,24 @@ char *opt_set_longlongval_si(const char *arg, long long *ll); char *opt_set_ulonglongval_bi(const char *arg, unsigned long long *ll); char *opt_set_ulonglongval_si(const char *arg, unsigned long long *ll); + +void opt_show_intval_bi(char buf[OPT_SHOW_LEN], const int *x); +void opt_show_longval_bi(char buf[OPT_SHOW_LEN], const long *x); +void opt_show_longlongval_bi(char buf[OPT_SHOW_LEN], const long long *x); +void opt_show_uintval_bi(char buf[OPT_SHOW_LEN], const unsigned int *x); +void opt_show_ulongval_bi(char buf[OPT_SHOW_LEN], const unsigned long *x); +void opt_show_ulonglongval_bi(char buf[OPT_SHOW_LEN], const unsigned long long *x); + +void opt_show_intval_si(char buf[OPT_SHOW_LEN], const int *x); +void opt_show_longval_si(char buf[OPT_SHOW_LEN], const long *x); +void opt_show_longlongval_si(char buf[OPT_SHOW_LEN], const long long *x); +void opt_show_uintval_si(char buf[OPT_SHOW_LEN], const unsigned int *x); +void opt_show_ulongval_si(char buf[OPT_SHOW_LEN], const unsigned long *x); +void opt_show_ulonglongval_si(char buf[OPT_SHOW_LEN], const unsigned long long *x); + + + + /* Increment. */ char *opt_inc_intval(int *i); diff --git a/ccan/opt/test/run-helpers.c b/ccan/opt/test/run-helpers.c index a71fe40c..d0dc52d6 100644 --- a/ccan/opt/test/run-helpers.c +++ b/ccan/opt/test/run-helpers.c @@ -59,7 +59,7 @@ static int saved_printf(const char *fmt, ...) ret = saved_vprintf(fmt, ap); va_end(ap); return ret; -} +} static int saved_fprintf(FILE *ignored, const char *fmt, ...) { @@ -70,7 +70,7 @@ static int saved_fprintf(FILE *ignored, const char *fmt, ...) ret = saved_vprintf(fmt, ap); va_end(ap); return ret; -} +} #undef malloc static void *last_allocation; @@ -82,7 +82,7 @@ static void *saved_malloc(size_t size) /* Test helpers. */ int main(int argc, char *argv[]) { - plan_tests(334); + plan_tests(452); /* opt_set_bool */ { @@ -421,6 +421,167 @@ int main(int argc, char *argv[]) ok1(parse_args(&argc, &argv, "-a", "8191P", NULL)); ok1(arg == 8191 * P); } + + /* opt_show_intval_bi */ + { + int i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = -77; + opt_show_intval_bi(buf, &i); + ok1(strcmp(buf, "-77") == 0); + i = 0; + opt_show_intval_bi(buf, &i); + ok1(strcmp(buf, "0") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 77; + opt_show_intval_bi(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = -1234 * k; + opt_show_intval_bi(buf, &i); + ok1(strcmp(buf, "-1234k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_intval_bi(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * M; + opt_show_intval_bi(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_longval_bi */ + { + long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = -77; + opt_show_longval_bi(buf, &i); + ok1(strcmp(buf, "-77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 77; + opt_show_longval_bi(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = -1 * k; + opt_show_longval_bi(buf, &i); + ok1(strcmp(buf, "-1k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_longval_bi(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * M; + opt_show_longval_bi(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 0; + opt_show_longval_bi(buf, &i); + ok1(strcmp(buf, "0") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_llongval_bi */ + { + long long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = -7777; + opt_show_longlongval_bi(buf, &i); + ok1(strcmp(buf, "-7777") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 7777; + opt_show_longlongval_bi(buf, &i); + ok1(strcmp(buf, "7777") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = -10240000 * k; + opt_show_longlongval_bi(buf, &i); + ok1(strcmp(buf, "-10000M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 5 * P; + opt_show_longlongval_bi(buf, &i); + ok1(strcmp(buf, "5P") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * P; + opt_show_longlongval_bi(buf, &i); + ok1(strcmp(buf, "1E") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_uintval_bi */ + { + unsigned int i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = 77; + opt_show_uintval_bi(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1234 * k; + opt_show_uintval_bi(buf, &i); + ok1(strcmp(buf, "1234k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_uintval_bi(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * M; + opt_show_uintval_bi(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_ulongval_bi */ + { + unsigned long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = 77; + opt_show_ulongval_bi(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = k; + opt_show_ulongval_bi(buf, &i); + ok1(strcmp(buf, "1k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_ulongval_bi(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * M; + opt_show_ulongval_bi(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 0; + opt_show_ulongval_bi(buf, &i); + ok1(strcmp(buf, "0") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_ullongval_bi */ + { + long long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = 7777; + opt_show_ulonglongval_bi(buf, &i); + ok1(strcmp(buf, "7777") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 10240000 * k; + opt_show_ulonglongval_bi(buf, &i); + ok1(strcmp(buf, "10000M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 5 * P; + opt_show_ulonglongval_bi(buf, &i); + ok1(strcmp(buf, "5P") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * P; + opt_show_ulonglongval_bi(buf, &i); + ok1(strcmp(buf, "1E") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } } { @@ -645,6 +806,167 @@ int main(int argc, char *argv[]) ok1(!parse_args(&argc, &argv, "-a", "-100G", NULL)); ok1(parse_args(&argc, &argv, "-a", "8E", NULL)); } + /* opt_show_intval_si */ + { + int i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = -77; + opt_show_intval_si(buf, &i); + ok1(strcmp(buf, "-77") == 0); + i = 0; + opt_show_intval_si(buf, &i); + ok1(strcmp(buf, "0") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 77; + opt_show_intval_si(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = -1234 * k; + opt_show_intval_si(buf, &i); + ok1(strcmp(buf, "-1234k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_intval_si(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1000 * M; + opt_show_intval_si(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_longval_si */ + { + long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = -77; + opt_show_longval_si(buf, &i); + ok1(strcmp(buf, "-77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 77; + opt_show_longval_si(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = -1 * k; + opt_show_longval_si(buf, &i); + ok1(strcmp(buf, "-1k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_longval_si(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1000 * M; + opt_show_longval_si(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 0; + opt_show_longval_si(buf, &i); + ok1(strcmp(buf, "0") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_llongval_si */ + { + long long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = -7777; + opt_show_longlongval_si(buf, &i); + ok1(strcmp(buf, "-7777") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 7777; + opt_show_longlongval_si(buf, &i); + ok1(strcmp(buf, "7777") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = -10240000 * k; + opt_show_longlongval_si(buf, &i); + ok1(strcmp(buf, "-10240M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 5 * P; + opt_show_longlongval_si(buf, &i); + ok1(strcmp(buf, "5P") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 2000 * P; + opt_show_longlongval_si(buf, &i); + ok1(strcmp(buf, "2E") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_uintval_si */ + { + unsigned int i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = 77; + opt_show_uintval_si(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1234 * k; + opt_show_uintval_si(buf, &i); + ok1(strcmp(buf, "1234k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_uintval_si(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1000 * M; + opt_show_uintval_si(buf, &i); + ok1(strcmp(buf, "1G") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_ulongval_si */ + { + unsigned long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = 77; + opt_show_ulongval_si(buf, &i); + ok1(strcmp(buf, "77") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = k; + opt_show_ulongval_si(buf, &i); + ok1(strcmp(buf, "1k") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 500 * M; + opt_show_ulongval_si(buf, &i); + ok1(strcmp(buf, "500M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1024 * M; + opt_show_ulongval_si(buf, &i); + ok1(strcmp(buf, "1024M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 0; + opt_show_ulongval_si(buf, &i); + ok1(strcmp(buf, "0") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + + /* opt_show_ullongval_si */ + { + long long i; + char buf[OPT_SHOW_LEN+2] = { 0 }; + buf[OPT_SHOW_LEN] = '!'; + i = 7777; + opt_show_ulonglongval_si(buf, &i); + ok1(strcmp(buf, "7777") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 10240000 * k; + opt_show_ulonglongval_si(buf, &i); + ok1(strcmp(buf, "10240M") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 5 * P; + opt_show_ulonglongval_si(buf, &i); + ok1(strcmp(buf, "5P") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + i = 1000 * P; + opt_show_ulonglongval_si(buf, &i); + ok1(strcmp(buf, "1E") == 0); + ok1(buf[OPT_SHOW_LEN] == '!'); + } + }