struct list_head ifs;
struct uci_network {
+ struct ucimap_section_data map;
struct list_head list;
struct list_head alias;
};
struct uci_alias {
+ struct ucimap_section_data map;
struct list_head list;
const char *name;
network_parse_ip(void *section, struct uci_optmap *om, union ucimap_data *data, const char *str)
{
struct uci_network *net = section;
- unsigned char *target = data->s;
+ unsigned char *target = (unsigned char *) data->s;
unsigned int tmp[4];
int i;
};
static struct uci_sectionmap network_interface = {
+ UCIMAP_SECTION(struct uci_network, map),
.type = "interface",
.alloc_len = sizeof(struct uci_network),
.init = network_init_interface,
};
static struct uci_sectionmap network_alias = {
+ UCIMAP_SECTION(struct uci_alias, map),
.type = "alias",
.options = network_alias_options,
- .alloc_len = sizeof(struct uci_network),
.init = network_init_alias,
.add = network_add_alias,
.n_options = ARRAY_SIZE(network_alias_options),
union ucimap_data *data;
};
-struct uci_sectionmap_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;
- unsigned long allocmap_len;
-
- /* map for changed fields */
- unsigned char *cmap;
- bool done;
-};
-
-
#define ucimap_foreach_option(_sm, _o) \
if (!(_sm)->options_size) \
(_sm)->options_size = sizeof(struct uci_optmap); \
}
static inline void *
-ucimap_section_ptr(struct uci_sectionmap_data *sd)
+ucimap_section_ptr(struct ucimap_section_data *sd)
{
- void *data = sd + 1;
- return data;
+ return ((char *) sd - sd->sm->smap_offset);
}
static inline union ucimap_data *
-ucimap_get_data(struct uci_sectionmap_data *sd, struct uci_optmap *om)
+ucimap_get_data(struct ucimap_section_data *sd, struct uci_optmap *om)
{
void *data;
}
static void
-ucimap_add_alloc(struct uci_sectionmap_data *sd, void *ptr)
+ucimap_add_alloc(struct ucimap_section_data *sd, void *ptr)
{
struct uci_alloc *a = &sd->allocmap[sd->allocmap_len++];
a->type = UCIMAP_SIMPLE;
}
static void
-ucimap_free_section(struct uci_map *map, struct uci_sectionmap_data *sd)
+ucimap_free_section(struct uci_map *map, struct ucimap_section_data *sd)
{
void *section;
int i;
struct list_head *ptr, *tmp;
list_for_each_safe(ptr, tmp, &map->sdata) {
- struct uci_sectionmap_data *sd = list_entry(ptr, struct uci_sectionmap_data, list);
+ struct ucimap_section_data *sd = list_entry(ptr, struct ucimap_section_data, list);
ucimap_free_section(map, sd);
}
}
}
static void
-ucimap_add_value(union ucimap_data *data, struct uci_optmap *om, struct uci_sectionmap_data *sd, const char *str)
+ucimap_add_value(union ucimap_data *data, struct uci_optmap *om, struct ucimap_section_data *sd, const char *str)
{
union ucimap_data tdata = *data;
char *eptr = NULL;
static int
-ucimap_parse_options(struct uci_map *map, struct uci_sectionmap *sm, struct uci_sectionmap_data *sd, struct uci_section *s)
+ucimap_parse_options(struct uci_map *map, struct uci_sectionmap *sm, struct ucimap_section_data *sd, struct uci_section *s)
{
struct uci_element *e, *l;
struct uci_option *o;
static int
ucimap_parse_section(struct uci_map *map, struct uci_sectionmap *sm, struct uci_section *s)
{
- struct uci_sectionmap_data *sd = NULL;
+ struct ucimap_section_data *sd = NULL;
struct uci_optmap *om;
char *section_name;
void *section;
int n_alloc = 2;
int err;
- sd = malloc(sm->alloc_len + sizeof(struct uci_sectionmap_data));
+ sd = malloc(sm->alloc_len);
if (!sd)
return UCI_ERR_MEM;
- memset(sd, 0, sm->alloc_len + sizeof(struct uci_sectionmap_data));
+ memset(sd, 0, sm->alloc_len);
INIT_LIST_HEAD(&sd->list);
+ sd->map = map;
+ sd->sm = sm;
ucimap_foreach_option(sm, om) {
if (ucimap_is_list(om->type)) {
}
}
- sd->map = map;
- sd->sm = sm;
sd->allocmap = malloc(n_alloc * sizeof(struct uci_alloc));
if (!sd->allocmap)
goto error_mem;
}
section = ucimap_section_ptr(sd);
-
err = sm->init(map, section, s);
if (err)
goto error;
}
void
-ucimap_set_changed(void *section, void *field)
+ucimap_set_changed(struct ucimap_section_data *sd, void *field)
{
- char *sptr = (char *)section - sizeof(struct uci_sectionmap_data);
- struct uci_sectionmap_data *sd = (struct uci_sectionmap_data *) sptr;
+ void *section = ucimap_section_ptr(sd);
struct uci_sectionmap *sm = sd->sm;
struct uci_optmap *om;
int ofs = (char *)field - (char *)section;
int
ucimap_store_section(struct uci_map *map, struct uci_package *p, void *section)
{
- char *sptr = (char *)section - sizeof(struct uci_sectionmap_data);
- struct uci_sectionmap_data *sd = (struct uci_sectionmap_data *) sptr;
+ char *sptr = (char *)section - sizeof(struct ucimap_section_data);
+ struct ucimap_section_data *sd = (struct ucimap_section_data *) sptr;
struct uci_sectionmap *sm = sd->sm;
struct uci_section *s = NULL;
struct uci_optmap *om;
void *
ucimap_find_section(struct uci_map *map, struct uci_fixup *f)
{
- struct uci_sectionmap_data *sd;
+ struct ucimap_section_data *sd;
struct list_head *p;
- void *ret;
list_for_each(p, &map->sdata) {
- sd = list_entry(p, struct uci_sectionmap_data, list);
+ sd = list_entry(p, struct ucimap_section_data, list);
if (sd->sm != f->sm)
continue;
if (strcmp(f->name, sd->section_name) != 0)
continue;
- ret = (char *)sd + sizeof(struct uci_sectionmap_data);
- return ret;
+ return ucimap_section_ptr(sd);
}
return NULL;
}
free(f);
}
list_for_each_safe(p, tmp, &map->sdata) {
- struct uci_sectionmap_data *sd = list_entry(p, struct uci_sectionmap_data, list);
+ struct ucimap_section_data *sd = list_entry(p, struct ucimap_section_data, list);
void *section;
if (sd->done)
continue;
- section = (char *) sd + sizeof(struct uci_sectionmap_data);
+ section = ucimap_section_ptr(sd);
if (sd->sm->add(map, section) != 0)
ucimap_free_section(map, sd);
}
.name = #_field, \
.offset = offsetof(_type, _field)
+
+#define UCIMAP_SECTION(_name, _field) \
+ .alloc_len = sizeof(_name), \
+ .smap_offset = offsetof(_name, _field)
+
struct uci_sectionmap;
struct uci_optmap;
struct ucimap_list;
struct ucimap_list *list;
};
+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;
+ unsigned long allocmap_len;
+
+ /* map for changed fields */
+ unsigned char *cmap;
+ bool done;
+};
+
+
struct uci_listmap {
struct list_head list;
union ucimap_data data;
/* length of the struct to map into */
unsigned int alloc_len;
+ /* sectionmap offset */
+ unsigned int smap_offset;
+
/* give the caller time to initialize the preallocated struct */
int (*init)(struct uci_map *map, void *section, struct uci_section *s);
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 void ucimap_set_changed(struct ucimap_section_data *sd, 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);