X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Fopt%2Fhelpers.c;h=dfeb4e2e790a553173830d039ae84b8026df2fa8;hb=ef92843f2c74ab9d4fa7f167a2182e5e8955df91;hp=7022afbbf090a53346388bdbd6a3f5d2b00ce290;hpb=af7afcd46e70e87397c33408d88f2bedd2c90bd8;p=ccan diff --git a/ccan/opt/helpers.c b/ccan/opt/helpers.c index 7022afbb..dfeb4e2e 100644 --- a/ccan/opt/helpers.c +++ b/ccan/opt/helpers.c @@ -56,7 +56,8 @@ char *opt_set_charp(const char *arg, char **p) return NULL; } -/* Set an integer value, various forms. Sets to 1 on arg == NULL. */ +/* Set an integer value, various forms. + FIXME: set to 1 on arg == NULL ? */ char *opt_set_intval(const char *arg, int *i) { long l; @@ -65,8 +66,8 @@ char *opt_set_intval(const char *arg, int *i) if (err) return err; *i = l; - /* Beware truncation... */ - if (*i != l) + /* Beware truncation, but don't generate untestable code. */ + if (sizeof(*i) != sizeof(l) && *i != l) return arg_bad("value '%s' does not fit into an integer", arg); return err; } @@ -102,7 +103,7 @@ char *opt_set_ulongval(const char *arg, unsigned long *ul) { long int l; char *err; - + err = opt_set_longval(arg, &l); if (err) return err; @@ -153,7 +154,7 @@ void opt_show_charp(char buf[OPT_SHOW_LEN], char *const *p) buf[2+len] = '\0'; } -/* Set an integer value, various forms. Sets to 1 on arg == NULL. */ +/* Show an integer value, various forms. */ void opt_show_intval(char buf[OPT_SHOW_LEN], const int *i) { snprintf(buf, OPT_SHOW_LEN, "%i", *i); @@ -369,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); +} +