From 889d5a32714758e15a22ee7db5e999293b8511cd Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Tue, 5 Dec 2017 23:49:27 +0200 Subject: [PATCH] lib: var-expand - Add table size and merge utility functions --- src/lib/test-var-expand.c | 37 +++++++++++++++++++++++++++++++++++++ src/lib/var-expand.c | 26 ++++++++++++++++++++++++++ src/lib/var-expand.h | 15 +++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/src/lib/test-var-expand.c b/src/lib/test-var-expand.c index 4553adb857..7f6e7444d2 100644 --- a/src/lib/test-var-expand.c +++ b/src/lib/test-var-expand.c @@ -376,6 +376,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(); @@ -386,4 +422,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 5ac5b59667..2ed06bb3a9 100644 --- a/src/lib/var-expand.c +++ b/src/lib/var-expand.c @@ -762,3 +762,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 aea8d77b33..2fc876eb20 100644 --- a/src/lib/var-expand.h +++ b/src/lib/var-expand.h @@ -36,4 +36,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