From 477c19a7223f662ab03d0a077ac6454ab4442ff3 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 31 Aug 2009 22:44:34 +0200 Subject: [PATCH] ucimap: add new UCIMAP_LIST_AUTO for automatically converting multiple list items whitespace-separated in an option --- test/config/network | 7 +++ test/references/ucimap_example.result | 4 +- ucimap-example.c | 2 +- ucimap.c | 68 +++++++++++++++++++++++++-- ucimap.h | 5 ++ 5 files changed, 81 insertions(+), 5 deletions(-) diff --git a/test/config/network b/test/config/network index b201c48..6e2b5cc 100644 --- a/test/config/network +++ b/test/config/network @@ -17,4 +17,11 @@ config 'interface' 'wan' option 'proto' 'dhcp' option 'ifname' 'eth1' option 'enabled' 'on' + option 'aliases' 'c d' + +config 'alias' 'c' + option 'interface' 'wan' + +config 'alias' 'd' + option 'interface' 'wan' diff --git a/test/references/ucimap_example.result b/test/references/ucimap_example.result index c3dfb68..4a20965 100644 --- a/test/references/ucimap_example.result +++ b/test/references/ucimap_example.result @@ -4,11 +4,13 @@ New network section 'lan' ipaddr: 2.3.4.5 test: 123 enabled: off -New alias: b New alias: a +New alias: b New network section 'wan' type: dhcp ifname: eth1 ipaddr: 0.0.0.0 test: -1 enabled: on +New alias: c +New alias: d diff --git a/ucimap-example.c b/ucimap-example.c index 157c32f..affb070 100644 --- a/ucimap-example.c +++ b/ucimap-example.c @@ -170,7 +170,7 @@ static struct my_optmap network_interface_options[] = { { .map = { UCIMAP_OPTION(struct uci_network, aliases), - .type = UCIMAP_LIST | UCIMAP_SECTION, + .type = UCIMAP_LIST | UCIMAP_SECTION | UCIMAP_LIST_AUTO, .data.sm = &network_alias } } diff --git a/ucimap.c b/ucimap.c index 7dba62a..b1ba853 100644 --- a/ucimap.c +++ b/ucimap.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "ucimap.h" struct uci_alloc { @@ -78,6 +79,12 @@ ucimap_is_list(enum ucimap_type type) return ((type & UCIMAP_TYPE) == UCIMAP_LIST); } +static inline bool +ucimap_is_list_auto(enum ucimap_type type) +{ + return ucimap_is_list(type) && !!(type & UCIMAP_LIST_AUTO); +} + static inline bool ucimap_is_custom(enum ucimap_type type) { @@ -172,7 +179,7 @@ ucimap_add_fixup(struct uci_map *map, union ucimap_data *data, struct uci_optmap f->name = str; f->type = om->type; f->data = data; - list_add(&f->list, &map->fixup); + list_add_tail(&f->list, &map->fixup); } static void @@ -242,6 +249,37 @@ ucimap_add_value(union ucimap_data *data, struct uci_optmap *om, struct ucimap_s } +static void +ucimap_convert_list(union ucimap_data *data, struct uci_optmap *om, struct ucimap_section_data *sd, const char *str) +{ + char *s, *p; + + s = strdup(str); + if (!s) + return; + + ucimap_add_alloc(sd, s); + + do { + while (isspace(*s)) + s++; + + if (!*s) + break; + + p = s; + while (*s && !isspace(*s)) + s++; + + if (isspace(*s)) { + *s = 0; + s++; + } + + ucimap_add_value(data, om, sd, p); + } while (*s); +} + static int ucimap_parse_options(struct uci_map *map, struct uci_sectionmap *sm, struct ucimap_section_data *sd, struct uci_section *s) { @@ -269,6 +307,8 @@ ucimap_parse_options(struct uci_map *map, struct uci_sectionmap *sm, struct ucim uci_foreach_element(&o->v.list, l) { ucimap_add_value(data, om, sd, l->name); } + } else if ((o->type == UCI_TYPE_STRING) && ucimap_is_list_auto(om->type)) { + ucimap_convert_list(data, om, sd, o->v.string); } } @@ -316,11 +356,33 @@ ucimap_parse_section(struct uci_map *map, struct uci_sectionmap *sm, struct uci_ if (strcmp(e->name, om->name) != 0) continue; - uci_foreach_element(&o->v.list, tmp) { - n_elements++; + if (o->type == UCI_TYPE_LIST) { + uci_foreach_element(&o->v.list, tmp) { + n_elements++; + } + } else if ((o->type == UCI_TYPE_STRING) && + ucimap_is_list_auto(om->type)) { + const char *data = o->v.string; + do { + while (isspace(*data)) + data++; + + if (!*data) + break; + + n_elements++; + + while (*data && !isspace(*data)) + data++; + } while (*data); + + /* for the duplicated data string */ + if (n_elements > 0) + n_alloc++; } break; } + /* add one more for the ucimap_list */ n_alloc += n_elements + 1; size = sizeof(struct ucimap_list) + n_elements * sizeof(union ucimap_data); diff --git a/ucimap.h b/ucimap.h index ccd6127..a114644 100644 --- a/ucimap.h +++ b/ucimap.h @@ -68,6 +68,11 @@ enum ucimap_type { UCIMAP_SECTION = 0x3, UCIMAP_CUSTOM = 0x4, UCIMAP_SUBTYPE = 0xf, /* subtype mask */ + + /* automatically create lists from + * options with space-separated items */ + UCIMAP_LIST_AUTO = 0x0100, + UCIMAP_FLAGS = 0xff00, /* flags mask */ }; union ucimap_data { -- 2.41.1