/* * Copyright (C) 2013 Patrick "P. J." McDermott * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program. If not, see * . */ #include #include #include #include #include #include "xml.h" #include "logging.h" struct xml_node { void *data; XML_StartElementHandler start; XML_EndElementHandler end; XML_CharacterDataHandler charhndl; struct xml_node *parent; }; int xml_check_tag(const char *found, const char *expected) { return strcmp(found, expected) == 0; } void xml_unexpected_start_tag(XML_Parser p, const char *found, const char *expected) { warn("Found \"%s\" start tag where expected one of \"%s\" in map", found, expected); XML_StopParser(p, XML_FALSE); } void xml_unexpected_end_tag(XML_Parser p, const char *found, const char *expected) { warn("Found \"%s\" end tag where expected one of \"%s\" in map", found, expected); XML_StopParser(p, XML_FALSE); } void xml_get_uint32_attr(XML_Parser p, const char **attr, const char *name, Uint32 *dest, int req) { for (; attr[0] != NULL; attr += 2) { if (strcmp(attr[0], name) == 0) { if (sscanf(attr[1], "%" PRIu32, dest) == 1) { return; } else if (req) { warn("Invalid \"%s\" attribute value", name); XML_StopParser(p, XML_FALSE); } } } if (req) { warn("Required attribute \"%s\" not found", name); XML_StopParser(p, XML_FALSE); } } void xml_get_int_attr(XML_Parser p, const char **attr, const char *name, int *dest, int req) { for (; attr[0] != NULL; attr += 2) { if (strcmp(attr[0], name) == 0) { if (sscanf(attr[1], "%d", dest) == 1) { return; } else if (req) { warn("Invalid \"%s\" attribute value", name); XML_StopParser(p, XML_FALSE); } } } if (req) { warn("Required attribute \"%s\" not found", name); XML_StopParser(p, XML_FALSE); } } void xml_get_string_attr(XML_Parser p, const char **attr, const char *name, char **dest, int req) { for (; attr[0] != NULL; attr += 2) { if (strcmp(attr[0], name) == 0) { *dest = strdup(attr[1]); return; } } if (req) { warn("Required attribute \"%s\" not found", name); XML_StopParser(p, XML_FALSE); } } void xml_node_push(XML_Parser p, void *data, XML_StartElementHandler start, XML_EndElementHandler end, XML_CharacterDataHandler charhndl) { struct xml_node *n; n = malloc(sizeof(*n)); if (n == NULL) { return; } n->data = data; n->start = start; n->end = end; n->charhndl = charhndl; n->parent = (struct xml_node *) XML_GetUserData(p); XML_SetUserData(p, n); XML_SetStartElementHandler(p, n->start); XML_SetEndElementHandler(p, n->end); XML_SetCharacterDataHandler(p, n->charhndl); } void * xml_node_pop(XML_Parser p) { struct xml_node *n; void *data; n = (struct xml_node *) XML_GetUserData(p); data = n->data; XML_SetUserData(p, n->parent); free(n); n = (struct xml_node *) XML_GetUserData(p); if (n == NULL) { XML_SetStartElementHandler(p, NULL); XML_SetEndElementHandler(p, NULL); XML_SetCharacterDataHandler(p, NULL); } else { XML_SetStartElementHandler(p, n->start); XML_SetEndElementHandler(p, n->end); XML_SetCharacterDataHandler(p, n->charhndl); } return data; } void * xml_node_peek(XML_Parser p) { struct xml_node *n; n = (struct xml_node *) XML_GetUserData(p); return n->data; }