1 /* 2 * ucimap.h - Library for the Unified Configuration Interface 3 * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License version 2.1 7 * as published by the Free Software Foundation 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU Lesser General Public License for more details. 13 */ 14 15 /* 16 * This file contains ucimap, an API for mapping UCI to C data structures 17 */ 18 19 #ifndef __UCIMAP_H 20 #define __UCIMAP_H 21 22 #include <stdbool.h> 23 #include "uci.h" 24 25 #ifndef ARRAY_SIZE 26 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 27 #endif 28 29 #define BITFIELD_SIZE(_fields) (((_fields) / 8) + 1) 30 31 #define CLR_BIT(_name, _bit) do { \ 32 _name[(_bit) / 8] &= ~(1 << ((_bit) % 8)); \ 33 } while (0) 34 35 #define SET_BIT(_name, _bit) do { \ 36 _name[(_bit) / 8] |= (1 << ((_bit) % 8)); \ 37 } while (0) 38 39 #define TEST_BIT(_name, _bit) \ 40 (_name[(_bit) / 8] & (1 << ((_bit) % 8))) 41 42 #ifndef __GNUC__ 43 44 #define __optmap_gen_type(_type, _field) -1 45 46 #ifndef likely 47 #define likely(_expr) !!(_expr) 48 #endif 49 50 #ifndef unlikely 51 #define unlikely(_expr) !!(_expr) 52 #endif 53 54 #else /* __GNUC__ */ 55 56 #define __compatible(_type, _field, _newtype) \ 57 __builtin_types_compatible_p(typeof(&(((_type *)0)->_field)), _newtype *) 58 59 #define __list_compatible(_type, _field, __val, __else) \ 60 __builtin_choose_expr(__compatible(_type, _field, struct ucimap_list *), __val, __else) 61 62 #define __int_compatible(_type, _field, __val, __else) \ 63 __builtin_choose_expr(__compatible(_type, _field, int), __val, \ 64 __builtin_choose_expr(__compatible(_type, _field, unsigned int), __val, \ 65 __else)) 66 67 #define __string_compatible(_type, _field, __val, __else) \ 68 __builtin_choose_expr(__compatible(_type, _field, char *), __val, \ 69 __builtin_choose_expr(__compatible(_type, _field, unsigned char *), __val, \ 70 __builtin_choose_expr(__compatible(_type, _field, const char *), __val, \ 71 __builtin_choose_expr(__compatible(_type, _field, const unsigned char *), __val, \ 72 __else)))) 73 74 #define __bool_compatible(_type, _field, __val, __else) \ 75 __builtin_choose_expr(__compatible(_type, _field, bool), __val, __else) 76 77 78 #define __optmap_gen_type(_type, _field) \ 79 __list_compatible(_type, _field, UCIMAP_LIST, \ 80 __int_compatible(_type, _field, UCIMAP_INT, \ 81 __string_compatible(_type, _field, UCIMAP_STRING, \ 82 __bool_compatible(_type, _field, UCIMAP_BOOL, \ 83 -1)))) 84 85 #ifndef likely 86 #define likely(x) __builtin_expect(!!(x), 1) 87 #endif 88 89 #ifndef unlikely 90 #define unlikely(x) __builtin_expect(!!(x), 0) 91 #endif 92 93 #endif /* __GNUC__ */ 94 95 #define UCIMAP_OPTION(_type, _field) \ 96 .name = #_field, \ 97 .offset = offsetof(_type, _field), \ 98 .detected_type = __optmap_gen_type(_type, _field), \ 99 .type_name = #_type 100 101 102 #define UCIMAP_SECTION(_name, _field) \ 103 .alloc_len = sizeof(_name), \ 104 .smap_offset = offsetof(_name, _field), \ 105 .type_name = #_name 106 107 struct uci_sectionmap; 108 struct uci_optmap; 109 110 struct ucimap_list; 111 struct ucimap_fixup; 112 struct ucimap_alloc; 113 struct ucimap_alloc_custom; 114 struct ucimap_section_data; 115 116 struct uci_map { 117 struct uci_sectionmap **sections; 118 unsigned int n_sections; 119 bool parsed; 120 void *priv; 121 122 /* private */ 123 struct ucimap_fixup *fixup; 124 struct ucimap_fixup **fixup_tail; 125 struct ucimap_section_data *sdata; 126 struct ucimap_section_data *pending; 127 struct ucimap_section_data **sdata_tail; 128 }; 129 130 enum ucimap_type { 131 /* types */ 132 UCIMAP_SIMPLE = 0x00, 133 UCIMAP_LIST = 0x10, 134 UCIMAP_TYPE = 0xf0, /* type mask */ 135 136 /* subtypes */ 137 UCIMAP_CUSTOM = 0x0, 138 UCIMAP_STRING = 0x1, 139 UCIMAP_BOOL = 0x2, 140 UCIMAP_INT = 0x3, 141 UCIMAP_SECTION = 0x4, 142 UCIMAP_SUBTYPE = 0xf, /* subtype mask */ 143 144 /* automatically create lists from 145 * options with space-separated items */ 146 UCIMAP_LIST_AUTO = 0x0100, 147 UCIMAP_FLAGS = 0xff00, /* flags mask */ 148 }; 149 150 union ucimap_data { 151 int i; 152 bool b; 153 char *s; 154 void *ptr; 155 void **data; 156 struct ucimap_list *list; 157 }; 158 159 struct ucimap_section_data { 160 struct uci_map *map; 161 struct uci_sectionmap *sm; 162 const char *section_name; 163 164 /* map for changed fields */ 165 unsigned char *cmap; 166 bool done; 167 168 /* internal */ 169 struct ucimap_section_data *next, **ref; 170 struct ucimap_alloc *allocmap; 171 struct ucimap_alloc_custom *alloc_custom; 172 unsigned int allocmap_len; 173 unsigned int alloc_custom_len; 174 }; 175 176 struct uci_sectionmap { 177 /* type string for the uci section */ 178 const char *type; 179 180 /* length of the struct to map into, filled in by macro */ 181 unsigned int alloc_len; 182 183 /* sectionmap offset, filled in by macro */ 184 unsigned int smap_offset; 185 186 /* return a pointer to the section map data (allocate if necessary) */ 187 struct ucimap_section_data *(*alloc)(struct uci_map *map, 188 struct uci_sectionmap *sm, struct uci_section *s); 189 190 /* give the caller time to initialize the preallocated struct */ 191 int (*init)(struct uci_map *map, void *section, struct uci_section *s); 192 193 /* pass the fully processed struct to the callback after the section end */ 194 int (*add)(struct uci_map *map, void *section); 195 196 /* let the callback clean up its own stuff in the section */ 197 int (*free)(struct uci_map *map, void *section); 198 199 /* list of option mappings for this section */ 200 struct uci_optmap *options; 201 unsigned int n_options; 202 unsigned int options_size; 203 204 /* internal */ 205 const char *type_name; 206 }; 207 208 struct uci_optmap { 209 unsigned int offset; 210 const char *name; 211 enum ucimap_type type; 212 int (*parse)(void *section, struct uci_optmap *om, union ucimap_data *data, const char *string); 213 int (*format)(void *section, struct uci_optmap *om, union ucimap_data *data, char **string); 214 void (*free)(void *section, struct uci_optmap *om, void *ptr); 215 union { 216 struct { 217 int base; 218 int min; 219 int max; 220 } i; 221 struct { 222 int maxlen; 223 } s; 224 struct uci_sectionmap *sm; 225 } data; 226 227 /* internal */ 228 int detected_type; 229 const char *type_name; 230 }; 231 232 struct ucimap_list { 233 int n_items; 234 int size; 235 union ucimap_data item[]; 236 }; 237 238 /** 239 * ucimap_init: initialize the ucimap data structure 240 * @map: ucimap data structure 241 * 242 * you must call this function before doing any other ucimap operation 243 * on the data structure 244 */ 245 extern int ucimap_init(struct uci_map *map); 246 247 /** 248 * ucimap_cleanup: clean up all allocated data from ucimap 249 * @map: ucimap data structure 250 */ 251 extern void ucimap_cleanup(struct uci_map *map); 252 253 /** 254 * ucimap_parse: parse all sections in an uci package using ucimap 255 * @map: ucimap data structure 256 * @pkg: uci package 257 */ 258 extern void ucimap_parse(struct uci_map *map, struct uci_package *pkg); 259 260 /** 261 * ucimap_set_changed: mark a field in a custom data structure as changed 262 * @sd: pointer to the ucimap section data 263 * @field: pointer to the field inside the custom data structure 264 * 265 * @sd must be set to the section data inside the data structure that contains @field 266 */ 267 extern void ucimap_set_changed(struct ucimap_section_data *sd, void *field); 268 269 /** 270 * ucimap_store_section: copy all changed data from the converted data structure to uci 271 * @map: ucimap data structure 272 * @p: uci package to store the changes in 273 * @sd: pointer to the ucimap section data 274 * 275 * changes are not saved or committed automatically 276 */ 277 extern int ucimap_store_section(struct uci_map *map, struct uci_package *p, struct ucimap_section_data *sd); 278 279 /** 280 * ucimap_parse_section: parse a single section 281 * @map: ucimap data structure 282 * @sm: uci section map 283 * @sd: pointer to the ucimap section data 284 * @s: pointer to the uci section 285 * 286 * this function overwrites the ucimap section data, do not use on a section 287 * that has been parsed already 288 */ 289 extern int ucimap_parse_section(struct uci_map *map, struct uci_sectionmap *sm, struct ucimap_section_data *sd, struct uci_section *s); 290 291 /** 292 * ucimap_free_section: free a data structure for a converted section 293 * @map: ucimap data structure 294 * @sd: pointer to the ucimap section data 295 * 296 * this function will clean up all data that was allocated by ucimap for this section. 297 * all references to the data structure become invalid 298 */ 299 extern void ucimap_free_section(struct uci_map *map, struct ucimap_section_data *sd); 300 301 /** 302 * ucimap_resize_list: allocate or resize a uci list 303 * @sd: pointer to the ucimap section data 304 * @list: pointer to the list field 305 * @items: new size 306 * 307 * @sd must point to the data structure that contains @list. 308 * @list must point to the field containing a pointer to the list, not the list directly 309 * the memory allocated for this list is tracked for the section and freed automatically 310 */ 311 extern int ucimap_resize_list(struct ucimap_section_data *sd, struct ucimap_list **list, int items); 312 313 /** 314 * ucimap_free_item: free the allocated memory for a data structure member 315 * @sd: pointer to the ucimap section data 316 * @item: pointer to the field inside the data structure 317 * 318 * @sd must point to the data structure that contains @item. 319 * @item must point to the field containing a pointer to the allocated item 320 */ 321 extern void ucimap_free_item(struct ucimap_section_data *sd, void *item); 322 323 #endif 324
This page was automatically generated by LXR 0.3.1. • OpenWrt