/* xmlin.c - XML Parser routines for parsing register/device definitions * * (C) 2005 by Harald Welte * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: xmlin.c,v 1.31 2005/06/02 20:53:52 laforge Exp $ * */ #include #include #include #include "mmio_test.h" static struct test_device * parse_xml_device(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) { struct test_device *test_dev; test_dev = (struct test_device *) malloc(sizeof(*test_dev)); if (!test_dev) { fprintf(stderr, "out of memory\n"); return NULL; } memset(test_dev, 0, sizeof(*test_dev)); test_dev->name = xmlGetProp(cur, (const xmlChar *) "name"); for (cur = cur->xmlChildrenNode; cur; cur = cur->next) { if ((!xmlStrcmp(cur->name, (const xmlChar *) "pci_id")) && (cur->ns == ns)) { struct test_pci_id *pciid = malloc(sizeof(*pciid)); char *vendor_str, *device_str; if (!pciid) { fprintf(stderr, "out of memory\n"); return NULL; } memset(pciid, 0, sizeof(*pciid)); vendor_str = xmlGetProp(cur, (const xmlChar *) "vendor_id"); device_str = xmlGetProp(cur, (const xmlChar *) "device_id"); if (!vendor_str || !device_str) { free(pciid); break; } pciid->vendor_id = strtol(vendor_str, NULL, 16); pciid->device_id = strtol(device_str, NULL, 16); pciid->next = test_dev->pci_ids; test_dev->pci_ids = pciid; } else if ((!xmlStrcmp(cur->name, (const xmlChar *) "register")) && (cur->ns == ns)) { struct test_register *reg = malloc(sizeof(*reg)); char *res_str, *offset_str, *size_str; if (!reg) { fprintf(stderr, "out of memory\n"); return NULL; } memset(reg, 0, sizeof(*reg)); reg->name = xmlGetProp(cur, (const xmlChar *) "name"); res_str = xmlGetProp(cur, (const xmlChar *) "resource"); offset_str = xmlGetProp(cur, (const xmlChar *) "offset"); size_str = xmlGetProp(cur, (const xmlChar *) "size"); if (size_str) reg->mmap_size = strtol(size_str, NULL, 10); else reg->mmap_size = 4096; if (!res_str || !offset_str) { free(reg); break; } reg->offset = strtol(offset_str, NULL, 16); reg->resource = strtol(res_str, NULL, 10); reg->next = test_dev->regs; test_dev->regs = reg; } } return test_dev; } struct test_device * parse_xml(char *file) { struct test_device *devices = NULL; xmlDocPtr doc; xmlNsPtr ns; xmlNodePtr cur; xmlInitParser(); doc = xmlParseFile(file); if (!doc) { fprintf(stderr, "error parsing XML file `%s'\n", file); return NULL; } cur = xmlDocGetRootElement(doc); if (!cur) { fprintf(stderr, "empty XML document\n"); xmlFreeDoc(doc); return NULL; } ns = xmlSearchNsByHref(doc, cur, (const xmlChar *) "http://www.gnumonks.org/xml/dtd/mmio_test/0.01"); if (!ns) { fprintf(stderr, "document of wrong type, namespace not found\n"); xmlFreeDoc(doc); return NULL; } if (xmlStrcmp(cur->name, (const xmlChar *)"mmio_test")) { fprintf(stderr, "document of wrong type, root node not mmio_test\n"); xmlFreeDoc(doc); return NULL; } for (cur = cur->xmlChildrenNode; cur; cur = cur->next) { if ((!xmlStrcmp(cur->name, (const xmlChar *) "device")) && (cur->ns == ns)) { struct test_device *cur_dev; cur_dev = parse_xml_device(doc, ns, cur); if (cur_dev) { cur_dev->next = devices; devices = cur_dev; } else { fprintf(stderr, "unable to parse XML\n"); xmlFreeDoc(doc); return NULL; } } } return devices; }