X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=strutil.c;h=6cb13a6ac3aa22fb1830dc635d170cc12628c986;hb=ce95428cca4ee7f8263389dd44a02d228d2be88e;hp=5c547aa9ecf408f25787b3b7c2a339152fabee79;hpb=50985c2019b2b5a6ce394589d89ee925b4f5e3a9;p=libsigrok.git diff --git a/strutil.c b/strutil.c index 5c547aa9..6cb13a6a 100644 --- a/strutil.c +++ b/strutil.c @@ -24,14 +24,14 @@ #include "libsigrok.h" #include "libsigrok-internal.h" -/* Message logging helpers with driver-specific prefix string. */ -#define DRIVER_LOG_DOMAIN "strutil: " -#define sr_log(l, s, args...) sr_log(l, DRIVER_LOG_DOMAIN s, ## args) -#define sr_spew(s, args...) sr_spew(DRIVER_LOG_DOMAIN s, ## args) -#define sr_dbg(s, args...) sr_dbg(DRIVER_LOG_DOMAIN s, ## args) -#define sr_info(s, args...) sr_info(DRIVER_LOG_DOMAIN s, ## args) -#define sr_warn(s, args...) sr_warn(DRIVER_LOG_DOMAIN s, ## args) -#define sr_err(s, args...) sr_err(DRIVER_LOG_DOMAIN s, ## args) +/* Message logging helpers with subsystem-specific prefix string. */ +#define LOG_PREFIX "strutil: " +#define sr_log(l, s, args...) sr_log(l, LOG_PREFIX s, ## args) +#define sr_spew(s, args...) sr_spew(LOG_PREFIX s, ## args) +#define sr_dbg(s, args...) sr_dbg(LOG_PREFIX s, ## args) +#define sr_info(s, args...) sr_info(LOG_PREFIX s, ## args) +#define sr_warn(s, args...) sr_warn(LOG_PREFIX s, ## args) +#define sr_err(s, args...) sr_err(LOG_PREFIX s, ## args) /** * @file @@ -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); } /**