From 6d33fb11630891c17c7113ad6ea8e693b05c5c4a Mon Sep 17 00:00:00 2001 From: Michael R Sweet Date: Wed, 18 Apr 2007 14:55:08 +0000 Subject: [PATCH] Add mxmlElementSetAttrf function (STR #43) --- CHANGES | 1 + README | 5 +- doc/reference.html | 30 +++++++++++ doc/relnotes.html | 2 + mxml-attr.c | 130 +++++++++++++++++++++++++++++++++------------ mxml.h | 6 +++ mxml.xml | 23 ++++++++ 7 files changed, 161 insertions(+), 36 deletions(-) diff --git a/CHANGES b/CHANGES index b758c1d..0e1380a 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,7 @@ CHANGES IN Mini-XML 2.3 - Added two exceptions to the LGPL to support static linking of applications against Mini-XML. + - Added mxmlElementSetAttrf() function (STR #43) - Added snprintf() emulation function for test program (STR #32) - Added the _CRT_SECURE_NO_DEPRECATE definition when diff --git a/README b/README index 891b0cb..27bcb83 100644 --- a/README +++ b/README @@ -4,8 +4,7 @@ README - 2007-04-17 INTRODUCTION - This README file describes the Mini-XML library version - 2.4. + This README file describes the Mini-XML library version 2.3. Mini-XML is a small XML parsing library that you can use to read XML and XML-like data files in your application without @@ -184,7 +183,7 @@ GETTING HELP AND REPORTING PROBLEMS LEGAL STUFF - The Mini-XML library is Copyright 2003-2005 by Michael Sweet. + The Mini-XML library is Copyright 2003-2007 by Michael Sweet. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General diff --git a/doc/reference.html b/doc/reference.html index 2242cb1..283120a 100644 --- a/doc/reference.html +++ b/doc/reference.html @@ -49,6 +49,7 @@
  • mxmlDelete()
  • mxmlElementGetAttr()
  • mxmlElementSetAttr()
  • +
  • mxmlElementSetAttrf()
  • mxmlEntityAddCallback()
  • mxmlEntityGetName()
  • mxmlEntityGetValue()
  • @@ -194,6 +195,35 @@ mxmlElementSetAttr(

    Returns

    Nothing.

    +

    mxmlElementSetAttrf()

    +

    Description

    +

    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.

    +

    Syntax

    +
    +void
    +mxmlElementSetAttrf(
    +    mxml_node_t * node,
    +    const char * name,
    +    const char * format,
    +    ...);
    +
    +

    Arguments

    +
    + + + + + + +
    NameDescription
    nodeElement node
    nameName of attribute
    formatPrintf-style attribute value
    ...Additional arguments as needed
    +

    Returns

    +

    Nothing.

    +

    mxmlEntityAddCallback()

    Description

    Add a callback to convert entities to Unicode.

    diff --git a/doc/relnotes.html b/doc/relnotes.html index d0f646f..023f32a 100644 --- a/doc/relnotes.html +++ b/doc/relnotes.html @@ -10,6 +10,8 @@
  • Added two exceptions to the LGPL to support static linking of applications against Mini-XML.
  • +
  • Added mxmlElementSetAttrf() function (STR #43)
  • +
  • Added snprintf() emulation function for test program (STR #32)
  • diff --git a/mxml-attr.c b/mxml-attr.c index f9e4b70..b708087 100644 --- a/mxml-attr.c +++ b/mxml-attr.c @@ -3,7 +3,7 @@ * * Attribute support code for Mini-XML, a small XML-like file parsing library. * - * Copyright 2003-2005 by Michael Sweet. + * Copyright 2003-2007 by Michael Sweet. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,8 +17,10 @@ * * Contents: * - * mxmlElementGetAttr() - Get an attribute. - * mxmlElementSetAttr() - Set 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. */ /* @@ -29,6 +31,14 @@ #include "mxml.h" +/* + * Local functions... + */ + +static int mxml_set_attr(mxml_node_t *node, const char *name, + char *value); + + /* * 'mxmlElementGetAttr()' - Get an attribute. * @@ -103,8 +113,7 @@ mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */ const char *name, /* I - Name of attribute */ const char *value) /* I - Attribute value */ { - int i; /* Looping var */ - mxml_attr_t *attr; /* New attribute */ + char *valuec; /* Copy of value */ #ifdef DEBUG @@ -119,6 +128,77 @@ mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */ 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. + */ + +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... */ @@ -129,26 +209,19 @@ mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */ if (!strcmp(attr->name, name)) { /* - * Replace the attribute value and return... + * Free the old value as needed... */ if (attr->value) free(attr->value); - if (value) - { - if ((attr->value = strdup(value)) == NULL) - mxml_error("Unable to allocate memory for attribute '%s' in element %s!", - name, node->value.element.name); - } - else - attr->value = NULL; + attr->value = value; - return; + return (0); } /* - * Attribute not found, so add a new one... + * Add a new attribute... */ if (node->value.element.num_attrs == 0) @@ -161,33 +234,24 @@ mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */ { mxml_error("Unable to allocate memory for attribute '%s' in element %s!", name, node->value.element.name); - return; + return (-1); } node->value.element.attrs = attr; attr += node->value.element.num_attrs; - attr->name = strdup(name); - if (value) - attr->value = strdup(value); - else - attr->value = NULL; - - if (!attr->name || (!attr->value && value)) + if ((attr->name = strdup(name)) == NULL) { - if (attr->name) - free(attr->name); - - if (attr->value) - free(attr->value); - mxml_error("Unable to allocate memory for attribute '%s' in element %s!", name, node->value.element.name); - - return; + return (-1); } - + + attr->value = value; + node->value.element.num_attrs ++; + + return (0); } diff --git a/mxml.h b/mxml.h index 4102769..a703c0a 100644 --- a/mxml.h +++ b/mxml.h @@ -165,6 +165,12 @@ extern void mxmlDelete(mxml_node_t *node); extern const char *mxmlElementGetAttr(mxml_node_t *node, const char *name); extern void mxmlElementSetAttr(mxml_node_t *node, const char *name, const char *value); +extern void mxmlElementSetAttrf(mxml_node_t *node, const char *name, + const char *format, ...) +# ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 3, 4))) +# endif /* __GNUC__ */ +; extern int mxmlEntityAddCallback(int (*cb)(const char *name)); extern const char *mxmlEntityGetName(int val); extern int mxmlEntityGetValue(const char *name); diff --git a/mxml.xml b/mxml.xml index ed2b65a..1e42b76 100644 --- a/mxml.xml +++ b/mxml.xml @@ -76,6 +76,29 @@ not an element. Attribute value + + 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. + + mxml_node_t * + Element node + + + const char * + Name of attribute + + + const char * + Printf-style attribute value + + + Additional arguments as needed + + int