X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuci.git;a=blobdiff_plain;f=ucimap.c;h=9853e7e89fb337207cd122d486da68ce1c912722;hp=b477264b23dca1b905784bddb8fd6d32de2d9ad0;hb=796bfd3cf5f2540674a78825b101691ce43e1069;hpb=c81b25ffd34632dc6ac56fe61faaf44eca822259 diff --git a/ucimap.c b/ucimap.c index b477264..9853e7e 100644 --- a/ucimap.c +++ b/ucimap.c @@ -59,23 +59,13 @@ struct ucimap_fixup { static inline bool ucimap_is_alloc(enum ucimap_type type) { - switch(type & UCIMAP_SUBTYPE) { - case UCIMAP_STRING: - return true; - default: - return false; - } + return (type & UCIMAP_SUBTYPE) == UCIMAP_STRING; } static inline bool ucimap_is_fixup(enum ucimap_type type) { - switch(type & UCIMAP_SUBTYPE) { - case UCIMAP_SECTION: - return true; - default: - return false; - } + return (type & UCIMAP_SUBTYPE) == UCIMAP_SECTION; } static inline bool @@ -201,11 +191,24 @@ ucimap_find_section(struct uci_map *map, struct ucimap_fixup *f) return NULL; } +static union ucimap_data * +ucimap_list_append(struct ucimap_list *list) +{ + if (unlikely(list->size <= list->n_items)) { + /* should not happen */ + DPRINTF("ERROR: overflow while filling a list (size=%d)\n", list->size); + return NULL; + } + return &list->item[list->n_items++]; +} + + static bool ucimap_handle_fixup(struct uci_map *map, struct ucimap_fixup *f) { void *ptr = ucimap_find_section(map, f); struct ucimap_list *list; + union ucimap_data *data; if (!ptr) return false; @@ -216,7 +219,11 @@ ucimap_handle_fixup(struct uci_map *map, struct ucimap_fixup *f) break; case UCIMAP_LIST: list = f->data->list; - list->item[list->n_items++].ptr = ptr; + data = ucimap_list_append(f->data->list); + if (!data) + return false; + + data->ptr = ptr; break; } return true; @@ -340,13 +347,9 @@ ucimap_add_value(union ucimap_data *data, struct uci_optmap *om, struct ucimap_s int val; if (ucimap_is_list(om->type) && !ucimap_is_fixup(om->type)) { - if (unlikely(data->list->size <= data->list->n_items)) { - /* should not happen */ - DPRINTF("ERROR: overflow while filling a list\n"); + data = ucimap_list_append(data->list); + if (!data) return; - } - - data = &data->list->item[data->list->n_items++]; } switch(om->type & UCIMAP_SUBTYPE) { @@ -391,11 +394,10 @@ ucimap_add_value(union ucimap_data *data, struct uci_optmap *om, struct ucimap_s ucimap_add_fixup(sd, data, om, str); return; case UCIMAP_CUSTOM: - tdata.s = (char *) data; break; } if (om->parse) { - if (om->parse(ucimap_section_ptr(sd), om, &tdata, str) < 0) + if (om->parse(ucimap_section_ptr(sd), om, data, str) < 0) return; if (ucimap_is_custom(om->type) && om->free) { if (tdata.ptr != data->ptr) @@ -602,6 +604,7 @@ ucimap_parse_section(struct uci_map *map, struct uci_sectionmap *sm, struct ucim union ucimap_data *data; struct uci_element *e; int n_elements = 0; + int n_elements_alloc = 0; int n_elements_custom = 0; int size; @@ -615,7 +618,8 @@ ucimap_parse_section(struct uci_map *map, struct uci_sectionmap *sm, struct ucim if (o->type == UCI_TYPE_LIST) { uci_foreach_element(&o->v.list, tmp) { - ucimap_count_alloc(om, &n_elements, &n_elements_custom); + ucimap_count_alloc(om, &n_elements_alloc, &n_elements_custom); + n_elements++; } } else if ((o->type == UCI_TYPE_STRING) && ucimap_is_list_auto(om->type)) { @@ -628,7 +632,7 @@ ucimap_parse_section(struct uci_map *map, struct uci_sectionmap *sm, struct ucim break; n_elements++; - ucimap_count_alloc(om, &n_elements, &n_elements_custom); + ucimap_count_alloc(om, &n_elements_alloc, &n_elements_custom); while (*data && !isspace(*data)) data++; @@ -641,7 +645,7 @@ ucimap_parse_section(struct uci_map *map, struct uci_sectionmap *sm, struct ucim break; } /* add one more for the ucimap_list */ - n_alloc += n_elements + 1; + n_alloc += n_elements_alloc + 1; n_alloc_custom += n_elements_custom; size = sizeof(struct ucimap_list) + n_elements * sizeof(union ucimap_data); @@ -650,8 +654,8 @@ ucimap_parse_section(struct uci_map *map, struct uci_sectionmap *sm, struct ucim if (!data->list) goto error_mem; - data->list->size = n_elements; memset(data->list, 0, size); + data->list->size = n_elements; } else { ucimap_count_alloc(om, &n_alloc, &n_alloc_custom); } @@ -780,13 +784,6 @@ ucimap_data_to_string(struct ucimap_section_data *sd, struct uci_optmap *om, uni } if (om->format) { - union ucimap_data tdata; - - if (ucimap_is_custom(om->type)) { - tdata.s = (char *)data; - data = &tdata; - } - if (om->format(ucimap_section_ptr(sd), om, data, &str) < 0) return NULL;