diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/blocks/fs.c | 20 | ||||
| -rw-r--r-- | src/blocks/ram.c | 20 | ||||
| -rw-r--r-- | src/format.c | 93 | ||||
| -rw-r--r-- | src/format.h | 21 | ||||
| -rw-r--r-- | src/util.c | 9 | ||||
| -rw-r--r-- | src/util.h | 2 |
6 files changed, 104 insertions, 61 deletions
diff --git a/src/blocks/fs.c b/src/blocks/fs.c index 9c0a50c..188f14a 100644 --- a/src/blocks/fs.c +++ b/src/blocks/fs.c @@ -25,13 +25,13 @@ typedef enum { FS_USED_PERC, } block_fs_mark_t; -static const format_pair_t block_fs_pairs[] = { - { "total", FS_TOTAL }, - { "free", FS_FREE }, - { "used", FS_USED }, - { "free-percentage", FS_FREE_PERC }, - { "used-percentage", FS_USED_PERC }, - { NULL }, +static const format_option_t block_fs_options[] = { + { { "total", FS_TOTAL } }, + { { "free", FS_FREE } }, + { { "used", FS_USED } }, + { { "free-percentage", FS_FREE_PERC } }, + { { "used-percentage", FS_USED_PERC } }, + { { NULL } }, }; static const struct timespec block_fs_interval = { @@ -59,9 +59,9 @@ static void block_fs_update(block_t *block) size_t rest = start >= size ? 0 : size - start; if (rest == 0) break; - switch (fs->format.marks[i]) { + switch (fs->format.parts[i].mark) { case FS_STRING: - start += snprintf(buffer + start, rest, "%s", fs->format.parts[i]); + start += snprintf(buffer + start, rest, "%s", fs->format.parts[i].string); break; case FS_TOTAL: start += snprintf(buffer + start, rest, "%ld", sbuf.f_bsize * (uint64_t)sbuf.f_blocks); @@ -124,7 +124,7 @@ static bool block_fs_validate(block_t *block, const block_scheme_t *scheme) return false; } - int marked = format_remark(&fs->format, block->label, block_fs_pairs); + int marked = format_remark(&fs->format, block->label, block_fs_options); if (marked < 0) return false; diff --git a/src/blocks/ram.c b/src/blocks/ram.c index 0536c26..4841860 100644 --- a/src/blocks/ram.c +++ b/src/blocks/ram.c @@ -21,13 +21,13 @@ typedef enum { RAM_USED_PERC, } block_ram_mark_t; -static const format_pair_t block_ram_pairs[] = { - { "total", RAM_TOTAL }, - { "free", RAM_FREE }, - { "used", RAM_USED }, - { "free-percentage", RAM_FREE_PERC }, - { "used-percentage", RAM_USED_PERC }, - { NULL }, +static const format_option_t block_ram_options[] = { + { { "total", RAM_TOTAL } }, + { { "free", RAM_FREE } }, + { { "used", RAM_USED } }, + { { "free-percentage", RAM_FREE_PERC } }, + { { "used-percentage", RAM_USED_PERC } }, + { { NULL } }, }; static const struct timespec block_ram_interval = { @@ -74,9 +74,9 @@ static void block_ram_update(block_t *block) size_t rest = start >= size ? 0 : size - start; if (rest == 0) break; - switch (ram->format.marks[i]) { + switch (ram->format.parts[i].mark) { case RAM_STRING: - start += snprintf(buffer + start, rest, "%s", ram->format.parts[i]); + start += snprintf(buffer + start, rest, "%s", ram->format.parts[i].string); break; case RAM_TOTAL: start += snprintf(buffer + start, rest, "%ld", total); @@ -138,7 +138,7 @@ static bool block_ram_validate(block_t *block, const block_scheme_t *scheme) return false; } - int marked = format_remark(&ram->format, block->label, block_ram_pairs); + int marked = format_remark(&ram->format, block->label, block_ram_options); if (marked < 0) return false; diff --git a/src/format.c b/src/format.c index 49d5d35..2a2ee03 100644 --- a/src/format.c +++ b/src/format.c @@ -11,18 +11,14 @@ do { \ if (n + 1 >= length) { \ length += (need); \ - parts = realloc(parts, length * sizeof(char *)); \ + parts = realloc(parts, length * sizeof(format_pair_t)); \ assert(parts != NULL); \ - marks = realloc(marks, length * sizeof(uint8_t)); \ - assert(marks != NULL); \ } \ } while (0) bool format_init(format_t *format, const char *string, char delim) { - char **parts = NULL; - uint8_t *marks = NULL; - + format_pair_t *parts = NULL; size_t length = 0, n = 0; size_t start = 0, end = 0; @@ -34,19 +30,16 @@ bool format_init(format_t *format, const char *string, char delim) format_grow(2); if (start != end) { - parts[n] = strslice(string, start, end); - marks[n] = false; + parts[n].string = strslice(string, start, end); + parts[n].mark = 0; n++; } start = end += 2; while (string[end] != '}') { if (string[end] == '\0' || (string[end] == '$' && string[end + 1] == '{')) { - for (size_t k = 0; k < n; k++) - free(parts[k]); - - free(parts); - free(marks); + format->parts = parts, format->length = length; + format_free(format); return false; } end++; @@ -58,8 +51,8 @@ bool format_init(format_t *format, const char *string, char delim) while (start <= end && isspace(string[start])) start++, l--; while (start <= end && isspace(string[end])) end--, l--; - parts[n] = strslice(string, start, start + l); - marks[n] = true; + parts[n].string = strslice(string, start, start + l); + parts[n].mark = 1; n++; start = end = ++next; @@ -75,35 +68,70 @@ next: while (string[end] != '\0') end++; format_grow(1); - parts[n] = strslice(string, start, end); - marks[n] = false; + parts[n].string = strslice(string, start, end); + parts[n].mark = 0; n++; } format->parts = parts; - format->marks = marks; format->length = n; return true; } -int format_remark(format_t *format, const char *label, const format_pair_t *pairs) +static size_t format_option_cmp(const char *a, const char *b) { - int errors = 0, marked = 0; + size_t i = 0; + while (b[i] != '\0') { + if (a[i] != b[i]) return 0; + i++; + } + return i; +} +static bool format_option_match(format_pair_t *part, const format_option_t *option) +{ + format_mark_t mark = 0; + size_t off = 0; + + for (format_pair_t *ps = option->prefixes; ps != NULL && ps->string != NULL; ps++) { + off = format_option_cmp(part->string, ps->string); + if (off != 0) { + mark |= ps->mark; + break; + } + } + + size_t tmp = format_option_cmp(part->string + off, option->option.string); + if (tmp == 0) return false; + off += tmp; + mark |= option->option.mark; + + for (format_pair_t *ss = option->suffixes; ss != NULL && ss->string != NULL; ss++) { + tmp = format_option_cmp(part->string + off, ss->string); + if (tmp != 0) { + mark |= ss->mark; + break; + } + } + + if (part->string[tmp] != '\0') + return false; + + part->mark = mark; + return true; +} + +int format_remark(format_t *format, const char *label, const format_option_t *options) +{ + int errors = 0, marked = 0; for (size_t i = 0; i < format->length; i++) { - // Skip regular strings - if (!format->marks[i]) continue; - size_t l = strlen(format->parts[i]); - for (size_t j = 0; pairs[j].key != NULL; j++) { - size_t kl = strlen(pairs[j].key); + // Skip regular strings + if (!format->parts[i].mark) continue; - if ((pairs[j].prefix && !strncmp(pairs[j].key, format->parts[i], kl)) || - (pairs[j].postfix && l > kl && !strncmp(pairs[j].key, format->parts[i] + (l - kl), kl)) || - !strcmp(pairs[j].key, format->parts[i])) - { - format->marks[i] = pairs[j].mark; + for (size_t j = 0; !iszero(&options[j], sizeof(format_option_t)); j++) { + if (format_option_match(&format->parts[i], &options[j])) { marked++; goto next; } @@ -111,7 +139,7 @@ int format_remark(format_t *format, const char *label, const format_pair_t *pair errors++; if (label != NULL) - log_error("Unknown format option '%s' for block '%s'", format->parts[i], label); + log_error("Unknown format option '%s' for block '%s'", format->parts[i].string, label); next: } @@ -121,8 +149,7 @@ next: void format_free(format_t *format) { for (size_t i = 0; i < format->length; i++) - free(format->parts[i]); + free(format->parts[i].string); free(format->parts); - free(format->marks); } diff --git a/src/format.h b/src/format.h index 8f8eafc..e5173de 100644 --- a/src/format.h +++ b/src/format.h @@ -4,22 +4,27 @@ #include <stdint.h> #include <stdbool.h> +typedef int format_mark_t; + typedef struct { - char **parts; - uint8_t *marks; + char *string; + format_mark_t mark; +} format_pair_t; + +typedef struct { + format_pair_t *parts; size_t length; } format_t; typedef struct { - const char *key; - uint8_t mark; - bool prefix; - bool postfix; -} format_pair_t; + format_pair_t option; + format_pair_t *prefixes; + format_pair_t *suffixes; +} format_option_t; bool format_init(format_t *format, const char *string, char delim); -int format_remark(format_t *format, const char *label, const format_pair_t *pairs); +int format_remark(format_t *format, const char *label, const format_option_t *options); void format_free(format_t *format); @@ -216,3 +216,12 @@ void strfree(char **list) free(list); } + +bool iszero(const void *ptr, size_t size) +{ + for (size_t i = 0; i < size; i++) { + if (((const char *)ptr)[i] != 0) + return false; + } + return true; +} @@ -71,4 +71,6 @@ char *strformat(const char *string, char delim, const char *keys[], const char * void strfree(char **list); +bool iszero(const void *ptr, size_t size); + #endif |
