Browse Source

more plugin support

Felix Fietkau 16 years ago
parent
commit
7cefa00ead
5 changed files with 94 additions and 20 deletions
  1. 40 2
      libuci.c
  2. 1 1
      list.c
  3. 4 11
      uci.h
  4. 46 3
      uci_internal.h
  5. 3 3
      util.c

+ 40 - 2
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;

+ 1 - 1
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;

+ 4 - 11
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

+ 46 - 3
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

+ 3 - 3
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;