]> source.dussan.org Git - rspamd.git/commitdiff
Initial implementation of documentation strings in rspamd
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 27 Dec 2015 15:23:31 +0000 (15:23 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 27 Dec 2015 15:23:31 +0000 (15:23 +0000)
src/libserver/cfg_file.h
src/libserver/cfg_rcl.c
src/libserver/cfg_rcl.h
src/libserver/cfg_utils.c

index 3db5233dffdf1f556b583b47ed9fe1694a258c76..929f8a78db6afd8371446d76f6ec5a4b7aac1922 100644 (file)
@@ -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                    */
index bff732c4f6eb5e3ea439440dd37f6fed1668f9ce..aa5c918643889c5b065663e9ac62370d82aa33c6 100644 (file)
@@ -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;
+}
index d7b1c0de2fe550de52947dcf45184a712cc1f772..43f240157ec8883adabf011368739a7dd0b5665b 100644 (file)
@@ -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_ */
index 185c28adbcb3fce34ed4ec842d090a3ed5953e9d..a3d80193900a72f3342a9621f25b4b958afefaa3 100644 (file)
@@ -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);