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.
+
+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
+
+Name | Description |
+
+node | Element node |
+name | Name of attribute |
+format | Printf-style attribute value |
+... | Additional arguments as needed |
+
+Returns
+Nothing.
+
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