From 0d088e48b5e4480fe2421bb90d601131bed35c8a Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Tue, 19 Nov 2024 01:13:47 +0100 Subject: Update format --- src/format.c | 93 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 33 deletions(-) (limited to 'src/format.c') 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); } -- cgit v1.2.3