summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2008-02-12 13:19:42 +0100
committerFelix Fietkau <nbd@openwrt.org>2008-02-12 13:19:42 +0100
commit7cefa00eadb4292d2c915a38a86e588c6e539d26 (patch)
treed8c0319b26ec3b3c28c3e73ae196e6a81c889e7a
parent406d259cd1faab6de1ee2b817970c9f71d7945a2 (diff)
downloaduci-7cefa00eadb4292d2c915a38a86e588c6e539d26.tar.gz
more plugin support
-rw-r--r--libuci.c42
-rw-r--r--list.c2
-rw-r--r--uci.h15
-rw-r--r--uci_internal.h49
-rw-r--r--util.c6
5 files changed, 94 insertions, 20 deletions
diff --git a/libuci.c b/libuci.c
index a503699..59e2ea9 100644
--- 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 376d38b..339ad3e 100644
--- 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 674981c..ab65d1c 100644
--- 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
diff --git a/uci_internal.h b/uci_internal.h
index 5b5a50d..fdaf04a 100644
--- a/uci_internal.h
+++ b/uci_internal.h
@@ -15,6 +15,13 @@
#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 35aa2b6..ac7b8cb 100644
--- 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;