2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2003 Poul-Henning Kamp
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The names of the authors may not be used to endorse or promote
16 * products derived from this software without specific prior written
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 #include <sys/queue.h>
46 #include <sys/sysctl.h>
55 struct gprovider *provider;
56 struct gconsumer *consumer;
58 struct sbuf *sbuf[20];
66 StartElement(void *userData, const char *name, const char **attr)
75 mt->sbuf[mt->level] = sbuf_new_auto();
78 for (i = 0; attr[i] != NULL; i += 2) {
79 if (!strcmp(attr[i], "id")) {
80 id = (void *)strtoul(attr[i + 1], NULL, 0);
82 } else if (!strcmp(attr[i], "ref")) {
83 ref = (void *)strtoul(attr[i + 1], NULL, 0);
85 printf("%*.*s[%s = %s]\n",
86 mt->level + 1, mt->level + 1, "",
87 attr[i], attr[i + 1]);
89 if (!strcmp(name, "class") && mt->class == NULL) {
90 mt->class = calloc(1, sizeof *mt->class);
91 if (mt->class == NULL) {
93 XML_StopParser(mt->parser, 0);
94 warn("Cannot allocate memory during processing of '%s' "
98 mt->class->lg_id = id;
99 LIST_INSERT_HEAD(&mt->mesh->lg_class, mt->class, lg_class);
100 LIST_INIT(&mt->class->lg_geom);
101 LIST_INIT(&mt->class->lg_config);
104 if (!strcmp(name, "geom") && mt->geom == NULL) {
105 mt->geom = calloc(1, sizeof *mt->geom);
106 if (mt->geom == NULL) {
108 XML_StopParser(mt->parser, 0);
109 warn("Cannot allocate memory during processing of '%s' "
113 mt->geom->lg_id = id;
114 LIST_INSERT_HEAD(&mt->class->lg_geom, mt->geom, lg_geom);
115 LIST_INIT(&mt->geom->lg_provider);
116 LIST_INIT(&mt->geom->lg_consumer);
117 LIST_INIT(&mt->geom->lg_config);
120 if (!strcmp(name, "class") && mt->geom != NULL) {
121 mt->geom->lg_class = ref;
124 if (!strcmp(name, "consumer") && mt->consumer == NULL) {
125 mt->consumer = calloc(1, sizeof *mt->consumer);
126 if (mt->consumer == NULL) {
128 XML_StopParser(mt->parser, 0);
129 warn("Cannot allocate memory during processing of '%s' "
133 mt->consumer->lg_id = id;
134 LIST_INSERT_HEAD(&mt->geom->lg_consumer, mt->consumer,
136 LIST_INIT(&mt->consumer->lg_config);
139 if (!strcmp(name, "geom") && mt->consumer != NULL) {
140 mt->consumer->lg_geom = ref;
143 if (!strcmp(name, "provider") && mt->consumer != NULL) {
144 mt->consumer->lg_provider = ref;
147 if (!strcmp(name, "provider") && mt->provider == NULL) {
148 mt->provider = calloc(1, sizeof *mt->provider);
149 if (mt->provider == NULL) {
151 XML_StopParser(mt->parser, 0);
152 warn("Cannot allocate memory during processing of '%s' "
156 mt->provider->lg_id = id;
157 LIST_INSERT_HEAD(&mt->geom->lg_provider, mt->provider,
159 LIST_INIT(&mt->provider->lg_consumers);
160 LIST_INIT(&mt->provider->lg_config);
163 if (!strcmp(name, "geom") && mt->provider != NULL) {
164 mt->provider->lg_geom = ref;
167 if (!strcmp(name, "config")) {
168 if (mt->provider != NULL) {
169 mt->config = &mt->provider->lg_config;
172 if (mt->consumer != NULL) {
173 mt->config = &mt->consumer->lg_config;
176 if (mt->geom != NULL) {
177 mt->config = &mt->geom->lg_config;
180 if (mt->class != NULL) {
181 mt->config = &mt->class->lg_config;
188 EndElement(void *userData, const char *name)
197 if (sbuf_finish(mt->sbuf[mt->level]) == 0)
198 p = strdup(sbuf_data(mt->sbuf[mt->level]));
199 sbuf_delete(mt->sbuf[mt->level]);
200 mt->sbuf[mt->level] = NULL;
204 XML_StopParser(mt->parser, 0);
205 warn("Cannot allocate memory during processing of '%s' "
209 if (strlen(p) == 0) {
214 if (!strcmp(name, "name")) {
215 if (mt->provider != NULL) {
216 mt->provider->lg_name = p;
218 } else if (mt->geom != NULL) {
219 mt->geom->lg_name = p;
221 } else if (mt->class != NULL) {
222 mt->class->lg_name = p;
226 if (!strcmp(name, "rank") && mt->geom != NULL) {
227 mt->geom->lg_rank = strtoul(p, NULL, 0);
231 if (!strcmp(name, "mode") && mt->provider != NULL) {
232 mt->provider->lg_mode = p;
235 if (!strcmp(name, "mode") && mt->consumer != NULL) {
236 mt->consumer->lg_mode = p;
239 if (!strcmp(name, "mediasize") && mt->provider != NULL) {
240 mt->provider->lg_mediasize = strtoumax(p, NULL, 0);
244 if (!strcmp(name, "sectorsize") && mt->provider != NULL) {
245 mt->provider->lg_sectorsize = strtoul(p, NULL, 0);
249 if (!strcmp(name, "stripesize") && mt->provider != NULL) {
250 mt->provider->lg_stripesize = strtoumax(p, NULL, 0);
254 if (!strcmp(name, "stripeoffset") && mt->provider != NULL) {
255 mt->provider->lg_stripeoffset = strtoumax(p, NULL, 0);
260 if (!strcmp(name, "config")) {
266 if (mt->config != NULL || (!strcmp(name, "wither") &&
267 (mt->provider != NULL || mt->geom != NULL))) {
268 if (mt->config != NULL)
270 else if (mt->provider != NULL)
271 c = &mt->provider->lg_config;
273 c = &mt->geom->lg_config;
274 gc = calloc(1, sizeof *gc);
277 XML_StopParser(mt->parser, 0);
278 warn("Cannot allocate memory during processing of '%s' "
283 gc->lg_name = strdup(name);
284 if (gc->lg_name == NULL) {
286 XML_StopParser(mt->parser, 0);
287 warn("Cannot allocate memory during processing of '%s' "
294 LIST_INSERT_HEAD(c, gc, lg_config);
299 #if DEBUG_LIBGEOM > 0
300 printf("Unexpected XML: name=%s data=\"%s\"\n", name, p);
305 if (!strcmp(name, "consumer") && mt->consumer != NULL) {
309 if (!strcmp(name, "provider") && mt->provider != NULL) {
313 if (!strcmp(name, "geom") && mt->consumer != NULL) {
316 if (!strcmp(name, "geom") && mt->provider != NULL) {
319 if (!strcmp(name, "geom") && mt->geom != NULL) {
323 if (!strcmp(name, "class") && mt->geom != NULL) {
326 if (!strcmp(name, "class") && mt->class != NULL) {
333 CharData(void *userData , const XML_Char *s , int len)
342 while (isspace(*b) && b < e)
344 while (isspace(*e) && e > b)
346 if (e != b || (*b && !isspace(*b)))
347 sbuf_bcat(mt->sbuf[mt->level], b, e - b + 1);
351 geom_lookupid(struct gmesh *gmp, const void *id)
355 for (gip = gmp->lg_ident; gip->lg_id != NULL; gip++)
356 if (gip->lg_id == id)
362 geom_xml2tree(struct gmesh *gmp, char *p)
368 struct gprovider *pr;
369 struct gconsumer *co;
372 memset(gmp, 0, sizeof *gmp);
373 LIST_INIT(&gmp->lg_class);
374 parser = XML_ParserCreate(NULL);
377 mt = calloc(1, sizeof *mt);
379 XML_ParserFree(parser);
385 XML_SetUserData(parser, mt);
386 XML_SetElementHandler(parser, StartElement, EndElement);
387 XML_SetCharacterDataHandler(parser, CharData);
388 i = XML_Parse(parser, p, strlen(p), 1);
392 error = XML_GetErrorCode(parser) == XML_ERROR_NO_MEMORY ?
395 XML_ParserFree(parser);
400 gmp->lg_ident = calloc(sizeof *gmp->lg_ident, mt->nident + 1);
402 if (gmp->lg_ident == NULL)
405 /* Collect all identifiers */
406 LIST_FOREACH(cl, &gmp->lg_class, lg_class) {
407 gmp->lg_ident[i].lg_id = cl->lg_id;
408 gmp->lg_ident[i].lg_ptr = cl;
409 gmp->lg_ident[i].lg_what = ISCLASS;
411 LIST_FOREACH(ge, &cl->lg_geom, lg_geom) {
412 gmp->lg_ident[i].lg_id = ge->lg_id;
413 gmp->lg_ident[i].lg_ptr = ge;
414 gmp->lg_ident[i].lg_what = ISGEOM;
416 LIST_FOREACH(pr, &ge->lg_provider, lg_provider) {
417 gmp->lg_ident[i].lg_id = pr->lg_id;
418 gmp->lg_ident[i].lg_ptr = pr;
419 gmp->lg_ident[i].lg_what = ISPROVIDER;
422 LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) {
423 gmp->lg_ident[i].lg_id = co->lg_id;
424 gmp->lg_ident[i].lg_ptr = co;
425 gmp->lg_ident[i].lg_what = ISCONSUMER;
430 /* Substitute all identifiers */
431 LIST_FOREACH(cl, &gmp->lg_class, lg_class) {
432 LIST_FOREACH(ge, &cl->lg_geom, lg_geom) {
434 geom_lookupid(gmp, ge->lg_class)->lg_ptr;
435 LIST_FOREACH(pr, &ge->lg_provider, lg_provider) {
437 geom_lookupid(gmp, pr->lg_geom)->lg_ptr;
439 LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) {
441 geom_lookupid(gmp, co->lg_geom)->lg_ptr;
442 if (co->lg_provider != NULL) {
445 co->lg_provider)->lg_ptr;
447 &co->lg_provider->lg_consumers,
457 geom_gettree(struct gmesh *gmp)
465 error = geom_xml2tree(gmp, p);
471 delete_config(struct gconf *gp)
479 LIST_REMOVE(cf, lg_config);
487 geom_deletetree(struct gmesh *gmp)
491 struct gprovider *pr;
492 struct gconsumer *co;
495 gmp->lg_ident = NULL;
497 cl = LIST_FIRST(&gmp->lg_class);
500 LIST_REMOVE(cl, lg_class);
501 delete_config(&cl->lg_config);
502 if (cl->lg_name) free(cl->lg_name);
504 ge = LIST_FIRST(&cl->lg_geom);
507 LIST_REMOVE(ge, lg_geom);
508 delete_config(&ge->lg_config);
509 if (ge->lg_name) free(ge->lg_name);
511 pr = LIST_FIRST(&ge->lg_provider);
514 LIST_REMOVE(pr, lg_provider);
515 delete_config(&pr->lg_config);
516 if (pr->lg_name) free(pr->lg_name);
517 if (pr->lg_mode) free(pr->lg_mode);
521 co = LIST_FIRST(&ge->lg_consumer);
524 LIST_REMOVE(co, lg_consumer);
525 delete_config(&co->lg_config);
526 if (co->lg_mode) free(co->lg_mode);