+
+/**
+ * Data type of a section.
+ * If you store the section into a structure, use this macro.
+ *
+ * Storing a section into a structure is useful mostly when you may have multiple instances of the
+ * section (eg. <<conf_multi,array or list>>).
+ *
+ * Example:
+ *
+ * struct list_node {
+ * cnode n; // This one is for the list itself
+ * char *name;
+ * uns value;
+ * };
+ *
+ * static struct clist nodes;
+ *
+ * static struct cf_section node = {
+ * CF_TYPE(struct list_node),
+ * CF_ITEMS {
+ * CF_STRING("name", PTR_TO(struct list_node, name)),
+ * CF_UNS("value", PTR_TO(struct list_node, value)),
+ * CF_END
+ * }
+ * };
+ *
+ * static struct cf_section section = {
+ * CF_LIST("node", &nodes, &node),
+ * CF_END
+ * };
+ *
+ * You could use <<def_CF_STATIC,`CF_STATIC`>> or <<def_CF_DYNAMIC,`CF_DYNAMIC`>>
+ * macros to create arrays.
+ */
+#define CF_TYPE(s) .size = sizeof(s)
+/**
+ * An init <<hooks,hook>>.
+ * You can use this to initialize dynamically allocated items (for a dynamic array or list).
+ * The hook returns an error message or NULL if everything was OK.
+ */
+#define CF_INIT(f) .init = (cf_hook*) f
+/**
+ * A commit <<hooks,hook>>.
+ * You can use this one to check sanity of loaded data and postprocess them.
+ * You must call @cf_journal_block() if you change anything.
+ *
+ * Return error message or NULL if everything went OK.
+ **/
+#define CF_COMMIT(f) .commit = (cf_hook*) f
+/**
+ * A <<hooks,copy function>>.
+ * You need to provide one for too complicated sections where a memcpy is not
+ * enough to copy it properly. It happens, for example, when you have a dynamically
+ * allocated section containing a list of other sections.
+ *
+ * You return an error message or NULL if you succeed.
+ **/
+#define CF_COPY(f) .copy = (cf_copier*) f /** **/