dovecot-2.0: Settings parser: Support keeping track of what sett...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Sep 2 23:18:50 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/649245b1552e
changeset: 9854:649245b1552e
user: Timo Sirainen <tss at iki.fi>
date: Wed Sep 02 16:18:10 2009 -0400
description:
Settings parser: Support keeping track of what settings were explicitly set.
diffstat:
2 files changed, 114 insertions(+), 16 deletions(-)
src/lib-settings/settings-parser.c | 125 +++++++++++++++++++++++++++++++-----
src/lib-settings/settings-parser.h | 5 +
diffs (249 lines):
diff -r 2765e7fb2202 -r 649245b1552e src/lib-settings/settings-parser.c
--- a/src/lib-settings/settings-parser.c Wed Sep 02 15:33:21 2009 -0400
+++ b/src/lib-settings/settings-parser.c Wed Sep 02 16:18:10 2009 -0400
@@ -27,7 +27,13 @@ struct setting_link {
SET_DEFLIST : array of set_structs
SET_STRLIST : array of const_strings */
ARRAY_TYPE(void_array) *array;
+ /* Pointer to structure containing the values */
void *set_struct;
+ /* Pointer to structure containing non-zero values for settings that
+ have been changed. */
+ void *change_struct;
+ /* SET_DEFLIST: array of change_structs */
+ ARRAY_TYPE(void_array) *change_array;
};
struct setting_parser_context {
@@ -125,6 +131,10 @@ settings_parser_init_list(pool_t set_poo
ctx->roots[i].info = roots[i];
ctx->roots[i].set_struct =
p_malloc(ctx->set_pool, roots[i]->struct_size);
+ if ((flags & SETTINGS_PARSER_FLAG_TRACK_CHANGES) != 0) {
+ ctx->roots[i].change_struct =
+ p_malloc(ctx->set_pool, roots[i]->struct_size);
+ }
setting_parser_copy_defaults(roots[i], ctx->set_pool,
ctx->roots[i].set_struct);
}
@@ -161,6 +171,13 @@ void **settings_parser_get_list(struct s
for (i = 0; i < ctx->root_count; i++)
sets[i] = ctx->roots[i].set_struct;
return sets;
+}
+
+void *settings_parser_get_changes(struct setting_parser_context *ctx)
+{
+ i_assert(ctx->root_count == 1);
+
+ return ctx->roots[0].change_struct;
}
const char *settings_parser_get_error(struct setting_parser_context *ctx)
@@ -245,7 +262,8 @@ static int
static int
get_deflist(struct setting_parser_context *ctx, struct setting_link *parent,
const struct setting_parser_info *info,
- const char *key, const char *value, ARRAY_TYPE(void_array) *result)
+ const char *key, const char *value, ARRAY_TYPE(void_array) *result,
+ ARRAY_TYPE(void_array) *change_result)
{
struct setting_link *link;
const char *const *list;
@@ -255,6 +273,8 @@ get_deflist(struct setting_parser_contex
if (!array_is_created(result))
p_array_init(result, ctx->set_pool, 5);
+ if (change_result != NULL && !array_is_created(change_result))
+ p_array_init(change_result, ctx->set_pool, 5);
list = t_strsplit(value, "\t ");
for (; *list != NULL; list++) {
@@ -273,6 +293,7 @@ get_deflist(struct setting_parser_contex
link->parent = parent;
link->info = info;
link->array = result;
+ link->change_array = change_result;
hash_table_insert(ctx->links, full_key, link);
}
return 0;
@@ -283,7 +304,7 @@ settings_parse(struct setting_parser_con
const struct setting_define *def,
const char *key, const char *value)
{
- void *ptr, *ptr2;
+ void *ptr, *ptr2, *change_ptr;
ctx->prev_info = link->info;
@@ -294,6 +315,13 @@ settings_parse(struct setting_parser_con
link->set_struct);
array_append(link->array, &link->set_struct, 1);
+ if ((ctx->flags & SETTINGS_PARSER_FLAG_TRACK_CHANGES) != 0) {
+ link->change_struct = p_malloc(ctx->set_pool,
+ link->info->struct_size);
+ array_append(link->change_array,
+ &link->change_struct, 1);
+ }
+
if (link->info->parent_offset != (size_t)-1 &&
link->parent != NULL) {
ptr = STRUCT_MEMBER_P(link->set_struct,
@@ -302,40 +330,54 @@ settings_parse(struct setting_parser_con
}
}
+ change_ptr = link->change_struct == NULL ? NULL :
+ STRUCT_MEMBER_P(link->change_struct, def->offset);
+
ptr = STRUCT_MEMBER_P(link->set_struct, def->offset);
switch (def->type) {
case SET_BOOL:
- return get_bool(ctx, value, (bool *)ptr);
+ if (get_bool(ctx, value, (bool *)ptr) < 0)
+ return -1;
+ break;
case SET_UINT:
- return get_uint(ctx, value, (unsigned int *)ptr);
+ if (get_uint(ctx, value, (unsigned int *)ptr) < 0)
+ return -1;
+ break;
case SET_STR:
*((char **)ptr) = p_strdup(ctx->set_pool, value);
- return 0;
+ break;
case SET_STR_VARS:
*((char **)ptr) = p_strconcat(ctx->set_pool,
ctx->str_vars_are_expanded ?
SETTING_STRVAR_EXPANDED :
SETTING_STRVAR_UNEXPANDED,
value, NULL);
- return 0;
+ break;
case SET_ENUM:
/* get the available values from default string */
i_assert(link->info->defaults != NULL);
ptr2 = STRUCT_MEMBER_P(link->info->defaults, def->offset);
- return get_enum(ctx, value, (char **)ptr, *(const char **)ptr2);
+ if (get_enum(ctx, value, (char **)ptr,
+ *(const char **)ptr2) < 0)
+ return -1;
+ break;
case SET_DEFLIST:
ctx->prev_info = def->list_info;
return get_deflist(ctx, link, def->list_info,
- key, value, (ARRAY_TYPE(void_array) *)ptr);
+ key, value, (ARRAY_TYPE(void_array) *)ptr,
+ (ARRAY_TYPE(void_array) *)change_ptr);
case SET_STRLIST: {
ctx->prev_info = &strlist_info;
- return get_deflist(ctx, link, &strlist_info,
- key, value, (ARRAY_TYPE(void_array) *)ptr);
- }
- }
-
- i_unreached();
- return -1;
+ if (get_deflist(ctx, link, &strlist_info, key, value,
+ (ARRAY_TYPE(void_array) *)ptr, NULL) < 0)
+ return -1;
+ break;
+ }
+ }
+
+ if (change_ptr != NULL)
+ *((char *)change_ptr) = 1;
+ return 0;
}
static bool
@@ -931,6 +973,55 @@ void *settings_dup(const struct setting_
return dest_set;
}
+static void *
+settings_changes_dup(const struct setting_parser_info *info,
+ const void *change_set, pool_t pool)
+{
+ const struct setting_define *def;
+ const void *src;
+ void *dest_set, *dest, *const *children;
+ unsigned int i, count;
+
+ if (change_set == NULL)
+ return NULL;
+
+ dest_set = p_malloc(pool, info->struct_size);
+ for (def = info->defines; def->key != NULL; def++) {
+ src = CONST_PTR_OFFSET(change_set, def->offset);
+ dest = PTR_OFFSET(dest_set, def->offset);
+
+ switch (def->type) {
+ case SET_BOOL:
+ case SET_UINT:
+ case SET_STR_VARS:
+ case SET_STR:
+ case SET_ENUM:
+ case SET_STRLIST:
+ *((char *)dest) = *((char *)src);
+ break;
+ case SET_DEFLIST: {
+ const ARRAY_TYPE(void_array) *src_arr = src;
+ ARRAY_TYPE(void_array) *dest_arr = dest;
+ void *child_set;
+
+ if (!array_is_created(src_arr))
+ break;
+
+ children = array_get(src_arr, &count);
+ p_array_init(dest_arr, pool, count);
+ for (i = 0; i < count; i++) {
+ child_set = settings_changes_dup(def->list_info,
+ children[i],
+ pool);
+ array_append(dest_arr, &child_set, 1);
+ }
+ break;
+ }
+ }
+ }
+ return dest_set;
+}
+
static void
info_update_real(pool_t pool, const struct dynamic_settings_parser *parsers)
{
@@ -1110,6 +1201,10 @@ settings_parser_dup(struct setting_parse
settings_dup(old_ctx->roots[i].info,
old_ctx->roots[i].set_struct,
new_ctx->set_pool);
+ new_ctx->roots[i].change_struct =
+ settings_changes_dup(old_ctx->roots[i].info,
+ old_ctx->roots[i].change_struct,
+ new_ctx->set_pool);
hash_table_insert(links, &old_ctx->roots[i],
&new_ctx->roots[i]);
}
diff -r 2765e7fb2202 -r 649245b1552e src/lib-settings/settings-parser.h
--- a/src/lib-settings/settings-parser.h Wed Sep 02 15:33:21 2009 -0400
+++ b/src/lib-settings/settings-parser.h Wed Sep 02 16:18:10 2009 -0400
@@ -75,7 +75,8 @@ ARRAY_DEFINE_TYPE(dynamic_settings_parse
ARRAY_DEFINE_TYPE(dynamic_settings_parser, struct dynamic_settings_parser);
enum settings_parser_flags {
- SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS = 0x01
+ SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS = 0x01,
+ SETTINGS_PARSER_FLAG_TRACK_CHANGES = 0x02
};
struct setting_parser_context;
@@ -93,6 +94,8 @@ void *settings_parser_get(struct setting
void *settings_parser_get(struct setting_parser_context *ctx);
/* If there are multiple roots, return list to all of their settings. */
void **settings_parser_get_list(struct setting_parser_context *ctx);
+/* Like settings_parser_get(), but return change struct. */
+void *settings_parser_get_changes(struct setting_parser_context *ctx);
/* Return the last error. */
const char *settings_parser_get_error(struct setting_parser_context *ctx);
More information about the dovecot-cvs
mailing list