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];
64 StartElement(void *userData, const char *name, const char **attr)
73 mt->sbuf[mt->level] = sbuf_new_auto();
76 for (i = 0; attr[i] != NULL; i += 2) {
77 if (!strcmp(attr[i], "id")) {
78 id = (void *)strtoul(attr[i + 1], NULL, 0);
80 } else if (!strcmp(attr[i], "ref")) {
81 ref = (void *)strtoul(attr[i + 1], NULL, 0);
83 printf("%*.*s[%s = %s]\n",
84 mt->level + 1, mt->level + 1, "",
85 attr[i], attr[i + 1]);
87 if (!strcmp(name, "class") && mt->class == NULL) {
88 mt->class = calloc(1, sizeof *mt->class);
89 if (mt->class == NULL) {
91 XML_StopParser(mt->parser, 0);
92 warn("Cannot allocate memory during processing of '%s' "
96 mt->class->lg_id = id;
97 LIST_INSERT_HEAD(&mt->mesh->lg_class, mt->class, lg_class);
98 LIST_INIT(&mt->class->lg_geom);
99 LIST_INIT(&mt->class->lg_config);
102 if (!strcmp(name, "geom") && mt->geom == NULL) {
103 mt->geom = calloc(1, sizeof *mt->geom);
104 if (mt->geom == NULL) {
106 XML_StopParser(mt->parser, 0);
107 warn("Cannot allocate memory during processing of '%s' "
111 mt->geom->lg_id = id;
112 LIST_INSERT_HEAD(&mt->class->lg_geom, mt->geom, lg_geom);
113 LIST_INIT(&mt->geom->lg_provider);
114 LIST_INIT(&mt->geom->lg_consumer);
115 LIST_INIT(&mt->geom->lg_config);
118 if (!strcmp(name, "class") && mt->geom != NULL) {
119 mt->geom->lg_class = ref;
122 if (!strcmp(name, "consumer") && mt->consumer == NULL) {
123 mt->consumer = calloc(1, sizeof *mt->consumer);
124 if (mt->consumer == NULL) {
126 XML_StopParser(mt->parser, 0);
127 warn("Cannot allocate memory during processing of '%s' "
131 mt->consumer->lg_id = id;
132 LIST_INSERT_HEAD(&mt->geom->lg_consumer, mt->consumer,
134 LIST_INIT(&mt->consumer->lg_config);
137 if (!strcmp(name, "geom") && mt->consumer != NULL) {
138 mt->consumer->lg_geom = ref;
141 if (!strcmp(name, "provider") && mt->consumer != NULL) {
142 mt->consumer->lg_provider = ref;
145 if (!strcmp(name, "provider") && mt->provider == NULL) {
146 mt->provider = calloc(1, sizeof *mt->provider);
147 if (mt->provider == NULL) {
149 XML_StopParser(mt->parser, 0);
150 warn("Cannot allocate memory during processing of '%s' "
154 mt->provider->lg_id = id;
155 LIST_INSERT_HEAD(&mt->geom->lg_provider, mt->provider,
157 LIST_INIT(&mt->provider->lg_consumers);
158 LIST_INIT(&mt->provider->lg_config);
161 if (!strcmp(name, "geom") && mt->provider != NULL) {
162 mt->provider->lg_geom = ref;
165 if (!strcmp(name, "config")) {
166 if (mt->provider != NULL) {
167 mt->config = &mt->provider->lg_config;
170 if (mt->consumer != NULL) {
171 mt->config = &mt->consumer->lg_config;
174 if (mt->geom != NULL) {
175 mt->config = &mt->geom->lg_config;
178 if (mt->class != NULL) {
179 mt->config = &mt->class->lg_config;
186 EndElement(void *userData, const char *name)
195 if (sbuf_finish(mt->sbuf[mt->level]) == 0)
196 p = strdup(sbuf_data(mt->sbuf[mt->level]));
197 sbuf_delete(mt->sbuf[mt->level]);
198 mt->sbuf[mt->level] = NULL;
202 XML_StopParser(mt->parser, 0);
203 warn("Cannot allocate memory during processing of '%s' "
207 if (strlen(p) == 0) {
212 if (!strcmp(name, "name")) {
213 if (mt->provider != NULL) {
214 mt->provider->lg_name = p;
216 } else if (mt->geom != NULL) {
217 mt->geom->lg_name = p;
219 } else if (mt->class != NULL) {
220 mt->class->lg_name = p;
224 if (!strcmp(name, "rank") && mt->geom != NULL) {
225 mt->geom->lg_rank = strtoul(p, NULL, 0);
229 if (!strcmp(name, "mode") && mt->provider != NULL) {
230 mt->provider->lg_mode = p;
233 if (!strcmp(name, "mode") && mt->consumer != NULL) {
234 mt->consumer->lg_mode = p;
237 if (!strcmp(name, "mediasize") && mt->provider != NULL) {
238 mt->provider->lg_mediasize = strtoumax(p, NULL, 0);
242 if (!strcmp(name, "sectorsize") && mt->provider != NULL) {
243 mt->provider->lg_sectorsize = strtoul(p, NULL, 0);
247 if (!strcmp(name, "stripesize") && mt->provider != NULL) {
248 mt->provider->lg_stripesize = strtoumax(p, NULL, 0);
252 if (!strcmp(name, "stripeoffset") && mt->provider != NULL) {
253 mt->provider->lg_stripeoffset = strtoumax(p, NULL, 0);
258 if (!strcmp(name, "config")) {
264 if (mt->config != NULL || (!strcmp(name, "wither") &&
265 (mt->provider != NULL || mt->geom != NULL))) {
266 if (mt->config != NULL)
268 else if (mt->provider != NULL)
269 c = &mt->provider->lg_config;
271 c = &mt->geom->lg_config;
272 gc = calloc(1, sizeof *gc);
275 XML_StopParser(mt->parser, 0);
276 warn("Cannot allocate memory during processing of '%s' "
280 gc->lg_name = strdup(name);
281 if (gc->lg_name == NULL) {
284 XML_StopParser(mt->parser, 0);
285 warn("Cannot allocate memory during processing of '%s' "
290 LIST_INSERT_HEAD(c, gc, lg_config);
295 #if DEBUG_LIBGEOM > 0
296 printf("Unexpected XML: name=%s data=\"%s\"\n", name, p);
301 if (!strcmp(name, "consumer") && mt->consumer != NULL) {
305 if (!strcmp(name, "provider") && mt->provider != NULL) {
309 if (!strcmp(name, "geom") && mt->consumer != NULL) {
312 if (!strcmp(name, "geom") && mt->provider != NULL) {
315 if (!strcmp(name, "geom") && mt->geom != NULL) {
319 if (!strcmp(name, "class") && mt->geom != NULL) {
322 if (!strcmp(name, "class") && mt->class != NULL) {
329 CharData(void *userData , const XML_Char *s , int len)
338 while (isspace(*b) && b < e)
340 while (isspace(*e) && e > b)
342 if (e != b || (*b && !isspace(*b)))
343 sbuf_bcat(mt->sbuf[mt->level], b, e - b + 1);
347 geom_lookupid(struct gmesh *gmp, const void *id)
351 for (gip = gmp->lg_ident; gip->lg_id != NULL; gip++)
352 if (gip->lg_id == id)
358 geom_xml2tree(struct gmesh *gmp, char *p)
364 struct gprovider *pr;
365 struct gconsumer *co;
368 memset(gmp, 0, sizeof *gmp);
369 LIST_INIT(&gmp->lg_class);
370 parser = XML_ParserCreate(NULL);
373 mt = calloc(1, sizeof *mt);
375 XML_ParserFree(parser);
381 XML_SetUserData(parser, mt);
382 XML_SetElementHandler(parser, StartElement, EndElement);
383 XML_SetCharacterDataHandler(parser, CharData);
384 i = XML_Parse(parser, p, strlen(p), 1);
388 error = XML_GetErrorCode(parser) == XML_ERROR_NO_MEMORY ?
391 XML_ParserFree(parser);
396 gmp->lg_ident = calloc(sizeof *gmp->lg_ident, mt->nident + 1);
398 if (gmp->lg_ident == NULL)
401 /* Collect all identifiers */
402 LIST_FOREACH(cl, &gmp->lg_class, lg_class) {
403 gmp->lg_ident[i].lg_id = cl->lg_id;
404 gmp->lg_ident[i].lg_ptr = cl;
405 gmp->lg_ident[i].lg_what = ISCLASS;
407 LIST_FOREACH(ge, &cl->lg_geom, lg_geom) {
408 gmp->lg_ident[i].lg_id = ge->lg_id;
409 gmp->lg_ident[i].lg_ptr = ge;
410 gmp->lg_ident[i].lg_what = ISGEOM;
412 LIST_FOREACH(pr, &ge->lg_provider, lg_provider) {
413 gmp->lg_ident[i].lg_id = pr->lg_id;
414 gmp->lg_ident[i].lg_ptr = pr;
415 gmp->lg_ident[i].lg_what = ISPROVIDER;
418 LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) {
419 gmp->lg_ident[i].lg_id = co->lg_id;
420 gmp->lg_ident[i].lg_ptr = co;
421 gmp->lg_ident[i].lg_what = ISCONSUMER;
426 /* Substitute all identifiers */
427 LIST_FOREACH(cl, &gmp->lg_class, lg_class) {
428 LIST_FOREACH(ge, &cl->lg_geom, lg_geom) {
430 geom_lookupid(gmp, ge->lg_class)->lg_ptr;
431 LIST_FOREACH(pr, &ge->lg_provider, lg_provider) {
433 geom_lookupid(gmp, pr->lg_geom)->lg_ptr;
435 LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) {
437 geom_lookupid(gmp, co->lg_geom)->lg_ptr;
438 if (co->lg_provider != NULL) {
441 co->lg_provider)->lg_ptr;
443 &co->lg_provider->lg_consumers,
453 geom_gettree(struct gmesh *gmp)
461 error = geom_xml2tree(gmp, p);
467 delete_config(struct gconf *gp)
475 LIST_REMOVE(cf, lg_config);
483 geom_deletetree(struct gmesh *gmp)
487 struct gprovider *pr;
488 struct gconsumer *co;
491 gmp->lg_ident = NULL;
493 cl = LIST_FIRST(&gmp->lg_class);
496 LIST_REMOVE(cl, lg_class);
497 delete_config(&cl->lg_config);
498 if (cl->lg_name) free(cl->lg_name);
500 ge = LIST_FIRST(&cl->lg_geom);
503 LIST_REMOVE(ge, lg_geom);
504 delete_config(&ge->lg_config);
505 if (ge->lg_name) free(ge->lg_name);
507 pr = LIST_FIRST(&ge->lg_provider);
510 LIST_REMOVE(pr, lg_provider);
511 delete_config(&pr->lg_config);
512 if (pr->lg_name) free(pr->lg_name);
513 if (pr->lg_mode) free(pr->lg_mode);
517 co = LIST_FIRST(&ge->lg_consumer);
520 LIST_REMOVE(co, lg_consumer);
521 delete_config(&co->lg_config);
522 if (co->lg_mode) free(co->lg_mode);