From 123d035b8164999b086c08ed472cd83ead72599c Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Sun, 8 Sep 2024 18:53:33 +0200 Subject: Implement strformat --- src/blocks/ram.c | 47 +++++++++++++++++++++-------------- src/util.c | 76 +++++++++++++++++++++++++++++++++++--------------------- src/util.h | 13 +--------- 3 files changed, 76 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/blocks/ram.c b/src/blocks/ram.c index 4400a59..780ff9e 100644 --- a/src/blocks/ram.c +++ b/src/blocks/ram.c @@ -7,15 +7,6 @@ #include "../any_log.h" -static const char *ram_formats[] = { - "%{total}", - "%{free}", - "%{used}", - "%{free-percentage}", - "%{used-percentage}", - NULL, -}; - static void block_ram_update(block_t *block) { FILE *meminfo = fopen("/proc/meminfo", "rb"); @@ -31,15 +22,34 @@ static void block_ram_update(block_t *block) &total, &unused, &available, &buffers, &cached)); fclose(meminfo); - char ram_values[6][32] = { 0 }; - - snprintf(ram_values[0], 32, "%ld", total); - snprintf(ram_values[1], 32, "%ld", available); - snprintf(ram_values[2], 32, "%ld", total - available); - snprintf(ram_values[3], 32, "%ld", 100 * available / total); - snprintf(ram_values[4], 32, "%ld", 100 * (total - available) / total); - block->text.text = strformat(block->state, ram_formats, (const char **)ram_values); + static const char *ram_formats[] = { + "total", + "free", + "used", + "free-percentage", + "used-percentage", + NULL, + }; + + char buffer[32][5] = { 0 }; + snprintf(buffer[0], 32, "%ld", total); + snprintf(buffer[1], 32, "%ld", available); + snprintf(buffer[2], 32, "%ld", total - available); + snprintf(buffer[3], 32, "%ld", 100 * available / total); + snprintf(buffer[4], 32, "%ld", 100 * (total - available) / total); + + const char *ram_values[] = { + buffer[0], + buffer[1], + buffer[2], + buffer[3], + buffer[4], + NULL, + }; + + + block->text.text = strformat(block->state, '%', ram_formats, ram_values); assert(block->text.text != NULL); } @@ -58,8 +68,7 @@ static bool block_ram_validate(block_t *block, const block_scheme_t *scheme) block->state = block->text.text; block->text.text = NULL; - size_t count = strcount(block->state, ram_formats); - if (count == 0) { + if (strstr(block->state, "%{") == NULL) { log_warn("Block '%s' does not use any ram variable", block->label); block->update_cb = NULL; diff --git a/src/util.c b/src/util.c index 0a2ade8..805d397 100644 --- a/src/util.c +++ b/src/util.c @@ -6,18 +6,6 @@ #include "util.h" #include "any_log.h" -void pair_copy(pair_t *copy, const pair_t *pair) -{ - copy->key = strcopy(pair->key); - copy->value = strcopy(pair->value); -} - -void pair_free(pair_t *pair) -{ - free(pair->key); - free(pair->value); -} - char *color_to_string(color_t *color) { unsigned int r = color->r * 255, @@ -127,26 +115,56 @@ size_t strprefix(const char *string, const char *prefix) return i; } -size_t strcount(const char *string, const char *subs[]) +// FIXME: Slow and inefficient +char *strformat(const char *string, char delim, const char **keys, const char **values) { - size_t count = 0; - for (int i = 0; string[i] != '\0'; ) { -next: - for (int j = 0; subs[j] != NULL; j++) { - size_t pl = strprefix(string + i, subs[j]); - if (pl) { - i += pl; - count++; - goto next; + 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; } - ++i; + buffer[n++] = string[i]; +next: } - return count; -} -char *strformat(const char *string, const char *keys[], const char *values[]) -{ - // TODO - return NULL; + buffer[n] = '\0'; + return buffer; } diff --git a/src/util.h b/src/util.h index d7cb6bd..770790d 100644 --- a/src/util.h +++ b/src/util.h @@ -8,15 +8,6 @@ #define unreachable() log_panic("Unreachable code"); -typedef struct { - char *key; - char *value; -} pair_t; - -void pair_copy(pair_t *copy, const pair_t *pair); - -void pair_free(pair_t *pair); - // Color representation normalized to [0, 1] // typedef struct { @@ -61,8 +52,6 @@ bool strfind(const char *string, const char *cases[]); size_t strprefix(const char *string, const char *prefix); -size_t strcount(const char *string, const char *subs[]); - -char *strformat(const char *string, const char *keys[], const char *values[]); +char *strformat(const char *string, char delim, const char *keys[], const char *values[]); #endif -- cgit v1.2.3