X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=ucimap.c;h=b1ba8534b4ada7a36f0e03dda23b951ca916a471;hb=477c19a7223f662ab03d0a077ac6454ab4442ff3;hp=7dba62afa6b7e077fa2e52cd16d96fb70bc83f1d;hpb=237a389754d974d579d4c650d65a404b835de5c6;p=uci.git 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);