From: Felix Fietkau Date: Sun, 30 Aug 2009 00:51:11 +0000 (+0200) Subject: ucimap: implement format callback for custom data types X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=82a71ad8d80c1d5831916efff87cb03b77096032;p=uci.git ucimap: implement format callback for custom data types --- diff --git a/ucimap-example.c b/ucimap-example.c index 9fc71e2..baea550 100644 --- a/ucimap-example.c +++ b/ucimap-example.c @@ -58,6 +58,18 @@ network_parse_ip(void *section, struct uci_optmap *om, union ucimap_data *data, return 0; } +static int +network_format_ip(void *sction, struct uci_optmap *om, union ucimap_data *data, char **str) +{ + static char buf[16]; + unsigned char *ip = (unsigned char *) data->s; + + sprintf(buf, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); + *str = buf; + + return 0; +} + static int network_init_interface(struct uci_map *map, void *section, struct uci_section *s) { @@ -139,6 +151,7 @@ static struct my_optmap network_interface_options[] = { .type = UCIMAP_CUSTOM, .name = "ipaddr", .parse = network_parse_ip, + .format = network_format_ip, } }, { @@ -241,9 +254,9 @@ int main(int argc, char **argv) printf("New alias: %s\n", alias->name); } #if 0 - net->ipaddr = "2.3.4.5"; - ucimap_set_changed(net, &net->ipaddr); - ucimap_store_section(&network_map, pkg, net); + memcpy(net->ipaddr, "\x01\x03\x04\x05", 4); + ucimap_set_changed(&net->map, &net->ipaddr); + ucimap_store_section(&network_map, pkg, &net->map); uci_save(ctx, pkg); #endif } diff --git a/ucimap.c b/ucimap.c index d4dc05f..021c270 100644 --- a/ucimap.c +++ b/ucimap.c @@ -410,10 +410,8 @@ ucimap_set_changed(struct ucimap_section_data *sd, void *field) } int -ucimap_store_section(struct uci_map *map, struct uci_package *p, void *section) +ucimap_store_section(struct uci_map *map, struct uci_package *p, struct ucimap_section_data *sd) { - 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; @@ -434,13 +432,14 @@ ucimap_store_section(struct uci_map *map, struct uci_package *p, void *section) ucimap_foreach_option(sm, om) { union ucimap_data *data; static char buf[32]; - const char *str = NULL; + char *str = NULL; + i++; if (ucimap_is_list(om->type)) continue; data = ucimap_get_data(sd, om); - if (!TEST_BIT(sd->cmap, i)) + if (!TEST_BIT(sd->cmap, i - 1)) continue; ucimap_fill_ptr(&ptr, s, om->name); @@ -456,17 +455,32 @@ ucimap_store_section(struct uci_map *map, struct uci_package *p, void *section) sprintf(buf, "%d", !!data->b); str = buf; break; + case UCIMAP_CUSTOM: + break; default: continue; } + if (om->format) { + union ucimap_data tdata, *data; + + data = ucimap_get_data(sd, om); + if (ucimap_is_custom(om->type)) { + tdata.s = (char *)data; + data = &tdata; + } + + if (om->format(ucimap_section_ptr(sd), om, data, &str) < 0) + continue; + } + if (!str) + continue; ptr.value = str; ret = uci_set(s->package->ctx, &ptr); if (ret) return ret; - CLR_BIT(sd->cmap, i); - i++; + CLR_BIT(sd->cmap, i - 1); } return 0; diff --git a/ucimap.h b/ucimap.h index 921ab4e..fc34090 100644 --- a/ucimap.h +++ b/ucimap.h @@ -133,6 +133,7 @@ struct uci_optmap { const char *name; enum ucimap_type type; int (*parse)(void *section, struct uci_optmap *om, union ucimap_data *data, const char *string); + int (*format)(void *section, struct uci_optmap *om, union ucimap_data *data, char **string); union { struct { int base; @@ -154,6 +155,6 @@ struct ucimap_list { extern int ucimap_init(struct uci_map *map); extern void ucimap_cleanup(struct uci_map *map); 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 int ucimap_store_section(struct uci_map *map, struct uci_package *p, struct ucimap_section_data *sd); extern void ucimap_parse(struct uci_map *map, struct uci_package *pkg);