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);
233 if (!strcmp(name, "stripesize") && mt->provider != NULL) {
234 mt->provider->lg_stripesize = strtoumax(p, NULL, 0);
238 if (!strcmp(name, "stripeoffset") && mt->provider != NULL) {
239 mt->provider->lg_stripeoffset = strtoumax(p, NULL, 0);
244 if (!strcmp(name, "config")) {
249 if (mt->config != NULL) {
250 gc = calloc(1, sizeof *gc);
252 warn("Cannot allocate memory during processing of '%s' "
256 gc->lg_name = strdup(name);
257 if (gc->lg_name == NULL) {
258 warn("Cannot allocate memory during processing of '%s' "
263 LIST_INSERT_HEAD(mt->config, gc, lg_config);
268 printf("Unexpected XML: name=%s data=\"%s\"\n", name, p);
272 if (!strcmp(name, "consumer") && mt->consumer != NULL) {
276 if (!strcmp(name, "provider") && mt->provider != NULL) {
280 if (!strcmp(name, "geom") && mt->consumer != NULL) {
283 if (!strcmp(name, "geom") && mt->provider != NULL) {
286 if (!strcmp(name, "geom") && mt->geom != NULL) {
290 if (!strcmp(name, "class") && mt->geom != NULL) {
293 if (!strcmp(name, "class") && mt->class != NULL) {
300 CharData(void *userData , const XML_Char *s , int len)
309 while (isspace(*b) && b < e)
311 while (isspace(*e) && e > b)
313 if (e != b || (*b && !isspace(*b)))
314 sbuf_bcat(mt->sbuf[mt->level], b, e - b + 1);
318 geom_lookupid(struct gmesh *gmp, const void *id)
322 for (gip = gmp->lg_ident; gip->lg_id != NULL; gip++)
323 if (gip->lg_id == id)
329 geom_xml2tree(struct gmesh *gmp, char *p)
335 struct gprovider *pr;
336 struct gconsumer *co;
339 memset(gmp, 0, sizeof *gmp);
340 LIST_INIT(&gmp->lg_class);
341 parser = XML_ParserCreate(NULL);
344 mt = calloc(1, sizeof *mt);
346 XML_ParserFree(parser);
350 XML_SetUserData(parser, mt);
351 XML_SetElementHandler(parser, StartElement, EndElement);
352 XML_SetCharacterDataHandler(parser, CharData);
353 i = XML_Parse(parser, p, strlen(p), 1);
354 XML_ParserFree(parser);
359 gmp->lg_ident = calloc(sizeof *gmp->lg_ident, mt->nident + 1);
361 if (gmp->lg_ident == NULL)
364 /* Collect all identifiers */
365 LIST_FOREACH(cl, &gmp->lg_class, lg_class) {
366 gmp->lg_ident[i].lg_id = cl->lg_id;
367 gmp->lg_ident[i].lg_ptr = cl;
368 gmp->lg_ident[i].lg_what = ISCLASS;
370 LIST_FOREACH(ge, &cl->lg_geom, lg_geom) {
371 gmp->lg_ident[i].lg_id = ge->lg_id;
372 gmp->lg_ident[i].lg_ptr = ge;
373 gmp->lg_ident[i].lg_what = ISGEOM;
375 LIST_FOREACH(pr, &ge->lg_provider, lg_provider) {
376 gmp->lg_ident[i].lg_id = pr->lg_id;
377 gmp->lg_ident[i].lg_ptr = pr;
378 gmp->lg_ident[i].lg_what = ISPROVIDER;
381 LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) {
382 gmp->lg_ident[i].lg_id = co->lg_id;
383 gmp->lg_ident[i].lg_ptr = co;
384 gmp->lg_ident[i].lg_what = ISCONSUMER;
389 /* Substitute all identifiers */
390 LIST_FOREACH(cl, &gmp->lg_class, lg_class) {
391 LIST_FOREACH(ge, &cl->lg_geom, lg_geom) {
393 geom_lookupid(gmp, ge->lg_class)->lg_ptr;
394 LIST_FOREACH(pr, &ge->lg_provider, lg_provider) {
396 geom_lookupid(gmp, pr->lg_geom)->lg_ptr;
398 LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) {
400 geom_lookupid(gmp, co->lg_geom)->lg_ptr;
401 if (co->lg_provider != NULL) {
404 co->lg_provider)->lg_ptr;
406 &co->lg_provider->lg_consumers,
416 geom_gettree(struct gmesh *gmp)
424 error = geom_xml2tree(gmp, p);
430 delete_config(struct gconf *gp)
438 LIST_REMOVE(cf, lg_config);
446 geom_deletetree(struct gmesh *gmp)
450 struct gprovider *pr;
451 struct gconsumer *co;
454 gmp->lg_ident = NULL;
456 cl = LIST_FIRST(&gmp->lg_class);
459 LIST_REMOVE(cl, lg_class);
460 delete_config(&cl->lg_config);
461 if (cl->lg_name) free(cl->lg_name);
463 ge = LIST_FIRST(&cl->lg_geom);
466 LIST_REMOVE(ge, lg_geom);
467 delete_config(&ge->lg_config);
468 if (ge->lg_name) free(ge->lg_name);
470 pr = LIST_FIRST(&ge->lg_provider);
473 LIST_REMOVE(pr, lg_provider);
474 delete_config(&pr->lg_config);
475 if (pr->lg_name) free(pr->lg_name);
476 if (pr->lg_mode) free(pr->lg_mode);
480 co = LIST_FIRST(&ge->lg_consumer);
483 LIST_REMOVE(co, lg_consumer);
484 delete_config(&co->lg_config);
485 if (co->lg_mode) free(co->lg_mode);