From: Felix Fietkau Date: Tue, 12 Feb 2008 12:19:42 +0000 (+0100) Subject: more plugin support X-Git-Url: http://git.openwrt.org/?p=project%2Fuci.git;a=commitdiff_plain;h=7cefa00eadb4292d2c915a38a86e588c6e539d26 more plugin support --- 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;