changeset 9856:6103d925e018 HEAD

config: Code cleanups.
author Timo Sirainen <tss@iki.fi>
date Wed, 02 Sep 2009 16:48:06 -0400
parents 5ae02fad67da
children 0830fbbdfecd
files src/config/config-filter.c src/config/config-filter.h src/config/config-parser.c src/config/config-parser.h src/config/config-request.c src/config/doveconf.c
diffstat 6 files changed, 113 insertions(+), 93 deletions(-) [+]
line wrap: on
line diff
--- a/src/config/config-filter.c	Wed Sep 02 16:21:41 2009 -0400
+++ b/src/config/config-filter.c	Wed Sep 02 16:48:06 2009 -0400
@@ -99,9 +99,9 @@
 		return 1;
 }
 
-const struct config_setting_parser_list *
-config_filter_match_parsers(struct config_filter_context *ctx,
-			    const struct config_filter *filter)
+const struct config_filter_parser_list *
+config_filter_find(struct config_filter_context *ctx,
+		   const struct config_filter *filter)
 {
 	struct config_filter_parser_list *best = NULL;
 	unsigned int i;
@@ -117,5 +117,5 @@
 		    filter_cmp(&best->filter, &ctx->parsers[i]->filter) > 0)
 			best = ctx->parsers[i];
 	}
-	return best == NULL ? NULL : best->parser_list;
+	return best;
 }
--- a/src/config/config-filter.h	Wed Sep 02 16:21:41 2009 -0400
+++ b/src/config/config-filter.h	Wed Sep 02 16:48:06 2009 -0400
@@ -11,18 +11,21 @@
 
 struct config_filter_parser_list {
 	struct config_filter filter;
-	struct config_setting_parser_list *parser_list;
+	/* NULL-terminated array of parsers */
+	struct config_module_parser *parsers;
 };
 
 struct config_filter_context *config_filter_init(pool_t pool);
 void config_filter_deinit(struct config_filter_context **ctx);
 
+/* Replace filter's parsers with given parser list. */
 void config_filter_add_all(struct config_filter_context *ctx,
 			   struct config_filter_parser_list *const *parsers);
 
-const struct config_setting_parser_list *
-config_filter_match_parsers(struct config_filter_context *ctx,
-			    const struct config_filter *filter);
+/* Find the filter that best matches what we have. */
+const struct config_filter_parser_list *
+config_filter_find(struct config_filter_context *ctx,
+		   const struct config_filter *filter);
 
 /* Returns TRUE if filter matches mask. */
 bool config_filter_match(const struct config_filter *mask,
--- a/src/config/config-parser.c	Wed Sep 02 16:21:41 2009 -0400
+++ b/src/config/config-parser.c	Wed Sep 02 16:48:06 2009 -0400
@@ -43,15 +43,15 @@
 
 	ARRAY_DEFINE(all_parsers, struct config_filter_parser_list *);
 	/* parsers matching cur_filter */
-	ARRAY_TYPE(config_setting_parsers) cur_parsers;
-	struct config_setting_parser_list *root_parsers;
+	ARRAY_TYPE(config_module_parsers) cur_parsers;
+	struct config_module_parser *root_parsers;
 	struct config_filter_stack *cur_filter;
 	struct input_stack *cur_input;
 
 	struct config_filter_context *filter;
 };
 
-struct config_setting_parser_list *config_setting_parsers;
+struct config_module_parser *config_module_parsers;
 struct config_filter_context *config_filter;
 
 static const char *info_type_name_find(const struct setting_parser_info *info)
@@ -93,11 +93,11 @@
 }
 
 static int
-config_parsers_parse_line(struct config_setting_parser_list *parsers,
+config_parsers_parse_line(struct config_module_parser *parsers,
 			  const char *key, const char *line,
 			  const char *section_name, const char **error_r)
 {
-	struct config_setting_parser_list *l;
+	struct config_module_parser *l;
 	bool found = FALSE;
 	int ret;
 
@@ -120,12 +120,16 @@
 }
 
 static int
-config_apply_line(struct config_setting_parser_list *const *all_parsers,
-		  const char *key, const char *line, const char *section_name,
+config_apply_line(struct parser_context *ctx, const char *key,
+		  const char *line, const char *section_name,
 		  const char **error_r)
 {
-	for (; *all_parsers != NULL; all_parsers++) {
-		if (config_parsers_parse_line(*all_parsers, key, line,
+	struct config_module_parser *const *parsers;
+	unsigned int i, count;
+
+	parsers = array_get(&ctx->cur_parsers, &count);
+	for (i = 0; i < count; i++) {
+		if (config_parsers_parse_line(parsers[i], key, line,
 					      section_name, error_r) < 0)
 			return -1;
 	}
@@ -148,16 +152,15 @@
 	return t_strconcat(t_strdup_until(input->path, p+1), path, NULL);
 }
 
-static struct config_setting_parser_list *
-config_setting_parser_list_dup(pool_t pool,
-			       const struct config_setting_parser_list *src)
+static struct config_module_parser *
+config_module_parsers_dup(pool_t pool, const struct config_module_parser *src)
 {
-	struct config_setting_parser_list *dest;
+	struct config_module_parser *dest;
 	unsigned int i, count;
 
 	for (count = 0; src[count].module_name != NULL; count++) ;
 
-	dest = p_new(pool, struct config_setting_parser_list, count + 1);
+	dest = p_new(pool, struct config_module_parser, count + 1);
 	for (i = 0; i < count; i++) {
 		dest[i] = src[i];
 		dest[i].parser = settings_parser_dup(src[i].parser, pool);
@@ -169,7 +172,7 @@
 config_add_new_parser(struct parser_context *ctx)
 {
 	struct config_filter_parser_list *parser;
-	struct config_setting_parser_list *const *cur_parsers;
+	struct config_module_parser *const *cur_parsers;
 	unsigned int count;
 
 	parser = p_new(ctx->pool, struct config_filter_parser_list, 1);
@@ -178,12 +181,11 @@
 	cur_parsers = array_get(&ctx->cur_parsers, &count);
 	if (count == 0) {
 		/* first one */
-		parser->parser_list = ctx->root_parsers;
+		parser->parsers = ctx->root_parsers;
 	} else {
 		/* duplicate the first settings list */
-		parser->parser_list =
-			config_setting_parser_list_dup(ctx->pool,
-						       cur_parsers[0]);
+		parser->parsers =
+			config_module_parsers_dup(ctx->pool, cur_parsers[0]);
 	}
 
 	array_append(&ctx->all_parsers, &parser, 1);
@@ -200,8 +202,32 @@
 	ctx->cur_filter = filter;
 }
 
-static struct config_setting_parser_list *const *
-config_update_cur_parsers(struct parser_context *ctx)
+static bool
+config_filter_add_new_parser(struct parser_context *ctx,
+			     const char *key, const char *value,
+			     const char **error_r)
+{
+	struct config_filter *filter = &ctx->cur_filter->filter;
+
+	if (strcmp(key, "protocol") == 0) {
+		filter->service = p_strdup(ctx->pool, value);
+	} else if (strcmp(key, "local_ip") == 0) {
+		if (net_parse_range(value, &filter->local_net,
+				    &filter->local_bits) < 0)
+			*error_r = "Invalid network mask";
+	} else if (strcmp(key, "remote_ip") == 0) {
+		if (net_parse_range(value, &filter->remote_net,
+				    &filter->remote_bits) < 0)
+			*error_r = "Invalid network mask";
+	} else {
+		return FALSE;
+	}
+
+	config_add_new_parser(ctx);
+	return TRUE;
+}
+
+static void config_update_cur_parsers(struct parser_context *ctx)
 {
 	struct config_filter_parser_list *const *all_parsers;
 	unsigned int i, count;
@@ -218,16 +244,14 @@
 		if (config_filters_equal(&all_parsers[i]->filter,
 					 &ctx->cur_filter->filter)) {
 			array_insert(&ctx->cur_parsers, 0,
-				     &all_parsers[i]->parser_list, 1);
+				     &all_parsers[i]->parsers, 1);
 			full_found = TRUE;
 		} else {
 			array_append(&ctx->cur_parsers,
-				     &all_parsers[i]->parser_list, 1);
+				     &all_parsers[i]->parsers, 1);
 		}
 	}
 	i_assert(full_found);
-	(void)array_append_space(&ctx->cur_parsers);
-	return array_idx(&ctx->cur_parsers, 0);
 }
 
 static int
@@ -235,7 +259,7 @@
 				struct config_filter_parser_list *parser,
 				const char **error_r)
 {
-	struct config_setting_parser_list *l = parser->parser_list;
+	struct config_module_parser *l = parser->parsers;
 	const char *errormsg;
 
 	for (; l->module_name != NULL; l++) {
@@ -373,7 +397,7 @@
 
 static enum config_line_type
 config_parse_line(char *line, string_t *full_line, const char **key_r,
-		  const char **section_r, const char **value_r)
+		  const char **value_r)
 {
 	const char *key;
 	unsigned int len;
@@ -381,7 +405,6 @@
 
 	*key_r = NULL;
 	*value_r = NULL;
-	*section_r = NULL;
 
 	/* @UNSAFE: line is modified */
 
@@ -467,10 +490,10 @@
 	line[-1] = '\0';
 
 	if (*line == '{')
-		*section_r = "";
+		*value_r = "";
 	else {
 		/* get section name */
-		*section_r = line;
+		*value_r = line;
 		while (!IS_WHITE(*line) && *line != '\0')
 			line++;
 
@@ -483,7 +506,10 @@
 			*value_r = "Expecting '='";
 			return CONFIG_LINE_TYPE_ERROR;
 		}
-		*value_r = line;
+		if (line[1] != '\0') {
+			*value_r = "Garbage after '{'";
+			return CONFIG_LINE_TYPE_ERROR;
+		}
 	}
 	return CONFIG_LINE_TYPE_SECTION_BEGIN;
 }
@@ -492,13 +518,13 @@
 		      const char **error_r)
 {
 	enum settings_parser_flags parser_flags =
-                SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS;
+		SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS |
+		SETTINGS_PARSER_FLAG_TRACK_CHANGES;
 	struct input_stack root;
-	struct config_setting_parser_list *const *parsers;
 	struct parser_context ctx;
 	unsigned int pathlen = 0;
 	unsigned int i, count, counter = 0, cur_counter;
-	const char *errormsg, *key, *value, *section;
+	const char *errormsg, *key, *value;
 	string_t *str, *full_line;
 	enum config_line_type type;
 	char *line;
@@ -516,7 +542,7 @@
 
 	for (count = 0; all_roots[count].module_name != NULL; count++) ;
 	ctx.root_parsers =
-		p_new(ctx.pool, struct config_setting_parser_list, count+1);
+		p_new(ctx.pool, struct config_module_parser, count+1);
 	for (i = 0; i < count; i++) {
 		ctx.root_parsers[i].module_name = all_roots[i].module_name;
 		ctx.root_parsers[i].root = all_roots[i].root;
@@ -529,7 +555,7 @@
 	p_array_init(&ctx.all_parsers, ctx.pool, 128);
 	ctx.cur_filter = p_new(ctx.pool, struct config_filter_stack, 1);
 	config_add_new_parser(&ctx);
-	parsers = config_update_cur_parsers(&ctx);
+	config_update_cur_parsers(&ctx);
 
 	memset(&root, 0, sizeof(root));
 	root.path = path;
@@ -544,7 +570,7 @@
 	while ((line = i_stream_read_next_line(ctx.cur_input->input)) != NULL) {
 		ctx.cur_input->linenum++;
 		type = config_parse_line(line, full_line,
-					 &key, &section, &value);
+					 &key, &value);
 		switch (type) {
 		case CONFIG_LINE_TYPE_SKIP:
 			break;
@@ -562,46 +588,36 @@
 				/* file reading failed */
 				break;
 			}
-			(void)config_apply_line(parsers, key, str_c(str), NULL, &errormsg);
+			(void)config_apply_line(&ctx, key, str_c(str), NULL, &errormsg);
 			break;
 		case CONFIG_LINE_TYPE_SECTION_BEGIN:
 			config_add_new_filter(&ctx);
 			ctx.cur_filter->pathlen = pathlen;
-			if (strcmp(key, "protocol") == 0) {
-				ctx.cur_filter->filter.service =
-					p_strdup(ctx.pool, section);
-				config_add_new_parser(&ctx);
-				parsers = config_update_cur_parsers(&ctx);
-			} else if (strcmp(key, "local_ip") == 0) {
-				if (net_parse_range(section, &ctx.cur_filter->filter.local_net,
-						    &ctx.cur_filter->filter.local_bits) < 0)
-					errormsg = "Invalid network mask";
-				config_add_new_parser(&ctx);
-				parsers = config_update_cur_parsers(&ctx);
-			} else if (strcmp(key, "remote_ip") == 0) {
-				if (net_parse_range(section, &ctx.cur_filter->filter.remote_net,
-						    &ctx.cur_filter->filter.remote_bits) < 0)
-					errormsg = "Invalid network mask";
-				config_add_new_parser(&ctx);
-				parsers = config_update_cur_parsers(&ctx);
-			} else {
-				str_truncate(str, pathlen);
-				str_append(str, key);
-				pathlen = str_len(str);
-				cur_counter = counter++;
+
+			if (config_filter_add_new_parser(&ctx, key, value,
+							 &errormsg)) {
+				/* new real filter */
+				config_update_cur_parsers(&ctx);
+				break;
+			}
 
-				str_append_c(str, '=');
-				str_printfa(str, "%u", cur_counter);
+			/* new config section */
+			str_truncate(str, pathlen);
+			str_append(str, key);
+			pathlen = str_len(str);
+			cur_counter = counter++;
 
-				if (config_apply_line(parsers, key, str_c(str), section, &errormsg) < 0)
-					break;
+			str_append_c(str, '=');
+			str_printfa(str, "%u", cur_counter);
 
-				str_truncate(str, pathlen);
-				str_append_c(str, SETTINGS_SEPARATOR);
-				str_printfa(str, "%u", cur_counter);
-				str_append_c(str, SETTINGS_SEPARATOR);
-				pathlen = str_len(str);
-			}
+			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_c(str, SETTINGS_SEPARATOR);
+			pathlen = str_len(str);
 			break;
 		case CONFIG_LINE_TYPE_SECTION_END:
 			if (ctx.cur_filter->prev == NULL)
@@ -609,7 +625,7 @@
 			else {
 				pathlen = ctx.cur_filter->pathlen;
 				ctx.cur_filter = ctx.cur_filter->prev;
-				parsers = config_update_cur_parsers(&ctx);
+				config_update_cur_parsers(&ctx);
 			}
 			break;
 		case CONFIG_LINE_TYPE_INCLUDE:
@@ -647,7 +663,7 @@
 
 	if (config_filter != NULL)
 		config_filter_deinit(&config_filter);
-	config_setting_parsers = ctx.root_parsers;
+	config_module_parsers = ctx.root_parsers;
 
 	(void)array_append_space(&ctx.all_parsers);
 	config_filter = config_filter_init(ctx.pool);
--- a/src/config/config-parser.h	Wed Sep 02 16:21:41 2009 -0400
+++ b/src/config/config-parser.h	Wed Sep 02 16:48:06 2009 -0400
@@ -1,15 +1,15 @@
 #ifndef CONFIG_PARSER_H
 #define CONFIG_PARSER_H
 
-struct config_setting_parser_list {
+struct config_module_parser {
 	const char *module_name;
 	struct setting_parser_info *root;
 	struct setting_parser_context *parser;
 	void *settings;
 };
-ARRAY_DEFINE_TYPE(config_setting_parsers, struct config_setting_parser_list *);
+ARRAY_DEFINE_TYPE(config_module_parsers, struct config_module_parser *);
 
-extern struct config_setting_parser_list *config_setting_parsers;
+extern struct config_module_parser *config_module_parsers;
 extern struct config_filter_context *config_filter;
 
 int config_parse_file(const char *path, bool expand_files,
--- a/src/config/config-request.c	Wed Sep 02 16:21:41 2009 -0400
+++ b/src/config/config-request.c	Wed Sep 02 16:48:06 2009 -0400
@@ -46,10 +46,10 @@
 }
 
 static bool
-config_setting_parser_is_in_service(const struct config_setting_parser_list *list,
-				    const char *module)
+config_module_parser_is_in_service(const struct config_module_parser *list,
+				   const char *module)
 {
-	struct config_setting_parser_list *l;
+	struct config_module_parser *l;
 
 	if (strcmp(list->module_name, module) == 0)
 		return TRUE;
@@ -58,7 +58,7 @@
 		return TRUE;
 	}
 
-	for (l = config_setting_parsers; l->module_name != NULL; l++) {
+	for (l = config_module_parsers; l->module_name != NULL; l++) {
 		if (strcmp(l->module_name, module) != 0)
 			continue;
 
@@ -235,7 +235,8 @@
 			   const char *module, enum config_dump_scope scope,
 			   config_request_callback_t *callback, void *context)
 {
-	const struct config_setting_parser_list *l;
+	const struct config_module_parser *l;
+	const struct config_filter_parser_list *list;
 	struct settings_export_context ctx;
 
 	memset(&ctx, 0, sizeof(ctx));
@@ -248,10 +249,10 @@
 	ctx.keys = hash_table_create(default_pool, ctx.pool, 0,
 				     str_hash, (hash_cmp_callback_t *)strcmp);
 
-	l = config_filter_match_parsers(config_filter, filter);
-	for (; l->module_name != NULL; l++) {
+	list = config_filter_find(config_filter, filter);
+	for (l = list->parsers; l->module_name != NULL; l++) {
 		if (*module == '\0' ||
-		    config_setting_parser_is_in_service(l, module)) {
+		    config_module_parser_is_in_service(l, module)) {
 			settings_export(&ctx, l->root,
 					settings_parser_get(l->parser),
 					settings_parser_get_changes(l->parser));
--- a/src/config/doveconf.c	Wed Sep 02 16:21:41 2009 -0400
+++ b/src/config/doveconf.c	Wed Sep 02 16:48:06 2009 -0400
@@ -180,12 +180,12 @@
 
 static const char *get_mail_location(void)
 {
-	struct config_setting_parser_list *l;
+	struct config_module_parser *l;
 	const struct setting_define *def;
 	const char *const *value;
 	const void *set;
 
-	for (l = config_setting_parsers; l->module_name != NULL; l++) {
+	for (l = config_module_parsers; l->module_name != NULL; l++) {
 		if (strcmp(l->module_name, "mail") != 0)
 			continue;