dovecot-2.0: config: Added SET_DEFLIST_UNIQUE type. Settings in ...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Oct 24 02:11:27 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/eaac22ecc168
changeset: 10175:eaac22ecc168
user: Timo Sirainen <tss at iki.fi>
date: Fri Oct 23 19:10:42 2009 -0400
description:
config: Added SET_DEFLIST_UNIQUE type. Settings in unique sections can be overridden.
diffstat:
4 files changed, 214 insertions(+), 53 deletions(-)
src/config/config-parser.c | 50 +++++++-
src/config/config-request.c | 7 -
src/lib-settings/settings-parser.c | 207 ++++++++++++++++++++++++++++--------
src/lib-settings/settings-parser.h | 3
diffs (truncated from 466 to 300 lines):
diff -r 429641734346 -r eaac22ecc168 src/config/config-parser.c
--- a/src/config/config-parser.c Fri Oct 23 19:09:33 2009 -0400
+++ b/src/config/config-parser.c Fri Oct 23 19:10:42 2009 -0400
@@ -565,14 +565,49 @@ static int config_parse_finish(struct pa
return 0;
}
+static const char *section_name_escape(const char *name)
+{
+#define CHAR_NEED_ESCAPE(c) \
+ ((c) == '=' || (c) == SETTINGS_SEPARATOR || (c) == '\\')
+ string_t *str;
+ unsigned int i;
+
+ for (i = 0; name[i] != '\0'; i++) {
+ if (CHAR_NEED_ESCAPE(name[i]))
+ break;
+ }
+ if (name[i] == '\0')
+ return name;
+
+ str = t_str_new(i + strlen(name+i) + 8);
+ str_append_n(str, name, i);
+ for (; name[i] != '\0'; i++) {
+ switch (name[i]) {
+ case '=':
+ str_append(str, "\\e");
+ break;
+ case SETTINGS_SEPARATOR:
+ str_append(str, "\\s");
+ break;
+ case '\\':
+ str_append(str, "\\\\");
+ break;
+ default:
+ str_append_c(str, name[i]);
+ break;
+ }
+ }
+ return str_c(str);
+}
+
int config_parse_file(const char *path, bool expand_files,
const char **error_r)
{
struct input_stack root;
struct parser_context ctx;
unsigned int pathlen = 0;
- unsigned int i, count, counter = 0, cur_counter;
- const char *errormsg, *key, *value;
+ unsigned int i, count, counter = 0;
+ const char *errormsg, *key, *value, *section_name;
string_t *str, *full_line;
enum config_line_type type;
char *line;
@@ -650,20 +685,25 @@ prevfile:
}
/* new config section */
+ if (*value == '\0') {
+ /* no section name, use a counter */
+ section_name = dec2str(counter++);
+ } else {
+ section_name = section_name_escape(value);
+ }
str_truncate(str, pathlen);
str_append(str, key);
pathlen = str_len(str);
- cur_counter = counter++;
str_append_c(str, '=');
- str_printfa(str, "%u", cur_counter);
+ str_append(str, section_name);
if (config_apply_line(&ctx, key, str_c(str), value, &errormsg) < 0)
break;
str_truncate(str, pathlen);
str_append_c(str, SETTINGS_SEPARATOR);
- str_printfa(str, "%u", cur_counter);
+ str_append(str, section_name);
str_append_c(str, SETTINGS_SEPARATOR);
pathlen = str_len(str);
break;
diff -r 429641734346 -r eaac22ecc168 src/config/config-request.c
--- a/src/config/config-request.c Fri Oct 23 19:09:33 2009 -0400
+++ b/src/config/config-request.c Fri Oct 23 19:10:42 2009 -0400
@@ -157,7 +157,8 @@ static void settings_export(struct setti
str_append(ctx->value, *val);
break;
}
- case SET_DEFLIST: {
+ case SET_DEFLIST:
+ case SET_DEFLIST_UNIQUE: {
const ARRAY_TYPE(void_array) *val = value;
const ARRAY_TYPE(void_array) *change_val = change_value;
@@ -212,8 +213,8 @@ static void settings_export(struct setti
def->key, NULL);
if (hash_table_lookup(ctx->keys, key) == NULL) {
ctx->callback(key, str_c(ctx->value),
- def->type == SET_DEFLIST,
- ctx->context);
+ SETTING_TYPE_IS_DEFLIST(def->type),
+ ctx->context);
hash_table_insert(ctx->keys, key, key);
}
}
diff -r 429641734346 -r eaac22ecc168 src/lib-settings/settings-parser.c
--- a/src/lib-settings/settings-parser.c Fri Oct 23 19:09:33 2009 -0400
+++ b/src/lib-settings/settings-parser.c Fri Oct 23 19:10:42 2009 -0400
@@ -61,6 +61,11 @@ static const struct setting_parser_info
MEMBER(parent_offset) (size_t)-1
};
+static int
+settings_apply(struct setting_link *dest_link,
+ const struct setting_link *src_link,
+ pool_t pool, const char **conflict_key_r);
+
struct setting_parser_context *
settings_parser_init(pool_t set_pool, const struct setting_parser_info *root,
enum settings_parser_flags flags)
@@ -262,6 +267,7 @@ static int get_enum(struct setting_parse
static int
get_deflist(struct setting_parser_context *ctx, struct setting_link *parent,
+ const struct setting_define *def,
const struct setting_parser_info *info,
const char *key, const char *value, ARRAY_TYPE(void_array) *result,
ARRAY_TYPE(void_array) *change_result)
@@ -284,7 +290,11 @@ get_deflist(struct setting_parser_contex
full_key = p_strconcat(ctx->parser_pool, key,
SETTINGS_SEPARATOR_S, *list, NULL);
- if (hash_table_lookup(ctx->links, full_key) != NULL) {
+ link = hash_table_lookup(ctx->links, full_key);
+ if (link != NULL) {
+ if (def != NULL && def->type == SET_DEFLIST_UNIQUE &&
+ link->parent == parent && link->info == info)
+ return 0;
ctx->error = p_strconcat(ctx->parser_pool, full_key,
" already exists", NULL);
return -1;
@@ -363,13 +373,14 @@ settings_parse(struct setting_parser_con
return -1;
break;
case SET_DEFLIST:
+ case SET_DEFLIST_UNIQUE:
ctx->prev_info = def->list_info;
- return get_deflist(ctx, link, def->list_info,
+ return get_deflist(ctx, link, def, def->list_info,
key, value, (ARRAY_TYPE(void_array) *)ptr,
(ARRAY_TYPE(void_array) *)change_ptr);
case SET_STRLIST: {
ctx->prev_info = &strlist_info;
- if (get_deflist(ctx, link, &strlist_info, key, value,
+ if (get_deflist(ctx, link, NULL, &strlist_info, key, value,
(ARRAY_TYPE(void_array) *)ptr, NULL) < 0)
return -1;
break;
@@ -707,10 +718,10 @@ bool settings_check(const struct setting
}
for (def = info->defines; def->key != NULL; def++) {
- if (def->type != SET_DEFLIST)
+ if (!SETTING_TYPE_IS_DEFLIST(def->type))
continue;
- val = CONST_PTR_OFFSET(set, def->offset);;
+ val = CONST_PTR_OFFSET(set, def->offset);
if (!array_is_created(val))
continue;
@@ -791,6 +802,12 @@ settings_var_expand_info(const struct se
for (def = info->defines; def->key != NULL; def++) {
value = PTR_OFFSET(set, def->offset);
switch (def->type) {
+ case SET_BOOL:
+ case SET_UINT:
+ case SET_STR:
+ case SET_ENUM:
+ case SET_STRLIST:
+ break;
case SET_STR_VARS: {
const char **val = value;
@@ -811,7 +828,8 @@ settings_var_expand_info(const struct se
}
break;
}
- case SET_DEFLIST: {
+ case SET_DEFLIST:
+ case SET_DEFLIST_UNIQUE: {
const ARRAY_TYPE(void_array) *val = value;
if (!array_is_created(val))
@@ -825,8 +843,6 @@ settings_var_expand_info(const struct se
}
break;
}
- default:
- break;
}
}
}
@@ -855,6 +871,12 @@ bool settings_vars_have_key(const struct
for (def = info->defines; def->key != NULL; def++) {
value = CONST_PTR_OFFSET(set, def->offset);
switch (def->type) {
+ case SET_BOOL:
+ case SET_UINT:
+ case SET_STR:
+ case SET_ENUM:
+ case SET_STRLIST:
+ break;
case SET_STR_VARS: {
const char *const *val = value;
@@ -873,7 +895,8 @@ bool settings_vars_have_key(const struct
}
break;
}
- case SET_DEFLIST: {
+ case SET_DEFLIST:
+ case SET_DEFLIST_UNIQUE: {
const ARRAY_TYPE(void_array) *val = value;
if (!array_is_created(val))
@@ -889,8 +912,6 @@ bool settings_vars_have_key(const struct
}
break;
}
- default:
- break;
}
}
return FALSE;
@@ -936,6 +957,7 @@ setting_copy(enum setting_type type, con
break;
}
case SET_DEFLIST:
+ case SET_DEFLIST_UNIQUE:
return FALSE;
case SET_STRLIST: {
const ARRAY_TYPE(const_string) *src_arr = src;
@@ -1025,7 +1047,8 @@ settings_changes_dup(const struct settin
case SET_STRLIST:
*((char *)dest) = *((char *)src);
break;
- case SET_DEFLIST: {
+ case SET_DEFLIST:
+ case SET_DEFLIST_UNIQUE: {
const ARRAY_TYPE(void_array) *src_arr = src;
ARRAY_TYPE(void_array) *dest_arr = dest;
void *child_set;
@@ -1268,7 +1291,7 @@ settings_changes_init(const struct setti
dest_set = p_malloc(pool, info->struct_size);
for (def = info->defines; def->key != NULL; def++) {
- if (def->type != SET_DEFLIST)
+ if (!SETTING_TYPE_IS_DEFLIST(def->type))
continue;
src_arr = CONST_PTR_OFFSET(change_set, def->offset);
@@ -1288,6 +1311,119 @@ settings_changes_init(const struct setti
return dest_set;
}
+static void settings_copy_deflist(const struct setting_define *def,
+ const struct setting_link *src_link,
+ struct setting_link *dest_link,
+ pool_t pool)
+{
+ const ARRAY_TYPE(void_array) *src_arr;
+ ARRAY_TYPE(void_array) *dest_arr;
+ void *const *children, *child_set;
+ unsigned int i, count;
+
+ src_arr = CONST_PTR_OFFSET(src_link->set_struct, def->offset);
+ dest_arr = PTR_OFFSET(dest_link->set_struct, def->offset);
+
+ if (!array_is_created(src_arr))
+ return;
+
+ children = array_get(src_arr, &count);
+ if (!array_is_created(dest_arr))
+ p_array_init(dest_arr, pool, count);
+ for (i = 0; i < count; i++) {
+ child_set = settings_dup(def->list_info, children[i], pool);
+ array_append(dest_arr, &child_set, 1);
+ settings_set_parent(def->list_info, child_set,
+ dest_link->set_struct);
+ }
+
+ /* copy changes */
+ dest_arr = PTR_OFFSET(dest_link->change_struct, def->offset);
+ if (!array_is_created(dest_arr))
+ p_array_init(dest_arr, pool, count);
+ for (i = 0; i < count; i++) {
More information about the dovecot-cvs
mailing list