more plugin support
authorFelix Fietkau <nbd@openwrt.org>
Tue, 12 Feb 2008 12:19:42 +0000 (13:19 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Tue, 12 Feb 2008 12:19:42 +0000 (13:19 +0100)
libuci.c
list.c
uci.h
uci_internal.h
util.c

index a503699bd1bbf5298a2b994c7c6d030ca6194ada..59e2ea96c42fd4dcf1fabe3b2b5df2e35f6b4390 100644 (file)
--- a/libuci.c
+++ b/libuci.c
@@ -193,18 +193,56 @@ int uci_load(struct uci_context *ctx, const char *name, struct uci_package **pac
        return 0;
 }
 
-int uci_add_backend(struct uci_context *ctx, struct uci_backend *b)
+#ifdef UCI_PLUGIN_SUPPORT
+
+__plugin int uci_add_backend(struct uci_context *ctx, struct uci_backend *b)
 {
        struct uci_element *e;
        UCI_HANDLE_ERR(ctx);
+
        e = uci_lookup_list(&ctx->backends, b->e.name);
        if (e)
                UCI_THROW(ctx, UCI_ERR_DUPLICATE);
 
-       uci_list_add(&ctx->backends, &b->e.list);
+       e = uci_malloc(ctx, sizeof(struct uci_backend));
+       memcpy(e, b, sizeof(struct uci_backend));
+
+       uci_list_add(&ctx->backends, &e->list);
        return 0;
 }
 
+__plugin int uci_del_backend(struct uci_context *ctx, struct uci_backend *b)
+{
+       struct uci_element *e, *tmp;
+
+       UCI_HANDLE_ERR(ctx);
+
+       e = uci_lookup_list(&ctx->backends, b->e.name);
+       if (!e || uci_to_backend(e)->ptr != b->ptr)
+               UCI_THROW(ctx, UCI_ERR_NOTFOUND);
+       b = uci_to_backend(e);
+
+       if (ctx->backend && ctx->backend->ptr == b->ptr)
+               ctx->backend = &uci_file_backend;
+
+       uci_foreach_element_safe(&ctx->root, tmp, e) {
+               struct uci_package *p = uci_to_package(e);
+
+               if (!p->backend)
+                       continue;
+
+               if (p->backend->ptr == b->ptr)
+                       UCI_INTERNAL(uci_unload, ctx, p);
+       }
+
+       uci_list_del(&b->e.list);
+       free(b);
+
+       return 0;
+}
+
+#endif
+
 int uci_set_backend(struct uci_context *ctx, const char *name)
 {
        struct uci_element *e;
diff --git a/list.c b/list.c
index 376d38b768dc789fcbc6870682ea9ef50c2cb382..339ad3e336385b95246aed8dcddbeac92616a42a 100644 (file)
--- a/list.c
+++ b/list.c
@@ -180,7 +180,7 @@ uci_free_section(struct uci_section *s)
        uci_free_element(&s->e);
 }
 
-static struct uci_package *
+__plugin struct uci_package *
 uci_alloc_package(struct uci_context *ctx, const char *name)
 {
        struct uci_package *p;
diff --git a/uci.h b/uci.h
index 674981c8f369685ecc894ef843a34e91c02fc1a6..ab65d1ca79f9d58350b9cb566b6d60ca9203fa91 100644 (file)
--- a/uci.h
+++ b/uci.h
@@ -311,6 +311,10 @@ struct uci_backend
        char **(*list_configs)(struct uci_context *ctx);
        struct uci_package *(*load)(struct uci_context *ctx, const char *name);
        void (*commit)(struct uci_context *ctx, struct uci_package **p, bool overwrite);
+
+       /* private: */
+       const void *ptr;
+       void *priv;
 };
 
 struct uci_context
@@ -390,17 +394,6 @@ struct uci_history
        char *value;
 };
 
-#define UCI_BACKEND(_var, _name, ...)  \
-struct uci_backend _var = {            \
-       .e.list = {                     \
-               .next = &_var.e.list,   \
-               .prev = &_var.e.list,   \
-       },                              \
-       .e.name = _name,                \
-       .e.type = UCI_TYPE_BACKEND,     \
-       __VA_ARGS__                     \
-}
-
 
 /* linked list handling */
 #ifndef offsetof
index 5b5a50dfcd41ece6ce7eb3babab243e5d964f6ff..fdaf04a303c1dea6f9755df57a6027cd7651dc7a 100644 (file)
 #ifndef __UCI_INTERNAL_H
 #define __UCI_INTERNAL_H
 
+#define __public
+#ifdef UCI_PLUGIN_SUPPORT
+#define __plugin extern
+#else
+#define __plugin static
+#endif
+
 struct uci_parse_context
 {
        /* error context */
@@ -32,9 +39,45 @@ struct uci_parse_context
        int bufsz;
 };
 
-int uci_add_backend(struct uci_context *ctx, struct uci_backend *b);
-void uci_add_history(struct uci_context *ctx, struct uci_list *list, int cmd, char *section, char *option, char *value);
-void uci_free_history(struct uci_history *h);
+__plugin void *uci_malloc(struct uci_context *ctx, size_t size);
+__plugin void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size);
+__plugin char *uci_strdup(struct uci_context *ctx, const char *str);
+__plugin void uci_add_history(struct uci_context *ctx, struct uci_list *list, int cmd, char *section, char *option, char *value);
+__plugin void uci_free_history(struct uci_history *h);
+__plugin struct uci_package *uci_alloc_package(struct uci_context *ctx, const char *name);
+
+#ifdef UCI_PLUGIN_SUPPORT
+/**
+ * uci_add_backend: add an extra backend
+ * @ctx: uci context
+ * @name: name of the backend
+ *
+ * The default backend is "file", which uses /etc/config for config storage
+ */
+__plugin int uci_add_backend(struct uci_context *ctx, struct uci_backend *b);
+
+/**
+ * uci_add_backend: add an extra backend
+ * @ctx: uci context
+ * @name: name of the backend
+ *
+ * The default backend is "file", which uses /etc/config for config storage
+ */
+__plugin int uci_del_backend(struct uci_context *ctx, struct uci_backend *b);
+#endif
+
+#define UCI_BACKEND(_var, _name, ...)  \
+struct uci_backend _var = {            \
+       .e.list = {                     \
+               .next = &_var.e.list,   \
+               .prev = &_var.e.list,   \
+       },                              \
+       .e.name = _name,                \
+       .e.type = UCI_TYPE_BACKEND,     \
+       .ptr = &_var,                   \
+       __VA_ARGS__                     \
+}
+
 
 /*
  * functions for debug and error handling, for internal use only
diff --git a/util.c b/util.c
index 35aa2b6e8a66dca190a55ab21383824cbefd4b50..ac7b8cb4c0e6f234f21e5d032c18c5d75289da04 100644 (file)
--- a/util.c
+++ b/util.c
@@ -27,7 +27,7 @@
 #define LINEBUF        32
 #define LINEBUF_MAX    4096
 
-static void *uci_malloc(struct uci_context *ctx, size_t size)
+__plugin void *uci_malloc(struct uci_context *ctx, size_t size)
 {
        void *ptr;
 
@@ -39,7 +39,7 @@ static void *uci_malloc(struct uci_context *ctx, size_t size)
        return ptr;
 }
 
-static void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size)
+__plugin void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size)
 {
        ptr = realloc(ptr, size);
        if (!ptr)
@@ -48,7 +48,7 @@ static void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size)
        return ptr;
 }
 
-static char *uci_strdup(struct uci_context *ctx, const char *str)
+__plugin char *uci_strdup(struct uci_context *ctx, const char *str)
 {
        char *ptr;