1 #ifndef VAR_EXPAND_H
2 #define VAR_EXPAND_H
3 
4 struct var_expand_table {
5 	char key;
6 	const char *value;
7 	const char *long_key;
8 };
9 
10 struct var_expand_func_table {
11 	const char *key;
12 	/* %{key:data}, or data is "" with %{key}.
13 	   Returns 1 on success, 0 if data is invalid, -1 on temporary error. */
14 	int (*func)(const char *data, void *context,
15 		    const char **value_r, const char **error_r);
16 };
17 
18 /* Expand % variables in src and append the string in dest.
19    table must end with key = 0. Returns 1 on success, 0 if the format string
20    contained invalid/unknown %variables, -1 if one of the functions returned
21    temporary error. Even in case of errors the dest string is still written as
22    fully as possible. */
23 int var_expand(string_t *dest, const char *str,
24 	       const struct var_expand_table *table,
25 	       const char **error_r);
26 /* Like var_expand(), but support also callback functions for
27    variable expansion. */
28 int var_expand_with_funcs(string_t *dest, const char *str,
29 			  const struct var_expand_table *table,
30 			  const struct var_expand_func_table *func_table,
31 			  void *func_context, const char **error_r) ATTR_NULL(3, 4, 5);
32 
33 /* Returns the actual key character for given string, ie. skip any modifiers
34    that are before it. The string should be the data after the '%' character.
35    For %{long_variable}, '{' is returned. */
36 char var_get_key(const char *str) ATTR_PURE;
37 /* Similar to var_get_key(), but works for long keys as well. For single char
38    keys size=1, while for e.g. %{key} size=3 and idx points to 'k'. */
39 void var_get_key_range(const char *str, unsigned int *idx_r,
40 		       unsigned int *size_r);
41 /* Returns TRUE if key variable is used in the string.
42    If key is '\0', it's ignored. If long_key is NULL, it's ignored. */
43 bool var_has_key(const char *str, char key, const char *long_key) ATTR_PURE;
44 
45 static inline size_t ATTR_PURE
var_expand_table_size(const struct var_expand_table * table)46 var_expand_table_size(const struct var_expand_table *table)
47 {
48 	size_t n = 0;
49 	while(table != NULL && (table[n].key != '\0' ||
50 				table[n].long_key != NULL))
51 		 n++;
52 	return n;
53 }
54 
55 struct var_expand_table *
56 var_expand_merge_tables(pool_t pool, const struct var_expand_table *a,
57 			const struct var_expand_table *b);
58 #define t_var_expand_merge_tables(a, b) \
59 	(const struct var_expand_table *)var_expand_merge_tables(pool_datastack_create(), (a), (b))
60 #endif
61