diff --git a/CHANGES b/CHANGES index 2093f23..62b2666 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,4 @@ -CHANGES - 2011-01-01 +CHANGES - 2011-01-02 -------------------- CHANGES IN Mini-XML 2.7 @@ -8,7 +8,7 @@ CHANGES IN Mini-XML 2.7 header to preserve source compatibility (STR #118) - Updated the source headers to reference the Mini-XML license and its exceptions to the LGPL2 (STR #108) - - Added a new mxmlFindValue() function to find the value node of a + - Added a new mxmlFindPath() function to find the value node of a named element (STR #110) - Building a static version of the library did not work on Windows (STR #112) diff --git a/COPYING b/COPYING index d7b975c..4d0aa78 100644 --- a/COPYING +++ b/COPYING @@ -6,21 +6,21 @@ The Mini-XML library and included programs are provided under the terms of the GNU Library General Public License version 2 (LGPL2) with the following exceptions: - 1. Static linking of applications to the Mini-XML library - does not constitute a derivative work and does not require - the author to provide source code for the application, use - the shared Mini-XML libraries, or link their applications - against a user-supplied version of Mini-XML. - - If you link the application to a modified version of - Mini-XML, then the changes to Mini-XML must be provided - under the terms of the LGPL2 in sections 1, 2, and 4. - - 2. You do not have to provide a copy of the Mini-XML license - with programs that are linked to the Mini-XML library, nor - do you have to identify the Mini-XML license in your - program or documentation as required by section 6 of the - LGPL2. + 1. Static linking of applications to the Mini-XML library +does not constitute a derivative work and does not require +the author to provide source code for the application, use +the shared Mini-XML libraries, or link their applications +against a user-supplied version of Mini-XML. + +If you link the application to a modified version of +Mini-XML, then the changes to Mini-XML must be provided +under the terms of the LGPL2 in sections 1, 2, and 4. + + 2. You do not have to provide a copy of the Mini-XML license +with programs that are linked to the Mini-XML library, nor +do you have to identify the Mini-XML license in your +program or documentation as required by section 6 of the +LGPL2. GNU LIBRARY GENERAL PUBLIC LICENSE diff --git a/Makefile.in b/Makefile.in index 3b8fe88..6e51352 100644 --- a/Makefile.in +++ b/Makefile.in @@ -3,7 +3,7 @@ # # Makefile for Mini-XML, a small XML-like file parsing library. # -# Copyright 2003-2010 by Michael R Sweet. +# Copyright 2003-2011 by Michael R Sweet. # # These coded instructions, statements, and computer programs are the # property of Michael R Sweet and are protected by Federal copyright @@ -69,9 +69,11 @@ INSTALL_SCRIPT = $(INSTALL) -m 755 # Rules... # +.SILENT: .SUFFIXES: .c .man .o .c.o: - $(CC) $(CFLAGS) -c $< + echo Compiling $< + $(CC) $(CFLAGS) -c -o $@ $< # @@ -101,6 +103,7 @@ all: Makefile config.h $(TARGETS) # clean: + echo Cleaning build files... $(RM) $(OBJS) $(TARGETS) $(RM) mxmldoc-static libmxml.a @@ -110,6 +113,7 @@ clean: # distclean: clean + echo Cleaning distribution files... $(RM) config.cache config.log config.status $(RM) Makefile config.h $(RM) -r autom4te*.cache @@ -123,9 +127,11 @@ distclean: clean .PHONY: clang clang-changes clang: + echo Doing static code analysis of all code using CLANG... $(RM) -r clang scan-build -V -k -o `pwd`/clang $(MAKE) $(MFLAGS) clean all clang-changes: + echo Doing static code analysis of changed code using CLANG... scan-build -V -k -o `pwd`/clang $(MAKE) $(MFLAGS) all @@ -134,41 +140,50 @@ clang-changes: # install: $(TARGETS) install-$(LIBMXML) install-libmxml.a + echo Installing mxmldoc in $(BUILDROOT)$(bindir)... $(INSTALL_DIR) $(BUILDROOT)$(bindir) - $(INSTALL_BIN) mxmldoc $(BUILDROOT)$(bindir) + $(INSTALL_BIN) mxmldoc $(BUILDROOT)$(bindir) + echo Installing documentation in $(BUILDROOT)$(docdir)... $(INSTALL_DIR) $(BUILDROOT)$(docdir) for file in $(DOCFILES); do \ $(INSTALL_MAN) $$file $(BUILDROOT)$(docdir); \ done + echo Installing header files in $(BUILDROOT)$(includedir)... $(INSTALL_DIR) $(BUILDROOT)$(includedir) $(INSTALL_DATA) mxml.h $(BUILDROOT)$(includedir) + echo Installing pkgconfig files in $(BUILDROOT)$(libdir)/pkgconfig... $(INSTALL_DIR) $(BUILDROOT)$(libdir)/pkgconfig $(INSTALL_DATA) mxml.pc $(BUILDROOT)$(libdir)/pkgconfig + echo Installing man pages in $(BUILDROOT)$(mandir)... $(INSTALL_DIR) $(BUILDROOT)$(mandir)/man1 $(INSTALL_MAN) doc/mxmldoc.man $(BUILDROOT)$(mandir)/man1/mxmldoc.1 $(INSTALL_DIR) $(BUILDROOT)$(mandir)/man3 $(INSTALL_MAN) doc/mxml.man $(BUILDROOT)$(mandir)/man3/mxml.3 install-libmxml.a: + echo Installing libmxml.a to $(BUILDROOT)$(libdir)... $(INSTALL_DIR) $(BUILDROOT)$(libdir) $(INSTALL_LIB) libmxml.a $(BUILDROOT)$(libdir) $(RANLIB) $(BUILDROOT)$(libdir)/libmxml.a -install-libmxml.so.1.4: +install-libmxml.so.1.5: + echo Installing libmxml.so to $(BUILDROOT)$(libdir)... $(INSTALL_DIR) $(BUILDROOT)$(libdir) - $(INSTALL_LIB) libmxml.so.1.4 $(BUILDROOT)$(libdir) + $(INSTALL_LIB) libmxml.so.1.5 $(BUILDROOT)$(libdir) $(RM) $(BUILDROOT)$(libdir)/libmxml.so - $(LN) libmxml.so.1.4 $(BUILDROOT)$(libdir)/libmxml.so + $(LN) libmxml.so.1.5 $(BUILDROOT)$(libdir)/libmxml.so $(RM) $(BUILDROOT)$(libdir)/libmxml.so.1 - $(LN) libmxml.so.1.4 $(BUILDROOT)$(libdir)/libmxml.so.1 + $(LN) libmxml.so.1.5 $(BUILDROOT)$(libdir)/libmxml.so.1 install-libmxml.sl.1: + echo Installing libmxml.sl to $(BUILDROOT)$(libdir)... $(INSTALL_DIR) $(BUILDROOT)$(libdir) $(INSTALL_LIB) libmxml.sl.1 $(BUILDROOT)$(libdir) $(RM) $(BUILDROOT)$(libdir)/libmxml.so $(LN) libmxml.sl.1 $(BUILDROOT)$(libdir)/libmxml.sl install-libmxml.1.dylib: + echo Installing libmxml.dylib to $(BUILDROOT)$(libdir)... $(INSTALL_DIR) $(BUILDROOT)$(libdir) $(INSTALL_LIB) libmxml.1.dylib $(BUILDROOT)$(libdir) $(RM) $(BUILDROOT)$(libdir)/libmxml.dylib @@ -180,35 +195,45 @@ install-libmxml.1.dylib: # uninstall: uninstall-$(LIBMXML) uninstall-libmxml.a + echo Uninstalling mxmldoc from $(BUILDROOT)$(bindir)... $(RM) $(BUILDROOT)$(bindir)/mxmldoc + echo Uninstalling documentation from $(BUILDROOT)$(docdir)... $(RM) -r $(BUILDROOT)$(docdir) + echo Uninstalling headers from $(BUILDROOT)$(includedir)... $(RM) $(BUILDROOT)$(includedir)/mxml.h + echo Uninstalling pkgconfig files from $(BUILDROOT)$(libdir)/pkgconfig... $(RM) $(BUILDROOT)$(libdir)/pkgconfig/mxml.pc + echo Uninstalling man pages from $(BUILDROOT)$(mandir)... $(RM) $(BUILDROOT)$(mandir)/man1/mxmldoc.1 $(RM) $(BUILDROOT)$(mandir)/man3/mxml.3 uninstall-libmxml.a: + echo Uninstalling libmxml.a from $(BUILDROOT)$(libdir)... $(RM) $(BUILDROOT)$(libdir)/libmxml.a -uninstall-libmxml.so.1.4: +uninstall-libmxml.so.1.5: + echo Uninstalling libmxml.so from $(BUILDROOT)$(libdir)... $(RM) $(BUILDROOT)$(libdir)/libmxml.so $(RM) $(BUILDROOT)$(libdir)/libmxml.so.1 $(RM) $(BUILDROOT)$(libdir)/libmxml.so.1.4 uninstall-libmxml.sl.1: + echo Uninstalling libmxml.sl from $(BUILDROOT)$(libdir)... $(RM) $(BUILDROOT)$(libdir)/libmxml.sl $(RM) $(BUILDROOT)$(libdir)/libmxml.sl.1 uninstall-libmxml.1.dylib: + echo Uninstalling libmxml.dylib from $(BUILDROOT)$(libdir)... $(RM) $(BUILDROOT)$(libdir)/libmxml.dylib $(RM) $(BUILDROOT)$(libdir)/libmxml.1.dylib # -# Make packages using EPM (http://www.easysw.com/epm/) +# Make packages using EPM (http://www.epmhome.org/) # epm: all + echo Creating distribution packages... epm --output-dir dist -v -f native mxml epm --output-dir dist -v -f portable mxml @@ -218,6 +243,7 @@ epm: all # Makefile: configure Makefile.in + echo Updating makefile... if test -f config.status; then \ ./config.status --recheck; \ ./config.status; \ @@ -228,6 +254,7 @@ Makefile: configure Makefile.in config.h: configure config.h.in + echo Updating config.h... autoconf if test -f config.status; then \ ./config.status --recheck; \ @@ -238,11 +265,24 @@ config.h: configure config.h.in touch config.h +# +# Figure out lines-of-code... +# + +.PHONY: sloc + +sloc: + echo "libmxml: \c" + sloccount $(LIBOBJS:.o=.c) mxml-private.c mxml.h 2>/dev/null | \ + grep "Total Physical" | awk '{print $$9}' + + # # libmxml.a # libmxml.a: $(LIBOBJS) + echo Creating $@... $(RM) $@ $(AR) $(ARFLAGS) $@ $(LIBOBJS) $(RANLIB) $@ @@ -252,14 +292,15 @@ mxml-entity.o mxml-file.o mxml-private.o: mxml-private.h # -# libmxml.so.1.4 +# libmxml.so.1.5 # -libmxml.so.1.4: $(LIBOBJS) - $(DSO) $(DSOFLAGS) -o libmxml.so.1.4 $(LIBOBJS) +libmxml.so.1.5: $(LIBOBJS) + echo Creating $@... + $(DSO) $(DSOFLAGS) -o libmxml.so.1.5 $(LIBOBJS) $(RM) libmxml.so libmxml.so.1 - $(LN) libmxml.so.1.4 libmxml.so - $(LN) libmxml.so.1.4 libmxml.so.1 + $(LN) libmxml.so.1.5 libmxml.so + $(LN) libmxml.so.1.5 libmxml.so.1 # @@ -267,6 +308,7 @@ libmxml.so.1.4: $(LIBOBJS) # libmxml.sl.1: $(LIBOBJS) + echo Creating $@... $(DSO) $(DSOFLAGS) -o libmxml.sl.1 $(LIBOBJS) $(RM) libmxml.sl $(LN) libmxml.sl.1 libmxml.sl @@ -277,9 +319,10 @@ libmxml.sl.1: $(LIBOBJS) # libmxml.1.dylib: $(LIBOBJS) + echo Creating $@... $(DSO) $(DSOFLAGS) -o libmxml.1.dylib \ -install_name $(libdir)/libmxml.dylib \ - -current_version 1.4.0 \ + -current_version 1.5.0 \ -compatibility_version 1.0.0 \ $(LIBOBJS) $(RM) libmxml.dylib @@ -291,9 +334,11 @@ libmxml.1.dylib: $(LIBOBJS) # mxmldoc: $(LIBMXML) mxmldoc.o + echo Linking $@... $(CC) -L. $(LDFLAGS) -o $@ mxmldoc.o -lmxml $(LIBS) mxmldoc-static: libmxml.a mxmldoc.o + echo Linking $@... $(CC) $(LDFLAGS) -o $@ mxmldoc.o libmxml.a $(LIBS) mxmldoc.o: mxml.h @@ -304,6 +349,7 @@ mxmldoc.o: mxml.h # testmxml: libmxml.a testmxml.o + echo Linking $@... $(CC) $(LDFLAGS) -o $@ testmxml.o libmxml.a $(LIBS) @echo Testing library... ./testmxml test.xml >temp1.xml 2>temp1s.xml @@ -335,6 +381,7 @@ testmxml.o: mxml.h # mxml.xml: mxmldoc-static mxml.h $(PUBLIBOBJS:.o=.c) + echo Generating API documentation... $(RM) mxml.xml ./mxmldoc-static --header doc/reference.heading mxml.xml mxml.h $(PUBLIBOBJS:.o=.c) >doc/reference.html if test "x`uname`" = xDarwin; then \ @@ -351,6 +398,7 @@ mxml.xml: mxmldoc-static mxml.h $(PUBLIBOBJS:.o=.c) fi valgrind: mxmldoc-static + echo Doing dynamic code analysis using Valgrind... $(RM) valgrind.xml valgrind --tool=memcheck --leak-check=yes ./mxmldoc-static \ valgrind.xml mxml.h $(PUBLIBOBJS:.o=.c) \ @@ -362,6 +410,7 @@ valgrind: mxmldoc-static # doc/mxml.man: mxmldoc-static mxml.xml + echo "Generating mxml(3) man page..." $(RM) doc/mxml.man ./mxmldoc-static --man mxml --title "Mini-XML API" \ --intro doc/intro.man --footer doc/footer.man \ diff --git a/README b/README index 620c5d7..248b090 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -README - 2010-11-08 +README - 2011-01-02 ------------------- @@ -133,7 +133,7 @@ DOCUMENTATION /* Find the first "a" element with "href" to a URL */ node = mxmlFindElement(tree, tree, "a", "href", - "http://www.easysw.com/~mike/mxml/", + "http://www.minixml.org/", MXML_DESCEND); /* Find the first element with a "src" attribute*/ @@ -156,11 +156,25 @@ DOCUMENTATION ... do something ... } - The "mxmlFindValue()" function finds the (first) value node under a specific + The "mxmlFindPath()" function finds the (first) value node under a specific element using a "path": - mxml_node_t *value = mxmlFindValue(tree, "path/to/*/foo/bar"); - + mxml_node_t *value = mxmlFindPath(tree, "path/to/*/foo/bar"); + + The "mxmlGetInteger()", "mxmlGetOpaque()", "mxmlGetReal()", and + "mxmlGetText()" functions retrieve the value from a node: + + mxml_node_t *node; + + int intvalue = mxmlGetInteger(node); + + const char *opaquevalue = mxmlGetOpaque(node); + + double realvalue = mxmlGetReal(node); + + int whitespacevalue; + const char *textvalue = mxmlGetText(node, &whitespacevalue); + Finally, once you are done with the XML data, use the "mxmlDelete()" function to recursively free the memory that is used for a particular node or the entire tree: @@ -178,5 +192,5 @@ GETTING HELP AND REPORTING PROBLEMS LEGAL STUFF - The Mini-XML library is Copyright 2003-2010 by Michael Sweet. License terms + The Mini-XML library is Copyright 2003-2011 by Michael Sweet. License terms are described in the file "COPYING". diff --git a/configure.in b/configure.in index 753c8d7..d2a686e 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ dnl "$Id$" dnl dnl Configuration script for Mini-XML, a small XML-like file parsing library. dnl -dnl Copyright 2003-2010 by Michael R Sweet. +dnl Copyright 2003-2011 by Michael R Sweet. dnl dnl These coded instructions, statements, and computer programs are the dnl property of Michael R Sweet and are protected by Federal copyright @@ -171,7 +171,7 @@ if test x$enable_shared != xno; then case "$uname" in SunOS* | UNIX_S*) AC_MSG_RESULT(yes) - LIBMXML="libmxml.so.1.4" + LIBMXML="libmxml.so.1.5" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-h,libmxml.so.1 -G -R\$(libdir) \$(OPTIM)" LDFLAGS="$LDFLAGS -R\$(libdir)" @@ -187,14 +187,14 @@ if test x$enable_shared != xno; then IRIX) AC_MSG_RESULT(yes) - LIBMXML="libmxml.so.1.4" + LIBMXML="libmxml.so.1.5" 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.4" + LIBMXML="libmxml.so.1.5" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1,-rpath,\$(libdir) -shared \$(OPTIM)" LDFLAGS="$LDFLAGS -Wl,-rpath,\$(libdir)" @@ -202,7 +202,7 @@ if test x$enable_shared != xno; then *BSD*) AC_MSG_RESULT(yes) - LIBMXML="libmxml.so.1.4" + LIBMXML="libmxml.so.1.5" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-soname,libmxml.so.1,-R\$(libdir) -shared \$(OPTIM)" LDFLAGS="$LDFLAGS -Wl,-R\$(libdir)" diff --git a/doc/advanced.html b/doc/advanced.html index a1aef45..67fcbb8 100644 --- a/doc/advanced.html +++ b/doc/advanced.html @@ -64,7 +64,7 @@ child nodes:

type = mxmlElementGetAttr(node, "type"); if (type == NULL) - type = node->value.element.name; + type = mxmlGetElement(node); if (!strcmp(type, "integer")) return (MXML_INTEGER); @@ -125,7 +125,7 @@ text editor:

* just common HTML elements... */ - name = node->value.element.name; + name = mxmlGetElement(node); if (!strcmp(name, "html") || !strcmp(name, "head") || @@ -243,10 +243,10 @@ following:

*/ if (sscanf(data, "%u-%u-%uT%u:%u:%uZ", - &(dt->year), &(dt->month), - &(dt->day), &(dt->hour), - &(dt->minute), - &(dt->second)) != 6) + &(dt->year), &(dt->month), + &(dt->day), &(dt->hour), + &(dt->minute), + &(dt->second)) != 6) { /* * Unable to read numbers, free the data @@ -296,8 +296,7 @@ following:

* function pointers... */ - node->value.custom.data = dt; - node->value.custom.destroy = free; + mxmlSetCustom(node, data, destroy); /* * Return with no errors... @@ -314,6 +313,7 @@ allocated custom data for the node and a pointer to a destructor function which will free the custom data when the node is deleted.

+

The save callback receives the node pointer and returns an allocated string containing the custom data value. The following save callback could be used for our ISO date/time type:

@@ -326,7 +326,7 @@ save callback could be used for our ISO date/time type:

iso_date_time_t *dt; - dt = (iso_date_time_t *)node->custom.data; + dt = (iso_date_time_t *)mxmlGetCustom(node); snprintf(data, sizeof(data), "%04u-%02u-%02uT%02u:%02u:%02uZ", @@ -404,9 +404,8 @@ an index is approximately equal to walking the XML document tree. Nodes in the index are sorted by element name and attribute value.

-

Indices are stored in mxml_index_t structures. The -mxmlIndexNew() function +

Indices are stored in mxml_index_t +structures. The mxmlIndexNew() function creates a new index:

@@ -568,7 +567,7 @@ directives like  <?xml ... ?> and  <!DOCTYPE ... >
         * Retain headings and titles...
         */
 
-        char *name = node->value.element.name;
+        char *name = mxmlGetElement(node);
 
         if (!strcmp(name, "html") ||
             !strcmp(name, "head") ||
@@ -584,15 +583,17 @@ directives like  <?xml ... ?> and  <!DOCTYPE ... >
       }
       else if (event == MXML_SAX_DIRECTIVE)
         mxmlRetain(node);
-      else if (event == MXML_SAX_DATA &&
-               node->parent->ref_count > 1)
+      else if (event == MXML_SAX_DATA)
       {
-       /*
-        * If the parent was retained, then retain
-        * this data node as well.
-        */
+        if (mxmlGetRefCount(mxmlGetParent(node)) > 1)
+        {
+         /*
+          * If the parent was retained, then retain
+          * this data node as well.
+          */
 
-        mxmlRetain(node);
+          mxmlRetain(node);
+        }
       }
     }
 
@@ -622,9 +623,9 @@ title and headings in the document would look like:

if (body) { - for (heading = body->child; + for (heading = mxmlGetFirstChild(body); heading; - heading = heading->next) + heading = mxmlGetNextSibling(heading)) print_children(heading); } diff --git a/doc/basics.html b/doc/basics.html index 9ca0838..7823fa6 100644 --- a/doc/basics.html +++ b/doc/basics.html @@ -23,7 +23,7 @@ functionality:

attribute values with no preset limits, just available memory. -
  • Support for integer, real, opaque ("cdata"), and text +
  • Support for integer, real, opaque ("CDATA"), and text data types in "leaf" nodes.
  • "Find", "index", and "walk" functions for easily @@ -63,74 +63,12 @@ for your installation:

    Nodes

    -

    Every piece of information in an XML file (elements, text, -numbers) is stored in memory in "nodes". Nodes are defined by -the mxml_node_t -structure. The type member -defines the node type (element, integer, opaque, real, or text) -which determines which value you want to look at in the value union.

    +

    Every piece of information in an XML file is stored in memory in "nodes". +Nodes are defined by the mxml_node_t +structure. Each node has a typed value, optional user data, a parent node, +sibling nodes (previous and next), and potentially child nodes.

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Table 2-1: Mini-XML Node Value Members
    ValueTypeNode member
    Customvoid *node->value.custom.data
    Elementchar *node->value.element.name
    Integerintnode->value.integer
    Opaque (string)char *node->value.opaque
    Realdoublenode->value.real
    Textchar *node->value.text.string
    - -

    Each node also has a user_data member which allows you -to associate application-specific data with each node as needed.

    - -

    New nodes are created using the mxmlNewElement, mxmlNewInteger, mxmlNewOpaque, mxmlNewReal, mxmlNewText, mxmlNewTextf, and mxmlNewXML functions. Only -elements can have child nodes, and the top node must be an element, usually the -<?xml version="1.0" encoding="utf-8"?> node created by -mxmlNewXML().

    - -

    Nodes have pointers to the node above (parent), below -(child), left (prev), and right (next) -of the current node. If you have an XML file like the following:

    +

    For example, if you have an XML file like the following:

         <?xml version="1.0" encoding="utf-8"?>
    @@ -148,8 +86,7 @@ of the current node. If you have an XML file like the following:

    </data>
    -

    the node tree for the file would look like the following in -memory:

    +

    the node tree for the file would look like the following in memory:

         ?xml version="1.0" encoding="utf-8"?
    @@ -165,17 +102,127 @@ memory:

    val4 val5 val6
    -

    where "-" is a pointer to the next node and "|" is a pointer -to the first child node.

    +

    where "-" is a pointer to the sibling node and "|" is a pointer +to the first child or parent node.

    -

    Once you are done with the XML data, use the mxmlDelete function to recursively -free the memory that is used for a particular node or the entire -tree:

    +

    The mxmlGetType function gets the type of +a node, one of MXML_CUSTOM, MXML_ELEMENT, +MXML_INTEGER, MXML_OPAQUE, MXML_REAL, or +MXML_TEXT. The parent and sibling nodes are accessed using the +mxmlGetParent, +mxmlGetNext, and +mxmlGetPrevious functions. The +mxmlGetUserData function gets any user +data associated with the node.

    + +

    CDATA Nodes

    + +

    CDATA (MXML_ELEMENT) nodes are created using the +mxmlNewCDATA function. The +mxmlGetCDATA function retrieves the +CDATA string pointer for a node.

    + +
    Note: + +

    CDATA nodes are currently stored in memory as special elements. This will +be changed in a future major release of Mini-XML.

    +
    + +

    Custom Nodes

    + +

    Custom (MXML_CUSTOM) nodes are created using the +mxmlNewCustom function or using a custom +load callback specified using the +mxmlSetCustomHandlers function. +The mxmlGetCustom function retrieves the +custom value pointer for a node.

    + +

    Comment Nodes

    + +

    Comment (MXML_ELEMENT) nodes are created using the +mxmlNewElement function. The +mxmlGetElement function retrieves the +comment string pointer for a node, including the surrounding "!--" and "--" +characters.

    + +
    Note: + +

    Comment nodes are currently stored in memory as special elements. This will +be changed in a future major release of Mini-XML.

    +
    + +

    Element Nodes

    + +

    Element (MXML_ELEMENT) nodes are created using the +mxmlNewElement function. The +mxmlGetElement function retrieves the +element name, the +mxmlElementGetAttr function retrieves +the value string for a named attribute associated with the element, and the +mxmlGetFirstChild and +mxmlGetLastChild functions retrieve the +first and last child nodes for the element, respectively.

    + +

    Integer Nodes

    + +

    Integer (MXML_INTEGER) nodes are created using the +mxmlNewInteger function. The +mxmlGetInteger function retrieves the +integer value for a node.

    + +

    Opaque Nodes

    + +

    Opaque (MXML_OPAQUE) nodes are created using the +mxmlNewOpaque function. The +mxmlGetOpaque function retrieves the +opaque string pointer for a node. Opaque nodes are like string nodes but +preserve all whitespace between nodes.

    + +

    Text Nodes

    + +

    Text (MXML_TEXT) nodes are created using the +mxmlNewText and +mxmlNewTextf functions. Each text node +consists of a text string and (leading) whitespace value - the +mxmlGetText function retrieves the +text string pointer and whitespace value for a node.

    + + +

    Processing Instruction Nodes

    + +

    Processing instruction (MXML_ELEMENT) nodes are created using the +mxmlNewElement function. The +mxmlGetElement function retrieves the +processing instruction string for a node, including the surrounding "?" +characters.

    + +
    Note: + +

    Processing instruction nodes are currently stored in memory as special +elements. This will be changed in a future major release of Mini-XML.

    +
    + +

    Real Number Nodes

    + +

    Real number (MXML_REAL) nodes are created using the +mxmlNewReal function. The +mxmlGetReal function retrieves the +CDATA string pointer for a node.

    + + +

    XML Declaration Nodes

    + +

    XML declaration (MXML_ELEMENT) nodes are created using the +mxmlNewXML function. The +mxmlGetElement function retrieves the +XML declaration string for a node, including the surrounding "?" characters.

    + +
    Note: + +

    XML declaration nodes are currently stored in memory as special elements. +This will be changed in a future major release of Mini-XML.

    +
    -
    -    mxmlDelete(tree);
    -

    Creating XML Documents

    @@ -216,41 +263,39 @@ create the XML document described in the previous section:

    mxmlNewText(node, 0, "val8"); -

    We start by creating the <?xml version="1.0" encoding="utf-8"?> -node common to all XML files using the mxmlNewXML function:

    + +

    We start by creating the declaration node common to all XML files using the +mxmlNewXML function:

         xml = mxmlNewXML("1.0");
     
    -

    We then create the <data> node used for this -document using the mxmlNewElement function. The -first argument specifies the parent node (xml) while the -second specifies the element name (data):

    +

    We then create the <data> node used for this document using +the mxmlNewElement function. The first +argument specifies the parent node (xml) while the second specifies the +element name (data):

         data = mxmlNewElement(xml, "data");
     
    -

    Each <node>...</node> in the file is -created using the mxmlNewElement and mxmlNewText functions. The first -argument of mxmlNewText specifies the parent node -(node). The second argument specifies whether whitespace -appears before the text - 0 or false in this case. The last -argument specifies the actual text to add:

    +

    Each <node>...</node> in the file is created using the +mxmlNewElement and mxmlNewText +functions. The first argument of mxmlNewText specifies the parent node +(node). The second argument specifies whether whitespace appears before +the text - 0 or false in this case. The last argument specifies the actual text +to add:

         node = mxmlNewElement(data, "node");
         mxmlNewText(node, 0, "val1");
     
    -

    The resulting in-memory XML document can then be saved or -processed just like one loaded from disk or a string.

    +

    The resulting in-memory XML document can then be saved or processed just like +one loaded from disk or a string.

    - +

    Loading XML

    You load an XML file using the ?xml element if the parent node is NULL.

    - +

    Saving XML

    You save an XML file using the mxmlSaveAllocString() returns a string buffer that was allocated using malloc().

    +

    Controlling Line Wrapping

    When saving XML documents, Mini-XML normally wraps output @@ -382,6 +428,25 @@ overrides the default wrap margin:

    mxmlSetWrapMargin(0); +

    Memory Management

    + +

    Once you are done with the XML data, use the mxmlDelete function to recursively +free the memory that is used for a particular node or the entire +tree:

    + +
    +    mxmlDelete(tree);
    +
    + +

    You can also use reference counting to manage memory usage. The +mxmlRetain and +mxmlRelease functions increment and +decrement a node's use count, respectively. When the use count goes to 0, +mxmlRelease will automatically call mxmlDelete to actually +free the memory used by the node tree. New nodes automatically start with a +use count of 1.

    +

    Finding and Iterating Nodes

    @@ -522,13 +587,15 @@ three constants:

    -

    Finding Value Nodes

    +

    Finding Specific Nodes

    -

    You can find the value of a specific node in the tree using the mxmlFindValue, for example: +

    You can find specific nodes in the tree using the mxmlFindPath, for example:

    -    mxml_node_t *value = mxmlFindValue(tree, "path/to/*/foo/bar");
    +    mxml_node_t *value;
    +
    +    value = mxmlFindPath(tree, "path/to/*/foo/bar");
     

    The second argument is a "path" to the parent node. Each component of the diff --git a/doc/docset.intro b/doc/docset.intro index a900653..a179ddd 100644 --- a/doc/docset.intro +++ b/doc/docset.intro @@ -18,7 +18,7 @@ as do most vendors' ANSI C compilers) and a "make" program.

  • Supports arbitrary element names, attributes, and attribute values with no preset limits, just available memory.
  • -
  • Supports integer, real, opaque ("cdata"), and text data types in +
  • Supports integer, real, opaque ("CDATA"), and text data types in "leaf" nodes.
  • Functions for creating, indexing, and managing trees of data.
  • @@ -146,6 +146,29 @@ for (node = mxmlFindElement(tree, tree, "name", NULL, } +

    The "mxmlFindPath()" function finds the (first) value node under a specific +element using a "path":

    + +
    +mxml_node_t *value = mxmlFindPath(tree, "path/to/*/foo/bar");
    +
    + +

    The "mxmlGetInteger()", "mxmlGetOpaque()", "mxmlGetReal()", and +"mxmlGetText()" functions retrieve the value from a node:

    + +
    +mxml_node_t *node;
    +
    +int intvalue = mxmlGetInteger(node);
    +
    +const char *opaquevalue = mxmlGetOpaque(node);
    +
    +double realvalue = mxmlGetReal(node);
    +
    +int whitespacevalue;
    +const char *textvalue = mxmlGetText(node, &whitespacevalue);
    +
    +

    Finally, once you are done with the XML data, use the "mxmlDelete()" function to recursively free the memory that is used for a particular node or the entire tree:

    diff --git a/doc/footer.man b/doc/footer.man index 62efb92..db38303 100644 --- a/doc/footer.man +++ b/doc/footer.man @@ -1,4 +1,4 @@ .SH SEE ALSO mxmldoc(1), Mini-XML Programmers Manual, http://www.minixml.org/ .SH COPYRIGHT -Copyright 2003-2008 by Michael Sweet. +Copyright 2003-2011 by Michael Sweet. diff --git a/doc/hires/logo.png b/doc/hires/logo.png deleted file mode 100644 index c966856..0000000 Binary files a/doc/hires/logo.png and /dev/null differ diff --git a/doc/install.html b/doc/install.html index 2a76973..5884501 100644 --- a/doc/install.html +++ b/doc/install.html @@ -94,7 +94,7 @@ of formats. The epm program is available from the following URL:

    -    http://www.easysw.com/epm/
    +    http://www.epmhome.org/
     

    Use the make command with the epm target diff --git a/doc/intro.html b/doc/intro.html index 7ad8fe0..53e93e3 100644 --- a/doc/intro.html +++ b/doc/intro.html @@ -37,7 +37,7 @@ and removed libxml2.

    Thanks to lots of feedback and support from various developers, Mini-XML has evolved since then to provide a more -complete XML implementation and now stands at a whopping 3,747 +complete XML implementation and now stands at a whopping 3,965 lines of code, compared to 103,893 lines of code for libxml2 version 2.6.9.

    diff --git a/doc/intro.man b/doc/intro.man index 7d05617..55bf45a 100644 --- a/doc/intro.man +++ b/doc/intro.man @@ -19,7 +19,7 @@ preserving the XML data hierarchy. Supports arbitrary element names, attributes, and attribute values with no preset limits, just available memory. .IP \(bu 4 -Supports integer, real, opaque ("cdata"), and text data types in +Supports integer, real, opaque ("CDATA"), and text data types in "leaf" nodes. .IP \(bu 4 Functions for creating, indexing, and managing trees of data. @@ -141,11 +141,27 @@ You can also iterate with the same function: } .fi .PP -To find the value of a specific node in the tree, use the "mxmlFindValue()" +To find the value of a specific node in the tree, use the "mxmlFindPath()" function: .nf - mxml_node_t *value = mxmlFindValue(tree, "path/to/*/foo/bar"); + mxml_node_t *value = mxmlFindPath(tree, "path/to/*/foo/bar"); +.fi +.PP +The "mxmlGetInteger()", "mxmlGetOpaque()", "mxmlGetReal()", and "mxmlGetText()" +functions retrieve the value from a node: +.nf + + mxml_node_t *node; + + int intvalue = mxmlGetInteger(node); + + const char *opaquevalue = mxmlGetOpaque(node); + + double realvalue = mxmlGetReal(node); + + int whitespacevalue; + const char *textvalue = mxmlGetText(node, &whitespacevalue); .fi .PP Finally, once you are done with the XML data, use the diff --git a/doc/license.html b/doc/license.html index da6f593..5a8ed3e 100644 --- a/doc/license.html +++ b/doc/license.html @@ -9,30 +9,26 @@ License the terms of the GNU Library General Public License version 2 (LGPL2) with the following exceptions:

    -
      - -
    1. Static linking of applications to the Mini-XML - library does not constitute a derivative work and does - not require the author to provide source code for the - application, use the shared Mini-XML libraries, or link - their applications against a user-supplied version of - Mini-XML. - -

      If you link the application to a modified version - of Mini-XML, then the changes to Mini-XML must be - provided under the terms of the LGPL2 in sections 1, 2, - and 4.

      -
    2. - -
    3. You do not have to provide a copy of the Mini-XML - license with programs that are linked to the Mini-XML - library, nor do you have to identify the Mini-XML license - in your program or documentation as required by section 6 - of the LGPL2.
    4. - -
    - - +

    1. Static linking of applications to the Mini-XML +library does not constitute a derivative work and does +not require the author to provide source code for the +application, use the shared Mini-XML libraries, or link +their applications against a user-supplied version of +Mini-XML.

    + +

    If you link the application to a modified version +of Mini-XML, then the changes to Mini-XML must be +provided under the terms of the LGPL2 in sections 1, 2, +and 4.

    + +

    2. You do not have to provide a copy of the Mini-XML +license with programs that are linked to the Mini-XML +library, nor do you have to identify the Mini-XML license +in your program or documentation as required by section 6 +of the LGPL2.

    + +

     

    +

    GNU LIBRARY GENERAL PUBLIC LICENSE

    Version 2, June 1991
    Copyright (C) 1991 Free Software Foundation, Inc. diff --git a/doc/logo.opacity b/doc/logo.opacity deleted file mode 100644 index f27a031..0000000 Binary files a/doc/logo.opacity and /dev/null differ diff --git a/doc/logo.png b/doc/logo.png deleted file mode 100644 index 836d655..0000000 Binary files a/doc/logo.png and /dev/null differ diff --git a/doc/mxml.html b/doc/mxml.html index 7dba598..d66adda 100644 --- a/doc/mxml.html +++ b/doc/mxml.html @@ -44,7 +44,20 @@ A { text-decoration: none } Getting Started with Mini-XML

    -
  • Finding and Iterating Nodes
  • -
  • Finding Value Nodes
  • +
  • Memory Management
  • +
  • Finding and Iterating Nodes
  • +
  • Finding Specific Nodes
  • More Mini-XML Programming Techniques @@ -203,7 +218,7 @@ libxml2 library with something substantially smaller and libxml2.

    Thanks to lots of feedback and support from various developers, Mini-XML has evolved since then to provide a more complete XML - implementation and now stands at a whopping 3,747 lines of code, + implementation and now stands at a whopping 3,965 lines of code, compared to 103,893 lines of code for libxml2 version 2.6.9.

    Aside from Gutenprint, Mini-XML is used for the following projects/software applications:

    @@ -386,7 +401,7 @@ rpmbuild(8) software to create Red Hat Package Manager ("RPM") epm(1) program to create software packages in a variety of formats. The epm program is available from the following URL:

    -    http://www.easysw.com/epm/
    +    http://www.epmhome.org/
     

    Use the make command with the epm target to create portable and native packages for your system:

    @@ -413,7 +428,7 @@ hspace="10" src="2.gif" width="100">Getting Started with Mini-XML
  • Writing of UTF-8 encoded XML files and strings.
  • Support for arbitrary element names, attributes, and attribute values with no preset limits, just available memory.
  • -
  • Support for integer, real, opaque ("cdata"), and text data types in +
  • Support for integer, real, opaque ("CDATA"), and text data types in "leaf" nodes.
  • "Find", "index", and "walk" functions for easily accessing data in an XML document.
  • @@ -440,47 +455,12 @@ hspace="10" src="2.gif" width="100">Getting Started with Mini-XML pkg-config --libs mxml ENTER

    Nodes

    -

    Every piece of information in an XML file (elements, text, numbers) - is stored in memory in "nodes". Nodes are defined by the -mxml_node_t structure. The type - member defines the node type (element, integer, opaque, real, or - text) which determines which value you want to look at in the -value union.

    - - -
    - - - - - - - - - -
    Table 2-1: Mini-XML Node Value - Members
    ValueTypeNode member
    Customvoid * -node->value.custom.data
    Elementchar * -node->value.element.name
    Integerintnode->value.integer -
    Opaque (string)char * -node->value.opaque
    Realdoublenode->value.real
    Textchar *node->value.text.string -
    -
    -

    Each node also has a user_data member which allows you to - associate application-specific data with each node as needed.

    -

    New nodes are created using the -mxmlNewElement, mxmlNewInteger -, mxmlNewOpaque, -mxmlNewReal, mxmlNewText -, mxmlNewTextf, and -mxmlNewXML functions. Only elements can have child nodes, - and the top node must be an element, usually the <?xml - version="1.0" encoding="utf-8"?> node created by mxmlNewXML() -.

    -

    Nodes have pointers to the node above (parent), below ( -child), left (prev), and right (next) of the - current node. If you have an XML file like the following:

    +

    Every piece of information in an XML file is stored in memory in + "nodes". Nodes are defined by the +mxml_node_t structure. Each node has a typed value, optional + user data, a parent node, sibling nodes (previous and next), and + potentially child nodes.

    +

    For example, if you have an XML file like the following:

         <?xml version="1.0" encoding="utf-8"?>
         <data>
    @@ -510,15 +490,96 @@ child), left (prev), and right (next) of the
                                |      |      |
                              val4   val5   val6
     
    -

    where "-" is a pointer to the next node and "|" is a pointer to the - first child node.

    -

    Once you are done with the XML data, use the -mxmlDelete function to recursively free the memory that is used - for a particular node or the entire tree:

    -
    -    mxmlDelete(tree);
    -
    +

    where "-" is a pointer to the sibling node and "|" is a pointer to + the first child or parent node.

    +

    The mxmlGetType function gets the + type of a node, one of MXML_CUSTOM, MXML_ELEMENT, +MXML_INTEGER, MXML_OPAQUE, MXML_REAL, or +MXML_TEXT. The parent and sibling nodes are accessed using the +mxmlGetParent, mxmlGetNext +, and mxmlGetPrevious functions. + The mxmlGetUserData function + gets any user data associated with the node.

    +

    CDATA Nodes

    +

    CDATA (MXML_ELEMENT) nodes are created using the +mxmlNewCDATA function. The +mxmlGetCDATA function retrieves the CDATA string pointer for a + node.

    +
    Note: +

    CDATA nodes are currently stored in memory as special elements. This + will be changed in a future major release of Mini-XML.

    +
    +

    Custom Nodes

    +

    Custom (MXML_CUSTOM) nodes are created using the +mxmlNewCustom function or using a custom load callback + specified using the +mxmlSetCustomHandlers function. The +mxmlGetCustom function retrieves the custom value pointer for a + node.

    +

    Comment Nodes

    +

    Comment (MXML_ELEMENT) nodes are created using the +mxmlNewElement function. The +mxmlGetElement function retrieves the comment string pointer + for a node, including the surrounding "!--" and "--" characters.

    +
    Note: +

    Comment nodes are currently stored in memory as special elements. + This will be changed in a future major release of Mini-XML.

    +
    +

    Element Nodes

    +

    Element (MXML_ELEMENT) nodes are created using the +mxmlNewElement function. The +mxmlGetElement function retrieves the element name, the +mxmlElementGetAttr function retrieves the value string for + a named attribute associated with the element, and the +mxmlGetFirstChild and +mxmlGetLastChild functions retrieve the first and last child + nodes for the element, respectively.

    +

    Integer Nodes

    +

    Integer (MXML_INTEGER) nodes are created using the +mxmlNewInteger function. The +mxmlGetInteger function retrieves the integer value for a node.

    +

    Opaque Nodes

    +

    Opaque (MXML_OPAQUE) nodes are created using the +mxmlNewOpaque function. The +mxmlGetOpaque function retrieves the opaque string pointer for + a node. Opaque nodes are like string nodes but preserve all whitespace + between nodes.

    +

    Text Nodes

    +

    Text (MXML_TEXT) nodes are created using the +mxmlNewText and mxmlNewTextf + functions. Each text node consists of a text string and (leading) + whitespace value - the mxmlGetText + function retrieves the text string pointer and whitespace value for a + node.

    + + +

    Processing Instruction Nodes

    +

    Processing instruction (MXML_ELEMENT) nodes are created + using the mxmlNewElement + function. The mxmlGetElement + function retrieves the processing instruction string for a node, + including the surrounding "?" characters.

    +
    Note: +

    Processing instruction nodes are currently stored in memory as + special elements. This will be changed in a future major release of + Mini-XML.

    +
    +

    Real Number Nodes

    +

    Real number (MXML_REAL) nodes are created using the +mxmlNewReal function. The +mxmlGetReal function retrieves the CDATA string pointer for a + node.

    + +

    XML Declaration Nodes

    +

    XML declaration (MXML_ELEMENT) nodes are created using the mxmlNewXML function. The +mxmlGetElement function retrieves the XML declaration + string for a node, including the surrounding "?" characters.

    +
    Note: +

    XML declaration nodes are currently stored in memory as special + elements. This will be changed in a future major release of Mini-XML.

    +

    Creating XML Documents

    You can create and update XML documents in memory using the various @@ -555,9 +616,10 @@ mxmlNew functions. The following code will create the XML document node = mxmlNewElement(data, "node"); mxmlNewText(node, 0, "val8"); -

    We start by creating the <?xml version="1.0" encoding="utf-8"?> - node common to all XML files using the -mxmlNewXML function:

    + + +

    We start by creating the declaration node common to all XML files + using the mxmlNewXML function:

         xml = mxmlNewXML("1.0");
     
    @@ -581,7 +643,7 @@ mxmlNewElement and mxmlNewText

    The resulting in-memory XML document can then be saved or processed just like one loaded from disk or a string.

    - +

    Loading XML

    You load an XML file using the mxmlLoadFile function:

    @@ -629,7 +691,7 @@ mxmlLoadFile(). The second argument specifies the string or character buffer to load and must be a complete XML document including the ?xml element if the parent node is NULL.

    - +

    Saving XML

    You save an XML file using the mxmlSaveFile function:

    @@ -670,6 +732,8 @@ mxmlSaveFile(). The mxmlSaveString function takes pointer and size arguments for saving the XML document to a fixed-size buffer, while mxmlSaveAllocString() returns a string buffer that was allocated using malloc().

    + +

    Controlling Line Wrapping

    When saving XML documents, Mini-XML normally wraps output lines at column 75 so that the text is readable in terminal windows. The @@ -682,9 +746,22 @@ mxmlSaveFile(). The mxmlSaveString function takes pointer /* Disable wrapping */ mxmlSetWrapMargin(0); +

    Memory Management

    +

    Once you are done with the XML data, use the +mxmlDelete function to recursively free the memory that is used + for a particular node or the entire tree:

    +
    +    mxmlDelete(tree);
    +
    +

    You can also use reference counting to manage memory usage. The +mxmlRetain and mxmlRelease + functions increment and decrement a node's use count, respectively. + When the use count goes to 0, mxmlRelease will automatically + call mxmlDelete to actually free the memory used by the node + tree. New nodes automatically start with a use count of 1.

    -

    Finding and Iterating Nodes

    +

    Finding and Iterating Nodes

    The mxmlWalkPrev and mxmlWalkNextfunctions can be used to iterate through the XML node tree:

    @@ -806,11 +883,13 @@ mxmlSaveFile(). The mxmlSaveString function takes pointer the order would be reversed, ending at "?xml".

    -

    Finding Value Nodes

    -

    You can find the value of a specific node in the tree using the -mxmlFindValue, for example:

    +

    Finding Specific Nodes

    +

    You can find specific nodes in the tree using the +mxmlFindPath, for example:

    -    mxml_node_t *value = mxmlFindValue(tree, "path/to/*/foo/bar");
    +    mxml_node_t *value;
    +
    +    value = mxmlFindPath(tree, "path/to/*/foo/bar");
     

    The second argument is a "path" to the parent node. Each component of the path is separated by a slash (/) and represents a named element in @@ -865,7 +944,7 @@ MXML_REAL, or MXML_TEXT. The function is called after type = mxmlElementGetAttr(node, "type"); if (type == NULL) - type = node->value.element.name; + type = mxmlGetElement(node); if (!strcmp(type, "integer")) return (MXML_INTEGER); @@ -916,7 +995,7 @@ MXML_WS_BEFORE_CLOSE, or MXML_WS_AFTER_CLOSE. The callback * just common HTML elements... */ - name = node->value.element.name; + name = mxmlGetElement(node); if (!strcmp(name, "html") || !strcmp(name, "head") || @@ -1080,8 +1159,7 @@ MXML_WS_BEFORE_CLOSE, or MXML_WS_AFTER_CLOSE. The callback * function pointers... */ - node->value.custom.data = dt; - node->value.custom.destroy = free; + mxmlSetCustom(node, data, destroy); /* * Return with no errors... @@ -1095,6 +1173,8 @@ MXML_WS_BEFORE_CLOSE, or MXML_WS_AFTER_CLOSE. The callback contain a void pointer to the allocated custom data for the node and a pointer to a destructor function which will free the custom data when the node is deleted.

    + +

    The save callback receives the node pointer and returns an allocated string containing the custom data value. The following save callback could be used for our ISO date/time type:

    @@ -1106,7 +1186,7 @@ MXML_WS_BEFORE_CLOSE, or MXML_WS_AFTER_CLOSE. The callback iso_date_time_t *dt; - dt = (iso_date_time_t *)node->custom.data; + dt = (iso_date_time_t *)mxmlGetCustom(node); snprintf(data, sizeof(data), "%04u-%02u-%02uT%02u:%02u:%02uZ", @@ -1297,7 +1377,7 @@ mxmlRetain function. For example, the following SAX callback * Retain headings and titles... */ - char *name = node->value.element.name; + char *name = mxmlGetElement(node); if (!strcmp(name, "html") || !strcmp(name, "head") || @@ -1313,15 +1393,17 @@ mxmlRetain function. For example, the following SAX callback } else if (event == MXML_SAX_DIRECTIVE) mxmlRetain(node); - else if (event == MXML_SAX_DATA && - node->parent->ref_count > 1) + else if (event == MXML_SAX_DATA) { - /* - * If the parent was retained, then retain - * this data node as well. - */ + if (mxmlGetRefCount(mxmlGetParent(node)) > 1) + { + /* + * If the parent was retained, then retain + * this data node as well. + */ - mxmlRetain(node); + mxmlRetain(node); + } } } @@ -1349,9 +1431,9 @@ mxmlRetain function. For example, the following SAX callback if (body) { - for (heading = body->child; + for (heading = mxmlGetFirstChild(body); heading; - heading = heading->next) + heading = mxmlGetNextSibling(heading)) print_children(heading); } @@ -1417,7 +1499,7 @@ hspace="10" src="4.gif" width="100">Using the mxmldoc Utility will document all public names it finds in your source files - any names starting with the underscore character (_) or names that are documented with the @private@ directive are - treated as private and are undocumented.

    + treated as private and are not documented.

    Comments appearing directly before a function or type definition are used to document that function or type. Comments appearing after argument, definition, return type, or variable declarations are used to @@ -1472,8 +1554,8 @@ hspace="10" src="4.gif" width="100">Using the mxmldoc Utility included in the documentation

  • @since ...@ - flags the item as new since a particular release. The text following the @since up to the closing @ - is highlighted in the generated documentation, e.g. @since CUPS - 1.3@.
  • + is highlighted in the generated documentation, e.g. @since Mini-XML + 2.7@. @@ -1513,22 +1595,19 @@ hspace="10" src="A.gif" width="100">Mini-XML License

    The Mini-XML library and included programs are provided under the terms of the GNU Library General Public License version 2 (LGPL2) with the following exceptions:

    -
      -
    1. Static linking of applications to the Mini-XML library does not - constitute a derivative work and does not require the author to provide - source code for the application, use the shared Mini-XML libraries, or - link their applications against a user-supplied version of Mini-XML. +

      1. Static linking of applications to the Mini-XML library does + not constitute a derivative work and does not require the author to + provide source code for the application, use the shared Mini-XML + libraries, or link their applications against a user-supplied version + of Mini-XML.

      If you link the application to a modified version of Mini-XML, then the changes to Mini-XML must be provided under the terms of the LGPL2 in sections 1, 2, and 4.

      -
    2. -
    3. You do not have to provide a copy of the Mini-XML license with - programs that are linked to the Mini-XML library, nor do you have to - identify the Mini-XML license in your program or documentation as - required by section 6 of the LGPL2.
    4. -
    - - +

    2. You do not have to provide a copy of the Mini-XML license + with programs that are linked to the Mini-XML library, nor do you have + to identify the Mini-XML license in your program or documentation as + required by section 6 of the LGPL2.

    +

     

    GNU LIBRARY GENERAL PUBLIC LICENSE

    Version 2, June 1991
    Copyright (C) 1991 Free Software Foundation, Inc. @@ -1947,9 +2026,12 @@ hspace="10" src="A.gif" width="100">Mini-XML License hspace="10" src="B.gif" width="100">Release Notes

    Changes in Mini-XML 2.7

    diff --git a/doc/mxmldoc.xsd b/doc/mxmldoc.xsd index 3d1124b..26c6508 100644 --- a/doc/mxmldoc.xsd +++ b/doc/mxmldoc.xsd @@ -2,8 +2,8 @@ - Mini-XML 2.3 documentation schema for mxmldoc output. - Copyright 2003-2007 by Michael Sweet. + Mini-XML 2.7 documentation schema for mxmldoc output. + Copyright 2003-2011 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 diff --git a/doc/reference.html b/doc/reference.html index 1905021..55f3cdb 100644 --- a/doc/reference.html +++ b/doc/reference.html @@ -155,7 +155,7 @@ Reference
  • mxmlEntityGetValue
  • mxmlEntityRemoveCallback
  • mxmlFindElement
  • -
  • mxmlFindValue
  • +
  • mxmlFindPath
  • mxmlGetCDATA
  • mxmlGetCustom
  • mxmlGetElement
  • @@ -163,11 +163,12 @@ Reference
  • mxmlGetInteger
  • mxmlGetLastChild
  • -
  • mxmlGetNext
  • +
  • mxmlGetNextSibling
  • mxmlGetOpaque
  • mxmlGetParent
  • -
  • mxmlGetPrevious
  • +
  • mxmlGetPrevSibling
  • mxmlGetReal
  • +
  • mxmlGetRefCount
  • mxmlGetText
  • mxmlGetType
  • mxmlGetUserData
  • @@ -452,10 +453,10 @@ whether the search descends into child nodes; normally you will use MXML_DESCEND_FIRST for the initial search and MXML_NO_DESCEND to find additional direct descendents of the node. The top node argument constrains the search to a particular node's children.

    -

     Mini-XML 2.7 mxmlFindValue

    -

    Find a value with the given path.

    +

     Mini-XML 2.7 mxmlFindPath

    +

    Find a node with the given path.

    -mxml_node_t *mxmlFindValue (
    +mxml_node_t *mxmlFindPath (
        mxml_node_t *top,
        const char *path
    );

    @@ -467,17 +468,20 @@ constrains the search to a particular node's children.

    Path to element

    Return Value

    -

    First value node or NULL

    +

    Found node or NULL

    Discussion

    The "path" is a slash-separated list of element names. The name "*" is considered a wildcard for one or more levels of elements. For example, -"foo/one/two", "bar/two/one", "*/one", and so forth. +"foo/one/two", "bar/two/one", "*/one", and so forth.
    +
    +The first child node of the found node is returned if the given node has +children and the first child is a value node.

     Mini-XML 2.7 mxmlGetCDATA

    Get the value for a CDATA node.

    -char *mxmlGetCDATA (
    +const char *mxmlGetCDATA (
        mxml_node_t *node
    );

    Parameters

    @@ -494,7 +498,7 @@ char *mxmlGetCDATA (

     Mini-XML 2.7 mxmlGetCustom

    Get the value for a custom node.

    -void *mxmlGetCustom (
    +const void *mxmlGetCustom (
        mxml_node_t *node
    );

    Parameters

    @@ -512,7 +516,7 @@ value node.

     Mini-XML 2.7 mxmlGetElement

    Get the name for an element node.

    -char *mxmlGetElement (
    +const char *mxmlGetElement (
        mxml_node_t *node
    );

    Parameters

    @@ -580,10 +584,10 @@ int mxmlGetInteger (
    has no children.

    -

    mxmlGetNext

    +

    mxmlGetNextSibling

    Return the node type...

    -mxml_node_t *mxmlGetNext (
    +mxml_node_t *mxmlGetNextSibling (
        mxml_node_t *node
    );

    Parameters

    @@ -599,7 +603,7 @@ has no children.

     Mini-XML 2.7 mxmlGetOpaque

    Get an opaque string value for a node or its first child.

    -char *mxmlGetOpaque (
    +const char *mxmlGetOpaque (
        mxml_node_t *node
    );

    Parameters

    @@ -631,10 +635,10 @@ value node.

    NULL is returned for a root node.

    -

     Mini-XML 2.7 mxmlGetPrevious

    +

     Mini-XML 2.7 mxmlGetPrevSibling

    Get the previous node for the current parent.

    -mxml_node_t *mxmlGetPrevious (
    +mxml_node_t *mxmlGetPrevSibling (
        mxml_node_t *node
    );

    Parameters

    @@ -665,10 +669,29 @@ double mxmlGetReal (

    0.0 is returned if the node (or its first child) is not a real value node.

    +

     Mini-XML 2.7 mxmlGetRefCount

    +

    Get the current reference (use) count for a node.

    +

    +int mxmlGetRefCount (
    +    mxml_node_t *node
    +);

    +

    Parameters

    +
    +
    node
    +
    Node
    +
    +

    Return Value

    +

    Reference count

    +

    Discussion

    +

    The initial reference count of new nodes is 1. Use the mxmlRetain +and mxmlRelease functions to increment and decrement a node's +reference count. + +.

     Mini-XML 2.7 mxmlGetText

    Get the text value for a node or its first child.

    -char *mxmlGetText (
    +const char *mxmlGetText (
        mxml_node_t *node,
        int *whitespace
    );

    diff --git a/doc/relnotes.html b/doc/relnotes.html index c409162..6dceabf 100644 --- a/doc/relnotes.html +++ b/doc/relnotes.html @@ -9,10 +9,14 @@ hspace="10" width="100" height="100" alt="B">Release Notes
      +
    • Added data accessor ("get") functions and made the mxml_node_t and + mxml_index_t structures private but still available in the Mini-XML + header to preserve source compatibility (STR #118)
    • +
    • Updated the source headers to reference the Mini-XML license and its exceptions to the LGPL2 (STR #108)
    • -
    • Added a new mxmlFindValue() function to find the value node of a +
    • Added a new mxmlFindPath() function to find the value node of a named element (STR #110)
    • Building a static version of the library did not work on Windows diff --git a/doc/schema.html b/doc/schema.html index 15cce10..3ba0261 100644 --- a/doc/schema.html +++ b/doc/schema.html @@ -9,7 +9,7 @@ files produced by mxmldoc. This schema is available on-line at:

      -    http://www.easysw.com/~mike/mxmldoc.xsd
      +    http://www.minixml.org/mxmldoc.xsd
       

      mxmldoc.xsd

      @@ -19,8 +19,8 @@ at:

      <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:annotation> <xsd:documentation xml:lang="en"> - Mini-XML 2.3 documentation schema for mxmldoc output. - Copyright 2003-2007 by Michael Sweet. + Mini-XML 2.7 documentation schema for mxmldoc output. + Copyright 2003-2011 by Michael Sweet. </xsd:documentation> </xsd:annotation> diff --git a/mxml-get.c b/mxml-get.c index 2fb1e23..fa96d87 100644 --- a/mxml-get.c +++ b/mxml-get.c @@ -15,22 +15,22 @@ * * Contents: * - * mxmlGetCDATA() - Get the value for a CDATA node. - * mxmlGetCustom() - Get the value for a custom node. - * mxmlGetElement() - Get the name for an element node. - * mxmlGetFirstChild() - Get the first child of an element node. - * mxmlGetInteger() - Get the integer value from the specified node or its - * first child. - * mxmlGetLastChild() - Get the last child of an element node. - * mxmlGetNext() - Get the next node for the current parent. - * mxmlGetOpaque() - Get an opaque string value for a node or its first - * child. - * mxmlGetParent() - Get the parent node. - * mxmlGetPrevious() - Get the previous node for the current parent. - * mxmlGetReal() - Get the real value for a node or its first child. - * mxmlGetText() - Get the text value for a node or its first child. - * mxmlGetType() - Get the node type. - * mxmlGetUserData() - Get the user data pointer for a node. + * mxmlGetCDATA() - Get the value for a CDATA node. + * mxmlGetCustom() - Get the value for a custom node. + * mxmlGetElement() - Get the name for an element node. + * mxmlGetFirstChild() - Get the first child of an element node. + * mxmlGetInteger() - Get the integer value from the specified node or its + * first child. + * mxmlGetLastChild() - Get the last child of an element node. + * mxmlGetNextSibling() - Get the next node for the current parent. + * mxmlGetOpaque() - Get an opaque string value for a node or its first + * child. + * mxmlGetParent() - Get the parent node. + * mxmlGetPrevSibling() - Get the previous node for the current parent. + * mxmlGetReal() - Get the real value for a node or its first child. + * mxmlGetText() - Get the text value for a node or its first child. + * mxmlGetType() - Get the node type. + * mxmlGetUserData() - Get the user data pointer for a node. */ /* @@ -49,7 +49,7 @@ * @since Mini-XML 2.7@ */ -char * /* O - CDATA value or NULL */ +const char * /* O - CDATA value or NULL */ mxmlGetCDATA(mxml_node_t *node) /* I - Node to get */ { /* @@ -77,7 +77,7 @@ mxmlGetCDATA(mxml_node_t *node) /* I - Node to get */ * @since Mini-XML 2.7@ */ -void * /* O - Custom value or NULL */ +const void * /* O - Custom value or NULL */ mxmlGetCustom(mxml_node_t *node) /* I - Node to get */ { /* @@ -110,7 +110,7 @@ mxmlGetCustom(mxml_node_t *node) /* I - Node to get */ * @since Mini-XML 2.7@ */ -char * /* O - Element name or NULL */ +const char * /* O - Element name or NULL */ mxmlGetElement(mxml_node_t *node) /* I - Node to get */ { /* @@ -217,7 +217,7 @@ mxmlGetLastChild(mxml_node_t *node) /* I - Node to get */ /* - * 'mxmlGetNext()' - Get the next node for the current parent. + * 'mxmlGetNextSibling()' - Get the next node for the current parent. * * @code NULL@ is returned if this is the last child for the current parent. * @@ -225,7 +225,7 @@ mxmlGetLastChild(mxml_node_t *node) /* I - Node to get */ */ mxml_node_t * -mxmlGetNext(mxml_node_t *node) /* I - Node to get */ +mxmlGetNextSibling(mxml_node_t *node) /* I - Node to get */ { /* * Range check input... @@ -251,7 +251,7 @@ mxmlGetNext(mxml_node_t *node) /* I - Node to get */ * @since Mini-XML 2.7@ */ -char * /* O - Opaque string or NULL */ +const char * /* O - Opaque string or NULL */ mxmlGetOpaque(mxml_node_t *node) /* I - Node to get */ { /* @@ -303,7 +303,7 @@ mxmlGetParent(mxml_node_t *node) /* I - Node to get */ /* - * 'mxmlGetPrevious()' - Get the previous node for the current parent. + * 'mxmlGetPrevSibling()' - Get the previous node for the current parent. * * @code NULL@ is returned if this is the first child for the current parent. * @@ -311,7 +311,7 @@ mxmlGetParent(mxml_node_t *node) /* I - Node to get */ */ mxml_node_t * /* O - Previous node or NULL */ -mxmlGetPrevious(mxml_node_t *node) /* I - Node to get */ +mxmlGetPrevSibling(mxml_node_t *node) /* I - Node to get */ { /* * Range check input... @@ -370,7 +370,7 @@ mxmlGetReal(mxml_node_t *node) /* I - Node to get */ * @since Mini-XML 2.7@ */ -char * /* O - Text string or NULL */ +const char * /* O - Text string or NULL */ mxmlGetText(mxml_node_t *node, /* I - Node to get */ int *whitespace) /* O - 1 if string is preceded by whitespace, 0 otherwise */ { diff --git a/mxml-node.c b/mxml-node.c index fc72b56..d4c94a3 100644 --- a/mxml-node.c +++ b/mxml-node.c @@ -3,7 +3,7 @@ * * Node support code for Mini-XML, a small XML-like file parsing library. * - * Copyright 2003-2010 by Michael R Sweet. + * Copyright 2003-2011 by Michael R Sweet. * * These coded instructions, statements, and computer programs are the * property of Michael R Sweet and are protected by Federal copyright @@ -15,21 +15,6 @@ * * Contents: * - * mxmlAdd() - Add a node to a tree. - * mxmlDelete() - Delete a node and all of its children. - * mxmlNewCDATA() - Create a new CDATA node. - * mxmlNewCustom() - Create a new custom data node. - * mxmlNewElement() - Create a new element node. - * mxmlNewInteger() - Create a new integer node. - * mxmlNewOpaque() - Create a new opaque string. - * mxmlNewReal() - Create a new real number node. - * mxmlNewText() - Create a new text fragment node. - * mxmlNewTextf() - Create a new formatted text fragment node. - * mxmlNewXML() - Create a new XML document tree. - * mxmlRelease() - Release a node. - * mxmlRemove() - Remove a node from its parent. - * mxmlRetain() - Retain a node. - * mxml_new() - Create a new node. */ /* @@ -276,6 +261,34 @@ mxmlDelete(mxml_node_t *node) /* I - Node to delete */ } +/* + * 'mxmlGetRefCount()' - Get the current reference (use) count for a node. + * + * The initial reference count of new nodes is 1. Use the @link mxmlRetain@ + * and @link mxmlRelease@ functions to increment and decrement a node's + * reference count. + * + * @since Mini-XML 2.7@. + */ + +int /* O - Reference count */ +mxmlGetRefCount(mxml_node_t *node) /* I - Node */ +{ + /* + * Range check input... + */ + + if (!node) + return (0); + + /* + * Return the reference count... + */ + + return (node->ref_count); +} + + /* * 'mxmlNewCDATA()' - Create a new CDATA node. * diff --git a/mxml-search.c b/mxml-search.c index ab0e1b3..31265fc 100644 --- a/mxml-search.c +++ b/mxml-search.c @@ -118,22 +118,25 @@ mxmlFindElement(mxml_node_t *node, /* I - Current node */ /* - * 'mxmlFindValue()' - Find a value with the given path. + * 'mxmlFindPath()' - Find a node with the given path. * * The "path" is a slash-separated list of element names. The name "*" is * considered a wildcard for one or more levels of elements. For example, * "foo/one/two", "bar/two/one", "*\/one", and so forth. * + * The first child node of the found node is returned if the given node has + * children and the first child is a value node. + * * @since Mini-XML 2.7@ */ -mxml_node_t * /* O - First value node or NULL */ -mxmlFindValue(mxml_node_t *top, /* I - Top node */ - const char *path) /* I - Path to element */ +mxml_node_t * /* O - Found node or NULL */ +mxmlFindPath(mxml_node_t *top, /* I - Top node */ + const char *path) /* I - Path to element */ { mxml_node_t *node; /* Current node */ - char element[256], /* Current element name */ - *pathsep; /* Separator in path */ + char element[256]; /* Current element name */ + const char *pathsep; /* Separator in path */ int descend; /* mxmlFindElement option */ @@ -191,10 +194,13 @@ mxmlFindValue(mxml_node_t *top, /* I - Top node */ } /* - * If we get this far, return the first child of the current node... + * If we get this far, return the node or its first child... */ - return (node->child); + if (node->child && node->child->type != MXML_ELEMENT) + return (node->child); + else + return (node); } diff --git a/mxml.h b/mxml.h index 216a195..8886812 100644 --- a/mxml.h +++ b/mxml.h @@ -210,19 +210,20 @@ extern void mxmlEntityRemoveCallback(mxml_entity_cb_t cb); extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top, const char *name, const char *attr, const char *value, int descend); -extern mxml_node_t *mxmlFindValue(mxml_node_t *node, const char *path); -extern char *mxmlGetCDATA(mxml_node_t *node); -extern void *mxmlGetCustom(mxml_node_t *node); -extern char *mxmlGetElement(mxml_node_t *node); +extern mxml_node_t *mxmlFindPath(mxml_node_t *node, const char *path); +extern const char *mxmlGetCDATA(mxml_node_t *node); +extern const void *mxmlGetCustom(mxml_node_t *node); +extern const char *mxmlGetElement(mxml_node_t *node); extern mxml_node_t *mxmlGetFirstChild(mxml_node_t *node); extern int mxmlGetInteger(mxml_node_t *node); extern mxml_node_t *mxmlGetLastChild(mxml_node_t *node); -extern mxml_node_t *mxmlGetNext(mxml_node_t *node); -extern char *mxmlGetOpaque(mxml_node_t *node); +extern mxml_node_t *mxmlGetNextSibling(mxml_node_t *node); +extern const char *mxmlGetOpaque(mxml_node_t *node); extern mxml_node_t *mxmlGetParent(mxml_node_t *node); -extern mxml_node_t *mxmlGetPrevious(mxml_node_t *node); +extern mxml_node_t *mxmlGetPrevSibling(mxml_node_t *node); extern double mxmlGetReal(mxml_node_t *node); -extern char *mxmlGetText(mxml_node_t *node, int *whitespace); +extern int mxmlGetRefCount(mxml_node_t *node); +extern const char *mxmlGetText(mxml_node_t *node, int *whitespace); extern mxml_type_t mxmlGetType(mxml_node_t *node); extern void *mxmlGetUserData(mxml_node_t *node); extern void mxmlIndexDelete(mxml_index_t *ind); diff --git a/mxml.xml b/mxml.xml index fca5a40..f5950fd 100644 --- a/mxml.xml +++ b/mxml.xml @@ -197,17 +197,20 @@ constrains the search to a particular node's children. Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST - + mxml_node_t * - First value node or NULL + Found node or NULL - Find a value with the given path. + Find a node with the given path. The "path" is a slash-separated list of element names. The name "*" is considered a wildcard for one or more levels of elements. For example, "foo/one/two", "bar/two/one", "*/one", and so forth. +The first child node of the found node is returned if the given node has +children and the first child is a value node. + @since Mini-XML 2.7@ mxml_node_t * @@ -220,7 +223,7 @@ considered a wildcard for one or more levels of elements. For example, - char * + const char * CDATA value or NULL Get the value for a CDATA node. @@ -235,7 +238,7 @@ considered a wildcard for one or more levels of elements. For example, - void * + const void * Custom value or NULL Get the value for a custom node. @@ -251,7 +254,7 @@ value node. - char * + const char * Element name or NULL Get the name for an element node. @@ -312,7 +315,7 @@ has no children. Node to get - + mxml_node_t * Get the next node for the current parent. @@ -329,7 +332,7 @@ has no children. - char * + const char * Opaque string or NULL Get an opaque string value for a node or its first child. @@ -358,7 +361,7 @@ value node. Node to get - + mxml_node_t * Previous node or NULL @@ -388,9 +391,26 @@ value node. Node to get + + + int + Reference count + + Get the current reference (use) count for a node. + +The initial reference count of new nodes is 1. Use the @link mxmlRetain@ +and @link mxmlRelease@ functions to increment and decrement a node's +reference count. + +@since Mini-XML 2.7@. + + mxml_node_t * + Node + + - char * + const char * Text string or NULL Get the text value for a node or its first child. diff --git a/testmxml.c b/testmxml.c index 2fc1329..d06a9dc 100644 --- a/testmxml.c +++ b/testmxml.c @@ -261,10 +261,10 @@ main(int argc, /* I - Number of command-line args */ } /* - * Test mxmlFindValue... + * Test mxmlFindPath... */ - node = mxmlFindValue(tree, "*/two"); + node = mxmlFindPath(tree, "*/two"); if (!node) { fputs("ERROR: Unable to find value for \"*/two\".\n", stderr); @@ -278,7 +278,7 @@ main(int argc, /* I - Number of command-line args */ return (1); } - node = mxmlFindValue(tree, "foo/*/two"); + node = mxmlFindPath(tree, "foo/*/two"); if (!node) { fputs("ERROR: Unable to find value for \"foo/*/two\".\n", stderr); @@ -292,7 +292,7 @@ main(int argc, /* I - Number of command-line args */ return (1); } - node = mxmlFindValue(tree, "foo/bar/one/two"); + node = mxmlFindPath(tree, "foo/bar/one/two"); if (!node) { fputs("ERROR: Unable to find value for \"foo/bar/one/two\".\n", stderr); diff --git a/vcnet/mxml1.def b/vcnet/mxml1.def index 04ca1e5..90725f8 100644 --- a/vcnet/mxml1.def +++ b/vcnet/mxml1.def @@ -17,10 +17,26 @@ EXPORTS mxmlEntityGetValue mxmlEntityRemoveCallback mxmlFindElement - mxmlFindValue + mxmlFindPath + mxmlGetCDATA + mxmlGetCustom + mxmlGetElement + mxmlGetFirstChild + mxmlGetInteger + mxmlGetLastChild + mxmlGetNextSibling + mxmlGetOpaque + mxmlGetParent + mxmlGetPrevSibling + mxmlGetReal + mxmlGetRefCount + mxmlGetText + mxmlGetType + mxmlGetUserData mxmlIndexDelete mxmlIndexEnum mxmlIndexFind + mxmlIndexGetCount mxmlIndexNew mxmlIndexReset mxmlLoadFd @@ -55,6 +71,7 @@ EXPORTS mxmlSetReal mxmlSetText mxmlSetTextf + mxmlSetUserData mxmlSetWrapMargin mxmlWalkNext mxmlWalkPrev diff --git a/vcnet/mxml1.vcproj b/vcnet/mxml1.vcproj index cb933a4..0264008 100644 --- a/vcnet/mxml1.vcproj +++ b/vcnet/mxml1.vcproj @@ -196,6 +196,10 @@ RelativePath="..\mxml-file.c" > + +