2 * Copyright (c) 2003 Poul-Henning Kamp
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The names of the authors may not be used to endorse or promote
14 * products derived from this software without specific prior written
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 #include <sys/queue.h>
44 #include <sys/sysctl.h>
53 struct gprovider *provider;
54 struct gconsumer *consumer;
56 struct sbuf *sbuf[20];
62 StartElement(void *userData, const char *name, const char **attr)
71 mt->sbuf[mt->level] = sbuf_new_auto();
74 for (i = 0; attr[i] != NULL; i += 2) {
75 if (!strcmp(attr[i], "id")) {
76 id = (void *)strtoul(attr[i + 1], NULL, 0);
78 } else if (!strcmp(attr[i], "ref")) {
79 ref = (void *)strtoul(attr[i + 1], NULL, 0);
81 printf("%*.*s[%s = %s]\n",
82 mt->level + 1, mt->level + 1, "",
83 attr[i], attr[i + 1]);
85 if (!strcmp(name, "class") && mt->class == NULL) {
86 mt->class = calloc(1, sizeof *mt->class);
87 if (mt->class == NULL) {
88 warn("Cannot allocate memory during processing of '%s' "
92 mt->class->lg_id = id;
93 LIST_INSERT_HEAD(&mt->mesh->lg_class, mt->class, lg_class);
94 LIST_INIT(&mt->class->lg_geom);
95 LIST_INIT(&mt->class->lg_config);
98 if (!strcmp(name, "geom") && mt->geom == NULL) {
99 mt->geom = calloc(1, sizeof *mt->geom);
100 if (mt->geom == NULL) {
101 warn("Cannot allocate memory during processing of '%s' "
105 mt->geom->lg_id = id;
106 LIST_INSERT_HEAD(&mt->class->lg_geom, mt->geom, lg_geom);
107 LIST_INIT(&mt->geom->lg_provider);
108 LIST_INIT(&mt->geom->lg_consumer);
109 LIST_INIT(&mt->geom->lg_config);
112 if (!strcmp(name, "class") && mt->geom != NULL) {
113 mt->geom->lg_class = ref;
116 if (!strcmp(name, "consumer") && mt->consumer == NULL) {
117 mt->consumer = calloc(1, sizeof *mt->consumer);
118 if (mt->consumer == NULL) {
119 warn("Cannot allocate memory during processing of '%s' "
123 mt->consumer->lg_id = id;
124 LIST_INSERT_HEAD(&mt->geom->lg_consumer, mt->consumer,
126 LIST_INIT(&mt->consumer->lg_config);
129 if (!strcmp(name, "geom") && mt->consumer != NULL) {
130 mt->consumer->lg_geom = ref;
133 if (!strcmp(name, "provider") && mt->consumer != NULL) {
134 mt->consumer->lg_provider = ref;
137 if (!strcmp(name, "provider") && mt->provider == NULL) {
138 mt->provider = calloc(1, sizeof *mt->provider);
139 if (mt->provider == NULL) {
140 warn("Cannot allocate memory during processing of '%s' "
144 mt->provider->lg_id = id;
145 LIST_INSERT_HEAD(&mt->geom->lg_provider, mt->provider,
147 LIST_INIT(&mt->provider->lg_consumers);
148 LIST_INIT(&mt->provider->lg_config);
151 if (!strcmp(name, "geom") && mt->provider != NULL) {
152 mt->provider->lg_geom = ref;
155 if (!strcmp(name, "config")) {
156 if (mt->provider != NULL) {
157 mt->config = &mt->provider->lg_config;
160 if (mt->consumer != NULL) {
161 mt->config = &mt->consumer->lg_config;
164 if (mt->geom != NULL) {
165 mt->config = &mt->geom->lg_config;
168 if (mt->class != NULL) {
169 mt->config = &mt->class->lg_config;
176 EndElement(void *userData, const char *name)
183 sbuf_finish(mt->sbuf[mt->level]);
184 p = strdup(sbuf_data(mt->sbuf[mt->level]));
186 warn("Cannot allocate memory during processing of '%s' "
190 sbuf_delete(mt->sbuf[mt->level]);
191 mt->sbuf[mt->level] = NULL;
193 if (strlen(p) == 0) {
198 if (!strcmp(name, "name")) {
199 if (mt->provider != NULL) {
200 mt->provider->lg_name = p;
202 } else if (mt->geom != NULL) {
203 mt->geom->lg_name = p;
205 } else if (mt->class != NULL) {
206 mt->class->lg_name = p;
210 if (!strcmp(name, "rank") && mt->geom != NULL) {
211 mt->geom->lg_rank = strtoul(p, NULL, 0);
215 if (!strcmp(name, "mode") && mt->provider != NULL) {
216 mt->provider->lg_mode = p;
219 if (!strcmp(name, "mode") && mt->consumer != NULL) {
220 mt->consumer->lg_mode = p;
223 if (!strcmp(name, "mediasize") && mt->provider != NULL) {
224 mt->provider->lg_mediasize = strtoumax(p, NULL, 0);
228 if (!strcmp(name, "sectorsize") && mt->provider != NULL) {
229 mt->provider->lg_sectorsize = strtoul(p, NULL, 0);
234 if (!strcmp(name, "config")) {
239 if (mt->config != NULL) {
240 gc = calloc(1, sizeof *gc);
242 warn("Cannot allocate memory during processing of '%s' "
246 gc->lg_name = strdup(name);
247 if (gc->lg_name == NULL) {
248 warn("Cannot allocate memory during processing of '%s' "
253 LIST_INSERT_HEAD(mt->config, gc, lg_config);
258 printf("Unexpected XML: name=%s data=\"%s\"\n", name, p);
262 if (!strcmp(name, "consumer") && mt->consumer != NULL) {
266 if (!strcmp(name, "provider") && mt->provider != NULL) {
270 if (!strcmp(name, "geom") && mt->consumer != NULL) {
273 if (!strcmp(name, "geom") && mt->provider != NULL) {
276 if (!strcmp(name, "geom") && mt->geom != NULL) {
280 if (!strcmp(name, "class") && mt->geom != NULL) {
283 if (!strcmp(name, "class") && mt->class != NULL) {
290 CharData(void *userData , const XML_Char *s , int len)
299 while (isspace(*b) && b < e)
301 while (isspace(*e) && e > b)
303 if (e != b || (*b && !isspace(*b)))
304 sbuf_bcat(mt->sbuf[mt->level], b, e - b + 1);
308 geom_lookupid(struct gmesh *gmp, const void *id)
312 for (gip = gmp->lg_ident; gip->lg_id != NULL; gip++)
313 if (gip->lg_id == id)
319 geom_xml2tree(struct gmesh *gmp, char *p)
325 struct gprovider *pr;
326 struct gconsumer *co;
329 memset(gmp, 0, sizeof *gmp);
330 LIST_INIT(&gmp->lg_class);
331 parser = XML_ParserCreate(NULL);
332 mt = calloc(1, sizeof *mt);
336 XML_SetUserData(parser, mt);
337 XML_SetElementHandler(parser, StartElement, EndElement);
338 XML_SetCharacterDataHandler(parser, CharData);
339 i = XML_Parse(parser, p, strlen(p), 1);
342 XML_ParserFree(parser);
343 gmp->lg_ident = calloc(sizeof *gmp->lg_ident, mt->nident + 1);
344 if (gmp->lg_ident == NULL)
348 /* Collect all identifiers */
349 LIST_FOREACH(cl, &gmp->lg_class, lg_class) {
350 gmp->lg_ident[i].lg_id = cl->lg_id;
351 gmp->lg_ident[i].lg_ptr = cl;
352 gmp->lg_ident[i].lg_what = ISCLASS;
354 LIST_FOREACH(ge, &cl->lg_geom, lg_geom) {
355 gmp->lg_ident[i].lg_id = ge->lg_id;
356 gmp->lg_ident[i].lg_ptr = ge;
357 gmp->lg_ident[i].lg_what = ISGEOM;
359 LIST_FOREACH(pr, &ge->lg_provider, lg_provider) {
360 gmp->lg_ident[i].lg_id = pr->lg_id;
361 gmp->lg_ident[i].lg_ptr = pr;
362 gmp->lg_ident[i].lg_what = ISPROVIDER;
365 LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) {
366 gmp->lg_ident[i].lg_id = co->lg_id;
367 gmp->lg_ident[i].lg_ptr = co;
368 gmp->lg_ident[i].lg_what = ISCONSUMER;
373 /* Substitute all identifiers */
374 LIST_FOREACH(cl, &gmp->lg_class, lg_class) {
375 LIST_FOREACH(ge, &cl->lg_geom, lg_geom) {
377 geom_lookupid(gmp, ge->lg_class)->lg_ptr;
378 LIST_FOREACH(pr, &ge->lg_provider, lg_provider) {
380 geom_lookupid(gmp, pr->lg_geom)->lg_ptr;
382 LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) {
384 geom_lookupid(gmp, co->lg_geom)->lg_ptr;
385 if (co->lg_provider != NULL) {
388 co->lg_provider)->lg_ptr;
390 &co->lg_provider->lg_consumers,
400 geom_gettree(struct gmesh *gmp)
408 error = geom_xml2tree(gmp, p);
414 delete_config(struct gconf *gp)
422 LIST_REMOVE(cf, lg_config);
430 geom_deletetree(struct gmesh *gmp)
434 struct gprovider *pr;
435 struct gconsumer *co;
438 gmp->lg_ident = NULL;
440 cl = LIST_FIRST(&gmp->lg_class);
443 LIST_REMOVE(cl, lg_class);
444 delete_config(&cl->lg_config);
445 if (cl->lg_name) free(cl->lg_name);
447 ge = LIST_FIRST(&cl->lg_geom);
450 LIST_REMOVE(ge, lg_geom);
451 delete_config(&ge->lg_config);
452 if (ge->lg_name) free(ge->lg_name);
454 pr = LIST_FIRST(&ge->lg_provider);
457 LIST_REMOVE(pr, lg_provider);
458 delete_config(&pr->lg_config);
459 if (pr->lg_name) free(pr->lg_name);
460 if (pr->lg_mode) free(pr->lg_mode);
464 co = LIST_FIRST(&ge->lg_consumer);
467 LIST_REMOVE(co, lg_consumer);
468 delete_config(&co->lg_config);
469 if (co->lg_mode) free(co->lg_mode);