X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=strutil.c;h=f6cdb73b73f81836477378ee3baea38979c4282c;hb=8f996b89481670219c7576e2c68b128a0a2ce026;hp=b7b0af16d72bc9df0af4f78c658690150229a36d;hpb=29a27196a13de2ffd9b671185e4b464b9db9b549;p=libsigrok.git diff --git a/strutil.c b/strutil.c index b7b0af16..f6cdb73b 100644 --- a/strutil.c +++ b/strutil.c @@ -48,8 +48,8 @@ */ /** - * Convert a numeric value value to its "natural" string representation. - * in SI units + * Convert a numeric value value to its "natural" string representation + * in SI units. * * E.g. a value of 3000000, with units set to "W", would be converted * to "3 MW", 20000 to "20 kW", 31500 would become "31.5 kW". @@ -64,32 +64,30 @@ */ SR_API char *sr_si_string_u64(uint64_t x, const char *unit) { + uint8_t i; + uint64_t quot, divisor[] = { + SR_HZ(1), SR_KHZ(1), SR_MHZ(1), SR_GHZ(1), + SR_GHZ(1000), SR_GHZ(1000 * 1000), SR_GHZ(1000 * 1000 * 1000), + }; + const char *p, prefix[] = "\0kMGTPE"; + char fmt[8], fract[20] = "", *f; + if (unit == NULL) unit = ""; - if ((x >= SR_GHZ(1)) && (x % SR_GHZ(1) == 0)) { - return g_strdup_printf("%" PRIu64 " G%s", x / SR_GHZ(1), unit); - } else if ((x >= SR_GHZ(1)) && (x % SR_GHZ(1) != 0)) { - return g_strdup_printf("%" PRIu64 ".%" PRIu64 " G%s", - x / SR_GHZ(1), x % SR_GHZ(1), unit); - } else if ((x >= SR_MHZ(1)) && (x % SR_MHZ(1) == 0)) { - return g_strdup_printf("%" PRIu64 " M%s", - x / SR_MHZ(1), unit); - } else if ((x >= SR_MHZ(1)) && (x % SR_MHZ(1) != 0)) { - return g_strdup_printf("%" PRIu64 ".%" PRIu64 " M%s", - x / SR_MHZ(1), x % SR_MHZ(1), unit); - } else if ((x >= SR_KHZ(1)) && (x % SR_KHZ(1) == 0)) { - return g_strdup_printf("%" PRIu64 " k%s", - x / SR_KHZ(1), unit); - } else if ((x >= SR_KHZ(1)) && (x % SR_KHZ(1) != 0)) { - return g_strdup_printf("%" PRIu64 ".%" PRIu64 " k%s", - x / SR_KHZ(1), x % SR_KHZ(1), unit); - } else { - return g_strdup_printf("%" PRIu64 " %s", x, unit); + for (i = 0; (quot = x / divisor[i]) >= 1000; i++); + + if (i) { + sprintf(fmt, ".%%0%dlu", i * 3); + f = fract + sprintf(fract, fmt, x % divisor[i]) - 1; + + while (f >= fract && strchr("0.", *f)) + *f-- = 0; } - sr_err("%s: Error creating SI units string.", __func__); - return NULL; + p = prefix + i; + + return g_strdup_printf("%" PRIu64 "%s %.1s%s", quot, fract, p, unit); } /** @@ -232,7 +230,8 @@ SR_API char **sr_parse_triggerstring(const struct sr_dev_inst *sdi, return NULL; } - if (sdi->driver->config_list(SR_CONF_TRIGGER_TYPE, &gvar, sdi) != SR_OK) { + if (sdi->driver->config_list(SR_CONF_TRIGGER_TYPE, + &gvar, sdi, NULL) != SR_OK) { sr_err("%s: Device doesn't support any triggers.", __func__); return NULL; }