struct config_filter_parser *const *filter_parsers;
struct config_module_parser *module_parsers;
ARRAY_TYPE(const_string) errors;
+ HASH_TABLE(const char *, const struct setting_define *) key_hash;
};
ARRAY_DEFINE_TYPE(setting_parser_info_p, const struct setting_parser_info *);
return str_c(str);
}
+const struct setting_define *
+config_parsed_key_lookup(struct config_parsed *config, const char *key)
+{
+ const struct config_module_parser *l;
+ unsigned int key_idx;
+
+ if (hash_table_is_created(config->key_hash))
+ return hash_table_lookup(config->key_hash, key);
+ hash_table_create(&config->key_hash, config->pool, 0, str_hash, strcmp);
+
+ for (l = config->module_parsers; l->info != NULL; l++) {
+ for (key_idx = 0; l->info->defines[key_idx].key != NULL; key_idx++) {
+ hash_table_update(config->key_hash,
+ l->info->defines[key_idx].key,
+ &l->info->defines[key_idx]);
+ }
+ }
+ return hash_table_lookup(config->key_hash, key);
+}
+
void config_parsed_free(struct config_parsed **_config)
{
struct config_parsed *config = *_config;
return;
*_config = NULL;
+ hash_table_destroy(&config->key_hash);
pool_unref(&config->pool);
}
const char *
config_module_parsers_get_setting(const struct config_module_parser *module_parsers,
const char *info_name, const char *key);
+/* Lookup setting with the specified key. */
+const struct setting_define *
+config_parsed_key_lookup(struct config_parsed *config, const char *key);
void config_parsed_free(struct config_parsed **config);
void config_parse_load_modules(void);
return;
if (strip_prefix2 == NULL)
return;
- (void)str_begins(*key_prefix, strip_prefix2, key_prefix);
+
+ const char *suffix;
+ if (str_begins(*key_prefix, strip_prefix2, &suffix)) {
+ /* Prefix isn't stripped in all situations or it would result
+ in wrong output. For example:
+
+ *key_prefix = "dict_name"
+ strip_prefix = "dict_proxy_"
+ strip_prefix2 = "dict_"
+ suffix = "name"
+
+ Now if we return "name", it conflicts with "dict_proxy_name"
+ setting. So if such conflicting setting name exists, don't
+ strip the prefix.
+ */
+ const char *conflict_key =
+ t_strconcat(strip_prefix, t_strcut(suffix, '='), NULL);
+ if (config_parsed_key_lookup(config, conflict_key) == NULL) {
+ *key_prefix = suffix;
+ return;
+ }
+
+ }
}
static void ATTR_NULL(4)