diff options
| author | Federico Angelilli <code@fedang.net> | 2024-11-19 11:17:50 +0100 |
|---|---|---|
| committer | Federico Angelilli <code@fedang.net> | 2024-11-19 11:17:50 +0100 |
| commit | afcbe44a7cf454f3588a60180d93f65df9e5fcc7 (patch) | |
| tree | 7a3b94a9c9f7ef8cbd3062b26e31ef25b9d9a742 /src/util.c | |
| parent | 79a32360e76cb0739312e15299fc22941e51b64b (diff) | |
Add byte human readable formatting
Diffstat (limited to 'src/util.c')
| -rw-r--r-- | src/util.c | 108 |
1 files changed, 54 insertions, 54 deletions
@@ -2,6 +2,7 @@ #include <stdlib.h> #include <string.h> #include <stdio.h> +#include <math.h> #include "util.h" #include "any_log.h" @@ -152,60 +153,6 @@ size_t strprefix(const char *string, const char *prefix) return i; } -// FIXME: Slow and inefficient -char *strformat(const char *string, char delim, const char **keys, const char **values) -{ - size_t length = strlen(string); - size_t size = length; - size_t n = 0; - char *buffer = malloc(size); - - for (size_t i = 0; i < length; i++) { - if (string[i] == delim && i + 2 < length && string[i + 1] == '{') { - bool found = false; - size_t j = i + 2; - for ( ; j < length; j++) { - if (string[j] == '}') { - found = true; - break; - } - } - - if (found) { - for (int k = 0; keys[k] != NULL; k++) { - if (!strncmp(string + i + 2, keys[k], j - i - 2)) { - - size_t vl = strlen(values[k]); - while (n + vl >= size) { - size *= 1.5; - buffer = realloc(buffer, size); - if (buffer == NULL) - return NULL; - } - - memcpy(buffer + n, values[k], vl); - n += vl; - i = j; - goto next; - } - } - } - } - - if (n + 1 >= size) { - size *= 1.5; - buffer = realloc(buffer, size); - if (buffer == NULL) - return NULL; - } - buffer[n++] = string[i]; -next: - } - - buffer[n] = '\0'; - return buffer; -} - void strfree(char **list) { if (list == NULL) @@ -225,3 +172,56 @@ bool iszero(const void *ptr, size_t size) } return true; } + +int snprintf_units(char *buffer, size_t max, uint64_t bytes, unit_t unit) +{ + int base = unit & UNIT_SI ? 1000 : 1024; + double value = bytes; + const char *label = ""; + + switch (unit & ~UNIT_SI) { + case UNIT_B: + break; + + case UNIT_TB: + value /= base; + // fallthrough + + case UNIT_GB: + value /= base; + // fallthrough + + case UNIT_MB: + value /= base; + // fallthrough + + case UNIT_KB: + value /= base; + break; + + default: { + int i = -1; + do { + value /= base; + i++; + } while (round(value * 10) / 10 >= base && i < 4); + + const char *units[2][5] = { + { " B", " kB", " MB", " GB", " TB" }, + { " B", " KiB", " MiB", " GiB", " TiB" }, + }; + label = units[!(unit & UNIT_SI)][i]; + break; + } + } + + int prec = 1; + if (floor(value) >= 100.0) { + value = ceil(value); + prec = 0; + } + + int ret = snprintf(buffer, max, "%.*lf%s", prec, value, label); + assert(ret > 0); + return ret; +} |
