Add user_data and ref_count members to mxml_node_t structure.

Add mxmlRelease() and mxmlRetain() for reference-counted node management.

Add mxmlSetWrapMargin() to control wrapping of XML output.
This commit is contained in:
Michael R Sweet 2007-04-18 01:08:58 +00:00
parent f3b506c5eb
commit cb7c6c2311
10 changed files with 225 additions and 38 deletions

12
CHANGES
View File

@ -1,6 +1,16 @@
CHANGES - 12/07/2005
CHANGES - 2007-04-17
--------------------
CHANGES IN Mini-XML 2.4
- Added user_data and ref_count members to mxml_node_t
structure.
- Added mxmlReleaseNode() and mxmlRetainNode() APIs for
reference-counted nodes.
- Added mxmlSetWrapMargin() to control the wrapping of XML
output.
CHANGES IN Mini-XML 2.3
- Added two exceptions to the LGPL to support static

View File

@ -3,7 +3,7 @@
#
# Makefile for Mini-XML, a small XML-like file parsing library.
#
# Copyright 2003-2006 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
@ -157,13 +157,13 @@ install-libmxml.a:
$(INSTALL_LIB) libmxml.a $(BUILDROOT)$(libdir)
$(RANLIB) $(BUILDROOT)$(libdir)/libmxml.a
install-libmxml.so.1.2:
install-libmxml.so.1.3:
$(INSTALL_DIR) $(BUILDROOT)$(libdir)
$(INSTALL_LIB) libmxml.so.1.2 $(BUILDROOT)$(libdir)
$(INSTALL_LIB) libmxml.so.1.3 $(BUILDROOT)$(libdir)
$(RM) $(BUILDROOT)$(libdir)/libmxml.so
$(LN) libmxml.so.1.2 $(BUILDROOT)$(libdir)/libmxml.so
$(LN) libmxml.so.1.3 $(BUILDROOT)$(libdir)/libmxml.so
$(RM) $(BUILDROOT)$(libdir)/libmxml.so.1
$(LN) libmxml.so.1.2 $(BUILDROOT)$(libdir)/libmxml.so.1
$(LN) libmxml.so.1.3 $(BUILDROOT)$(libdir)/libmxml.so.1
install-libmxml.sl.1:
$(INSTALL_DIR) $(BUILDROOT)$(libdir)
@ -195,10 +195,10 @@ uninstall: uninstall-$(LIBMXML) uninstall-libmxml.a
uninstall-libmxml.a:
$(RM) $(BUILDROOT)$(libdir)/libmxml.a
uninstall-libmxml.so.1.2:
uninstall-libmxml.so.1.3:
$(RM) $(BUILDROOT)$(libdir)/libmxml.so
$(RM) $(BUILDROOT)$(libdir)/libmxml.so.1
$(RM) $(BUILDROOT)$(libdir)/libmxml.so.1.2
$(RM) $(BUILDROOT)$(libdir)/libmxml.so.1.3
uninstall-libmxml.sl.1:
$(RM) $(BUILDROOT)$(libdir)/libmxml.sl
@ -256,14 +256,14 @@ $(LIBOBJS): mxml.h
#
# libmxml.so.1.2
# libmxml.so.1.3
#
libmxml.so.1.2: $(LIBOBJS)
$(DSO) $(DSOFLAGS) -o libmxml.so.1.2 $(LIBOBJS)
libmxml.so.1.3: $(LIBOBJS)
$(DSO) $(DSOFLAGS) -o libmxml.so.1.3 $(LIBOBJS)
$(RM) libmxml.so libmxml.so.1
$(LN) libmxml.so.1.2 libmxml.so
$(LN) libmxml.so.1.2 libmxml.so.1
$(LN) libmxml.so.1.3 libmxml.so
$(LN) libmxml.so.1.3 libmxml.so.1
#
@ -283,7 +283,7 @@ libmxml.sl.1: $(LIBOBJS)
libmxml.1.dylib: $(LIBOBJS)
$(DSO) $(DSOFLAGS) -o libmxml.1.dylib \
-install_name $(libdir)/libmxml.dylib \
-current_version 1.2.0 \
-current_version 1.3.0 \
-compatibility_version 1.0.0 \
$(LIBOBJS)
$(RM) libmxml.dylib libmxml.1.dylib

4
README
View File

@ -1,11 +1,11 @@
README - 08/10/2005
README - 2007-04-17
-------------------
INTRODUCTION
This README file describes the Mini-XML library version
2.2.3.
2.4.
Mini-XML is a small XML parsing library that you can use to
read XML and XML-like data files in your application without

10
configure vendored
View File

@ -1269,7 +1269,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_config_headers="$ac_config_headers config.h"
VERSION=2.3
VERSION=2.4
cat >>confdefs.h <<_ACEOF
#define MXML_VERSION "Mini-XML v$VERSION"
@ -3320,7 +3320,7 @@ echo $ECHO_N "checking for shared library support... $ECHO_C" >&6
SunOS* | UNIX_S*)
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
LIBMXML="libmxml.so.1.2"
LIBMXML="libmxml.so.1.3"
DSO="\$(CC)"
DSOFLAGS="$DSOFLAGS -Wl,-h,libmxml.so.1 -G -R\$(libdir) \$(OPTIM)"
LDFLAGS="$LDFLAGS -R\$(libdir)"
@ -3338,7 +3338,7 @@ echo "${ECHO_T}yes" >&6
IRIX)
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
LIBMXML="libmxml.so.1.2"
LIBMXML="libmxml.so.1.3"
DSO="\$(CC)"
DSOFLAGS="$DSOFLAGS -Wl,-rpath,\$(libdir),-set_version,sgi1.0,-soname,libmxml.so.1 -shared \$(OPTIM)"
;;
@ -3346,7 +3346,7 @@ echo "${ECHO_T}yes" >&6
OSF1* | Linux | GNU)
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
LIBMXML="libmxml.so.1.2"
LIBMXML="libmxml.so.1.3"
DSO="\$(CC)"
DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1,-rpath,\$(libdir) -shared \$(OPTIM)"
LDFLAGS="$LDFLAGS -Wl,-rpath,\$(libdir)"
@ -3355,7 +3355,7 @@ echo "${ECHO_T}yes" >&6
*BSD*)
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
LIBMXML="libmxml.so.1.2"
LIBMXML="libmxml.so.1.3"
DSO="\$(CC)"
DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1,-R\$(libdir) -shared \$(OPTIM)"
LDFLAGS="$LDFLAGS -Wl,-R\$(libdir)"

View File

@ -3,7 +3,7 @@ dnl "$Id$"
dnl
dnl Configuration script for Mini-XML, a small XML-like file parsing library.
dnl
dnl Copyright 2003-2006 by Michael Sweet.
dnl Copyright 2003-2007 by Michael Sweet.
dnl
dnl This program is free software; you can redistribute it and/or
dnl modify it under the terms of the GNU Library General Public
@ -23,7 +23,7 @@ dnl Set the name of the config header file...
AC_CONFIG_HEADER(config.h)
dnl Version number...
VERSION=2.3
VERSION=2.4
AC_SUBST(VERSION)
AC_DEFINE_UNQUOTED(MXML_VERSION, "Mini-XML v$VERSION")
@ -120,7 +120,7 @@ if test x$enable_shared = xyes; then
case "$uname" in
SunOS* | UNIX_S*)
AC_MSG_RESULT(yes)
LIBMXML="libmxml.so.1.2"
LIBMXML="libmxml.so.1.3"
DSO="\$(CC)"
DSOFLAGS="$DSOFLAGS -Wl,-h,libmxml.so.1 -G -R\$(libdir) \$(OPTIM)"
LDFLAGS="$LDFLAGS -R\$(libdir)"
@ -136,14 +136,14 @@ if test x$enable_shared = xyes; then
IRIX)
AC_MSG_RESULT(yes)
LIBMXML="libmxml.so.1.2"
LIBMXML="libmxml.so.1.3"
DSO="\$(CC)"
DSOFLAGS="$DSOFLAGS -Wl,-rpath,\$(libdir),-set_version,sgi1.0,-soname,libmxml.so.1 -shared \$(OPTIM)"
;;
OSF1* | Linux | GNU)
AC_MSG_RESULT(yes)
LIBMXML="libmxml.so.1.2"
LIBMXML="libmxml.so.1.3"
DSO="\$(CC)"
DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1,-rpath,\$(libdir) -shared \$(OPTIM)"
LDFLAGS="$LDFLAGS -Wl,-rpath,\$(libdir)"
@ -151,7 +151,7 @@ if test x$enable_shared = xyes; then
*BSD*)
AC_MSG_RESULT(yes)
LIBMXML="libmxml.so.1.2"
LIBMXML="libmxml.so.1.3"
DSO="\$(CC)"
DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1,-R\$(libdir) -shared \$(OPTIM)"
LDFLAGS="$LDFLAGS -Wl,-R\$(libdir)"

View File

@ -2,7 +2,7 @@
<html>
<head>
<title>Documentation</title>
<meta name='creator' content='Mini-XML v2.3'>
<meta name='creator' content='Mini-XML v2.4'>
<style type='text/css'><!--
h1, h2, h3, p { font-family: sans-serif; text-align: justify; }
tt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }
@ -70,7 +70,9 @@
<li><a href='#mxmlNewReal'><tt>mxmlNewReal()</tt></a> </li>
<li><a href='#mxmlNewText'><tt>mxmlNewText()</tt></a> </li>
<li><a href='#mxmlNewTextf'><tt>mxmlNewTextf()</tt></a> </li>
<li><a href='#mxmlRelease'><tt>mxmlRelease()</tt></a> </li>
<li><a href='#mxmlRemove'><tt>mxmlRemove()</tt></a> </li>
<li><a href='#mxmlRetain'><tt>mxmlRetain()</tt></a> </li>
<li><a href='#mxmlSaveAllocString'><tt>mxmlSaveAllocString()</tt></a> </li>
<li><a href='#mxmlSaveFd'><tt>mxmlSaveFd()</tt></a> </li>
<li><a href='#mxmlSaveFile'><tt>mxmlSaveFile()</tt></a> </li>
@ -85,6 +87,7 @@
<li><a href='#mxmlSetReal'><tt>mxmlSetReal()</tt></a> </li>
<li><a href='#mxmlSetText'><tt>mxmlSetText()</tt></a> </li>
<li><a href='#mxmlSetTextf'><tt>mxmlSetTextf()</tt></a> </li>
<li><a href='#mxmlSetWrapMargin'><tt>mxmlSetWrapMargin()</tt></a> </li>
<li><a href='#mxmlWalkNext'><tt>mxmlWalkNext()</tt></a> </li>
<li><a href='#mxmlWalkPrev'><tt>mxmlWalkPrev()</tt></a> </li>
</ul>
@ -712,6 +715,27 @@ mxmlNewTextf(
<h4>Returns</h4>
<p>New node</p>
<!-- NEW PAGE -->
<h3 class='title'><a name='mxmlRelease'>mxmlRelease()</a></h3>
<h4>Description</h4>
<p>Release a node.
When the reference count reaches zero, the node (and any children)
is deleted via mxmlDelete().</p>
<h4>Syntax</h4>
<pre>
int
mxmlRelease(
<a href='#mxml_node_t'>mxml_node_t</a> * node);
</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>Node</td></tr>
</tbody></table></div>
<h4>Returns</h4>
<p>New reference count</p>
<!-- NEW PAGE -->
<h3 class='title'><a name='mxmlRemove'>mxmlRemove()</a></h3>
<h4>Description</h4>
<p>Remove a node from its parent.
@ -733,6 +757,24 @@ mxmlRemove(
<h4>Returns</h4>
<p>Nothing.</p>
<!-- NEW PAGE -->
<h3 class='title'><a name='mxmlRetain'>mxmlRetain()</a></h3>
<h4>Description</h4>
<p>Retain a node.</p>
<h4>Syntax</h4>
<pre>
int
mxmlRetain(
<a href='#mxml_node_t'>mxml_node_t</a> * node);
</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>Node</td></tr>
</tbody></table></div>
<h4>Returns</h4>
<p>New reference count</p>
<!-- NEW PAGE -->
<h3 class='title'><a name='mxmlSaveAllocString'>mxmlSaveAllocString()</a></h3>
<h4>Description</h4>
<p>Save an XML node tree to an allocated string.
@ -1072,6 +1114,26 @@ mxmlSetTextf(
<h4>Returns</h4>
<p>0 on success, -1 on failure</p>
<!-- NEW PAGE -->
<h3 class='title'><a name='mxmlSetWrapMargin'>mxmlSetWrapMargin()</a></h3>
<h4>Description</h4>
<p>Set the the wrap margin when saving XML data.
Wrapping is disabled when &quot;column&quot; is &lt;= 0.</p>
<h4>Syntax</h4>
<pre>
void
mxmlSetWrapMargin(
int column);
</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>column</tt></td><td>Column for wrapping</td></tr>
</tbody></table></div>
<h4>Returns</h4>
<p>Nothing.</p>
<!-- NEW PAGE -->
<h3 class='title'><a name='mxmlWalkNext'>mxmlWalkNext()</a></h3>
<h4>Description</h4>
<p>Walk to the next logical node in the tree.
@ -1228,7 +1290,9 @@ struct mxml_node_s
struct <a href='#mxml_node_s'>mxml_node_s</a> * next;
struct <a href='#mxml_node_s'>mxml_node_s</a> * parent;
struct <a href='#mxml_node_s'>mxml_node_s</a> * prev;
int ref_count;
mxml_type_t type;
void * user_data;
<a href='#mxml_value_t'>mxml_value_t</a> value;
};
</pre>
@ -1241,7 +1305,9 @@ struct mxml_node_s
<tr><td><tt>next</tt> </td><td>Next node under same parent</td></tr>
<tr><td><tt>parent</tt> </td><td>Parent node</td></tr>
<tr><td><tt>prev</tt> </td><td>Previous node under same parent</td></tr>
<tr><td><tt>ref_count</tt> </td><td>Use count</td></tr>
<tr><td><tt>type</tt> </td><td>Node type</td></tr>
<tr><td><tt>user_data</tt> </td><td>User data</td></tr>
<tr><td><tt>value</tt> </td><td>Node value</td></tr>
</tbody></table></div>
<!-- NEW PAGE -->

View File

@ -3,7 +3,7 @@
*
* File loading 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
@ -93,6 +93,13 @@ typedef struct mxml_fdbuf_s /**** File descriptor buffer (@private@) ****/
extern void (*mxml_error_cb)(const char *);
/*
* Settings...
*/
static int mxml_wrap = 72;
/*
* Custom data handlers...
*/
@ -472,6 +479,22 @@ mxmlSetErrorCallback(void (*cb)(const char *))
}
/*
* 'mxmlSetWrapMargin()' - Set the the wrap margin when saving XML data.
*
* Wrapping is disabled when "column" is <= 0.
*/
void
mxmlSetWrapMargin(int column) /* I - Column for wrapping */
{
if (column <= 0)
mxml_wrap = 2147483647;
else
mxml_wrap = column;
}
/*
* 'mxml_add_char()' - Add a character to a buffer, expanding as needed.
*/
@ -2549,7 +2572,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
*/
if (!strncmp(node->value.element.name, "?xml", 4))
col = MXML_WRAP;
col = mxml_wrap;
}
else if (mxml_write_name(node->value.element.name, p, putc_cb) < 0)
return (-1);
@ -2565,7 +2588,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
if (attr->value)
width += strlen(attr->value) + 3;
if ((col + width) > MXML_WRAP)
if ((col + width) > mxml_wrap)
{
if ((*putc_cb)('\n', p) < 0)
return (-1);
@ -2669,7 +2692,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
case MXML_INTEGER :
if (node->prev)
{
if (col > MXML_WRAP)
if (col > mxml_wrap)
{
if ((*putc_cb)('\n', p) < 0)
return (-1);
@ -2699,7 +2722,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
case MXML_REAL :
if (node->prev)
{
if (col > MXML_WRAP)
if (col > mxml_wrap)
{
if ((*putc_cb)('\n', p) < 0)
return (-1);
@ -2722,7 +2745,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
case MXML_TEXT :
if (node->value.text.whitespace && col > 0)
{
if (col > MXML_WRAP)
if (col > mxml_wrap)
{
if ((*putc_cb)('\n', p) < 0)
return (-1);

View File

@ -3,7 +3,7 @@
*
* Node 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
@ -27,7 +27,9 @@
* mxmlNewReal() - Create a new real number node.
* mxmlNewText() - Create a new text fragment node.
* mxmlNewTextf() - Create a new formatted text fragment node.
* mxmlRelease() - Release a node.
* mxmlRemove() - Remove a node from its parent.
* mxmlRetain() - Retain a node.
* mxml_new() - Create a new node.
*/
@ -653,6 +655,45 @@ mxmlRemove(mxml_node_t *node) /* I - Node to remove */
}
/*
* 'mxmlRelease()' - Release a node.
*
* When the reference count reaches zero, the node (and any children)
* is deleted via mxmlDelete().
*/
int /* O - New reference count */
mxmlRelease(mxml_node_t *node) /* I - Node */
{
if (node)
{
if ((-- node->ref_count) <= 0)
{
mxmlDelete(node);
return (0);
}
else
return (node->ref_count);
}
else
return (-1);
}
/*
* 'mxmlRetain()' - Retain a node.
*/
int /* O - New reference count */
mxmlRetain(mxml_node_t *node) /* I - Node */
{
if (node)
return (++ node->ref_count);
else
return (-1);
}
/*
* 'mxml_new()' - Create a new node.
*/
@ -689,7 +730,8 @@ mxml_new(mxml_node_t *parent, /* I - Parent node */
* Set the node type...
*/
node->type = type;
node->type = type;
node->ref_count = 1;
/*
* Add to the parent if present...

8
mxml.h
View File

@ -3,7 +3,7 @@
*
* Header file 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
@ -38,7 +38,6 @@
* Constants...
*/
# define MXML_WRAP 72 /* Wrap XML output at this column position */
# define MXML_TAB 8 /* Tabs every N columns */
# define MXML_NO_CALLBACK 0 /* Don't use a type callback */
@ -128,6 +127,8 @@ typedef struct mxml_node_s /**** An XML node. ****/
struct mxml_node_s *child; /* First child node */
struct mxml_node_s *last_child; /* Last child node */
mxml_value_t value; /* Node value */
int ref_count; /* Use count */
void *user_data; /* User data */
} mxml_node_t;
typedef struct mxml_index_s /**** An XML node index. ****/
@ -200,7 +201,9 @@ extern mxml_node_t *mxmlNewTextf(mxml_node_t *parent, int whitespace,
__attribute__ ((__format__ (__printf__, 3, 4)))
# endif /* __GNUC__ */
;
extern int mxmlRelease(mxml_node_t *node);
extern void mxmlRemove(mxml_node_t *node);
extern int mxmlRetain(mxml_node_t *node);
extern char *mxmlSaveAllocString(mxml_node_t *node,
const char *(*cb)(mxml_node_t *, int));
extern int mxmlSaveFd(mxml_node_t *node, int fd,
@ -228,6 +231,7 @@ extern int mxmlSetTextf(mxml_node_t *node, int whitespace,
__attribute__ ((__format__ (__printf__, 3, 4)))
# endif /* __GNUC__ */
;
extern void mxmlSetWrapMargin(int column);
extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top,
int descend);
extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top,

View File

@ -489,6 +489,20 @@ string must be nul-terminated and is formatted into the new node.</description>
<type /> <description>Additional args as needed</description>
</argument>
</function>
<function name="mxmlRelease">
<returnvalue>
<type>int</type>
<description>New reference count</description>
</returnvalue>
<description>Release a node.
When the reference count reaches zero, the node (and any children)
is deleted via mxmlDelete().</description>
<argument name="node" direction="I">
<type>mxml_node_t *</type>
<description>Node</description>
</argument>
</function>
<function name="mxmlRemove">
<description>Remove a node from its parent.
@ -499,6 +513,17 @@ This function does nothing if the node has no parent.</description>
<description>Node to remove</description>
</argument>
</function>
<function name="mxmlRetain">
<returnvalue>
<type>int</type>
<description>New reference count</description>
</returnvalue>
<description>Retain a node.</description>
<argument name="node" direction="I">
<type>mxml_node_t *</type>
<description>Node</description>
</argument>
</function>
<function name="mxmlSaveAllocString">
<returnvalue>
<type>char *</type>
@ -764,6 +789,15 @@ The node is not changed if it is not a text node.</description>
<type /> <description>Additional arguments as needed</description>
</argument>
</function>
<function name="mxmlSetWrapMargin">
<description>Set the the wrap margin when saving XML data.
Wrapping is disabled when &quot;column&quot; is &lt;= 0.</description>
<argument name="column" direction="I">
<type>int</type>
<description>Column for wrapping</description>
</argument>
</function>
<function name="mxmlWalkNext">
<returnvalue>
<type>mxml_node_t *</type>
@ -929,10 +963,18 @@ the walk to the node's children.</description>
<type>struct mxml_node_s *</type>
<description>Previous node under same parent</description>
</variable>
<variable name="ref_count">
<type>int</type>
<description>Use count</description>
</variable>
<variable name="type">
<type>mxml_type_t</type>
<description>Node type</description>
</variable>
<variable name="user_data">
<type>void *</type>
<description>User data</description>
</variable>
<variable name="value">
<type>mxml_value_t</type>
<description>Node value</description>