ctx->set_struct, error_r);
}
-static void
-setting_copy(enum setting_type type, const void *src, void *dest, pool_t pool,
- bool keep_values)
-{
- switch (type) {
- case SET_BOOL: {
- const bool *src_bool = src;
- bool *dest_bool = dest;
-
- *dest_bool = *src_bool;
- break;
- }
- case SET_UINT:
- case SET_UINT_OCT:
- case SET_TIME:
- case SET_TIME_MSECS: {
- const unsigned int *src_uint = src;
- unsigned int *dest_uint = dest;
-
- *dest_uint = *src_uint;
- break;
- }
- case SET_SIZE: {
- const uoff_t *src_size = src;
- uoff_t *dest_size = dest;
-
- *dest_size = *src_size;
- break;
- }
- case SET_IN_PORT: {
- const in_port_t *src_size = src;
- in_port_t *dest_size = dest;
-
- *dest_size = *src_size;
- break;
- }
- case SET_STR:
- case SET_STR_NOVARS:
- case SET_ENUM: {
- const char *const *src_str = src;
- const char **dest_str = dest;
-
- if (keep_values)
- *dest_str = *src_str;
- else
- *dest_str = p_strdup(pool, *src_str);
- break;
- }
- case SET_STRLIST: {
- const ARRAY_TYPE(const_string) *src_arr = src;
- ARRAY_TYPE(const_string) *dest_arr = dest;
- const char *const *strings, *const *dest_strings, *dup;
- unsigned int i, j, count, dest_count;
-
- if (!array_is_created(src_arr))
- break;
-
- strings = array_get(src_arr, &count);
- i_assert(count % 2 == 0);
- if (!array_is_created(dest_arr))
- p_array_init(dest_arr, pool, count);
- dest_count = array_count(dest_arr);
- i_assert(dest_count % 2 == 0);
- for (i = 0; i < count; i += 2) {
- if (dest_count > 0) {
- dest_strings = array_front(dest_arr);
- for (j = 0; j < dest_count; j += 2) {
- if (strcmp(strings[i], dest_strings[j]) == 0)
- break;
- }
- if (j < dest_count)
- continue;
- }
- dup = keep_values ? strings[i] : p_strdup(pool, strings[i]);
- array_push_back(dest_arr, &dup);
- dup = keep_values ? strings[i+1] : p_strdup(pool, strings[i+1]);
- array_push_back(dest_arr, &dup);
- }
- break;
- }
- case SET_FILTER_ARRAY: {
- const ARRAY_TYPE(const_string) *src_arr = src;
- ARRAY_TYPE(const_string) *dest_arr = dest;
- const char *const *strings, *const *dest_strings, *dup;
- unsigned int i, j, count, dest_count;
-
- if (!array_is_created(src_arr))
- break;
-
- strings = array_get(src_arr, &count);
- if (!array_is_created(dest_arr))
- p_array_init(dest_arr, pool, count);
- dest_count = array_count(dest_arr);
- for (i = 0; i < count; i++) {
- if (dest_count > 0) {
- dest_strings = array_front(dest_arr);
- for (j = 0; j < dest_count; j++) {
- if (strcmp(strings[i], dest_strings[j]) == 0)
- break;
- }
- if (j < dest_count)
- continue;
- }
- dup = keep_values ? strings[i] : p_strdup(pool, strings[i]);
- array_push_back(dest_arr, &dup);
- }
- break;
- }
- case SET_FILTER_NAME:
- case SET_ALIAS:
- break;
- }
-}
-
-static void *settings_dup_full(const struct setting_parser_info *info,
- const void *set, pool_t pool, bool keep_values)
-{
- const struct setting_define *def;
- const void *src;
- void *dest_set, *dest;
-
- if (info->struct_size == 0)
- return NULL;
-
- /* don't just copy everything from set to dest_set. it may contain
- some non-setting fields allocated from the original pool. */
- dest_set = p_malloc(pool, info->struct_size);
- for (def = info->defines; def->key != NULL; def++) {
- src = CONST_PTR_OFFSET(set, def->offset);
- dest = PTR_OFFSET(dest_set, def->offset);
-
- setting_copy(def->type, src, dest, pool, keep_values);
- }
-
- i_assert(info->pool_offset1 > 0);
- pool_t *pool_p = PTR_OFFSET(dest_set, info->pool_offset1 - 1);
- *pool_p = pool;
- return dest_set;
-}
-
-struct setting_parser_context *
-settings_parser_dup(const struct setting_parser_context *old_ctx,
- pool_t new_pool)
-{
- struct setting_parser_context *new_ctx;
- pool_t parser_pool;
- bool keep_values;
-
- /* if source and destination pools are the same, there's no need to
- duplicate values */
- keep_values = new_pool == old_ctx->set_pool;
-
- pool_ref(new_pool);
- parser_pool = pool_alloconly_create(MEMPOOL_GROWING"dup settings parser",
- 1024);
- new_ctx = p_new(parser_pool, struct setting_parser_context, 1);
- new_ctx->refcount = 1;
- new_ctx->set_pool = new_pool;
- new_ctx->parser_pool = parser_pool;
- new_ctx->flags = old_ctx->flags;
- new_ctx->linenum = old_ctx->linenum;
- new_ctx->error = i_strdup(old_ctx->error);
-
- new_ctx->info = old_ctx->info;
- new_ctx->set_struct =
- settings_dup_full(old_ctx->info,
- old_ctx->set_struct,
- new_ctx->set_pool, keep_values);
- return new_ctx;
-}
-
const char *settings_section_escape(const char *name)
{
#define CHAR_NEED_ESCAPE(c) \