turn ucimap-example.c into a test case
[project/uci.git] / uci.h
diff --git a/uci.h b/uci.h
index d48ea7cef153349256adca7017e28fd178b92f60..74bbdffa921cf8e2e8a34fcb103b0a0cd969165d 100644 (file)
--- a/uci.h
+++ b/uci.h
@@ -56,6 +56,8 @@ struct uci_list
 };
 
 struct uci_ptr;
+struct uci_plugin;
+struct uci_hook_ops;
 struct uci_element;
 struct uci_package;
 struct uci_section;
@@ -177,6 +179,14 @@ extern int uci_set(struct uci_context *ctx, struct uci_ptr *ptr);
  */
 extern int uci_add_list(struct uci_context *ctx, struct uci_ptr *ptr);
 
+/**
+ * uci_reorder: Reposition a section
+ * @ctx: uci context
+ * @s: uci section to reposition
+ * @pos: new position in the section list
+ */
+extern int uci_reorder_section(struct uci_context *ctx, struct uci_section *s, int pos);
+
 /**
  * uci_rename: Rename an element
  * @ctx: uci context
@@ -275,6 +285,43 @@ extern int uci_set_backend(struct uci_context *ctx, const char *name);
  */
 extern bool uci_validate_text(const char *str);
 
+
+/**
+ * uci_add_hook: add a uci hook
+ * @ctx: uci context
+ * @ops: uci hook ops
+ *
+ * NB: allocated and freed by the caller
+ */
+extern int uci_add_hook(struct uci_context *ctx, const struct uci_hook_ops *ops);
+
+/**
+ * uci_remove_hook: remove a uci hook
+ * @ctx: uci context
+ * @ops: uci hook ops
+ */
+extern int uci_remove_hook(struct uci_context *ctx, const struct uci_hook_ops *ops);
+
+/**
+ * uci_load_plugin: load an uci plugin
+ * @ctx: uci context
+ * @filename: path to the uci plugin
+ *
+ * NB: plugin will be unloaded automatically when the context is freed
+ */
+int uci_load_plugin(struct uci_context *ctx, const char *filename);
+
+/**
+ * uci_load_plugins: load all uci plugins from a directory
+ * @ctx: uci context
+ * @pattern: pattern of uci plugin files (optional)
+ *
+ * if pattern is NULL, then uci_load_plugins will call uci_load_plugin
+ * for uci_*.so in <prefix>/lib/
+ */
+int uci_load_plugins(struct uci_context *ctx, const char *pattern);
+
+
 /* UCI data structures */
 enum uci_type {
        UCI_TYPE_UNSPEC = 0,
@@ -285,6 +332,8 @@ enum uci_type {
        UCI_TYPE_PATH = 5,
        UCI_TYPE_BACKEND = 6,
        UCI_TYPE_ITEM = 7,
+       UCI_TYPE_HOOK = 8,
+       UCI_TYPE_PLUGIN = 9,
 };
 
 enum uci_option_type {
@@ -346,6 +395,9 @@ struct uci_context
        bool internal, nested;
        char *buf;
        int bufsz;
+
+       struct uci_list hooks;
+       struct uci_list plugins;
 };
 
 struct uci_package
@@ -389,6 +441,7 @@ enum uci_command {
        UCI_CMD_REMOVE,
        UCI_CMD_CHANGE,
        UCI_CMD_RENAME,
+       UCI_CMD_REORDER,
        UCI_CMD_LIST_ADD,
 };
 
@@ -420,6 +473,31 @@ struct uci_ptr
        const char *value;
 };
 
+struct uci_hook_ops
+{
+       void (*load)(const struct uci_hook_ops *ops, struct uci_package *p);
+       void (*set)(const struct uci_hook_ops *ops, struct uci_package *p, struct uci_history *e);
+};
+
+struct uci_hook
+{
+       struct uci_element e;
+       const struct uci_hook_ops *ops;
+};
+
+struct uci_plugin_ops
+{
+       int (*attach)(struct uci_context *ctx);
+       void (*detach)(struct uci_context *ctx);
+};
+
+struct uci_plugin
+{
+       struct uci_element e;
+       const struct uci_plugin_ops *ops;
+       void *dlh;
+};
+
 
 /* linked list handling */
 #ifndef offsetof
@@ -432,8 +510,10 @@ struct uci_ptr
  * @type:   the type of the container struct this is embedded in.
  * @member: the name of the member within the struct.
  */
+#ifndef container_of
 #define container_of(ptr, type, member) \
        ((type *) ((char *)ptr - offsetof(type,member)))
+#endif
 
 
 /**
@@ -488,6 +568,8 @@ struct uci_ptr
 #define uci_type_package UCI_TYPE_PACKAGE
 #define uci_type_section UCI_TYPE_SECTION
 #define uci_type_option UCI_TYPE_OPTION
+#define uci_type_hook UCI_TYPE_HOOK
+#define uci_type_plugin UCI_TYPE_PLUGIN
 
 /* element typecasting */
 #ifdef UCI_DEBUG_TYPECAST
@@ -497,6 +579,8 @@ static const char *uci_typestr[] = {
        [uci_type_package] = "package",
        [uci_type_section] = "section",
        [uci_type_option] = "option",
+       [uci_type_hook] = "hook",
+       [uci_type_plugin] = "plugin",
 };
 
 static void uci_typecast_error(int from, int to)
@@ -518,6 +602,8 @@ BUILD_CAST(history)
 BUILD_CAST(package)
 BUILD_CAST(section)
 BUILD_CAST(option)
+BUILD_CAST(hook)
+BUILD_CAST(plugin)
 
 #else
 #define uci_to_backend(ptr) container_of(ptr, struct uci_backend, e)
@@ -525,6 +611,8 @@ BUILD_CAST(option)
 #define uci_to_package(ptr) container_of(ptr, struct uci_package, e)
 #define uci_to_section(ptr) container_of(ptr, struct uci_section, e)
 #define uci_to_option(ptr)  container_of(ptr, struct uci_option, e)
+#define uci_to_hook(ptr)    container_of(ptr, struct uci_hook, e)
+#define uci_to_plugin(ptr)  container_of(ptr, struct uci_plugin, e)
 #endif
 
 /**