changeset 22786:7b6f77272538

lib: var-expand - Add table size and merge utility functions
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Tue, 05 Dec 2017 23:49:27 +0200
parents bfb8e1924e75
children 9e83365e368b
files src/lib/test-var-expand.c src/lib/var-expand.c src/lib/var-expand.h
diffstat 3 files changed, 78 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/test-var-expand.c	Sat Jan 20 21:32:07 2018 +0100
+++ b/src/lib/test-var-expand.c	Tue Dec 05 23:49:27 2017 +0200
@@ -376,6 +376,42 @@
 	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 @@
 	test_var_has_key();
 	test_var_expand_extensions();
 	test_var_expand_if();
+	test_var_expand_merge_tables();
 }
--- a/src/lib/var-expand.c	Sat Jan 20 21:32:07 2018 +0100
+++ b/src/lib/var-expand.c	Tue Dec 05 23:49:27 2017 +0200
@@ -762,3 +762,29 @@
 		}
 	}
 }
+
+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; i<a_size; i++) {
+		struct var_expand_table *entry =
+			array_append_space(&table);
+		entry->key = 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; i<b_size; i++) {
+		struct var_expand_table *entry =
+			array_append_space(&table);
+		entry->key = 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);
+}
--- a/src/lib/var-expand.h	Sat Jan 20 21:32:07 2018 +0100
+++ b/src/lib/var-expand.h	Tue Dec 05 23:49:27 2017 +0200
@@ -36,4 +36,19 @@
    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