From: Aki Tuomi Date: Tue, 5 Dec 2017 21:49:27 +0000 (+0200) Subject: lib: var-expand - Add table size and merge utility functions X-Git-Tag: 2.3.0.rc1~245 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=857a9e1f1cf3a2241403bfb201421bb1a66038b1;p=thirdparty%2Fdovecot%2Fcore.git lib: var-expand - Add table size and merge utility functions --- diff --git a/src/lib/test-var-expand.c b/src/lib/test-var-expand.c index 32ab2ad839..9c45af23fe 100644 --- a/src/lib/test-var-expand.c +++ b/src/lib/test-var-expand.c @@ -421,6 +421,42 @@ static void test_var_expand_if(void) test_end(); } +static void test_var_expand_merge_tables(void) +{ + const struct var_expand_table one[] = { + { 'a', "1", "alpha" }, + { '\0', "2", "beta" }, + { '\0', NULL, NULL } + }, + two[] = { + { 't', "3", "theta" }, + { '\0', "4", "phi" }, + { '\0', NULL, NULL } + }, + *merged = NULL; + + + test_begin("var_expand_merge_tables"); + + merged = t_var_expand_merge_tables(one, two); + + test_assert(var_expand_table_size(merged) == 4); + for(unsigned int i = 0; i < var_expand_table_size(merged); i++) { + if (i < 2) { + test_assert_idx(merged[i].key == one[i].key, i); + test_assert_idx(merged[i].value == one[i].value || strcmp(merged[i].value, one[i].value) == 0, i); + test_assert_idx(merged[i].long_key == one[i].long_key || strcmp(merged[i].long_key, one[i].long_key) == 0, i); + } else if (i < 4) { + test_assert_idx(merged[i].key == two[i-2].key, i); + test_assert_idx(merged[i].value == two[i-2].value || strcmp(merged[i].value, two[i-2].value) == 0, i); + test_assert_idx(merged[i].long_key == two[i-2].long_key || strcmp(merged[i].long_key, two[i-2].long_key) == 0, i); + } else { + break; + } + } + test_end(); +} + void test_var_expand(void) { test_var_expand_ranges(); @@ -431,4 +467,5 @@ void test_var_expand(void) test_var_has_key(); test_var_expand_extensions(); test_var_expand_if(); + test_var_expand_merge_tables(); } diff --git a/src/lib/var-expand.c b/src/lib/var-expand.c index cdcb5da4dc..0e18bb6238 100644 --- a/src/lib/var-expand.c +++ b/src/lib/var-expand.c @@ -777,3 +777,29 @@ var_expand_unregister_func_array(const struct var_expand_extension_func_table *f } } } + +struct var_expand_table * +var_expand_merge_tables(pool_t pool, const struct var_expand_table *a, + const struct var_expand_table *b) +{ + ARRAY(struct var_expand_table) table; + size_t a_size = var_expand_table_size(a); + size_t b_size = var_expand_table_size(b); + p_array_init(&table, pool, a_size + b_size + 1); + for(size_t i=0; ikey = a[i].key; + entry->value = p_strdup(pool, a[i].value); + entry->long_key = p_strdup(pool, a[i].long_key); + } + for(size_t i=0; ikey = b[i].key; + entry->value = p_strdup(pool, b[i].value); + entry->long_key = p_strdup(pool, b[i].long_key); + } + array_append_zero(&table); + return array_idx_modifiable(&table, 0); +} diff --git a/src/lib/var-expand.h b/src/lib/var-expand.h index 40798b0a58..c8485a4377 100644 --- a/src/lib/var-expand.h +++ b/src/lib/var-expand.h @@ -42,4 +42,19 @@ void var_get_key_range(const char *str, unsigned int *idx_r, If key is '\0', it's ignored. If long_key is NULL, it's ignored. */ bool var_has_key(const char *str, char key, const char *long_key) ATTR_PURE; +static inline size_t ATTR_PURE +var_expand_table_size(const struct var_expand_table *table) +{ + size_t n = 0; + while(table != NULL && (table[n].key != '\0' || + table[n].long_key != NULL)) + n++; + return n; +} + +struct var_expand_table * +var_expand_merge_tables(pool_t pool, const struct var_expand_table *a, + const struct var_expand_table *b); +#define t_var_expand_merge_tables(a, b) \ + (const struct var_expand_table *)var_expand_merge_tables(pool_datastack_create(), (a), (b)) #endif