Add mxmlElementSetAttrf function (STR #43)

This commit is contained in:
Michael R Sweet 2007-04-18 14:55:08 +00:00
parent 9fb36b4a2f
commit 6d33fb1163
7 changed files with 161 additions and 36 deletions

View File

@ -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

5
README
View File

@ -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

View File

@ -49,6 +49,7 @@
<li><a href='#mxmlDelete'><tt>mxmlDelete()</tt></a> </li>
<li><a href='#mxmlElementGetAttr'><tt>mxmlElementGetAttr()</tt></a> </li>
<li><a href='#mxmlElementSetAttr'><tt>mxmlElementSetAttr()</tt></a> </li>
<li><a href='#mxmlElementSetAttrf'><tt>mxmlElementSetAttrf()</tt></a> </li>
<li><a href='#mxmlEntityAddCallback'><tt>mxmlEntityAddCallback()</tt></a> </li>
<li><a href='#mxmlEntityGetName'><tt>mxmlEntityGetName()</tt></a> </li>
<li><a href='#mxmlEntityGetValue'><tt>mxmlEntityGetValue()</tt></a> </li>
@ -194,6 +195,35 @@ mxmlElementSetAttr(
<h4>Returns</h4>
<p>Nothing.</p>
<!-- NEW PAGE -->
<h3 class='title'><a name='mxmlElementSetAttrf'>mxmlElementSetAttrf()</a></h3>
<h4>Description</h4>
<p>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.</p>
<h4>Syntax</h4>
<pre>
void
mxmlElementSetAttrf(
<a href='#mxml_node_t'>mxml_node_t</a> * node,
const char * name,
const char * format,
...);
</pre>
<h4>Arguments</h4>
<div class='table'><table align='center' border='1' width='80%' cellpadding='5' cellspacing='0'>
<thead><tr><th>Name</th><th>Description</th></tr></thead>
<tbody>
<tr><td><tt>node</tt></td><td>Element node</td></tr>
<tr><td><tt>name</tt></td><td>Name of attribute</td></tr>
<tr><td><tt>format</tt></td><td>Printf-style attribute value</td></tr>
<tr><td><tt>...</tt></td><td>Additional arguments as needed</td></tr>
</tbody></table></div>
<h4>Returns</h4>
<p>Nothing.</p>
<!-- NEW PAGE -->
<h3 class='title'><a name='mxmlEntityAddCallback'>mxmlEntityAddCallback()</a></h3>
<h4>Description</h4>
<p>Add a callback to convert entities to Unicode.</p>

View File

@ -10,6 +10,8 @@
<li>Added two exceptions to the LGPL to support static
linking of applications against Mini-XML.</li>
<li>Added mxmlElementSetAttrf() function (STR #43)</li>
<li>Added snprintf() emulation function for test program
(STR #32)</li>

View File

@ -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);
}

6
mxml.h
View File

@ -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);

View File

@ -76,6 +76,29 @@ not an element.</description>
<description>Attribute value</description>
</argument>
</function>
<function name="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.</description>
<argument name="node" direction="I">
<type>mxml_node_t *</type>
<description>Element node</description>
</argument>
<argument name="name" direction="I">
<type>const char *</type>
<description>Name of attribute</description>
</argument>
<argument name="format" direction="I">
<type>const char *</type>
<description>Printf-style attribute value</description>
</argument>
<argument name="..." direction="I">
<type /> <description>Additional arguments as needed</description>
</argument>
</function>
<function name="mxmlEntityAddCallback">
<returnvalue>
<type>int</type>