/* * ucimap - library for mapping uci sections into data structures * Copyright (C) 2008 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 * as published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include #include "uci_list.h" #include "uci.h" #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #endif #define BITFIELD_SIZE(_fields) (((_fields) / 8) + 1) #define CLR_BIT(_name, _bit) do { \ _name[(_bit) / 8] &= ~(1 << ((_bit) % 8)); \ } while (0) #define SET_BIT(_name, _bit) do { \ _name[(_bit) / 8] |= (1 << ((_bit) % 8)); \ } while (0) #define TEST_BIT(_name, _bit) \ (_name[(_bit) / 8] & (1 << ((_bit) % 8))) #define OPTMAP_OPTION(_maptype, _type, _field, ...) \ { \ .type = _maptype, \ .name = #_field, \ .offset = offsetof(_type, _field), \ __VA_ARGS__ \ } struct uci_sectmap; struct uci_optmap; struct uci_map { struct uci_sectmap *sections; unsigned int n_sections; struct list_head sdata; void *priv; /* user data */ }; enum ucimap_type { UCIMAP_STRING, UCIMAP_BOOL, UCIMAP_INT, }; /* ucimap internal */ struct uci_sectmap_data { struct list_head list; struct uci_sectmap *sm; const char *section_name; unsigned long allocmap_len; /* list of allocations done by ucimap */ void **allocmap; /* map for changed fields */ unsigned char *cmap; }; struct uci_sectmap { /* type string for the uci section */ const char *type; /* length of the struct to map into */ unsigned int alloc_len; /* give the caller time to initialize the preallocated struct */ int (*init_section)(struct uci_map *map, void *section, struct uci_section *s); /* pass the fully processed struct to the callback after the section end */ int (*add_section)(struct uci_map *map, void *section); /* let the callback clean up its own stuff in the section */ int (*free_section)(struct uci_map *map, void *section); /* list of option mappings for this section */ struct uci_optmap *options; unsigned int n_options; }; struct uci_optmap { unsigned int offset; const char *name; enum ucimap_type type; union { struct { int base; int min; int max; } i; struct { int maxlen; } s; } data; }; extern int ucimap_init(struct uci_map *map); extern void ucimap_cleanup(struct uci_map *map); extern void ucimap_set_changed(void *section, void *field); extern int ucimap_store_section(struct uci_map *map, struct uci_package *p, void *section); extern void ucimap_parse(struct uci_map *map, struct uci_package *pkg);