commit 5ffee59: [Rework] Further refactoring
Vsevolod Stakhov
vsevolod at rspamd.com
Thu Aug 17 11:49:11 UTC 2023
Author: Vsevolod Stakhov
Date: 2023-08-15 15:49:11 +0100
URL: https://github.com/rspamd/rspamd/commit/5ffee59dfce8b60669f93fc59c8304f9ec4703f7
[Rework] Further refactoring
---
src/libserver/cfg_file.h | 31 +-
src/libserver/cfg_rcl.cxx | 792 ++++++++++++++++++++--------------------------
src/libserver/cfg_rcl.h | 28 +-
3 files changed, 362 insertions(+), 489 deletions(-)
diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h
index b20739806..703ca57ff 100644
--- a/src/libserver/cfg_file.h
+++ b/src/libserver/cfg_file.h
@@ -303,6 +303,7 @@ struct rspamd_config_post_init_script {
};
struct rspamd_lang_detector;
+struct rspamd_rcl_sections_map;
enum rspamd_config_settings_policy {
RSPAMD_SETTINGS_POLICY_DEFAULT = 0,
@@ -391,21 +392,21 @@ struct rspamd_config {
GList *script_modules; /**< linked list of script modules to load */
GHashTable *explicit_modules; /**< modules that should be always loaded */
- GList *filters; /**< linked list of all filters */
- GList *workers; /**< linked list of all workers params */
- GHashTable *wrk_parsers; /**< hash for worker config parsers, indexed by worker quarks */
- ucl_object_t *rcl_obj; /**< rcl object */
- ucl_object_t *config_comments; /**< comments saved from the config */
- ucl_object_t *doc_strings; /**< documentation strings for config options */
- GPtrArray *c_modules; /**< list of C modules */
- void *composites_manager; /**< hash of composite symbols indexed by its name */
- GList *classifiers; /**< list of all classifiers defined */
- GList *statfiles; /**< list of all statfiles in config file order */
- GHashTable *classifiers_symbols; /**< hashtable indexed by symbol name of classifiers */
- GHashTable *cfg_params; /**< all cfg params indexed by its name in this structure */
- gchar *dynamic_conf; /**< path to dynamic configuration */
- ucl_object_t *current_dynamic_conf; /**< currently loaded dynamic configuration */
- gint clock_res; /**< resolution of clock used */
+ GList *filters; /**< linked list of all filters */
+ GList *workers; /**< linked list of all workers params */
+ struct rspamd_rcl_sections_map *rcl_parser; /**< parser for RCL config */
+ ucl_object_t *rcl_obj; /**< rcl object */
+ ucl_object_t *config_comments; /**< comments saved from the config */
+ ucl_object_t *doc_strings; /**< documentation strings for config options */
+ GPtrArray *c_modules; /**< list of C modules */
+ void *composites_manager; /**< hash of composite symbols indexed by its name */
+ GList *classifiers; /**< list of all classifiers defined */
+ GList *statfiles; /**< list of all statfiles in config file order */
+ GHashTable *classifiers_symbols; /**< hashtable indexed by symbol name of classifiers */
+ GHashTable *cfg_params; /**< all cfg params indexed by its name in this structure */
+ gchar *dynamic_conf; /**< path to dynamic configuration */
+ ucl_object_t *current_dynamic_conf; /**< currently loaded dynamic configuration */
+ gint clock_res; /**< resolution of clock used */
GList *maps; /**< maps active */
gdouble map_timeout; /**< maps watch timeout */
diff --git a/src/libserver/cfg_rcl.cxx b/src/libserver/cfg_rcl.cxx
index 2fa637889..aadcc50a6 100644
--- a/src/libserver/cfg_rcl.cxx
+++ b/src/libserver/cfg_rcl.cxx
@@ -51,14 +51,14 @@ struct rspamd_rcl_sections_map;
struct rspamd_rcl_section {
struct rspamd_rcl_sections_map *top;
- const gchar *name; /**< name of section */
- const gchar *key_attr;
- const gchar *default_key;
+ std::string name; /**< name of section */
+ std::optional<std::string> key_attr;
+ std::optional<std::string> default_key;
rspamd_rcl_handler_t handler; /**< handler of section attributes */
enum ucl_type type; /**< type of attribute */
- gboolean required; /**< whether this param is required */
- gboolean strict_type; /**< whether we need strict type */
- ankerl::unordered_dense::map<std::string, struct rspamd_rcl_section> subsections;
+ bool required; /**< whether this param is required */
+ bool strict_type; /**< whether we need strict type */
+ ankerl::unordered_dense::map<std::string, std::shared_ptr<struct rspamd_rcl_section>> subsections;
ankerl::unordered_dense::map<std::string, struct rspamd_rcl_default_handler_data> default_parser; /**< generic parsing fields */
rspamd_rcl_section_fin_t fin; /** called at the end of section parsing */
gpointer fin_ud;
@@ -79,7 +79,8 @@ struct rspamd_worker_cfg_parser {
};
struct rspamd_rcl_sections_map {
- ankerl::unordered_dense::map<std::string, struct rspamd_rcl_section> sections;
+ ankerl::unordered_dense::map<std::string, std::shared_ptr<struct rspamd_rcl_section>> sections;
+ std::vector<std::shared_ptr<struct rspamd_rcl_section>> sections_order;
ankerl::unordered_dense::map<int, struct rspamd_worker_cfg_parser> workers_parser;
ankerl::unordered_dense::set<std::string> lua_modules_seen;
};
@@ -288,7 +289,7 @@ rspamd_rcl_options_handler(rspamd_mempool_t *pool, const ucl_object_t *obj,
dns = ucl_object_lookup(obj, "dns");
if (maybe_subsection && dns != nullptr) {
if (!rspamd_rcl_section_parse_defaults(cfg,
- maybe_subsection.value().get(), cfg->cfg_pool, dns,
+ *maybe_subsection.value().get(), cfg->cfg_pool, dns,
cfg, err)) {
return FALSE;
}
@@ -299,7 +300,7 @@ rspamd_rcl_options_handler(rspamd_mempool_t *pool, const ucl_object_t *obj,
upstream = ucl_object_lookup_any(obj, "upstream", "upstreams", nullptr);
if (maybe_subsection && upstream != nullptr) {
if (!rspamd_rcl_section_parse_defaults(cfg,
- maybe_subsection.value().get(), cfg->cfg_pool,
+ *maybe_subsection.value().get(), cfg->cfg_pool,
upstream, cfg, err)) {
return FALSE;
}
@@ -313,7 +314,7 @@ rspamd_rcl_options_handler(rspamd_mempool_t *pool, const ucl_object_t *obj,
LL_FOREACH(neighbours, cur)
{
- if (!rspamd_rcl_process_section(cfg, maybe_subsection.value().get(), cfg, cur,
+ if (!rspamd_rcl_process_section(cfg, *maybe_subsection.value().get(), cfg, cur,
pool, err)) {
return FALSE;
}
@@ -441,16 +442,17 @@ rspamd_rcl_group_handler(rspamd_mempool_t *pool, const ucl_object_t *obj,
description);
}
- struct rspamd_rcl_symbol_data sd;
- sd.gr = gr;
- sd.cfg = cfg;
+ struct rspamd_rcl_symbol_data sd = {
+ .gr = gr,
+ .cfg = cfg,
+ };
/* Handle symbols */
if (const auto *val = ucl_object_lookup(obj, "symbols"); val != nullptr && ucl_object_type(val) == UCL_OBJECT) {
auto subsection = rspamd::find_map(section->subsections, "symbols");
g_assert(subsection.has_value());
- if (!rspamd_rcl_process_section(cfg, subsection.value().get(), &sd, val,
+ if (!rspamd_rcl_process_section(cfg, *subsection.value().get(), &sd, val,
pool, err)) {
return FALSE;
@@ -968,26 +970,22 @@ rspamd_rcl_modules_handler(rspamd_mempool_t *pool, const ucl_object_t *obj,
const gchar *key, gpointer ud,
struct rspamd_rcl_section *section, GError **err)
{
- const ucl_object_t *val, *cur;
- struct rspamd_config *cfg = ud;
- const gchar *data;
+ auto *cfg = static_cast<rspamd_config *>(ud);
+ const char *data;
if (obj->type == UCL_OBJECT) {
- GHashTable *mods_seen = g_hash_table_new(rspamd_strcase_hash,
- rspamd_strcase_equal);
- val = ucl_object_lookup(obj, "path");
+ const auto *val = ucl_object_lookup(obj, "path");
if (val) {
+ const auto *cur = val;
LL_FOREACH(val, cur)
{
if (ucl_object_tostring_safe(cur, &data)) {
- if (!rspamd_rcl_add_lua_plugins_path(cfg,
- rspamd_mempool_strdup(cfg->cfg_pool, data),
+ if (!rspamd_rcl_add_lua_plugins_path(section->top,
+ cfg,
+ data,
TRUE,
- mods_seen,
err)) {
- g_hash_table_unref(mods_seen);
-
return FALSE;
}
}
@@ -998,7 +996,6 @@ rspamd_rcl_modules_handler(rspamd_mempool_t *pool, const ucl_object_t *obj,
CFG_RCL_ERROR,
EINVAL,
"path attribute is missing");
- g_hash_table_unref(mods_seen);
return FALSE;
}
@@ -1006,15 +1003,15 @@ rspamd_rcl_modules_handler(rspamd_mempool_t *pool, const ucl_object_t *obj,
val = ucl_object_lookup(obj, "fallback_path");
if (val) {
+ const auto *cur = val;
LL_FOREACH(val, cur)
{
if (ucl_object_tostring_safe(cur, &data)) {
- if (!rspamd_rcl_add_lua_plugins_path(cfg,
- rspamd_mempool_strdup(cfg->cfg_pool, data),
+ if (!rspamd_rcl_add_lua_plugins_path(section->top,
+ cfg,
+ data,
FALSE,
- mods_seen,
err)) {
- g_hash_table_unref(mods_seen);
return FALSE;
}
@@ -1025,27 +1022,24 @@ rspamd_rcl_modules_handler(rspamd_mempool_t *pool, const ucl_object_t *obj,
val = ucl_object_lookup(obj, "try_path");
if (val) {
+ const auto *cur = val;
LL_FOREACH(val, cur)
{
if (ucl_object_tostring_safe(cur, &data)) {
- if (!rspamd_rcl_add_lua_plugins_path(cfg,
- rspamd_mempool_strdup(cfg->cfg_pool, data),
+ if (!rspamd_rcl_add_lua_plugins_path(section->top,
+ cfg,
+ data,
FALSE,
- mods_seen,
err)) {
- g_hash_table_unref(mods_seen);
return FALSE;
}
}
}
}
-
- g_hash_table_unref(mods_seen);
}
else if (ucl_object_tostring_safe(obj, &data)) {
- if (!rspamd_rcl_add_lua_plugins_path(cfg,
- rspamd_mempool_strdup(cfg->cfg_pool, data), TRUE, nullptr, err)) {
+ if (!rspamd_rcl_add_lua_plugins_path(section->top, cfg, data, TRUE, err)) {
return FALSE;
}
}
@@ -1070,27 +1064,24 @@ rspamd_rcl_statfile_handler(rspamd_mempool_t *pool, const ucl_object_t *obj,
const gchar *key, gpointer ud,
struct rspamd_rcl_section *section, GError **err)
{
- struct statfile_parser_data *stud = ud;
- struct rspamd_classifier_config *ccf;
- struct rspamd_config *cfg;
- const ucl_object_t *val;
- struct rspamd_statfile_config *st;
+ auto *stud = (struct statfile_parser_data *) ud;
GList *labels;
g_assert(key != nullptr);
- cfg = stud->cfg;
- ccf = stud->ccf;
+ auto *cfg = stud->cfg;
+ auto *ccf = stud->ccf;
- st = rspamd_config_new_statfile(cfg, nullptr);
+ auto *st = rspamd_config_new_statfile(cfg, nullptr);
st->symbol = rspamd_mempool_strdup(cfg->cfg_pool, key);
- if (rspamd_rcl_section_parse_defaults(cfg, section, pool, obj, st, err)) {
+ if (rspamd_rcl_section_parse_defaults(cfg, *section, pool, obj, st, err)) {
ccf->statfiles = rspamd_mempool_glist_prepend(pool, ccf->statfiles, st);
if (st->label != nullptr) {
- labels = g_hash_table_lookup(ccf->labels, st->label);
+ labels = (GList *) g_hash_table_lookup(ccf->labels, st->label);
if (labels != nullptr) {
+ /* Must use append to preserve the head stored in the hash table */
labels = g_list_append(labels, st);
}
else {
@@ -1113,7 +1104,7 @@ rspamd_rcl_statfile_handler(rspamd_mempool_t *pool, const ucl_object_t *obj,
st->opts = (ucl_object_t *) obj;
st->clcf = ccf;
- val = ucl_object_lookup(obj, "spam");
+ const auto *val = ucl_object_lookup(obj, "spam");
if (val == nullptr) {
msg_info_config(
"statfile %s has no explicit 'spam' setting, trying to guess by symbol",
@@ -1152,47 +1143,41 @@ rspamd_rcl_classifier_handler(rspamd_mempool_t *pool,
struct rspamd_rcl_section *section,
GError **err)
{
- const ucl_object_t *val, *cur;
- ucl_object_iter_t it = nullptr;
- struct rspamd_config *cfg = ud;
- struct statfile_parser_data stud;
- const gchar *st_key;
- struct rspamd_classifier_config *ccf;
- gboolean res = TRUE;
- struct rspamd_rcl_section *stat_section;
- struct rspamd_tokenizer_config *tkcf = nullptr;
- lua_State *L = cfg->lua_state;
+ auto *cfg = static_cast<rspamd_config *>(ud);
g_assert(key != nullptr);
- ccf = rspamd_config_new_classifier(cfg, nullptr);
+ auto *ccf = rspamd_config_new_classifier(cfg, nullptr);
+ auto *tkcf = (rspamd_tokenizer_config *) nullptr;
ccf->classifier = rspamd_mempool_strdup(cfg->cfg_pool, key);
- if (rspamd_rcl_section_parse_defaults(cfg, section, cfg->cfg_pool, obj,
+ if (rspamd_rcl_section_parse_defaults(cfg, *section, cfg->cfg_pool, obj,
ccf, err)) {
- HASH_FIND_STR(section->subsections, "statfile", stat_section);
+ auto stat_section = rspamd::find_map(section->subsections, "statfile");
if (ccf->classifier == nullptr) {
- ccf->classifier = "bayes";
+ ccf->classifier = rspamd_mempool_strdup(cfg->cfg_pool, "bayes");
}
if (ccf->name == nullptr) {
ccf->name = ccf->classifier;
}
- it = ucl_object_iterate_new(obj);
+ auto it = ucl_object_iterate_new(obj);
+ const auto *val = obj;
+ auto res = TRUE;
while ((val = ucl_object_iterate_safe(it, true)) != nullptr && res) {
- st_key = ucl_object_key(val);
+ const auto *st_key = ucl_object_key(val);
if (st_key != nullptr) {
if (g_ascii_strcasecmp(st_key, "statfile") == 0) {
+ const auto *cur = val;
LL_FOREACH(val, cur)
{
- stud.cfg = cfg;
- stud.ccf = ccf;
- res = rspamd_rcl_process_section(cfg, stat_section, &stud,
+ struct statfile_parser_data stud = {.cfg = cfg, .ccf = ccf};
+ res = rspamd_rcl_process_section(cfg, *stat_section.value().get(), &stud,
cur, cfg->cfg_pool, err);
if (!res) {
@@ -1203,13 +1188,13 @@ rspamd_rcl_classifier_handler(rspamd_mempool_t *pool,
}
}
else if (g_ascii_strcasecmp(st_key, "tokenizer") == 0) {
- tkcf = rspamd_mempool_alloc0(cfg->cfg_pool, sizeof(*tkcf));
+ tkcf = rspamd_mempool_alloc0_type(cfg->cfg_pool, rspamd_tokenizer_config);
if (ucl_object_type(val) == UCL_STRING) {
tkcf->name = ucl_object_tostring(val);
}
else if (ucl_object_type(val) == UCL_OBJECT) {
- cur = ucl_object_lookup(val, "name");
+ const auto *cur = ucl_object_lookup(val, "name");
if (cur != nullptr) {
tkcf->name = ucl_object_tostring(cur);
tkcf->opts = val;
@@ -1233,16 +1218,17 @@ rspamd_rcl_classifier_handler(rspamd_mempool_t *pool,
}
if (tkcf == nullptr) {
- tkcf = rspamd_mempool_alloc0(cfg->cfg_pool, sizeof(*tkcf));
+ tkcf = rspamd_mempool_alloc0_type(cfg->cfg_pool, rspamd_tokenizer_config);
tkcf->name = nullptr;
}
ccf->tokenizer = tkcf;
/* Handle lua conditions */
- val = ucl_object_lookup_any(obj, "learn_condition", nullptr);
+ const auto *val = ucl_object_lookup_any(obj, "learn_condition", nullptr);
if (val) {
+ const auto *cur = val;
LL_FOREACH(val, cur)
{
if (ucl_object_type(cur) == UCL_STRING) {
@@ -1251,14 +1237,14 @@ rspamd_rcl_classifier_handler(rspamd_mempool_t *pool,
gint ref_idx;
lua_script = ucl_object_tolstring(cur, &slen);
- ref_idx = rspamd_lua_function_ref_from_str(L,
+ ref_idx = rspamd_lua_function_ref_from_str(RSPAMD_LUA_CFG_STATE(cfg),
lua_script, slen, "learn_condition", err);
if (ref_idx == LUA_NOREF) {
return FALSE;
}
- rspamd_lua_add_ref_dtor(L, cfg->cfg_pool, ref_idx);
+ rspamd_lua_add_ref_dtor(RSPAMD_LUA_CFG_STATE(cfg), cfg->cfg_pool, ref_idx);
ccf->learn_conditions = rspamd_mempool_glist_append(
cfg->cfg_pool,
ccf->learn_conditions,
@@ -1270,6 +1256,7 @@ rspamd_rcl_classifier_handler(rspamd_mempool_t *pool,
val = ucl_object_lookup_any(obj, "classify_condition", nullptr);
if (val) {
+ const auto *cur = val;
LL_FOREACH(val, cur)
{
if (ucl_object_type(cur) == UCL_STRING) {
@@ -1278,14 +1265,14 @@ rspamd_rcl_classifier_handler(rspamd_mempool_t *pool,
gint ref_idx;
lua_script = ucl_object_tolstring(cur, &slen);
- ref_idx = rspamd_lua_function_ref_from_str(L,
+ ref_idx = rspamd_lua_function_ref_from_str(RSPAMD_LUA_CFG_STATE(cfg),
lua_script, slen, "classify_condition", err);
if (ref_idx == LUA_NOREF) {
return FALSE;
}
- rspamd_lua_add_ref_dtor(L, cfg->cfg_pool, ref_idx);
+ rspamd_lua_add_ref_dtor(RSPAMD_LUA_CFG_STATE(cfg), cfg->cfg_pool, ref_idx);
ccf->classify_conditions = rspamd_mempool_glist_append(
cfg->cfg_pool,
ccf->classify_conditions,
@@ -1297,7 +1284,7 @@ rspamd_rcl_classifier_handler(rspamd_mempool_t *pool,
ccf->opts = (ucl_object_t *) obj;
cfg->classifiers = g_list_prepend(cfg->classifiers, ccf);
- return res;
+ return TRUE;
}
static gboolean
@@ -1308,7 +1295,7 @@ rspamd_rcl_composite_handler(rspamd_mempool_t *pool,
struct rspamd_rcl_section *section,
GError **err)
{
- struct rspamd_config *cfg = ud;
+ auto *cfg = static_cast<rspamd_config *>(ud);
void *composite;
const gchar *composite_name;
@@ -1316,7 +1303,7 @@ rspamd_rcl_composite_handler(rspamd_mempool_t *pool,
composite_name = key;
- const ucl_object_t *val = ucl_object_lookup(obj, "enabled");
+ const auto *val = ucl_object_lookup(obj, "enabled");
if (val != nullptr && !ucl_object_toboolean(val)) {
msg_info_config("composite %s is disabled", composite_name);
return TRUE;
@@ -1339,11 +1326,10 @@ rspamd_rcl_composites_handler(rspamd_mempool_t *pool,
struct rspamd_rcl_section *section,
GError **err)
{
- ucl_object_iter_t it = nullptr;
- const ucl_object_t *cur;
- gboolean success = TRUE;
+ auto success = TRUE;
- it = ucl_object_iterate_new(obj);
+ auto it = ucl_object_iterate_new(obj);
+ const auto *cur = obj;
while ((cur = ucl_object_iterate_safe(it, true))) {
success = rspamd_rcl_composite_handler(pool, cur,
@@ -1366,11 +1352,8 @@ rspamd_rcl_neighbours_handler(rspamd_mempool_t *pool,
struct rspamd_rcl_section *section,
GError **err)
{
- struct rspamd_config *cfg = ud;
- const ucl_object_t *hostval, *pathval;
- ucl_object_t *neigh;
- gboolean has_port = FALSE, has_proto = FALSE;
- GString *urlstr;
+ auto *cfg = static_cast<rspamd_config *>(ud);
+ auto has_port = FALSE, has_proto = FALSE;
const gchar *p;
if (key == nullptr) {
@@ -1381,7 +1364,7 @@ rspamd_rcl_neighbours_handler(rspamd_mempool_t *pool,
return FALSE;
}
- hostval = ucl_object_lookup(obj, "host");
+ const auto *hostval = ucl_object_lookup(obj, "host");
if (hostval == nullptr || ucl_object_type(hostval) != UCL_STRING) {
g_set_error(err,
@@ -1391,7 +1374,7 @@ rspamd_rcl_neighbours_handler(rspamd_mempool_t *pool,
return FALSE;
}
- neigh = ucl_object_typed_new(UCL_OBJECT);
+ auto *neigh = ucl_object_typed_new(UCL_OBJECT);
ucl_object_insert_key(neigh, ucl_object_copy(hostval), "host", 0, false);
if ((p = strrchr(ucl_object_tostring(hostval), ':')) != nullptr) {
@@ -1405,30 +1388,29 @@ rspamd_rcl_neighbours_handler(rspamd_mempool_t *pool,
}
/* Now make url */
- urlstr = g_string_sized_new(63);
- pathval = ucl_object_lookup(obj, "path");
+ auto urlstr = std::string{};
+ const auto *pathval = ucl_object_lookup(obj, "path");
if (!has_proto) {
- g_string_append_len(urlstr, "http://", sizeof("http://") - 1);
+ urlstr += "http://";
}
- g_string_append(urlstr, ucl_object_tostring(hostval));
+ urlstr += ucl_object_tostring(hostval);
if (!has_port) {
- g_string_append(urlstr, ":11334");
+ urlstr += ":11334";
}
if (pathval == nullptr) {
- g_string_append(urlstr, "/");
+ urlstr += "/";
}
else {
- g_string_append(urlstr, ucl_object_tostring(pathval));
+ urlstr += ucl_object_tostring(pathval);
}
ucl_object_insert_key(neigh,
- ucl_object_fromlstring(urlstr->str, urlstr->len),
+ ucl_object_fromlstring(urlstr.data(), urlstr.size()),
"url", 0, false);
- g_string_free(urlstr, TRUE);
ucl_object_insert_key(cfg->neighbours, neigh, key, 0, true);
return TRUE;
@@ -1436,67 +1418,92 @@ rspamd_rcl_neighbours_handler(rspamd_mempool_t *pool,
struct rspamd_rcl_section *
-rspamd_rcl_add_section(struct rspamd_rcl_section **top,
+rspamd_rcl_add_section(struct rspamd_rcl_sections_map **top,
+ struct rspamd_rcl_section *parent_section,
const gchar *name, const gchar *key_attr, rspamd_rcl_handler_t handler,
enum ucl_type type, gboolean required, gboolean strict_type)
{
- struct rspamd_rcl_section *new;
- ucl_object_t *parent_doc;
-
- new = g_malloc0(sizeof(struct rspamd_rcl_section));
- new->name = name;
- new->key_attr = key_attr;
- new->handler = handler;
- new->type = type;
- new->strict_type = strict_type;
-
- if (*top == nullptr) {
- parent_doc = nullptr;
- new->doc_ref = nullptr;
- }
- else {
- parent_doc = (*top)->doc_ref;
- new->doc_ref = ucl_object_ref(rspamd_rcl_add_doc_obj(parent_doc,
- nullptr,
- name,
- type,
- nullptr,
- 0,
- nullptr,
- 0));
- }
-
- HASH_ADD_KEYPTR(hh, *top, new->name, strlen(new->name), new);
- return new;
+ return rspamd_rcl_add_section_doc(top, parent_section, name, key_attr, handler,
+ type, required, strict_type, nullptr, nullptr);
}
struct rspamd_rcl_section *
-rspamd_rcl_add_section_doc(struct rspamd_rcl_section **top,
+rspamd_rcl_add_section_doc(struct rspamd_rcl_sections_map **top,
+ struct rspamd_rcl_section *parent_section,
const gchar *name, const gchar *key_attr, rspamd_rcl_handler_t handler,
enum ucl_type type, gboolean required, gboolean strict_type,
ucl_object_t *doc_target,
const gchar *doc_string)
{
- struct rspamd_rcl_section *new_section;
-
- new_section = g_malloc0(sizeof(struct rspamd_rcl_section));
- new_section->name = name;
- new_section->key_attr = key_attr;
- new_section->handler = handler;
- new_section->type = type;
- new_section->strict_type = strict_type;
-
- new_section->doc_ref = ucl_object_ref(rspamd_rcl_add_doc_obj(doc_target,
- doc_string,
- name,
- type,
- nullptr,
- 0,
- nullptr,
- 0));
-
- HASH_ADD_KEYPTR(hh, *top, new_section->name, strlen(new_section->name), new_section);
- return new_section;
+ if (top == nullptr) {
+ g_error("invalid arguments to rspamd_rcl_add_section");
+ return nullptr;
+ }
+ if (*top == nullptr) {
+ *top = new rspamd_rcl_sections_map;
+ }
+
+ auto fill_section = [&](struct rspamd_rcl_section *section) {
+ section->name = name;
+ if (key_attr) {
+ section->key_attr = std::string{key_attr};
+ }
+ section->handler = handler;
+ section->type = type;
+ section->strict_type = strict_type;
+
+ if (doc_target == nullptr) {
+ if (parent_section && parent_section->doc_ref) {
+ section->doc_ref = ucl_object_ref(rspamd_rcl_add_doc_obj(parent_section->doc_ref,
+ doc_string,
+ name,
+ type,
+ nullptr,
+ 0,
+ nullptr,
+ 0));
+ }
+ else {
+ section->doc_ref = nullptr;
+ }
+ }
+ else {
+ section->doc_ref = ucl_object_ref(rspamd_rcl_add_doc_obj(doc_target,
+ doc_string,
+ name,
+ type,
+ nullptr,
+ 0,
+ nullptr,
+ 0));
+ }
+ section->top = *top;
+ };
+
+ /* Select the appropriate container and insert section inside it */
+ if (parent_section) {
+ auto it = parent_section->subsections.insert(std::make_pair(std::string{name},
+ std::make_shared<rspamd_rcl_section>()));
+ if (!it.second) {
+ g_error("invalid arguments to rspamd_rcl_add_section");
+ return nullptr;
+ }
+
+ fill_section(it.first->second.get());
+ return it.first->second.get();
+ }
+ else {
+ auto it = (*top)->sections.insert(std::make_pair(std::string{name},
+ std::make_shared<rspamd_rcl_section>()));
+ if (!it.second) {
+ g_error("invalid arguments to rspamd_rcl_add_section");
+ return nullptr;
+ }
+
+ (*top)->sections_order.push_back(it.first->second);
+ fill_section(it.first->second.get());
+ return it.first->second.get();
+ }
}
struct rspamd_rcl_default_handler_data *
@@ -1507,13 +1514,13 @@ rspamd_rcl_add_default_handler(struct rspamd_rcl_section *section,
gint flags,
const gchar *doc_string)
{
- struct rspamd_rcl_default_handler_data *nhandler;
+ auto it = section->default_parser.emplace(std::make_pair(std::string{name}, rspamd_rcl_default_handler_data{}));
- nhandler = g_malloc0(sizeof(struct rspamd_rcl_default_handler_data));
- nhandler->key = g_strdup(name);
- nhandler->handler = handler;
- nhandler->pd.offset = offset;
- nhandler->pd.flags = flags;
+ auto &nhandler = it.first->second;
+ nhandler.key = name;
+ nhandler.handler = handler;
+ nhandler.pd.offset = offset;
+ nhandler.pd.flags = flags;
if (section->doc_ref != nullptr) {
rspamd_rcl_add_doc_obj(section->doc_ref,
@@ -1526,15 +1533,13 @@ rspamd_rcl_add_default_handler(struct rspamd_rcl_section *section,
*** OUTPUT TRUNCATED, 919 LINES SKIPPED ***
More information about the Commits
mailing list