From: Felix Fietkau Date: Sat, 5 Sep 2009 00:32:37 +0000 (+0200) Subject: replace the use of list.h in the ucimap core, relicense ucimap to LGPL v2.1, update... X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=c81b25ffd34632dc6ac56fe61faaf44eca822259;p=uci.git replace the use of list.h in the ucimap core, relicense ucimap to LGPL v2.1, update copyright headers --- diff --git a/Makefile b/Makefile index 1397ea5..11bb472 100644 --- a/Makefile +++ b/Makefile @@ -16,10 +16,10 @@ endef LIBUCI_DEPS=file.c history.c list.c util.c uci.h uci_config.h uci_internal.h -all: uci-static uci libuci.$(SHLIB_EXT) ucimap-example +all: uci libuci.$(SHLIB_EXT) uci-static ucimap-example cli.o: cli.c uci.h uci_config.h -ucimap.o: ucimap.c uci.h uci_config.h ucimap.h uci_list.h +ucimap.o: ucimap.c uci.h uci_config.h ucimap.h uci_config.h: FORCE @rm -f "$@.tmp" @@ -33,6 +33,15 @@ uci_config.h: FORCE rm -f "$@.tmp"; \ fi +%.o: %.c + $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $< + +%-shared.o: %.c + $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(FPIC) $< + +%-static.o: %.c + $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $< + uci: cli.o libuci.$(SHLIB_EXT) $(CC) -o $@ $< -L. -luci $(LIBS) @@ -40,16 +49,9 @@ uci-static: cli.o libuci.a $(CC) $(CFLAGS) -o $@ $^ $(LIBS) libuci-static.o: libuci.c $(LIBUCI_DEPS) - $(CC) $(CFLAGS) -c -o $@ $< - libuci-shared.o: libuci.c $(LIBUCI_DEPS) - $(CC) $(CFLAGS) $(FPIC) -c -o $@ $< - ucimap-static.o: ucimap.c $(LIBUCI_DEPS) ucimap.h - $(CC) $(CFLAGS) -c -o $@ $< - ucimap-shared.o: ucimap.c $(LIBUCI_DEPS) ucimap.h - $(CC) $(CFLAGS) $(FPIC) -c -o $@ $< libuci.a: libuci-static.o ucimap-static.o rm -f $@ @@ -60,8 +62,9 @@ libuci.$(SHLIB_EXT): libuci-shared.o ucimap-shared.o $(LINK) $(SHLIB_FLAGS) -o $(SHLIB_FILE) $^ $(LIBS) ln -sf $(SHLIB_FILE) $@ -ucimap-example: ucimap-example.c libuci.a - $(CC) $(CFLAGS) -I. -o $@ $^ $(LIBS) +ucimap-example.o: ucimap-example.c list.h +ucimap-example: ucimap-example.o libuci.a + $(CC) $(CFLAGS) -o $@ $^ $(LIBS) clean: rm -f uci uci-static *.[oa] *.so* *.dylib* uci_config.h ucimap-example @@ -72,7 +75,7 @@ install-dev: all $(MKDIR) -p $(DESTDIR)$(prefix)/lib $(MKDIR) -p $(DESTDIR)$(prefix)/include $(INSTALL) -m0644 libuci.a $(DESTDIR)$(prefix)/lib/ - $(INSTALL) -m0644 uci_config.h uci.h uci_list.h ucimap.h $(DESTDIR)$(prefix)/include/ + $(INSTALL) -m0644 uci_config.h uci.h ucimap.h $(DESTDIR)$(prefix)/include/ install-bin: all $(MKDIR) -p $(DESTDIR)$(prefix)/lib diff --git a/Makefile.inc b/Makefile.inc index 44c6aa5..ab5eb25 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -5,6 +5,7 @@ COPTS=-O2 WOPTS=-pedantic -Werror -Wall FPIC=-fPIC CFLAGS=$(COPTS) $(WOPTS) -std=gnu99 +CPPFLAGS=-I. AR=ar LD=ld diff --git a/uci_list.h b/list.h similarity index 100% rename from uci_list.h rename to list.h diff --git a/ucimap-example.c b/ucimap-example.c index d433f61..9b315d0 100644 --- a/ucimap-example.c +++ b/ucimap-example.c @@ -1,6 +1,6 @@ /* * ucimap-example - sample code for the ucimap library - * Copyright (C) 2008 Felix Fietkau + * Copyright (C) 2008-2009 Felix Fietkau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -16,6 +16,7 @@ #include #include #include +#include "list.h" struct list_head ifs; diff --git a/ucimap.c b/ucimap.c index 3d11c59..b477264 100644 --- a/ucimap.c +++ b/ucimap.c @@ -1,9 +1,9 @@ /* - * ucimap - library for mapping uci sections into data structures - * Copyright (C) 2008 Felix Fietkau + * ucimap.c - Library for the Unified Configuration Interface + * Copyright (C) 2008-2009 Felix Fietkau * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 + * it under the terms of the GNU Lesser General Public License version 2.1 * as published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, @@ -11,6 +11,11 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + +/* + * This file contains ucimap, an API for mapping UCI to C data structures + */ + #include #include #include @@ -23,18 +28,18 @@ #include "ucimap.h" #include "uci_internal.h" -struct uci_alloc { +struct ucimap_alloc { void *ptr; }; -struct uci_alloc_custom { +struct ucimap_alloc_custom { void *section; struct uci_optmap *om; void *ptr; }; -struct uci_fixup { - struct list_head list; +struct ucimap_fixup { + struct ucimap_fixup *next; struct uci_sectionmap *sm; const char *name; enum ucimap_type type; @@ -121,16 +126,17 @@ ucimap_get_data(struct ucimap_section_data *sd, struct uci_optmap *om) int ucimap_init(struct uci_map *map) { - INIT_LIST_HEAD(&map->pending); - INIT_LIST_HEAD(&map->sdata); - INIT_LIST_HEAD(&map->fixup); + map->fixup = NULL; + map->sdata = NULL; + map->fixup_tail = &map->fixup; + map->sdata_tail = &map->sdata; return 0; } static void ucimap_add_alloc(struct ucimap_section_data *sd, void *ptr) { - struct uci_alloc *a = &sd->allocmap[sd->allocmap_len++]; + struct ucimap_alloc *a = &sd->allocmap[sd->allocmap_len++]; a->ptr = ptr; } @@ -141,8 +147,8 @@ ucimap_free_section(struct uci_map *map, struct ucimap_section_data *sd) int i; section = ucimap_section_ptr(sd); - if (!list_empty(&sd->list)) - list_del(&sd->list); + if (sd->ref) + *sd->ref = sd->next; if (sd->sm->free) sd->sm->free(map, section); @@ -153,7 +159,7 @@ ucimap_free_section(struct uci_map *map, struct ucimap_section_data *sd) if (sd->alloc_custom) { for (i = 0; i < sd->alloc_custom_len; i++) { - struct uci_alloc_custom *a = &sd->alloc_custom[i]; + struct ucimap_alloc_custom *a = &sd->alloc_custom[i]; a->om->free(a->section, a->om, a->ptr); } free(sd->alloc_custom); @@ -166,30 +172,26 @@ ucimap_free_section(struct uci_map *map, struct ucimap_section_data *sd) void ucimap_cleanup(struct uci_map *map) { - struct list_head *ptr, *tmp; + struct ucimap_section_data *sd; - list_for_each_safe(ptr, tmp, &map->sdata) { - struct ucimap_section_data *sd = list_entry(ptr, struct ucimap_section_data, list); + for (sd = map->sdata; sd; sd = sd->next) { ucimap_free_section(map, sd); } } static void * -ucimap_find_section(struct uci_map *map, struct uci_fixup *f) +ucimap_find_section(struct uci_map *map, struct ucimap_fixup *f) { struct ucimap_section_data *sd; - struct list_head *p; - list_for_each(p, &map->sdata) { - sd = list_entry(p, struct ucimap_section_data, list); + for (sd = map->sdata; sd; sd = sd->next) { if (sd->sm != f->sm) continue; if (strcmp(f->name, sd->section_name) != 0) continue; return ucimap_section_ptr(sd); } - list_for_each(p, &map->pending) { - sd = list_entry(p, struct ucimap_section_data, list); + for (sd = map->pending; sd; sd = sd->next) { if (sd->sm != f->sm) continue; if (strcmp(f->name, sd->section_name) != 0) @@ -200,7 +202,7 @@ ucimap_find_section(struct uci_map *map, struct uci_fixup *f) } static bool -ucimap_handle_fixup(struct uci_map *map, struct uci_fixup *f) +ucimap_handle_fixup(struct uci_map *map, struct ucimap_fixup *f) { void *ptr = ucimap_find_section(map, f); struct ucimap_list *list; @@ -223,8 +225,8 @@ ucimap_handle_fixup(struct uci_map *map, struct uci_fixup *f) void ucimap_free_item(struct ucimap_section_data *sd, void *item) { - struct uci_alloc_custom *ac; - struct uci_alloc *a; + struct ucimap_alloc_custom *ac; + struct ucimap_alloc *a; void *ptr = *((void **) item); int i; @@ -249,7 +251,7 @@ ucimap_free_item(struct ucimap_section_data *sd, void *item) if (i != sd->alloc_custom_len - 1) memcpy(ac, &sd->alloc_custom[sd->alloc_custom_len - 1], - sizeof(struct uci_alloc_custom)); + sizeof(struct ucimap_alloc_custom)); ac->om->free(ac->section, ac->om, ac->ptr); sd->alloc_custom_len--; @@ -261,7 +263,7 @@ int ucimap_resize_list(struct ucimap_section_data *sd, struct ucimap_list **list, int items) { struct ucimap_list *new; - struct uci_alloc *a; + struct ucimap_alloc *a; int i, offset = 0; int size = sizeof(struct ucimap_list) + items * sizeof(union ucimap_data); @@ -298,10 +300,9 @@ set: static void ucimap_add_fixup(struct ucimap_section_data *sd, union ucimap_data *data, struct uci_optmap *om, const char *str) { - struct uci_fixup *f, tmp; + struct ucimap_fixup *f, tmp; struct uci_map *map = sd->map; - INIT_LIST_HEAD(&tmp.list); tmp.sm = om->data.sm; tmp.name = str; tmp.type = om->type; @@ -309,18 +310,20 @@ ucimap_add_fixup(struct ucimap_section_data *sd, union ucimap_data *data, struct if (ucimap_handle_fixup(map, &tmp)) return; - f = malloc(sizeof(struct uci_fixup)); + f = malloc(sizeof(struct ucimap_fixup)); if (!f) return; memcpy(f, &tmp, sizeof(tmp)); - list_add_tail(&f->list, &map->fixup); + f->next = NULL; + *map->fixup_tail = f; + map->fixup_tail = &f->next; } static void ucimap_add_custom_alloc(struct ucimap_section_data *sd, struct uci_optmap *om, void *ptr) { - struct uci_alloc_custom *a = &sd->alloc_custom[sd->alloc_custom_len++]; + struct ucimap_alloc_custom *a = &sd->alloc_custom[sd->alloc_custom_len++]; a->section = ucimap_section_ptr(sd); a->om = om; @@ -471,15 +474,24 @@ ucimap_parse_options(struct uci_map *map, struct uci_sectionmap *sm, struct ucim return 0; } +static void +ucimap_add_section_list(struct uci_map *map, struct ucimap_section_data *sd) +{ + sd->ref = map->sdata_tail; + *sd->ref = sd; + map->sdata_tail = &sd->next; +} + static void ucimap_add_section(struct ucimap_section_data *sd) { struct uci_map *map = sd->map; + sd->next = NULL; if (sd->sm->add(map, ucimap_section_ptr(sd)) < 0) ucimap_free_section(map, sd); else - list_add_tail(&sd->list, &map->sdata); + ucimap_add_section_list(map, sd); } #ifdef UCI_DEBUG @@ -579,7 +591,6 @@ ucimap_parse_section(struct uci_map *map, struct uci_sectionmap *sm, struct ucim int n_alloc_custom = 0; int err; - INIT_LIST_HEAD(&sd->list); sd->map = map; sd->sm = sm; @@ -646,12 +657,12 @@ ucimap_parse_section(struct uci_map *map, struct uci_sectionmap *sm, struct ucim } } - sd->allocmap = calloc(n_alloc, sizeof(struct uci_alloc)); + sd->allocmap = calloc(n_alloc, sizeof(struct ucimap_alloc)); if (!sd->allocmap) goto error_mem; if (n_alloc_custom > 0) { - sd->alloc_custom = calloc(n_alloc_custom, sizeof(struct uci_alloc_custom)); + sd->alloc_custom = calloc(n_alloc_custom, sizeof(struct ucimap_alloc_custom)); if (!sd->alloc_custom) goto error_mem; } @@ -683,7 +694,7 @@ ucimap_parse_section(struct uci_map *map, struct uci_sectionmap *sm, struct ucim if (map->parsed) { ucimap_add_section(sd); } else { - list_add_tail(&sd->list, &map->pending); + ucimap_add_section_list(map, sd); } err = ucimap_parse_options(map, sm, sd, s); @@ -853,10 +864,13 @@ void ucimap_parse(struct uci_map *map, struct uci_package *pkg) { struct uci_element *e; - struct list_head *p, *tmp; + struct ucimap_section_data *sd, **sd_tail; + struct ucimap_fixup *f; int i; - INIT_LIST_HEAD(&map->fixup); + sd_tail = map->sdata_tail; + map->parsed = false; + map->sdata_tail = &map->pending; uci_foreach_element(&pkg->sections, e) { struct uci_section *s = uci_to_section(e); @@ -880,20 +894,26 @@ ucimap_parse(struct uci_map *map, struct uci_package *pkg) ucimap_parse_section(map, sm, sd, s); } } - map->parsed = true; + if (!map->parsed) { + map->parsed = true; + map->sdata_tail = sd_tail; + } - list_for_each_safe(p, tmp, &map->fixup) { - struct uci_fixup *f = list_entry(p, struct uci_fixup, list); + f = map->fixup; + while (f) { + struct ucimap_fixup *next = f->next; ucimap_handle_fixup(map, f); - list_del(&f->list); free(f); + f = next; } + map->fixup_tail = &map->fixup; + map->fixup = NULL; - list_for_each_safe(p, tmp, &map->pending) { - struct ucimap_section_data *sd; - sd = list_entry(p, struct ucimap_section_data, list); - - list_del_init(&sd->list); + sd = map->pending; + while (sd) { + struct ucimap_section_data *next = sd->next; ucimap_add_section(sd); + sd = next; } + map->pending = NULL; } diff --git a/ucimap.h b/ucimap.h index 21aa83e..02966ea 100644 --- a/ucimap.h +++ b/ucimap.h @@ -1,9 +1,9 @@ /* - * ucimap - library for mapping uci sections into data structures - * Copyright (C) 2008 Felix Fietkau + * ucimap.h - Library for the Unified Configuration Interface + * Copyright (C) 2008-2009 Felix Fietkau * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 + * it under the terms of the GNU Lesser General Public License version 2.1 * as published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, @@ -11,11 +11,15 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + +/* + * This file contains ucimap, an API for mapping UCI to C data structures + */ + #ifndef __UCIMAP_H #define __UCIMAP_H #include -#include "uci_list.h" #include "uci.h" #ifndef ARRAY_SIZE @@ -103,19 +107,25 @@ struct uci_sectionmap; struct uci_optmap; + struct ucimap_list; -struct uci_alloc; -struct uci_alloc_custom; +struct ucimap_fixup; +struct ucimap_alloc; +struct ucimap_alloc_custom; +struct ucimap_section_data; struct uci_map { struct uci_sectionmap **sections; unsigned int n_sections; - struct list_head sdata; - struct list_head fixup; - struct list_head pending; bool parsed; - - void *priv; /* user data */ + void *priv; + + /* private */ + struct ucimap_fixup *fixup; + struct ucimap_fixup **fixup_tail; + struct ucimap_section_data *sdata; + struct ucimap_section_data *pending; + struct ucimap_section_data **sdata_tail; }; enum ucimap_type { @@ -148,20 +158,20 @@ union ucimap_data { }; struct ucimap_section_data { - struct list_head list; struct uci_map *map; struct uci_sectionmap *sm; const char *section_name; - /* list of allocations done by ucimap */ - struct uci_alloc *allocmap; - struct uci_alloc_custom *alloc_custom; - unsigned int allocmap_len; - unsigned int alloc_custom_len; - /* map for changed fields */ unsigned char *cmap; bool done; + + /* internal */ + struct ucimap_section_data *next, **ref; + struct ucimap_alloc *allocmap; + struct ucimap_alloc_custom *alloc_custom; + unsigned int allocmap_len; + unsigned int alloc_custom_len; }; struct uci_sectionmap {