diff options
Diffstat (limited to 'src/format_placeholders.c')
-rw-r--r-- | src/format_placeholders.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/format_placeholders.c b/src/format_placeholders.c new file mode 100644 index 0000000..650089d --- /dev/null +++ b/src/format_placeholders.c @@ -0,0 +1,70 @@ +/* + * vim:ts=4:sw=4:expandtab + * + * i3 - an improved dynamic tiling window manager + * © 2009 Michael Stapelberg and contributors (see also: LICENSE) + * + */ +// copied from i3:libi3/format_placeholders.c +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "i3status.h" + +#ifndef CS_STARTS_WITH +#define CS_STARTS_WITH(string, needle) (strncmp((string), (needle), strlen((needle))) == 0) +#endif + +/* + * Replaces occurrences of the defined placeholders in the format string. + * + */ +char *format_placeholders(const char *format, placeholder_t *placeholders, int num) { + if (format == NULL) + return NULL; + + /* We have to first iterate over the string to see how much buffer space + * we need to allocate. */ + int buffer_len = strlen(format) + 1; + for (const char *walk = format; *walk != '\0'; walk++) { + for (int i = 0; i < num; i++) { + if (!CS_STARTS_WITH(walk, placeholders[i].name)) + continue; + + buffer_len = buffer_len - strlen(placeholders[i].name) + strlen(placeholders[i].value); + walk += strlen(placeholders[i].name) - 1; + break; + } + } + + /* Now we can parse the format string. */ + char buffer[buffer_len]; + char *outwalk = buffer; + for (const char *walk = format; *walk != '\0'; walk++) { + if (*walk != '%') { + *(outwalk++) = *walk; + continue; + } + + bool matched = false; + for (int i = 0; i < num; i++) { + if (!CS_STARTS_WITH(walk, placeholders[i].name)) { + continue; + } + + matched = true; + outwalk += sprintf(outwalk, "%s", placeholders[i].value); + walk += strlen(placeholders[i].name) - 1; + break; + } + + if (!matched) + *(outwalk++) = *walk; + } + + *outwalk = '\0'; + return sstrdup(buffer); +} |