/* * "$Id: mxml-attr.c 408 2010-09-19 05:26:46Z mike $" * * Attribute support code for Mini-XML, a small XML-like file parsing library. * * Copyright 2003-2010 by Michael R Sweet. * * These coded instructions, statements, and computer programs are the * property of Michael R Sweet and are protected by Federal copyright * law. Distribution and use rights are outlined in the file "COPYING" * which should have been included with this file. If this file is * missing or damaged, see the license at: * * http://www.minixml.org/ * * Contents: * * mxmlElementDeleteAttr() - Delete an attribute. * mxmlElementGetAttr() - Get an attribute. * mxmlElementSetAttr() - Set an attribute. * mxmlElementSetAttrf() - Set an attribute with a formatted value. * mxml_set_attr() - Set or add an attribute name/value pair. */ /* * Include necessary headers... */ #include "mxml-config.h" #include "mxml.h" /* * Local functions... */ static int mxml_set_attr(mxml_node_t *node, const char *name, char *value); /* * 'mxmlElementDeleteAttr()' - Delete an attribute. * * @since Mini-XML 2.4@ */ void mxmlElementDeleteAttr(mxml_node_t *node,/* I - Element */ const char *name)/* I - Attribute name */ { int i; /* Looping var */ mxml_attr_t *attr; /* Cirrent attribute */ #ifdef DEBUG fprintf(stderr, "mxmlElementDeleteAttr(node=%p, name=\"%s\")\n", node, name ? name : "(null)"); #endif /* DEBUG */ /* * Range check input... */ if (!node || node->type != MXML_ELEMENT || !name) return; /* * Look for the attribute... */ for (i = node->value.element.num_attrs, attr = node->value.element.attrs; i > 0; i --, attr ++) { #ifdef DEBUG printf(" %s=\"%s\"\n", attr->name, attr->value); #endif /* DEBUG */ if (!strcmp(attr->name, name)) { /* * Delete this attribute... */ free(attr->name); free(attr->value); i --; if (i > 0) memmove(attr, attr + 1, i * sizeof(mxml_attr_t)); node->value.element.num_attrs --; return; } } } /* * 'mxmlElementGetAttr()' - Get an attribute. * * This function returns NULL if the node is not an element or the * named attribute does not exist. */ const char * /* O - Attribute value or NULL */ mxmlElementGetAttr(mxml_node_t *node, /* I - Element node */ const char *name) /* I - Name of attribute */ { int i; /* Looping var */ mxml_attr_t *attr; /* Cirrent attribute */ #ifdef DEBUG fprintf(stderr, "mxmlElementGetAttr(node=%p, name=\"%s\")\n", node, name ? name : "(null)"); #endif /* DEBUG */ /* * Range check input... */ if (!node || node->type != MXML_ELEMENT || !name) return (NULL); /* * Look for the attribute... */ for (i = node->value.element.num_attrs, attr = node->value.element.attrs; i > 0; i --, attr ++) { #ifdef DEBUG printf(" %s=\"%s\"\n", attr->name, attr->value); #endif /* DEBUG */ if (!strcmp(attr->name, name)) { #ifdef DEBUG printf(" Returning \"%s\"!\n", attr->value); #endif /* DEBUG */ return (attr->value); } } /* * Didn't find attribute, so return NULL... */ #ifdef DEBUG puts(" Returning NULL!\n"); #endif /* DEBUG */ return (NULL); } /* * 'mxmlElementSetAttr()' - Set an attribute. * * If the named attribute already exists, the value of the attribute * is replaced by the new string value. The string value is copied * into the element node. This function does nothing if the node is * not an element. */ void mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */ const char *name, /* I - Name of attribute */ const char *value) /* I - Attribute value */ { char *valuec; /* Copy of value */ #ifdef DEBUG fprintf(stderr, "mxmlElementSetAttr(node=%p, name=\"%s\", value=\"%s\")\n", node, name ? name : "(null)", value ? value : "(null)"); #endif /* DEBUG */ /* * Range check input... */ if (!node || node->type != MXML_ELEMENT || !name) return; if (value) valuec = strdup(value); else valuec = NULL; if (mxml_set_attr(node, name, valuec)) free(valuec); } /* * 'mxmlElementSetAttrf()' - Set an attribute with a formatted value. * * If the named attribute already exists, the value of the attribute * is replaced by the new formatted string. The formatted string value is * copied into the element node. This function does nothing if the node * is not an element. * * @since Mini-XML 2.3@ */ void mxmlElementSetAttrf(mxml_node_t *node, /* I - Element node */ const char *name, /* I - Name of attribute */ const char *format,/* I - Printf-style attribute value */ ...) /* I - Additional arguments as needed */ { va_list ap; /* Argument pointer */ char *value; /* Value */ #ifdef DEBUG fprintf(stderr, "mxmlElementSetAttrf(node=%p, name=\"%s\", format=\"%s\", ...)\n", node, name ? name : "(null)", format ? format : "(null)"); #endif /* DEBUG */ /* * Range check input... */ if (!node || node->type != MXML_ELEMENT || !name || !format) return; /* * Format the value... */ va_start(ap, format); value = _mxml_vstrdupf(format, ap); va_end(ap); if (!value) mxml_error("Unable to allocate memory for attribute '%s' in element %s!", name, node->value.element.name); else if (mxml_set_attr(node, name, value)) free(value); } /* * 'mxml_set_attr()' - Set or add an attribute name/value pair. */ static int /* O - 0 on success, -1 on failure */ mxml_set_attr(mxml_node_t *node, /* I - Element node */ const char *name, /* I - Attribute name */ char *value) /* I - Attribute value */ { int i; /* Looping var */ mxml_attr_t *attr; /* New attribute */ /* * Look for the attribute... */ for (i = node->value.element.num_attrs, attr = node->value.element.attrs; i > 0; i --, attr ++) if (!strcmp(attr->name, name)) { /* * Free the old value as needed... */ if (attr->value) free(attr->value); attr->value = value; return (0); } /* * Add a new attribute... */ if (node->value.element.num_attrs == 0) attr = malloc(sizeof(mxml_attr_t)); else attr = realloc(node->value.element.attrs, (node->value.element.num_attrs + 1) * sizeof(mxml_attr_t)); if (!attr) { mxml_error("Unable to allocate memory for attribute '%s' in element %s!", name, node->value.element.name); return (-1); } node->value.element.attrs = attr; attr += node->value.element.num_attrs; if ((attr->name = strdup(name)) == NULL) { mxml_error("Unable to allocate memory for attribute '%s' in element %s!", name, node->value.element.name); return (-1); } attr->value = value; node->value.element.num_attrs ++; return (0); } /* * End of "$Id: mxml-attr.c 408 2010-09-19 05:26:46Z mike $". */