diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-12-27 15:23:31 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-12-27 15:23:31 +0000 |
commit | 0eb0172c3c3cea2981ed728653cee127130e3177 (patch) | |
tree | 17f810c06291dd54a7d416c8c89a3815f48198ae | |
parent | 2275d0b9ebeda6a1edffb3f1f38d3b3af7c9c8a3 (diff) | |
download | rspamd-0eb0172c3c3cea2981ed728653cee127130e3177.tar.gz rspamd-0eb0172c3c3cea2981ed728653cee127130e3177.zip |
Initial implementation of documentation strings in rspamd
-rw-r--r-- | src/libserver/cfg_file.h | 1 | ||||
-rw-r--r-- | src/libserver/cfg_rcl.c | 82 | ||||
-rw-r--r-- | src/libserver/cfg_rcl.h | 31 | ||||
-rw-r--r-- | src/libserver/cfg_utils.c | 4 |
4 files changed, 112 insertions, 6 deletions
diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h index 3db5233df..929f8a78d 100644 --- a/src/libserver/cfg_file.h +++ b/src/libserver/cfg_file.h @@ -270,6 +270,7 @@ struct rspamd_config { 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 *doc_strings; /**< documentation strings for config options */ GHashTable * metrics; /**< hash of metrics indexed by metric name */ GList * metrics_list; /**< linked list of metrics */ GHashTable * metrics_symbols; /**< hash table of metrics indexed by symbol */ diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index bff732c4f..aa5c91864 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -61,6 +61,7 @@ struct rspamd_rcl_section { 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; + ucl_object_t *doc_ref; /**< reference to the section's documentation */ }; struct rspamd_worker_param_key { @@ -1214,6 +1215,7 @@ rspamd_rcl_add_section (struct rspamd_rcl_section **top, enum ucl_type type, gboolean required, gboolean strict_type) { struct rspamd_rcl_section *new; + ucl_object_t *parent_doc; new = g_slice_alloc0 (sizeof (struct rspamd_rcl_section)); new->name = name; @@ -1222,6 +1224,43 @@ rspamd_rcl_add_section (struct rspamd_rcl_section **top, new->type = type; new->strict_type = strict_type; + if (*top == NULL) { + parent_doc = NULL; + new->doc_ref = NULL; + } + else { + parent_doc = (*top)->doc_ref; + new->doc_ref = new->doc_ref = rspamd_rcl_add_doc_obj (parent_doc, + NULL, + name, + type, + NULL, + 0); + } + + HASH_ADD_KEYPTR (hh, *top, new->name, strlen (new->name), new); + return new; +} + +struct rspamd_rcl_section * +rspamd_rcl_add_section_doc (struct rspamd_rcl_section **top, + 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; + + new = g_slice_alloc0 (sizeof (struct rspamd_rcl_section)); + new->name = name; + new->key_attr = key_attr; + new->handler = handler; + new->type = type; + new->strict_type = strict_type; + + new->doc_ref = rspamd_rcl_add_doc_obj (doc_target, doc_string, + name, type, NULL, 0); + HASH_ADD_KEYPTR (hh, *top, new->name, strlen (new->name), new); return new; } @@ -1242,6 +1281,11 @@ rspamd_rcl_add_default_handler (struct rspamd_rcl_section *section, new->pd.offset = offset; new->pd.flags = flags; + if (section->doc_ref != NULL) { + rspamd_rcl_add_doc_obj (section->doc_ref, doc_string, name, UCL_NULL, + handler, flags); + } + HASH_ADD_KEYPTR (hh, section->default_parser, new->key, strlen ( new->key), new); return new; @@ -2804,3 +2848,41 @@ rspamd_config_read (struct rspamd_config *cfg, const gchar *filename, return TRUE; } + +ucl_object_t * +rspamd_rcl_add_doc_obj (ucl_object_t *doc_target, + const char *doc_string, + const char *doc_name, + ucl_type_t type, + rspamd_rcl_default_handler_t handler, + gint flags) +{ + ucl_object_t *doc_obj; + + if (doc_target == NULL || doc_name == NULL) { + return NULL; + } + + doc_obj = ucl_object_typed_new (UCL_OBJECT); + + /* Insert doc string itself */ + if (doc_string) { + ucl_object_insert_key (doc_obj, ucl_object_fromstring (doc_string), + "data", 0, false); + } + else { + ucl_object_insert_key (doc_obj, ucl_object_fromstring ("undocumented"), + "data", 0, false); + } + + if (type != UCL_NULL) { + ucl_object_insert_key (doc_obj, + ucl_object_fromstring (ucl_object_type_to_string (type)), + "type", 0, false); + } + + /* TODO: add type from handler */ + ucl_object_insert_key (doc_target, doc_obj, doc_name, 0, true); + + return doc_obj; +} diff --git a/src/libserver/cfg_rcl.h b/src/libserver/cfg_rcl.h index d7b1c0de2..43f240157 100644 --- a/src/libserver/cfg_rcl.h +++ b/src/libserver/cfg_rcl.h @@ -118,11 +118,20 @@ struct rspamd_rcl_default_handler_data *rspamd_rcl_add_default_handler ( * @param strict_type turn on strict check for types for this section * @return newly created structure */ -struct rspamd_rcl_section * rspamd_rcl_add_section ( - struct rspamd_rcl_section **top, - 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 *rspamd_rcl_add_section ( + struct rspamd_rcl_section **top, + 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 *rspamd_rcl_add_section_doc ( + struct rspamd_rcl_section **top, + 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); /** * Init common sections known to rspamd @@ -337,4 +346,16 @@ void rspamd_rcl_register_worker_option (struct rspamd_config *cfg, */ void rspamd_rcl_register_worker_parser (struct rspamd_config *cfg, gint type, gboolean (*func)(ucl_object_t *, gpointer), gpointer ud); + +/** + * Adds new documentation object to the configuration + * @param doc_target target object where to insert documentation (top object is used if this is NULL) + * @param doc_object documentation object to insert + */ +ucl_object_t* rspamd_rcl_add_doc_obj (ucl_object_t *doc_target, + const char *doc_string, + const char *doc_name, + ucl_type_t type, + rspamd_rcl_default_handler_t handler, + gint flags); #endif /* CFG_RCL_H_ */ diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index 185c28adb..a3d801939 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -200,6 +200,7 @@ rspamd_config_new (void) cfg->cache = rspamd_symbols_cache_new (cfg); cfg->ups_ctx = rspamd_upstreams_library_init (); cfg->re_cache = rspamd_re_cache_new (); + cfg->doc_strings = ucl_object_typed_new (UCL_OBJECT); REF_INIT_RETAIN (cfg, rspamd_config_free); @@ -210,7 +211,8 @@ void rspamd_config_free (struct rspamd_config *cfg) { rspamd_map_remove_all (cfg); - ucl_obj_unref (cfg->rcl_obj); + ucl_object_unref (cfg->rcl_obj); + ucl_object_unref (cfg->doc_strings); g_hash_table_remove_all (cfg->metrics); g_hash_table_unref (cfg->metrics); g_hash_table_unref (cfg->c_modules); |