Mini-XML is a small XML parsing library that you can use to read XML and
4 | XML-like data files in your application without requiring large non-standard
5 | libraries. Mini-XML only requires an ANSI C compatible compiler (GCC works,
6 | as do most vendors' ANSI C compilers) and a "make" program.
7 |
8 |
Mini-XML provides the following functionality:
9 |
10 |
11 |
12 |
Reading of UTF-8 and UTF-16 and writing of UTF-8 encoded XML files
13 | and strings.
14 |
15 |
Data is stored in a linked-list tree structure, preserving the XML
16 | data hierarchy.
17 |
18 |
Supports arbitrary element names, attributes, and attribute values
19 | with no preset limits, just available memory.
20 |
21 |
Supports integer, real, opaque ("CDATA"), and text data types in
22 | "leaf" nodes.
23 |
24 |
Functions for creating, indexing, and managing trees of data.
25 |
26 |
"Find" and "walk" functions for easily locating and navigating trees
27 | of data.
28 |
29 |
30 |
31 |
Mini-XML doesn't do validation or other types of processing on the data based
32 | upon schema files or other sources of definition information, nor does it
33 | support character entities other than those required by the XML
34 | specification.
Mini-XML provides a single header file which you include:
39 |
40 |
41 | #include <mxml.h>
42 |
43 |
44 |
Nodes are defined by the "mxml_node_t" structure;
45 | the "type" member defines the node type (element, integer, opaque, real, or
46 | text) which determines which value you want to look at in the "value" union.
47 | New nodes can be created using the
48 | "mxmlNewElement()",
49 | "mxmlNewInteger()",
50 | "mxmlNewOpaque()",
51 | "mxmlNewReal()", and
52 | "mxmlNewText()" functions. Only elements can have
53 | child nodes, and the top node must be an element, usually "?xml".
54 |
55 |
You load an XML file using the "mxmlLoadFile()" function:
Finally, once you are done with the XML data, use the
173 | "mxmlDelete()" function to recursively free the
174 | memory that is used for a particular node or the entire tree:
This chapter describes how to build, install, and package
9 | Mini-XML on your system from the source archive. You will need an
10 | ANSI/ISO-C compatible compiler to build Mini-XML - GCC works, as
11 | do most vendors' C compilers. If you are building Mini-XML on
12 | Windows, we recommend using the Visual C++ environment with the
13 | supplied solution file. For other operating systems, you'll need a
14 | POSIX-compatible shell and make program in addition to
15 | the C compiler.
16 |
17 |
Compiling Mini-XML
18 |
19 |
Mini-XML comes with both an autoconf-based configure script
20 | and a Visual C++ solution that can be used to compile the library
21 | and associated tools.
22 |
23 |
Compiling with Visual C++
24 |
25 |
Open the mxml.sln solution in the vcnet
26 | folder. Choose the desired build configuration, "Debug" (the
27 | default) or "Release", and then choose Build Solution
28 | from the Build menu.
29 |
30 |
Compiling with Command-Line Tools
31 |
32 |
Type the following command to configure the Mini-XML source
33 | code for your system:
34 |
35 |
36 | ./configure ENTER
37 |
38 |
39 |
The default install prefix is /usr/local, which
40 | can be overridden using the --prefix option:
41 |
42 |
43 | ./configure --prefix=/foo ENTER
44 |
45 |
46 |
Other configure options can be found using the
47 | --help option:
48 |
49 |
50 | ./configure --help ENTER
51 |
52 |
53 |
Once you have configured the software, use the
54 | make(1) program to do the build and run the test
55 | program to verify that things are working, as follows:
56 |
57 |
58 | make ENTER
59 |
60 |
61 |
62 |
Installing Mini-XML
63 |
64 |
If you are using Visual C++, copy the mxml.lib and
65 | and mxml.h files to the Visual C++ lib and
66 | include directories, respectively.
67 |
68 |
Otherwise, use the make command with the
69 | install target to install Mini-XML in the configured
70 | directories:
71 |
72 |
73 | make install ENTER
74 |
75 |
76 |
77 |
Creating Mini-XML Packages
78 |
79 |
Mini-XML includes two files that can be used to create binary
80 | packages. The first file is mxml.spec which is used
81 | by the rpmbuild(8) software to create Red Hat Package
82 | Manager ("RPM") packages which are commonly used on Linux. Since
83 | rpmbuild wants to compile the software on its own, you
84 | can provide it with the Mini-XML tar file to build the
85 | package:
86 |
87 |
88 | rpmbuild -ta mxml-version.tar.gz ENTER
89 |
90 |
91 |
The second file is mxml.list which is used by the
92 | epm(1) program to create software packages in a variety
93 | of formats. The epm program is available from the
94 | following URL:
Use the make command with the epm target
101 | to create portable and native packages for your system:
102 |
103 |
104 | make epm ENTER
105 |
106 |
107 |
The packages are stored in a subdirectory named
108 | dist for your convenience. The portable packages
109 | utilize scripts and tar files to install the software on the
110 | target system. After extracting the package archive, use the
111 | mxml.install script to install the software.
112 |
113 |
The native packages will be in the local OS's native format:
114 | RPM for Red Hat Linux, DPKG for Debian Linux, PKG for Solaris,
115 | and so forth. Use the corresponding commands to install the
116 | native packages.
This programmers manual describes Mini-XML version 2.8, a small
14 | XML parsing library that you can use to read and write XML data
15 | files in your C and C++ applications.
16 |
17 |
Mini-XML was initially developed for the Gutenprint project to replace
19 | the rather large and unwieldy libxml2 library with
20 | something substantially smaller and easier-to-use. It all began one
21 | morning in June of 2003 when Robert posted the following sentence to
22 | the developer's list:
23 |
24 |
It's bad enough that we require libxml2, but rolling
25 | our own XML parser is a bit more than we can handle.
26 |
27 |
I then replied with:
28 |
29 |
Given the limited scope of what you use in XML, it
30 | should be trivial to code a mini-XML API in a few hundred lines of
31 | code.
32 |
33 |
I took my own challenge and coded furiously for two days to
34 | produced the initial public release of Mini-XML, total lines of
35 | code: 696. Robert promptly integrated Mini-XML into Gutenprint
36 | and removed libxml2.
37 |
38 |
Thanks to lots of feedback and support from various
39 | developers, Mini-XML has evolved since then to provide a more
40 | complete XML implementation and now stands at a whopping 3,792
41 | lines of code, compared to 140,410 lines of code for libxml2
42 | version 2.9.1.
43 |
44 |
Aside from Gutenprint, Mini-XML is used for the
45 | following projects/software applications:
Please file a bug on msweet.org if you would like your project added or
57 | removed from this list, or if you have any comments/quotes you would like me to
58 | publish about your experiences with Mini-XML.
59 |
60 |
61 |
Organization of This Document
62 |
63 |
This manual is organized into the following chapters and
64 | appendices:
The XML specification from the World Wide Web
183 | Consortium (W3C)
184 |
185 |
186 |
187 |
188 |
Legal Stuff
189 |
190 |
The Mini-XML library is copyright 2003-2014 by Michael R Sweet. License terms
191 | are described in Appendix A - Mini-XML License.
192 |
193 |
194 |
195 |
--------------------------------------------------------------------------------
/doc/intro.man:
--------------------------------------------------------------------------------
1 | .SH INCLUDE FILE
2 | #include
3 | .SH LIBRARY
4 | \-lmxml
5 | .SH DESCRIPTION
6 | Mini-XML is a small XML parsing library that you can use to
7 | read XML and XML-like data files in your application without
8 | requiring large non-standard libraries. Mini-XML only
9 | requires an ANSI C compatible compiler (GCC works, as do
10 | most vendors' ANSI C compilers) and a "make" program.
11 | .PP
12 | Mini-XML provides the following functionality:
13 | .IP \(bu 4
14 | Reading of UTF-8 and UTF-16 and writing of UTF-8 encoded XML files and strings.
15 | .IP \(bu 4
16 | Data is stored in a linked-list tree structure,
17 | preserving the XML data hierarchy.
18 | .IP \(bu 4
19 | Supports arbitrary element names, attributes, and attribute
20 | values with no preset limits, just available memory.
21 | .IP \(bu 4
22 | Supports integer, real, opaque ("CDATA"), and text data types in
23 | "leaf" nodes.
24 | .IP \(bu 4
25 | Functions for creating, indexing, and managing trees of data.
26 | .IP \(bu 4
27 | "Find" and "walk" functions for easily locating and navigating
28 | trees of data.
29 | .PP
30 | Mini-XML doesn't do validation or other types of processing
31 | on the data based upon schema files or other sources of
32 | definition information, nor does it support character
33 | entities other than those required by the XML
34 | specification.
35 | .SH USING MINI-XML
36 | Mini-XML provides a single header file which you include:
37 | .nf
38 |
39 | #include
40 | .fi
41 | .PP
42 | Nodes are defined by the "mxml_node_t" structure; the "type"
43 | member defines the node type (element, integer, opaque,
44 | real, or text) which determines which value you want to look
45 | at in the "value" union. New nodes can be created using the
46 | "mxmlNewElement()", "mxmlNewInteger()", "mxmlNewOpaque()",
47 | "mxmlNewReal()", and "mxmlNewText()" functions. Only
48 | elements can have child nodes, and the top node must be an
49 | element, usually "?xml".
50 | .PP
51 | You load an XML file using the "mxmlLoadFile()" function:
52 | .nf
53 |
54 | FILE *fp;
55 | mxml_node_t *tree;
56 |
57 | fp = fopen("filename.xml", "r");
58 | tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
59 | fclose(fp);
60 | .fi
61 | .PP
62 | Similarly, you save an XML file using the "mxmlSaveFile()"
63 | function:
64 | .nf
65 |
66 | FILE *fp;
67 | mxml_node_t *tree;
68 |
69 | fp = fopen("filename.xml", "w");
70 | mxmlSaveFile(tree, fp, MXML_NO_CALLBACK);
71 | fclose(fp);
72 | .fi
73 | .PP
74 | The "mxmlLoadString()", "mxmlSaveAllocString()", and
75 | "mxmlSaveString()" functions load XML node trees from and save
76 | XML node trees to strings:
77 | .nf
78 |
79 | char buffer[8192];
80 | char *ptr;
81 | mxml_node_t *tree;
82 |
83 | ...
84 | tree = mxmlLoadString(NULL, buffer, MXML_NO_CALLBACK);
85 |
86 | ...
87 | mxmlSaveString(tree, buffer, sizeof(buffer),
88 | MXML_NO_CALLBACK);
89 |
90 | ...
91 | ptr = mxmlSaveAllocString(tree, MXML_NO_CALLBACK);
92 | .fi
93 | .PP
94 | You can find a named element/node using the "mxmlFindElement()"
95 | function:
96 | .nf
97 |
98 | mxml_node_t *node = mxmlFindElement(tree, tree, "name",
99 | "attr", "value",
100 | MXML_DESCEND);
101 | .fi
102 | .PP
103 | The "name", "attr", and "value" arguments can be passed as
104 | NULL to act as wildcards, e.g.:
105 | .nf
106 |
107 | /* Find the first "a" element */
108 | node = mxmlFindElement(tree, tree, "a", NULL, NULL,
109 | MXML_DESCEND);
110 |
111 | /* Find the first "a" element with "href" attribute */
112 | node = mxmlFindElement(tree, tree, "a", "href", NULL,
113 | MXML_DESCEND);
114 |
115 | /* Find the first "a" element with "href" to a URL */
116 | node = mxmlFindElement(tree, tree, "a", "href",
117 | "http://www.easysw.com/~mike/mxml/",
118 | MXML_DESCEND);
119 |
120 | /* Find the first element with a "src" attribute*/
121 | node = mxmlFindElement(tree, tree, NULL, "src", NULL,
122 | MXML_DESCEND);
123 |
124 | /* Find the first element with a "src" = "foo.jpg" */
125 | node = mxmlFindElement(tree, tree, NULL, "src",
126 | "foo.jpg", MXML_DESCEND);
127 | .fi
128 | .PP
129 | You can also iterate with the same function:
130 | .nf
131 |
132 | mxml_node_t *node;
133 |
134 | for (node = mxmlFindElement(tree, tree, "name", NULL,
135 | NULL, MXML_DESCEND);
136 | node != NULL;
137 | node = mxmlFindElement(node, tree, "name", NULL,
138 | NULL, MXML_DESCEND))
139 | {
140 | ... do something ...
141 | }
142 | .fi
143 | .PP
144 | To find the value of a specific node in the tree, use the "mxmlFindPath()"
145 | function:
146 | .nf
147 |
148 | mxml_node_t *value = mxmlFindPath(tree, "path/to/*/foo/bar");
149 | .fi
150 | .PP
151 | The "mxmlGetInteger()", "mxmlGetOpaque()", "mxmlGetReal()", and "mxmlGetText()"
152 | functions retrieve the value from a node:
153 | .nf
154 |
155 | mxml_node_t *node;
156 |
157 | int intvalue = mxmlGetInteger(node);
158 |
159 | const char *opaquevalue = mxmlGetOpaque(node);
160 |
161 | double realvalue = mxmlGetReal(node);
162 |
163 | int whitespacevalue;
164 | const char *textvalue = mxmlGetText(node, &whitespacevalue);
165 | .fi
166 | .PP
167 | Finally, once you are done with the XML data, use the
168 | "mxmlDelete()" function to recursively free the memory that
169 | is used for a particular node or the entire tree:
170 | .nf
171 |
172 | mxmlDelete(tree);
173 | .fi
174 |
--------------------------------------------------------------------------------
/doc/logo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chuckatkins/MiniXML/b20d77251f8d2242dbf8eb731a0cdb18edd1e7c6/doc/logo.gif
--------------------------------------------------------------------------------
/doc/logo.xcf.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chuckatkins/MiniXML/b20d77251f8d2242dbf8eb731a0cdb18edd1e7c6/doc/logo.xcf.gz
--------------------------------------------------------------------------------
/doc/makedocs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # "$Id$"
4 | #
5 | # Script to make documentation...
6 | #
7 | # Copyright 2003-2010 by Michael R Sweet.
8 | #
9 | # These coded instructions, statements, and computer programs are the
10 | # property of Michael R Sweet and are protected by Federal copyright
11 | # law. Distribution and use rights are outlined in the file "COPYING"
12 | # which should have been included with this file. If this file is
13 | # missing or damaged, see the license at:
14 | #
15 | # http://www.minixml.org/
16 | #
17 |
18 | htmldoc --verbose --path "hires;." --batch mxml.book -f mxml.pdf
19 |
20 | htmldoc --verbose --batch mxml.book --no-title -f mxml.html
21 |
22 | rm -rf mxml.d
23 | mkdir mxml.d
24 | htmldoc --verbose --batch mxml.book --no-title -t html -d mxml.d
25 |
26 | #
27 | # End of "$Id$".
28 | #
29 |
--------------------------------------------------------------------------------
/doc/mxml-cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chuckatkins/MiniXML/b20d77251f8d2242dbf8eb731a0cdb18edd1e7c6/doc/mxml-cover.jpg
--------------------------------------------------------------------------------
/doc/mxml.book:
--------------------------------------------------------------------------------
1 | #HTMLDOC 1.8.27.1
2 | -t pdf14 -f "mxml.pdf" --book --toclevels 3 --no-numbered --toctitle "Table of Contents" --title --titleimage "title.html" --linkstyle plain --size 4.25x6.875in --left 0.750in --right 0.50in --top 0.50in --bottom 0.50in --header .t. --header1 ... --footer h.1 --nup 1 --tocheader .t. --tocfooter ..i --duplex --portrait --color --no-pscommands --no-xrxcomments --compression=9 --jpeg=95 --fontsize 9.0 --fontspacing 1.2 --headingfont Helvetica --bodyfont Helvetica --headfootsize 8.0 --headfootfont Helvetica-Oblique --charset iso-8859-1 --links --embedfonts --pagemode outline --pagelayout single --firstpage c1 --pageeffect none --pageduration 10 --effectduration 1.0 --no-encryption --permissions all --owner-password "" --user-password "" --browserwidth 300 --no-strict --no-overflow
3 | intro.html
4 | install.html
5 | basics.html
6 | advanced.html
7 | mxmldoc.html
8 | license.html
9 | relnotes.html
10 | reference.html
11 | schema.html
12 |
--------------------------------------------------------------------------------
/doc/mxmldoc.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Using the mxmldoc
6 | Utility
7 |
8 |
This chapter describes how to use mxmldoc(1) program to
9 | automatically generate documentation from C and C++ source
10 | files.
11 |
12 |
13 |
The Basics
14 |
15 |
Originally developed to generate the Mini-XML and CUPS API
16 | documentation, mxmldoc is now a general-purpose utility
17 | which scans C and C++ source files to produce HTML and man page
18 | documentation along with an XML file representing the functions,
19 | types, and definitions in those source files. Unlike popular
20 | documentation generators like Doxygen or Javadoc, mxmldoc
21 | uses in-line comments rather than comment headers, allowing for more
22 | "natural" code documentation.
23 |
24 |
By default, mxmldoc produces HTML documentation. For
25 | example, the following command will scan all of the C source and
26 | header files in the current directory and produce a HTML
27 | documentation file called filename.html:
28 |
29 |
30 | mxmldoc *.h *.c >filename.html ENTER
31 |
32 |
33 |
You can also specify an XML file to create which contains all of
34 | the information from the source files. For example, the following
35 | command creates an XML file called filename.xml in
36 | addition to the HTML file:
37 |
38 |
39 | mxmldoc filename.xml *.h *.c >filename.html ENTER
40 |
41 |
42 |
The --no-output option disables the normal HTML
43 | output:
44 |
45 |
46 | mxmldoc --no-output filename.xml *.h *.c ENTER
47 |
48 |
49 |
You can then run mxmldoc again with the XML file alone
50 | to generate the HTML documentation:
51 |
52 |
53 | mxmldoc filename.xml >filename.html ENTER
54 |
55 |
56 |
Creating Man Pages
57 |
58 |
The --man filename option tells mxmldoc to
59 | create a man page instead of HTML documentation, for example:
Xcode documentation sets can only be built on Mac OS X with Xcode 3.0 or
80 | higher installed.
81 |
82 |
83 |
Commenting Your Code
84 |
85 |
As noted previously, mxmldoc looks for in-line comments
86 | to describe the functions, types, and constants in your code.
87 | Mxmldoc will document all public names it finds in your
88 | source files - any names starting with the underscore character (_)
89 | or names that are documented with the @private@ directive are treated as private
91 | and are not documented.
92 |
93 |
Comments appearing directly before a function or type definition
94 | are used to document that function or type. Comments appearing after
95 | argument, definition, return type, or variable declarations are used
96 | to document that argument, definition, return type, or variable. For
97 | example, the following code excerpt defines a key/value structure
98 | and a function that creates a new instance of that structure:
99 |
100 |
101 | /* A key/value pair. This is used with the
102 | dictionary structure. */
103 |
104 | struct keyval
105 | {
106 | char *key; /* Key string */
107 | char *val; /* Value string */
108 | };
109 |
110 | /* Create a new key/value pair. */
111 |
112 | struct keyval * /* New key/value pair */
113 | new_keyval(
114 | const char *key, /* Key string */
115 | const char *val) /* Value string */
116 | {
117 | ...
118 | }
119 |
120 |
121 |
Mxmldoc also knows to remove extra asterisks (*) from
122 | the comment string, so the comment string:
123 |
124 |
125 | /*
126 | * Compute the value of PI.
127 | *
128 | * The function connects to an Internet server
129 | * that streams audio of mathematical monks
130 | * chanting the first 100 digits of PI.
131 | */
132 |
133 |
134 |
will be shown as:
135 |
136 |
137 | Compute the value of PI.
138 |
139 | The function connects to an Internet server
140 | that streams audio of mathematical monks
141 | chanting the first 100 digits of PI.
142 |
143 |
144 |
Comments can also include the
145 | following special @name ...@ directive strings:
146 |
147 |
148 |
149 |
@deprecated@ - flags the item as deprecated to
150 | discourage its use
151 |
152 |
@private@ - flags the item as private so it
153 | will not be included in the documentation
154 |
155 |
@since ...@ - flags the item as new since a
156 | particular release. The text following the @since
157 | up to the closing @ is highlighted in the generated
158 | documentation, e.g. @since Mini-XML 2.7@.
159 |
160 |
161 |
162 |
163 |
164 |
Titles, Sections, and Introductions
165 |
166 |
Mxmldoc also provides options to set the title, section,
167 | and introduction text for the generated documentation. The
168 | --title text option specifies the title for the
169 | documentation. The title string is usually put in quotes:
170 |
171 |
172 | mxmldoc filename.xml \
173 | --title "My Famous Documentation" \
174 | >filename.html ENTER
175 |
176 |
177 |
The --section name option specifies the section for
178 | the documentation. For HTML documentation, the name is placed in
179 | a HTML comment such as:
180 |
181 |
182 | <!-- SECTION: name -->
183 |
184 |
185 |
For man pages, the section name is usually just a number ("3"),
186 | or a number followed by a vendor name ("3acme"). The section name is
187 | used in the .TH directive in the man page:
188 |
189 |
190 | .TH mylibrary 3acme "My Title" ...
191 |
192 |
193 |
The default section name for man page output is "3". There is no
194 | default section name for HTML output.
195 |
196 |
Finally, the --intro filename option specifies a file to
197 | embed after the title and section but before the generated
198 | documentation. For HTML documentation, the file must consist of
199 | valid HTML without the usual DOCTYPE, html, and
200 | body elements. For man page documentation, the file must
201 | consist of valid nroff(1) text.
202 |
203 |
204 |
205 |
--------------------------------------------------------------------------------
/doc/mxmldoc.man:
--------------------------------------------------------------------------------
1 | .\"
2 | .\" "$Id$"
3 | .\"
4 | .\" mxmldoc man page for mini-XML, a small XML-like file parsing library.
5 | .\"
6 | .\" Copyright 2003-2009 by Michael Sweet.
7 | .\"
8 | .\" This program is free software; you can redistribute it and/or
9 | .\" modify it under the terms of the GNU Library General Public
10 | .\" License as published by the Free Software Foundation; either
11 | .\" version 2, or (at your option) any later version.
12 | .\"
13 | .\" This program is distributed in the hope that it will be useful,
14 | .\" but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | .\" GNU General Public License for more details.
17 | .\"
18 | .TH mxmldoc 1 "Mini-XML" "4 May 2009" "Michael Sweet"
19 | .SH NAME
20 | mxmldoc \- mini-xml documentation generator
21 | .SH SYNOPSIS
22 | .B mxmldoc
23 | \-\-no-output [
24 | .I filename.xml
25 | ]
26 | .I source file(s)
27 | ]
28 | .br
29 | .B mxmldoc
30 | [ \-\-footer
31 | .I footerfile
32 | ] [ \-\-header
33 | .I headerfile
34 | ] [ \-\-intro
35 | .I introfile
36 | ] [ \-\-section
37 | .I section
38 | ] [ \-\-title
39 | .I title
40 | ] [
41 | .I filename.xml
42 | ] [
43 | .I source file(s)
44 | ] >
45 | .I filename.html
46 | .br
47 | .B mxmldoc
48 | \-\-docset
49 | .I directory.docset
50 | [ \-\-docversion
51 | .I version
52 | ] [ \-\-feedname
53 | .I name
54 | ] [ \-\-feedurl
55 | .I url
56 | ] [ \-\-footer
57 | .I footerfile
58 | ] [ \-\-header
59 | .I headerfile
60 | ] [ \-\-intro
61 | .I introfile
62 | ] [ \-\-section
63 | .I section
64 | ] [ \-\-title
65 | .I title
66 | ] [
67 | .I filename.xml
68 | ] [
69 | .I source file(s)
70 | ]
71 | .br
72 | .B mxmldoc
73 | \-\-tokens
74 | .I path
75 | [
76 | .I filename.xml
77 | ] [
78 | .I source file(s)
79 | ] > tokens.xml
80 | .br
81 | .B mxmldoc
82 | \-\-framed
83 | .I basename
84 | [ \-\-footer
85 | .I footerfile
86 | ] [ \-\-header
87 | .I headerfile
88 | ] [ \-\-intro
89 | .I introfile
90 | ] [ \-\-section
91 | .I section
92 | ] [ \-\-title
93 | .I title
94 | ] [
95 | .I filename.xml
96 | ] [
97 | .I source file(s)
98 | ]
99 | .br
100 | .B mxmldoc
101 | [ \-\-footer
102 | .I footerfile
103 | ] [ \-\-header
104 | .I headerfile
105 | ] [ \-\-intro
106 | .I introfile
107 | ] \-\-man
108 | .I manpage
109 | [ \-\-section
110 | .I section
111 | ] [ \-\-title
112 | .I title
113 | ] [
114 | .I filename.xml
115 | ] [
116 | .I source file(s)
117 | ] >
118 | .I filename.man
119 | .SH DESCRIPTION
120 | \fImxmldoc\fR scans the specified C and C++ source files to produce
121 | an XML representation of globally accessible classes, constants,
122 | enumerations, functions, structures, typedefs, unions, and variables
123 | - the XML file is updated as necessary. By default, a HTML
124 | representation of the XML file is written to the standard output.
125 | Use the \fI\-\-no-output\fR option to disable the HTML output.
126 | .PP
127 | Man page source can be generated using the \fI\-\-man\fR option.
128 | .PP
129 | If no source files are specified then the current XML file is
130 | converted to the standard output.
131 | .PP
132 | In general, any C or C++ source code is handled by \fImxmldoc\fR,
133 | however it was specifically written to handle code with
134 | documentation that is formatted according to the CUPS Developer
135 | Guide which is available at "http://www.cups.org/documentation.php".
136 | .SH OPTIONS
137 | .TP 5
138 | \-\-docset directory.docset
139 | .br
140 | Creates an Xcode documentation set in the specified directory.
141 | .TP 5
142 | \-\-docversion version
143 | .br
144 | Specifies the version number for the Xcode documentation set.
145 | .TP 5
146 | \-\-feedname name
147 | .br
148 | Specifies the Xcode documentation set feed name, typically the project or
149 | company name.
150 | .TP 5
151 | \-\-feedurl url
152 | .br
153 | Specifies the Xcode documentation set feed URL which must point to an ATOM file
154 | linking to updates.
155 | .TP 5
156 | \-\-footer footerfile
157 | .br
158 | Inserts the specified file at the bottom of the output documentation.
159 | .TP 5
160 | \-\-framed basename
161 | .br
162 | Creates HTML documentation using frames - one for the table-of-contents and
163 | one for the body.
164 | .TP 5
165 | \-\-header headerfile
166 | .br
167 | Inserts the specified file at the top of the output documentation.
168 | .TP 5
169 | \-\-intro introfile
170 | .br
171 | Inserts the specified file before the table of contents.
172 | .TP 5
173 | \-\-man manpage
174 | .br
175 | Generated a man page instead of HTML documentation.
176 | .TP 5
177 | \-\-no-output
178 | .br
179 | Disables generation of documentation on the standard output.
180 | .TP 5
181 | \-\-section section
182 | .br
183 | Sets the section/keywords in the output documentation.
184 | .TP 5
185 | \-\-title title
186 | .br
187 | Sets the title of the output documentation.
188 | .TP 5
189 | \-\-tokens
190 | .br
191 | Generates a Tokens.xml file for use with the Xcode documentation tools.
192 | .SH SEE ALSO
193 | mxml(3), Mini-XML Programmers Manual, http://www.minixml.org/
194 | .SH COPYRIGHT
195 | Copyright 2003-2009 by Michael Sweet.
196 | .\"
197 | .\" End of "$Id$".
198 | .\"
199 |
--------------------------------------------------------------------------------
/doc/mxmldoc.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Mini-XML 2.8 documentation schema for mxmldoc output.
6 | Copyright 2003-2014 by Michael Sweet.
7 |
8 | This program is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU Library General Public
10 | License as published by the Free Software Foundation; either
11 | version 2, or (at your option) any later version.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
--------------------------------------------------------------------------------
/doc/reference.heading:
--------------------------------------------------------------------------------
1 |
Permission is granted to copy, distribute and/or modify
27 | this document under the terms of the GNU Library General Public
28 | License, Version 2. A copy of this license is included in Appendix A - Mini-XML License.
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/install-sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # install - install a program, script, or datafile
4 | # This comes from X11R5 (mit/util/scripts/install.sh).
5 | #
6 | # Copyright 1991 by the Massachusetts Institute of Technology
7 | #
8 | # Permission to use, copy, modify, distribute, and sell this software and its
9 | # documentation for any purpose is hereby granted without fee, provided that
10 | # the above copyright notice appear in all copies and that both that
11 | # copyright notice and this permission notice appear in supporting
12 | # documentation, and that the name of M.I.T. not be used in advertising or
13 | # publicity pertaining to distribution of the software without specific,
14 | # written prior permission. M.I.T. makes no representations about the
15 | # suitability of this software for any purpose. It is provided "as is"
16 | # without express or implied warranty.
17 | #
18 | # Calling this script install-sh is preferred over install.sh, to prevent
19 | # `make' implicit rules from creating a file called install from it
20 | # when there is no Makefile.
21 | #
22 | # This script is compatible with the BSD install script, but was written
23 | # from scratch. It can only install one file at a time, a restriction
24 | # shared with many OS's install programs.
25 |
26 |
27 | # set DOITPROG to echo to test this script
28 |
29 | # Don't use :- since 4.3BSD and earlier shells don't like it.
30 | doit="${DOITPROG-}"
31 |
32 |
33 | # put in absolute paths if you don't have them in your path; or use env. vars.
34 |
35 | mvprog="${MVPROG-mv}"
36 | cpprog="${CPPROG-cp}"
37 | chmodprog="${CHMODPROG-chmod}"
38 | chownprog="${CHOWNPROG-chown}"
39 | chgrpprog="${CHGRPPROG-chgrp}"
40 | stripprog="${STRIPPROG-strip}"
41 | rmprog="${RMPROG-rm}"
42 | mkdirprog="${MKDIRPROG-mkdir}"
43 |
44 | transformbasename=""
45 | transform_arg=""
46 | instcmd="$mvprog"
47 | chmodcmd="$chmodprog 0755"
48 | chowncmd=""
49 | chgrpcmd=""
50 | stripcmd=""
51 | rmcmd="$rmprog -f"
52 | mvcmd="$mvprog"
53 | src=""
54 | dst=""
55 | dir_arg=""
56 |
57 | while [ x"$1" != x ]; do
58 | case $1 in
59 | -c) instcmd="$cpprog"
60 | shift
61 | continue;;
62 |
63 | -d) dir_arg=true
64 | shift
65 | continue;;
66 |
67 | -m) chmodcmd="$chmodprog $2"
68 | shift
69 | shift
70 | continue;;
71 |
72 | -o) chowncmd="$chownprog $2"
73 | shift
74 | shift
75 | continue;;
76 |
77 | -g) chgrpcmd="$chgrpprog $2"
78 | shift
79 | shift
80 | continue;;
81 |
82 | -s) stripcmd="$stripprog"
83 | shift
84 | continue;;
85 |
86 | -t=*) transformarg=`echo $1 | sed 's/-t=//'`
87 | shift
88 | continue;;
89 |
90 | -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
91 | shift
92 | continue;;
93 |
94 | *) if [ x"$src" = x ]
95 | then
96 | src=$1
97 | else
98 | # this colon is to work around a 386BSD /bin/sh bug
99 | :
100 | dst=$1
101 | fi
102 | shift
103 | continue;;
104 | esac
105 | done
106 |
107 | if [ x"$src" = x ]
108 | then
109 | echo "install: no input file specified"
110 | exit 1
111 | else
112 | :
113 | fi
114 |
115 | if [ x"$dir_arg" != x ]; then
116 | dst=$src
117 | src=""
118 |
119 | if [ -d $dst ]; then
120 | instcmd=:
121 | chmodcmd=""
122 | else
123 | instcmd=$mkdirprog
124 | fi
125 | else
126 |
127 | # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
128 | # might cause directories to be created, which would be especially bad
129 | # if $src (and thus $dsttmp) contains '*'.
130 |
131 | if [ -f $src -o -d $src ]
132 | then
133 | :
134 | else
135 | echo "install: $src does not exist"
136 | exit 1
137 | fi
138 |
139 | if [ x"$dst" = x ]
140 | then
141 | echo "install: no destination specified"
142 | exit 1
143 | else
144 | :
145 | fi
146 |
147 | # If destination is a directory, append the input filename; if your system
148 | # does not like double slashes in filenames, you may need to add some logic
149 |
150 | if [ -d $dst ]
151 | then
152 | dst="$dst"/`basename $src`
153 | else
154 | :
155 | fi
156 | fi
157 |
158 | ## this sed command emulates the dirname command
159 | dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
160 |
161 | # Make sure that the destination directory exists.
162 | # this part is taken from Noah Friedman's mkinstalldirs script
163 |
164 | # Skip lots of stat calls in the usual case.
165 | if [ ! -d "$dstdir" ]; then
166 | defaultIFS='
167 | '
168 | IFS="${IFS-${defaultIFS}}"
169 |
170 | oIFS="${IFS}"
171 | # Some sh's can't handle IFS=/ for some reason.
172 | IFS='%'
173 | set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
174 | IFS="${oIFS}"
175 |
176 | pathcomp=''
177 |
178 | while [ $# -ne 0 ] ; do
179 | pathcomp="${pathcomp}${1}"
180 | shift
181 |
182 | if [ ! -d "${pathcomp}" ] ;
183 | then
184 | $mkdirprog "${pathcomp}"
185 | else
186 | :
187 | fi
188 |
189 | pathcomp="${pathcomp}/"
190 | done
191 | fi
192 |
193 | if [ x"$dir_arg" != x ]
194 | then
195 | $doit $instcmd $dst &&
196 |
197 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
198 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
199 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
200 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
201 | else
202 |
203 | # If we're going to rename the final executable, determine the name now.
204 |
205 | if [ x"$transformarg" = x ]
206 | then
207 | dstfile=`basename $dst`
208 | else
209 | dstfile=`basename $dst $transformbasename |
210 | sed $transformarg`$transformbasename
211 | fi
212 |
213 | # don't allow the sed command to completely eliminate the filename
214 |
215 | if [ x"$dstfile" = x ]
216 | then
217 | dstfile=`basename $dst`
218 | else
219 | :
220 | fi
221 |
222 | # Make a temp file name in the proper directory.
223 |
224 | dsttmp=$dstdir/#inst.$$#
225 |
226 | # Move or copy the file name to the temp name
227 |
228 | $doit $instcmd $src $dsttmp &&
229 |
230 | trap "rm -f ${dsttmp}" 0 &&
231 |
232 | # and set any options; do chmod last to preserve setuid bits
233 |
234 | # If any of these fail, we abort the whole thing. If we want to
235 | # ignore errors from any of these, just make sure not to ignore
236 | # errors from the above "$doit $instcmd $src $dsttmp" command.
237 |
238 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
239 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
240 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
241 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
242 |
243 | # Now rename the file to the real destination.
244 |
245 | $doit $rmcmd -f $dstdir/$dstfile &&
246 | $doit $mvcmd $dsttmp $dstdir/$dstfile
247 |
248 | fi &&
249 |
250 |
251 | exit 0
252 |
--------------------------------------------------------------------------------
/makesrcdist:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # "$Id$"
4 | #
5 | # makesrcdist - make a source distribution of mxml.
6 | #
7 |
8 | echo "Getting distribution..."
9 |
10 | if test $# = 0; then
11 | echo -n "Version number for distribution? "
12 | read version
13 | else
14 | version=$1
15 | fi
16 |
17 | cd /tmp
18 |
19 | if test $version = snapshot; then
20 | url="https://svn.msweet.org/mxml/trunk"
21 | else
22 | url="svn+ssh://msweet.org/var/svn/mxml/tags/release-$version"
23 |
24 | svn copy svn+ssh://msweet.org/var/svn/mxml/trunk "$url" \
25 | -m "Tag $version" || exit 1
26 | fi
27 |
28 | rm -rf mxml-$version
29 | svn export $url mxml-$version
30 | cd mxml-$version
31 |
32 | echo "Removing Subversion files and directories..."
33 |
34 | rm -f makesrcdist TODO mvalidate.c
35 | rm -rf www
36 | rm -rf doc/mxml-cover* doc/hires
37 | cd ..
38 |
39 | echo "Making .tar.gz distribution..."
40 |
41 | tar czf mxml-$version.tar.gz mxml-$version
42 |
43 | echo "Removing distribution directory..."
44 |
45 | rm -rf mxml-$version
46 |
47 | echo "Done!"
48 |
49 | #
50 | # End of "$Id$".
51 | #
52 |
--------------------------------------------------------------------------------
/mvalidate.c:
--------------------------------------------------------------------------------
1 | /*
2 | * "$Id$"
3 | *
4 | * XML Schema validation program for Mini-XML, a small XML-like file
5 | * parsing library.
6 | *
7 | * Copyright 2003-2014 by Michael R Sweet.
8 | *
9 | * These coded instructions, statements, and computer programs are the
10 | * property of Michael R Sweet and are protected by Federal copyright
11 | * law. Distribution and use rights are outlined in the file "COPYING"
12 | * which should have been included with this file. If this file is
13 | * missing or damaged, see the license at:
14 | *
15 | * http://www.msweet.org/projects.php/Mini-XML
16 | */
17 |
18 | /*
19 | * Include necessary headers...
20 | */
21 |
22 | #include "config.h"
23 | #include "mxml.h"
24 |
25 |
26 | /*
27 | * 'main()' - Main entry for schema validation program.
28 | */
29 |
30 | int /* O - Exit status */
31 | main(int argc, /* I - Number of command-line args */
32 | char *argv[]) /* I - Command-line args */
33 | {
34 | return (0);
35 | }
36 |
37 |
38 | /*
39 | * End of "$Id$".
40 | */
41 |
--------------------------------------------------------------------------------
/mxml-attr.c:
--------------------------------------------------------------------------------
1 | /*
2 | * "$Id$"
3 | *
4 | * Attribute support code for Mini-XML, a small XML-like file parsing library.
5 | *
6 | * Copyright 2003-2014 by Michael R Sweet.
7 | *
8 | * These coded instructions, statements, and computer programs are the
9 | * property of Michael R Sweet and are protected by Federal copyright
10 | * law. Distribution and use rights are outlined in the file "COPYING"
11 | * which should have been included with this file. If this file is
12 | * missing or damaged, see the license at:
13 | *
14 | * http://www.msweet.org/projects.php/Mini-XML
15 | */
16 |
17 | /*
18 | * Include necessary headers...
19 | */
20 |
21 | #include "config.h"
22 | #include "mxml.h"
23 |
24 |
25 | /*
26 | * Local functions...
27 | */
28 |
29 | static int mxml_set_attr(mxml_node_t *node, const char *name,
30 | char *value);
31 |
32 |
33 | /*
34 | * 'mxmlElementDeleteAttr()' - Delete an attribute.
35 | *
36 | * @since Mini-XML 2.4@
37 | */
38 |
39 | void
40 | mxmlElementDeleteAttr(mxml_node_t *node,/* I - Element */
41 | const char *name)/* I - Attribute name */
42 | {
43 | int i; /* Looping var */
44 | mxml_attr_t *attr; /* Cirrent attribute */
45 |
46 |
47 | #ifdef DEBUG
48 | fprintf(stderr, "mxmlElementDeleteAttr(node=%p, name=\"%s\")\n",
49 | node, name ? name : "(null)");
50 | #endif /* DEBUG */
51 |
52 | /*
53 | * Range check input...
54 | */
55 |
56 | if (!node || node->type != MXML_ELEMENT || !name)
57 | return;
58 |
59 | /*
60 | * Look for the attribute...
61 | */
62 |
63 | for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
64 | i > 0;
65 | i --, attr ++)
66 | {
67 | #ifdef DEBUG
68 | printf(" %s=\"%s\"\n", attr->name, attr->value);
69 | #endif /* DEBUG */
70 |
71 | if (!strcmp(attr->name, name))
72 | {
73 | /*
74 | * Delete this attribute...
75 | */
76 |
77 | free(attr->name);
78 | free(attr->value);
79 |
80 | i --;
81 | if (i > 0)
82 | memmove(attr, attr + 1, i * sizeof(mxml_attr_t));
83 |
84 | node->value.element.num_attrs --;
85 |
86 | if (node->value.element.num_attrs == 0)
87 | free(node->value.element.attrs);
88 | return;
89 | }
90 | }
91 | }
92 |
93 |
94 | /*
95 | * 'mxmlElementGetAttr()' - Get an attribute.
96 | *
97 | * This function returns NULL if the node is not an element or the
98 | * named attribute does not exist.
99 | */
100 |
101 | const char * /* O - Attribute value or NULL */
102 | mxmlElementGetAttr(mxml_node_t *node, /* I - Element node */
103 | const char *name) /* I - Name of attribute */
104 | {
105 | int i; /* Looping var */
106 | mxml_attr_t *attr; /* Cirrent attribute */
107 |
108 |
109 | #ifdef DEBUG
110 | fprintf(stderr, "mxmlElementGetAttr(node=%p, name=\"%s\")\n",
111 | node, name ? name : "(null)");
112 | #endif /* DEBUG */
113 |
114 | /*
115 | * Range check input...
116 | */
117 |
118 | if (!node || node->type != MXML_ELEMENT || !name)
119 | return (NULL);
120 |
121 | /*
122 | * Look for the attribute...
123 | */
124 |
125 | for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
126 | i > 0;
127 | i --, attr ++)
128 | {
129 | #ifdef DEBUG
130 | printf(" %s=\"%s\"\n", attr->name, attr->value);
131 | #endif /* DEBUG */
132 |
133 | if (!strcmp(attr->name, name))
134 | {
135 | #ifdef DEBUG
136 | printf(" Returning \"%s\"!\n", attr->value);
137 | #endif /* DEBUG */
138 | return (attr->value);
139 | }
140 | }
141 |
142 | /*
143 | * Didn't find attribute, so return NULL...
144 | */
145 |
146 | #ifdef DEBUG
147 | puts(" Returning NULL!\n");
148 | #endif /* DEBUG */
149 |
150 | return (NULL);
151 | }
152 |
153 |
154 | /*
155 | * 'mxmlElementSetAttr()' - Set an attribute.
156 | *
157 | * If the named attribute already exists, the value of the attribute
158 | * is replaced by the new string value. The string value is copied
159 | * into the element node. This function does nothing if the node is
160 | * not an element.
161 | */
162 |
163 | void
164 | mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */
165 | const char *name, /* I - Name of attribute */
166 | const char *value) /* I - Attribute value */
167 | {
168 | char *valuec; /* Copy of value */
169 |
170 |
171 | #ifdef DEBUG
172 | fprintf(stderr, "mxmlElementSetAttr(node=%p, name=\"%s\", value=\"%s\")\n",
173 | node, name ? name : "(null)", value ? value : "(null)");
174 | #endif /* DEBUG */
175 |
176 | /*
177 | * Range check input...
178 | */
179 |
180 | if (!node || node->type != MXML_ELEMENT || !name)
181 | return;
182 |
183 | if (value)
184 | valuec = strdup(value);
185 | else
186 | valuec = NULL;
187 |
188 | if (mxml_set_attr(node, name, valuec))
189 | free(valuec);
190 | }
191 |
192 |
193 | /*
194 | * 'mxmlElementSetAttrf()' - Set an attribute with a formatted value.
195 | *
196 | * If the named attribute already exists, the value of the attribute
197 | * is replaced by the new formatted string. The formatted string value is
198 | * copied into the element node. This function does nothing if the node
199 | * is not an element.
200 | *
201 | * @since Mini-XML 2.3@
202 | */
203 |
204 | void
205 | mxmlElementSetAttrf(mxml_node_t *node, /* I - Element node */
206 | const char *name, /* I - Name of attribute */
207 | const char *format,/* I - Printf-style attribute value */
208 | ...) /* I - Additional arguments as needed */
209 | {
210 | va_list ap; /* Argument pointer */
211 | char *value; /* Value */
212 |
213 |
214 | #ifdef DEBUG
215 | fprintf(stderr,
216 | "mxmlElementSetAttrf(node=%p, name=\"%s\", format=\"%s\", ...)\n",
217 | node, name ? name : "(null)", format ? format : "(null)");
218 | #endif /* DEBUG */
219 |
220 | /*
221 | * Range check input...
222 | */
223 |
224 | if (!node || node->type != MXML_ELEMENT || !name || !format)
225 | return;
226 |
227 | /*
228 | * Format the value...
229 | */
230 |
231 | va_start(ap, format);
232 | value = _mxml_vstrdupf(format, ap);
233 | va_end(ap);
234 |
235 | if (!value)
236 | mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
237 | name, node->value.element.name);
238 | else if (mxml_set_attr(node, name, value))
239 | free(value);
240 | }
241 |
242 |
243 | /*
244 | * 'mxml_set_attr()' - Set or add an attribute name/value pair.
245 | */
246 |
247 | static int /* O - 0 on success, -1 on failure */
248 | mxml_set_attr(mxml_node_t *node, /* I - Element node */
249 | const char *name, /* I - Attribute name */
250 | char *value) /* I - Attribute value */
251 | {
252 | int i; /* Looping var */
253 | mxml_attr_t *attr; /* New attribute */
254 |
255 |
256 | /*
257 | * Look for the attribute...
258 | */
259 |
260 | for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
261 | i > 0;
262 | i --, attr ++)
263 | if (!strcmp(attr->name, name))
264 | {
265 | /*
266 | * Free the old value as needed...
267 | */
268 |
269 | if (attr->value)
270 | free(attr->value);
271 |
272 | attr->value = value;
273 |
274 | return (0);
275 | }
276 |
277 | /*
278 | * Add a new attribute...
279 | */
280 |
281 | if (node->value.element.num_attrs == 0)
282 | attr = malloc(sizeof(mxml_attr_t));
283 | else
284 | attr = realloc(node->value.element.attrs,
285 | (node->value.element.num_attrs + 1) * sizeof(mxml_attr_t));
286 |
287 | if (!attr)
288 | {
289 | mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
290 | name, node->value.element.name);
291 | return (-1);
292 | }
293 |
294 | node->value.element.attrs = attr;
295 | attr += node->value.element.num_attrs;
296 |
297 | if ((attr->name = strdup(name)) == NULL)
298 | {
299 | mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
300 | name, node->value.element.name);
301 | return (-1);
302 | }
303 |
304 | attr->value = value;
305 |
306 | node->value.element.num_attrs ++;
307 |
308 | return (0);
309 | }
310 |
311 |
312 | /*
313 | * End of "$Id$".
314 | */
315 |
--------------------------------------------------------------------------------
/mxml-private.c:
--------------------------------------------------------------------------------
1 | /*
2 | * "$Id$"
3 | *
4 | * Private functions for Mini-XML, a small XML-like file parsing library.
5 | *
6 | * Copyright 2003-2014 by Michael R Sweet.
7 | *
8 | * These coded instructions, statements, and computer programs are the
9 | * property of Michael R Sweet and are protected by Federal copyright
10 | * law. Distribution and use rights are outlined in the file "COPYING"
11 | * which should have been included with this file. If this file is
12 | * missing or damaged, see the license at:
13 | *
14 | * http://www.msweet.org/projects.php/Mini-XML
15 | */
16 |
17 | /*
18 | * Include necessary headers...
19 | */
20 |
21 | #include "mxml-private.h"
22 |
23 |
24 | /*
25 | * Some crazy people think that unloading a shared object is a good or safe
26 | * thing to do. Unfortunately, most objects are simply *not* safe to unload
27 | * and bad things *will* happen.
28 | *
29 | * The following mess of conditional code allows us to provide a destructor
30 | * function in Mini-XML for our thread-global storage so that it can possibly
31 | * be unloaded safely, although since there is no standard way to do so I
32 | * can't even provide any guarantees that you can do it safely on all platforms.
33 | *
34 | * This code currently supports AIX, HP-UX, Linux, Mac OS X, Solaris, and
35 | * Windows. It might work on the BSDs and IRIX, but I haven't tested that.
36 | */
37 |
38 | #if defined(__sun) || defined(_AIX)
39 | # pragma fini(_mxml_fini)
40 | # define _MXML_FINI _mxml_fini
41 | #elif defined(__hpux)
42 | # pragma FINI _mxml_fini
43 | # define _MXML_FINI _mxml_fini
44 | #elif defined(__GNUC__) /* Linux and Mac OS X */
45 | # define _MXML_FINI __attribute((destructor)) _mxml_fini
46 | #else
47 | # define _MXML_FINI _fini
48 | #endif /* __sun */
49 |
50 |
51 | /*
52 | * 'mxml_error()' - Display an error message.
53 | */
54 |
55 | void
56 | mxml_error(const char *format, /* I - Printf-style format string */
57 | ...) /* I - Additional arguments as needed */
58 | {
59 | va_list ap; /* Pointer to arguments */
60 | char s[1024]; /* Message string */
61 | _mxml_global_t *global = _mxml_global();
62 | /* Global data */
63 |
64 |
65 | /*
66 | * Range check input...
67 | */
68 |
69 | if (!format)
70 | return;
71 |
72 | /*
73 | * Format the error message string...
74 | */
75 |
76 | va_start(ap, format);
77 |
78 | vsnprintf(s, sizeof(s), format, ap);
79 |
80 | va_end(ap);
81 |
82 | /*
83 | * And then display the error message...
84 | */
85 |
86 | if (global->error_cb)
87 | (*global->error_cb)(s);
88 | else
89 | fprintf(stderr, "mxml: %s\n", s);
90 | }
91 |
92 |
93 | /*
94 | * 'mxml_ignore_cb()' - Default callback for ignored values.
95 | */
96 |
97 | mxml_type_t /* O - Node type */
98 | mxml_ignore_cb(mxml_node_t *node) /* I - Current node */
99 | {
100 | (void)node;
101 |
102 | return (MXML_IGNORE);
103 | }
104 |
105 |
106 | /*
107 | * 'mxml_integer_cb()' - Default callback for integer values.
108 | */
109 |
110 | mxml_type_t /* O - Node type */
111 | mxml_integer_cb(mxml_node_t *node) /* I - Current node */
112 | {
113 | (void)node;
114 |
115 | return (MXML_INTEGER);
116 | }
117 |
118 |
119 | /*
120 | * 'mxml_opaque_cb()' - Default callback for opaque values.
121 | */
122 |
123 | mxml_type_t /* O - Node type */
124 | mxml_opaque_cb(mxml_node_t *node) /* I - Current node */
125 | {
126 | (void)node;
127 |
128 | return (MXML_OPAQUE);
129 | }
130 |
131 |
132 | /*
133 | * 'mxml_real_cb()' - Default callback for real number values.
134 | */
135 |
136 | mxml_type_t /* O - Node type */
137 | mxml_real_cb(mxml_node_t *node) /* I - Current node */
138 | {
139 | (void)node;
140 |
141 | return (MXML_REAL);
142 | }
143 |
144 |
145 | #ifdef HAVE_PTHREAD_H /**** POSIX threading ****/
146 | # include
147 |
148 | static pthread_key_t _mxml_key = -1; /* Thread local storage key */
149 | static pthread_once_t _mxml_key_once = PTHREAD_ONCE_INIT;
150 | /* One-time initialization object */
151 | static void _mxml_init(void);
152 | static void _mxml_destructor(void *g);
153 |
154 |
155 | /*
156 | * '_mxml_destructor()' - Free memory used for globals...
157 | */
158 |
159 | static void
160 | _mxml_destructor(void *g) /* I - Global data */
161 | {
162 | free(g);
163 | }
164 |
165 |
166 | /*
167 | * '_mxml_fini()' - Clean up when unloaded.
168 | */
169 |
170 | static void
171 | _MXML_FINI(void)
172 | {
173 | _mxml_global_t *global; /* Global data */
174 |
175 |
176 | if (_mxml_key != -1)
177 | {
178 | if ((global = (_mxml_global_t *)pthread_getspecific(_mxml_key)) != NULL)
179 | _mxml_destructor(global);
180 |
181 | pthread_key_delete(_mxml_key);
182 | _mxml_key = -1;
183 | }
184 | }
185 |
186 |
187 | /*
188 | * '_mxml_global()' - Get global data.
189 | */
190 |
191 | _mxml_global_t * /* O - Global data */
192 | _mxml_global(void)
193 | {
194 | _mxml_global_t *global; /* Global data */
195 |
196 |
197 | pthread_once(&_mxml_key_once, _mxml_init);
198 |
199 | if ((global = (_mxml_global_t *)pthread_getspecific(_mxml_key)) == NULL)
200 | {
201 | global = (_mxml_global_t *)calloc(1, sizeof(_mxml_global_t));
202 | pthread_setspecific(_mxml_key, global);
203 |
204 | global->num_entity_cbs = 1;
205 | global->entity_cbs[0] = _mxml_entity_cb;
206 | global->wrap = 72;
207 | }
208 |
209 | return (global);
210 | }
211 |
212 |
213 | /*
214 | * '_mxml_init()' - Initialize global data...
215 | */
216 |
217 | static void
218 | _mxml_init(void)
219 | {
220 | pthread_key_create(&_mxml_key, _mxml_destructor);
221 | }
222 |
223 |
224 | #elif defined(WIN32) && defined(MXML1_EXPORTS) /**** WIN32 threading ****/
225 | # include
226 |
227 | static DWORD _mxml_tls_index; /* Index for global storage */
228 |
229 |
230 | /*
231 | * 'DllMain()' - Main entry for library.
232 | */
233 |
234 | BOOL WINAPI /* O - Success/failure */
235 | DllMain(HINSTANCE hinst, /* I - DLL module handle */
236 | DWORD reason, /* I - Reason */
237 | LPVOID reserved) /* I - Unused */
238 | {
239 | _mxml_global_t *global; /* Global data */
240 |
241 |
242 | (void)hinst;
243 | (void)reserved;
244 |
245 | switch (reason)
246 | {
247 | case DLL_PROCESS_ATTACH : /* Called on library initialization */
248 | if ((_mxml_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES)
249 | return (FALSE);
250 | break;
251 |
252 | case DLL_THREAD_DETACH : /* Called when a thread terminates */
253 | if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL)
254 | free(global);
255 | break;
256 |
257 | case DLL_PROCESS_DETACH : /* Called when library is unloaded */
258 | if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL)
259 | free(global);
260 |
261 | TlsFree(_mxml_tls_index);
262 | break;
263 |
264 | default:
265 | break;
266 | }
267 |
268 | return (TRUE);
269 | }
270 |
271 |
272 | /*
273 | * '_mxml_global()' - Get global data.
274 | */
275 |
276 | _mxml_global_t * /* O - Global data */
277 | _mxml_global(void)
278 | {
279 | _mxml_global_t *global; /* Global data */
280 |
281 |
282 | if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) == NULL)
283 | {
284 | global = (_mxml_global_t *)calloc(1, sizeof(_mxml_global_t));
285 |
286 | global->num_entity_cbs = 1;
287 | global->entity_cbs[0] = _mxml_entity_cb;
288 | global->wrap = 72;
289 |
290 | TlsSetValue(_mxml_tls_index, (LPVOID)global);
291 | }
292 |
293 | return (global);
294 | }
295 |
296 |
297 | #else /**** No threading ****/
298 | /*
299 | * '_mxml_global()' - Get global data.
300 | */
301 |
302 | _mxml_global_t * /* O - Global data */
303 | _mxml_global(void)
304 | {
305 | static _mxml_global_t global = /* Global data */
306 | {
307 | NULL, /* error_cb */
308 | 1, /* num_entity_cbs */
309 | { _mxml_entity_cb }, /* entity_cbs */
310 | 72, /* wrap */
311 | NULL, /* custom_load_cb */
312 | NULL /* custom_save_cb */
313 | };
314 |
315 |
316 | return (&global);
317 | }
318 | #endif /* HAVE_PTHREAD_H */
319 |
320 |
321 | /*
322 | * End of "$Id$".
323 | */
324 |
--------------------------------------------------------------------------------
/mxml-private.h:
--------------------------------------------------------------------------------
1 | /*
2 | * "$Id$"
3 | *
4 | * Private definitions for Mini-XML, a small XML-like file parsing library.
5 | *
6 | * Copyright 2003-2014 by Michael R Sweet.
7 | *
8 | * These coded instructions, statements, and computer programs are the
9 | * property of Michael R Sweet and are protected by Federal copyright
10 | * law. Distribution and use rights are outlined in the file "COPYING"
11 | * which should have been included with this file. If this file is
12 | * missing or damaged, see the license at:
13 | *
14 | * http://www.msweet.org/projects.php/Mini-XML
15 | */
16 |
17 | /*
18 | * Include necessary headers...
19 | */
20 |
21 | #include "config.h"
22 | #include "mxml.h"
23 |
24 |
25 | /*
26 | * Global, per-thread data...
27 | */
28 |
29 | typedef struct _mxml_global_s
30 | {
31 | void (*error_cb)(const char *);
32 | int num_entity_cbs;
33 | int (*entity_cbs[100])(const char *name);
34 | int wrap;
35 | mxml_custom_load_cb_t custom_load_cb;
36 | mxml_custom_save_cb_t custom_save_cb;
37 | } _mxml_global_t;
38 |
39 |
40 | /*
41 | * Functions...
42 | */
43 |
44 | extern _mxml_global_t *_mxml_global(void);
45 | extern int _mxml_entity_cb(const char *name);
46 |
47 |
48 | /*
49 | * End of "$Id$".
50 | */
51 |
--------------------------------------------------------------------------------
/mxml-search.c:
--------------------------------------------------------------------------------
1 | /*
2 | * "$Id$"
3 | *
4 | * Search/navigation functions for Mini-XML, a small XML-like file
5 | * parsing library.
6 | *
7 | * Copyright 2003-2014 by Michael R Sweet.
8 | *
9 | * These coded instructions, statements, and computer programs are the
10 | * property of Michael R Sweet and are protected by Federal copyright
11 | * law. Distribution and use rights are outlined in the file "COPYING"
12 | * which should have been included with this file. If this file is
13 | * missing or damaged, see the license at:
14 | *
15 | * http://www.msweet.org/projects.php/Mini-XML
16 | */
17 |
18 | /*
19 | * Include necessary headers...
20 | */
21 |
22 | #include "config.h"
23 | #include "mxml.h"
24 |
25 |
26 | /*
27 | * 'mxmlFindElement()' - Find the named element.
28 | *
29 | * The search is constrained by the name, attribute name, and value; any
30 | * NULL names or values are treated as wildcards, so different kinds of
31 | * searches can be implemented by looking for all elements of a given name
32 | * or all elements with a specific attribute. The descend argument determines
33 | * whether the search descends into child nodes; normally you will use
34 | * MXML_DESCEND_FIRST for the initial search and MXML_NO_DESCEND to find
35 | * additional direct descendents of the node. The top node argument
36 | * constrains the search to a particular node's children.
37 | */
38 |
39 | mxml_node_t * /* O - Element node or NULL */
40 | mxmlFindElement(mxml_node_t *node, /* I - Current node */
41 | mxml_node_t *top, /* I - Top node */
42 | const char *name, /* I - Element name or NULL for any */
43 | const char *attr, /* I - Attribute name, or NULL for none */
44 | const char *value, /* I - Attribute value, or NULL for any */
45 | int descend) /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */
46 | {
47 | const char *temp; /* Current attribute value */
48 |
49 |
50 | /*
51 | * Range check input...
52 | */
53 |
54 | if (!node || !top || (!attr && value))
55 | return (NULL);
56 |
57 | /*
58 | * Start with the next node...
59 | */
60 |
61 | node = mxmlWalkNext(node, top, descend);
62 |
63 | /*
64 | * Loop until we find a matching element...
65 | */
66 |
67 | while (node != NULL)
68 | {
69 | /*
70 | * See if this node matches...
71 | */
72 |
73 | if (node->type == MXML_ELEMENT &&
74 | node->value.element.name &&
75 | (!name || !strcmp(node->value.element.name, name)))
76 | {
77 | /*
78 | * See if we need to check for an attribute...
79 | */
80 |
81 | if (!attr)
82 | return (node); /* No attribute search, return it... */
83 |
84 | /*
85 | * Check for the attribute...
86 | */
87 |
88 | if ((temp = mxmlElementGetAttr(node, attr)) != NULL)
89 | {
90 | /*
91 | * OK, we have the attribute, does it match?
92 | */
93 |
94 | if (!value || !strcmp(value, temp))
95 | return (node); /* Yes, return it... */
96 | }
97 | }
98 |
99 | /*
100 | * No match, move on to the next node...
101 | */
102 |
103 | if (descend == MXML_DESCEND)
104 | node = mxmlWalkNext(node, top, MXML_DESCEND);
105 | else
106 | node = node->next;
107 | }
108 |
109 | return (NULL);
110 | }
111 |
112 |
113 | /*
114 | * 'mxmlFindPath()' - Find a node with the given path.
115 | *
116 | * The "path" is a slash-separated list of element names. The name "*" is
117 | * considered a wildcard for one or more levels of elements. For example,
118 | * "foo/one/two", "bar/two/one", "*\/one", and so forth.
119 | *
120 | * The first child node of the found node is returned if the given node has
121 | * children and the first child is a value node.
122 | *
123 | * @since Mini-XML 2.7@
124 | */
125 |
126 | mxml_node_t * /* O - Found node or NULL */
127 | mxmlFindPath(mxml_node_t *top, /* I - Top node */
128 | const char *path) /* I - Path to element */
129 | {
130 | mxml_node_t *node; /* Current node */
131 | char element[256]; /* Current element name */
132 | const char *pathsep; /* Separator in path */
133 | int descend; /* mxmlFindElement option */
134 |
135 |
136 | /*
137 | * Range check input...
138 | */
139 |
140 | if (!top || !path || !*path)
141 | return (NULL);
142 |
143 | /*
144 | * Search each element in the path...
145 | */
146 |
147 | node = top;
148 | while (*path)
149 | {
150 | /*
151 | * Handle wildcards...
152 | */
153 |
154 | if (!strncmp(path, "*/", 2))
155 | {
156 | path += 2;
157 | descend = MXML_DESCEND;
158 | }
159 | else
160 | descend = MXML_DESCEND_FIRST;
161 |
162 | /*
163 | * Get the next element in the path...
164 | */
165 |
166 | if ((pathsep = strchr(path, '/')) == NULL)
167 | pathsep = path + strlen(path);
168 |
169 | if (pathsep == path || (pathsep - path) >= sizeof(element))
170 | return (NULL);
171 |
172 | memcpy(element, path, pathsep - path);
173 | element[pathsep - path] = '\0';
174 |
175 | if (*pathsep)
176 | path = pathsep + 1;
177 | else
178 | path = pathsep;
179 |
180 | /*
181 | * Search for the element...
182 | */
183 |
184 | if ((node = mxmlFindElement(node, node, element, NULL, NULL,
185 | descend)) == NULL)
186 | return (NULL);
187 | }
188 |
189 | /*
190 | * If we get this far, return the node or its first child...
191 | */
192 |
193 | if (node->child && node->child->type != MXML_ELEMENT)
194 | return (node->child);
195 | else
196 | return (node);
197 | }
198 |
199 |
200 | /*
201 | * 'mxmlWalkNext()' - Walk to the next logical node in the tree.
202 | *
203 | * The descend argument controls whether the first child is considered
204 | * to be the next node. The top node argument constrains the walk to
205 | * the node's children.
206 | */
207 |
208 | mxml_node_t * /* O - Next node or NULL */
209 | mxmlWalkNext(mxml_node_t *node, /* I - Current node */
210 | mxml_node_t *top, /* I - Top node */
211 | int descend) /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */
212 | {
213 | if (!node)
214 | return (NULL);
215 | else if (node->child && descend)
216 | return (node->child);
217 | else if (node == top)
218 | return (NULL);
219 | else if (node->next)
220 | return (node->next);
221 | else if (node->parent && node->parent != top)
222 | {
223 | node = node->parent;
224 |
225 | while (!node->next)
226 | if (node->parent == top || !node->parent)
227 | return (NULL);
228 | else
229 | node = node->parent;
230 |
231 | return (node->next);
232 | }
233 | else
234 | return (NULL);
235 | }
236 |
237 |
238 | /*
239 | * 'mxmlWalkPrev()' - Walk to the previous logical node in the tree.
240 | *
241 | * The descend argument controls whether the previous node's last child
242 | * is considered to be the previous node. The top node argument constrains
243 | * the walk to the node's children.
244 | */
245 |
246 | mxml_node_t * /* O - Previous node or NULL */
247 | mxmlWalkPrev(mxml_node_t *node, /* I - Current node */
248 | mxml_node_t *top, /* I - Top node */
249 | int descend) /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */
250 | {
251 | if (!node || node == top)
252 | return (NULL);
253 | else if (node->prev)
254 | {
255 | if (node->prev->last_child && descend)
256 | {
257 | /*
258 | * Find the last child under the previous node...
259 | */
260 |
261 | node = node->prev->last_child;
262 |
263 | while (node->last_child)
264 | node = node->last_child;
265 |
266 | return (node);
267 | }
268 | else
269 | return (node->prev);
270 | }
271 | else if (node->parent != top)
272 | return (node->parent);
273 | else
274 | return (NULL);
275 | }
276 |
277 |
278 | /*
279 | * End of "$Id$".
280 | */
281 |
--------------------------------------------------------------------------------
/mxml-set.c:
--------------------------------------------------------------------------------
1 | /*
2 | * "$Id$"
3 | *
4 | * Node set functions for Mini-XML, a small XML-like file parsing library.
5 | *
6 | * Copyright 2003-2014 by Michael R Sweet.
7 | *
8 | * These coded instructions, statements, and computer programs are the
9 | * property of Michael R Sweet and are protected by Federal copyright
10 | * law. Distribution and use rights are outlined in the file "COPYING"
11 | * which should have been included with this file. If this file is
12 | * missing or damaged, see the license at:
13 | *
14 | * http://www.msweet.org/projects.php/Mini-XML
15 | */
16 |
17 | /*
18 | * Include necessary headers...
19 | */
20 |
21 | #include "config.h"
22 | #include "mxml.h"
23 |
24 |
25 | /*
26 | * 'mxmlSetCDATA()' - Set the element name of a CDATA node.
27 | *
28 | * The node is not changed if it (or its first child) is not a CDATA element node.
29 | *
30 | * @since Mini-XML 2.3@
31 | */
32 |
33 | int /* O - 0 on success, -1 on failure */
34 | mxmlSetCDATA(mxml_node_t *node, /* I - Node to set */
35 | const char *data) /* I - New data string */
36 | {
37 | /*
38 | * Range check input...
39 | */
40 |
41 | if (node && node->type == MXML_ELEMENT &&
42 | strncmp(node->value.element.name, "![CDATA[", 8) &&
43 | node->child && node->child->type == MXML_ELEMENT &&
44 | !strncmp(node->child->value.element.name, "![CDATA[", 8))
45 | node = node->child;
46 |
47 | if (!node || node->type != MXML_ELEMENT || !data ||
48 | strncmp(node->value.element.name, "![CDATA[", 8))
49 | return (-1);
50 |
51 | /*
52 | * Free any old element value and set the new value...
53 | */
54 |
55 | if (node->value.element.name)
56 | free(node->value.element.name);
57 |
58 | node->value.element.name = _mxml_strdupf("![CDATA[%s]]", data);
59 |
60 | return (0);
61 | }
62 |
63 |
64 | /*
65 | * 'mxmlSetCustom()' - Set the data and destructor of a custom data node.
66 | *
67 | * The node is not changed if it (or its first child) is not a custom node.
68 | *
69 | * @since Mini-XML 2.1@
70 | */
71 |
72 | int /* O - 0 on success, -1 on failure */
73 | mxmlSetCustom(
74 | mxml_node_t *node, /* I - Node to set */
75 | void *data, /* I - New data pointer */
76 | mxml_custom_destroy_cb_t destroy) /* I - New destructor function */
77 | {
78 | /*
79 | * Range check input...
80 | */
81 |
82 | if (node && node->type == MXML_ELEMENT &&
83 | node->child && node->child->type == MXML_CUSTOM)
84 | node = node->child;
85 |
86 | if (!node || node->type != MXML_CUSTOM)
87 | return (-1);
88 |
89 | /*
90 | * Free any old element value and set the new value...
91 | */
92 |
93 | if (node->value.custom.data && node->value.custom.destroy)
94 | (*(node->value.custom.destroy))(node->value.custom.data);
95 |
96 | node->value.custom.data = data;
97 | node->value.custom.destroy = destroy;
98 |
99 | return (0);
100 | }
101 |
102 |
103 | /*
104 | * 'mxmlSetElement()' - Set the name of an element node.
105 | *
106 | * The node is not changed if it is not an element node.
107 | */
108 |
109 | int /* O - 0 on success, -1 on failure */
110 | mxmlSetElement(mxml_node_t *node, /* I - Node to set */
111 | const char *name) /* I - New name string */
112 | {
113 | /*
114 | * Range check input...
115 | */
116 |
117 | if (!node || node->type != MXML_ELEMENT || !name)
118 | return (-1);
119 |
120 | /*
121 | * Free any old element value and set the new value...
122 | */
123 |
124 | if (node->value.element.name)
125 | free(node->value.element.name);
126 |
127 | node->value.element.name = strdup(name);
128 |
129 | return (0);
130 | }
131 |
132 |
133 | /*
134 | * 'mxmlSetInteger()' - Set the value of an integer node.
135 | *
136 | * The node is not changed if it (or its first child) is not an integer node.
137 | */
138 |
139 | int /* O - 0 on success, -1 on failure */
140 | mxmlSetInteger(mxml_node_t *node, /* I - Node to set */
141 | int integer) /* I - Integer value */
142 | {
143 | /*
144 | * Range check input...
145 | */
146 |
147 | if (node && node->type == MXML_ELEMENT &&
148 | node->child && node->child->type == MXML_INTEGER)
149 | node = node->child;
150 |
151 | if (!node || node->type != MXML_INTEGER)
152 | return (-1);
153 |
154 | /*
155 | * Set the new value and return...
156 | */
157 |
158 | node->value.integer = integer;
159 |
160 | return (0);
161 | }
162 |
163 |
164 | /*
165 | * 'mxmlSetOpaque()' - Set the value of an opaque node.
166 | *
167 | * The node is not changed if it (or its first child) is not an opaque node.
168 | */
169 |
170 | int /* O - 0 on success, -1 on failure */
171 | mxmlSetOpaque(mxml_node_t *node, /* I - Node to set */
172 | const char *opaque) /* I - Opaque string */
173 | {
174 | /*
175 | * Range check input...
176 | */
177 |
178 | if (node && node->type == MXML_ELEMENT &&
179 | node->child && node->child->type == MXML_OPAQUE)
180 | node = node->child;
181 |
182 | if (!node || node->type != MXML_OPAQUE || !opaque)
183 | return (-1);
184 |
185 | /*
186 | * Free any old opaque value and set the new value...
187 | */
188 |
189 | if (node->value.opaque)
190 | free(node->value.opaque);
191 |
192 | node->value.opaque = strdup(opaque);
193 |
194 | return (0);
195 | }
196 |
197 |
198 | /*
199 | * 'mxmlSetReal()' - Set the value of a real number node.
200 | *
201 | * The node is not changed if it (or its first child) is not a real number node.
202 | */
203 |
204 | int /* O - 0 on success, -1 on failure */
205 | mxmlSetReal(mxml_node_t *node, /* I - Node to set */
206 | double real) /* I - Real number value */
207 | {
208 | /*
209 | * Range check input...
210 | */
211 |
212 | if (node && node->type == MXML_ELEMENT &&
213 | node->child && node->child->type == MXML_REAL)
214 | node = node->child;
215 |
216 | if (!node || node->type != MXML_REAL)
217 | return (-1);
218 |
219 | /*
220 | * Set the new value and return...
221 | */
222 |
223 | node->value.real = real;
224 |
225 | return (0);
226 | }
227 |
228 |
229 | /*
230 | * 'mxmlSetText()' - Set the value of a text node.
231 | *
232 | * The node is not changed if it (or its first child) is not a text node.
233 | */
234 |
235 | int /* O - 0 on success, -1 on failure */
236 | mxmlSetText(mxml_node_t *node, /* I - Node to set */
237 | int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */
238 | const char *string) /* I - String */
239 | {
240 | /*
241 | * Range check input...
242 | */
243 |
244 | if (node && node->type == MXML_ELEMENT &&
245 | node->child && node->child->type == MXML_TEXT)
246 | node = node->child;
247 |
248 | if (!node || node->type != MXML_TEXT || !string)
249 | return (-1);
250 |
251 | /*
252 | * Free any old string value and set the new value...
253 | */
254 |
255 | if (node->value.text.string)
256 | free(node->value.text.string);
257 |
258 | node->value.text.whitespace = whitespace;
259 | node->value.text.string = strdup(string);
260 |
261 | return (0);
262 | }
263 |
264 |
265 | /*
266 | * 'mxmlSetTextf()' - Set the value of a text node to a formatted string.
267 | *
268 | * The node is not changed if it (or its first child) is not a text node.
269 | */
270 |
271 | int /* O - 0 on success, -1 on failure */
272 | mxmlSetTextf(mxml_node_t *node, /* I - Node to set */
273 | int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */
274 | const char *format, /* I - Printf-style format string */
275 | ...) /* I - Additional arguments as needed */
276 | {
277 | va_list ap; /* Pointer to arguments */
278 |
279 |
280 | /*
281 | * Range check input...
282 | */
283 |
284 | if (node && node->type == MXML_ELEMENT &&
285 | node->child && node->child->type == MXML_TEXT)
286 | node = node->child;
287 |
288 | if (!node || node->type != MXML_TEXT || !format)
289 | return (-1);
290 |
291 | /*
292 | * Free any old string value and set the new value...
293 | */
294 |
295 | if (node->value.text.string)
296 | free(node->value.text.string);
297 |
298 | va_start(ap, format);
299 |
300 | node->value.text.whitespace = whitespace;
301 | node->value.text.string = _mxml_strdupf(format, ap);
302 |
303 | va_end(ap);
304 |
305 | return (0);
306 | }
307 |
308 |
309 | /*
310 | * 'mxmlSetUserData()' - Set the user data pointer for a node.
311 | *
312 | * @since Mini-XML 2.7@
313 | */
314 |
315 | int /* O - 0 on success, -1 on failure */
316 | mxmlSetUserData(mxml_node_t *node, /* I - Node to set */
317 | void *data) /* I - User data pointer */
318 | {
319 | /*
320 | * Range check input...
321 | */
322 |
323 | if (!node)
324 | return (-1);
325 |
326 | /*
327 | * Set the user data pointer and return...
328 | */
329 |
330 | node->user_data = data;
331 | return (0);
332 | }
333 |
334 |
335 | /*
336 | * End of "$Id$".
337 | */
338 |
--------------------------------------------------------------------------------
/mxml.list.in:
--------------------------------------------------------------------------------
1 | #
2 | # "$Id$"
3 | #
4 | # EPM software list file for Mini-XML, a small XML library.
5 | #
6 | # Copyright 2003-2014 by Michael Sweet.
7 | #
8 | # This program is free software; you can redistribute it and/or
9 | # modify it under the terms of the GNU Library General Public
10 | # License as published by the Free Software Foundation; either
11 | # version 2, or (at your option) any later version.
12 | #
13 | # This program is distributed in the hope that it will be useful,
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | # GNU General Public License for more details.
17 | #
18 |
19 | # Directories...
20 | $prefix=@prefix@
21 | $exec_prefix=@exec_prefix@
22 | $bindir=@bindir@
23 | $datarootdir=@datarootdir@
24 | $docdir=@docdir@
25 | $includedir=@includedir@
26 | $libdir=@libdir@
27 | $mandir=@mandir@
28 | $srcdir=@srcdir@
29 |
30 | $PICFLAG=@PICFLAG@
31 |
32 | # Product information
33 | %product mxml
34 | %copyright 2003-2014 by Michael Sweet
35 | %vendor Michael Sweet
36 | %license ${srcdir}/COPYING
37 | %readme ${srcdir}/README
38 | %version @VERSION@
39 |
40 | %description <
28 | Vendor: Michael Sweet
29 |
30 | # Use buildroot so as not to disturb the version already installed
31 | BuildRoot: /var/tmp/%{name}-root
32 |
33 | %description
34 | Mini-XML is a small XML parsing library that you can use to read
35 | XML and XML-like data files in your application without
36 | requiring large non-standard libraries. Mini-XML provides the
37 | following functionality:
38 |
39 | - Reading of UTF-8 and UTF-16 and writing of UTF-8 encoded
40 | XML files and strings.
41 | - Data is stored in a linked-list tree structure, preserving
42 | the XML data hierarchy.
43 | - Supports arbitrary element names, attributes, and
44 | attribute values with no preset limits, just available
45 | memory.
46 | - Supports integer, real, opaque ("cdata"), and text data
47 | types in "leaf" nodes.
48 | - Functions for creating and managing trees of data.
49 | - "Find" and "walk" functions for easily locating and
50 | navigating trees of data.
51 |
52 | Mini-XML doesn't do validation or other types of processing on
53 | the data based upon schema files or other sources of definition
54 | information, nor does it support character entities other than
55 | those required by the XML specification.
56 |
57 | %prep
58 | %setup
59 |
60 | %build
61 | CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_OPT_FLAGS" ./configure --enable-shared --prefix=/usr
62 |
63 | # If we got this far, all prerequisite libraries must be here.
64 | make
65 |
66 | %install
67 | # Make sure the RPM_BUILD_ROOT directory exists.
68 | rm -rf $RPM_BUILD_ROOT
69 |
70 | make BUILDROOT=$RPM_BUILD_ROOT install
71 |
72 | %clean
73 | rm -rf $RPM_BUILD_ROOT
74 |
75 | %files
76 | %defattr(-,root,root)
77 |
78 | %dir /usr/bin
79 | /usr/bin/*
80 | %dir /usr/include
81 | /usr/include/mxml.h
82 | %dir /usr/lib
83 | /usr/lib/*
84 | %dir /usr/lib/pkgconfig
85 | /usr/lib/pkgconfig/mxml.pc
86 | %dir /usr/share/doc/mxml
87 | /usr/share/doc/mxml/*
88 | %dir /usr/share/man/man1
89 | /usr/share/man/man1/*
90 | %dir /usr/share/man/man3
91 | /usr/share/man/man3/*
92 |
93 | #
94 | # End of "$Id$".
95 | #
96 |
--------------------------------------------------------------------------------
/test.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
24 | 123
25 | Now is the time for all good men to come to the aid of their
26 | country.
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/test/class.cxx:
--------------------------------------------------------------------------------
1 | class foo_c : public bar_c // Foo class derived from bar
2 | {
3 | float foo; /* Real number */
4 | int bar; /* Integer */
5 |
6 | public:
7 |
8 | foo_c(float f, int b);
9 | ~foo_c();
10 |
11 | // 'get_bar()' - Get the value of bar.
12 | int // O - Value of bar
13 | get_bar()
14 | {
15 | return (bar);
16 | }
17 |
18 | // 'get_foo()' - Get the value of foo.
19 | float // O - Value of foo
20 | get_foo()
21 | {
22 | return (foo);
23 | }
24 |
25 | // 'set_bar()' - Set the value of bar.
26 | void
27 | set_bar(int b) // I - Value of bar
28 | {
29 | bar = b;
30 | }
31 |
32 | // 'set_foo()' - Set the value of foo.
33 | void
34 | set_foo(float f) // I - Value of foo
35 | {
36 | foo = f;
37 | }
38 |
39 | // 'set_foobar()' - Set foo and optionally bar (should show default args).
40 | void
41 | set_foobar(float f, // I - Value of foo
42 | int b = 0) // I - Value of bar
43 | {
44 | foo = f;
45 | bar = b;
46 | }
47 |
48 | protected:
49 |
50 | static int global; /* Global integer */
51 |
52 | // 'get_global()' - Get the global integer.
53 | int // O - Integer
54 | get_global()
55 | {
56 | return (global);
57 | }
58 |
59 | private:
60 |
61 | int barfoo; // Another private integer
62 |
63 | public:
64 |
65 | // 'get_barfoo()' - Get the barfoo value.
66 | int // O - Barfoo value
67 | get_barfoo()
68 | {
69 | return (barfoo);
70 | }
71 | }
72 |
73 | // 'foo_c::foo_c()' - Create a foo_c class.
74 | foo_c::foo_c(float f, // I - Value of foo
75 | int b) // I - Value of bar
76 | {
77 | foo = f;
78 | bar = b;
79 | }
80 |
81 | // 'foo_c::~foo_c()' - Destroy a foo_c class.
82 | foo_c::~foo_c()
83 | {
84 | }
85 |
--------------------------------------------------------------------------------
/test/dotest.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | (cd ..; make mxmldoc-static)
3 |
4 | files=""
5 | mode=""
6 |
7 | while test $# -gt 0; do
8 | arg="$1"
9 | shift
10 |
11 | case "$arg" in
12 | -f) framed="--framed framed" ;;
13 | -g) mode="gdb" ;;
14 | -v) mode="valgrind" ;;
15 | *.h | *.c | *.cxx) files="$files $arg" ;;
16 | *)
17 | echo "Usage: ./dotest.sh [-f] [-g] [-v] [files]"
18 | exit 1
19 | ;;
20 | esac
21 | done
22 |
23 | if test "$files" = ""; then
24 | files=*.cxx
25 | fi
26 |
27 | rm -f test.xml
28 |
29 | case "$mode" in
30 | gdb)
31 | echo "break malloc_error_break" >.gdbcmds
32 | echo "set env DYLD_INSERT_LIBRARIES /usr/lib/libgmalloc.dylib" >>.gdbcmds
33 | echo "run $framed test.xml $files >test.html 2>test.log" >>.gdbcmds
34 | gdb -x .gdbcmds ../mxmldoc-static
35 | ;;
36 |
37 | valgrind)
38 | valgrind --log-fd=3 --leak-check=yes \
39 | ../mxmldoc-static $framed test.xml $files \
40 | >test.html 2>test.log 3>test.valgrind
41 | ;;
42 |
43 | *)
44 | ../mxmldoc-static $framed test.xml $files >test.html 2>test.log
45 | ;;
46 | esac
47 |
48 |
--------------------------------------------------------------------------------
/test/enum.cxx:
--------------------------------------------------------------------------------
1 | typedef enum foo_enum_e /* Sample enumeration type */
2 | {
3 | FOO_ONE, /* One fish */
4 | FOO_TWO, /* Two fish */
5 | FOO_RED, /* Red fish */
6 | FOO_BLUE, /* Blue fish */
7 | FOO_PRIVATE /* Private fish @private@ */
8 | } foo_enum_t;
9 |
10 | typedef enum foo_enum2_e /* Sample enumeration type #2 */
11 | {
12 | FOO2_ONE, /* One fish #2 */
13 | FOO2_TWO, /* Two fish #2 */
14 | FOO2_RED, /* Red fish #2 */
15 | FOO2_BLUE, /* Blue fish #2 */
16 | FOO2_PRIVATE /* Private fish #2 @private@ */
17 | } foo_enum2_t;
18 |
--------------------------------------------------------------------------------
/test/function.cxx:
--------------------------------------------------------------------------------
1 | /*
2 | * 'foo_void_function()' - Do foo with bar.
3 | *
4 | * Use the @link foo_float_function@ or @link foo_int_function@ functions
5 | * instead. Pass @code NULL@ for "three" then there is no string to print.
6 | *
7 | * @deprecated@
8 | */
9 |
10 | void
11 | foo_void_function(int one, /* I - Integer */
12 | float *two, /* O - Real number */
13 | const char *three) /* I - String */
14 | {
15 | if (one)
16 | {
17 | puts("Hello, World!");
18 | }
19 | else
20 | puts(three);
21 |
22 | *two = 2.0f;
23 | }
24 |
25 |
26 | /*
27 | * 'foo_float_function()' - Do foo with bar.
28 | *
29 | * @since 1.2@
30 | */
31 |
32 | float /* O - Real number */
33 | foo_float_function(int one, /* I - Integer */
34 | const char *two) /* I - String */
35 | {
36 | if (one)
37 | {
38 | puts("Hello, World!");
39 | }
40 | else
41 | puts(two);
42 |
43 | return (2.0f);
44 | }
45 |
46 |
47 | /*
48 | * 'foo_default_string()' - Do something with a defaulted string arg.
49 | */
50 |
51 | int /* O - Integer value */
52 | foo_default_string(int one, /* I - Integer */
53 | const char *two = "2")
54 | /* I - String */
55 | {
56 | if (one)
57 | {
58 | puts("Hello, World!");
59 | }
60 | else
61 | puts(two);
62 |
63 | return (2);
64 | }
65 |
66 |
67 | /*
68 | * 'foo_default_int()' - Do something with a defaulted int arg.
69 | */
70 |
71 | int /* O - Integer value */
72 | foo_default_int(int one, /* I - Integer */
73 | int two = 2) /* I - Integer */
74 | {
75 | if (one)
76 | {
77 | puts("Hello, World!");
78 | }
79 | else
80 | puts(two);
81 |
82 | return (2);
83 | }
84 |
85 |
86 | /*
87 | * 'foo_void_func()' - Function taking no arguments.
88 | */
89 |
90 | void
91 | foo_void_func(void)
92 | {
93 | puts("foo_void_func()");
94 | }
95 |
96 |
97 | /*
98 | * 'foo_private_func()' - Private function.
99 | *
100 | * @private@
101 | */
102 |
103 | void
104 | foo_private_func(void)
105 | {
106 | puts("foo_private_func()");
107 | }
108 |
--------------------------------------------------------------------------------
/test/functype.cxx:
--------------------------------------------------------------------------------
1 | typedef int (*foo_func_t)(void *foo, int bar); /**** Foo function type ****/
2 |
--------------------------------------------------------------------------------
/test/struct.cxx:
--------------------------------------------------------------------------------
1 | typedef struct foo_s /* Foo structure */
2 | {
3 | float foo; /* Real number */
4 | int bar; /* Integer */
5 |
6 | foo_s(float f, int b);
7 | ~foo_s();
8 |
9 | // 'get_bar()' - Get the value of bar.
10 | int // O - Value of bar
11 | get_bar()
12 | {
13 | return (bar);
14 | }
15 |
16 | // 'get_foo()' - Get the value of foo.
17 | float // O - Value of foo
18 | get_foo()
19 | {
20 | return (foo);
21 | }
22 |
23 | // 'set_bar()' - Set the value of bar.
24 | void
25 | set_bar(int b) // I - Value of bar
26 | {
27 | bar = b;
28 | }
29 |
30 | // 'set_foo()' - Set the value of foo.
31 | void
32 | set_foo(float f) // I - Value of foo
33 | {
34 | foo = f;
35 | }
36 | } foo_t;
37 |
38 | // 'foo_s::foo_s()' - Create a foo_s structure.
39 | foo_s::foo_s(float f, // I - Value of foo
40 | int b) // I - Value of bar
41 | {
42 | foo = f;
43 | bar = b;
44 | }
45 |
46 | // 'foo_s::~foo_s()' - Destroy a foo_s structure.
47 | foo_s::~foo_s()
48 | {
49 | }
50 |
51 | typedef struct foo_private_s /* @private@ */
52 | {
53 | int a; /* Value of "a" */
54 | char b[255]; /* Value of "b" */
55 | } foo_private_t;
56 |
--------------------------------------------------------------------------------
/test/type.cxx:
--------------------------------------------------------------------------------
1 | typedef int foo_simple_t; /* Simple integer type */
2 |
3 | typedef int foo_simple_private_t; /* @private@ */
4 |
--------------------------------------------------------------------------------
/vcnet/config.h:
--------------------------------------------------------------------------------
1 | /*
2 | * "$Id$"
3 | *
4 | * Configuration file for Mini-XML, a small XML-like file parsing library.
5 | *
6 | * Copyright 2003-2014 by Michael R Sweet.
7 | *
8 | * These coded instructions, statements, and computer programs are the
9 | * property of Michael R Sweet and are protected by Federal copyright
10 | * law. Distribution and use rights are outlined in the file "COPYING"
11 | * which should have been included with this file. If this file is
12 | * missing or damaged, see the license at:
13 | *
14 | * http://www.msweet.org/projects.php/Mini-XML
15 | */
16 |
17 | /*
18 | * Beginning with VC2005, Microsoft breaks ISO C and POSIX conformance
19 | * by deprecating a number of functions in the name of security, even
20 | * when many of the affected functions are otherwise completely secure.
21 | * The _CRT_SECURE_NO_DEPRECATE definition ensures that we won't get
22 | * warnings from their use...
23 | *
24 | * Then Microsoft decided that they should ignore this in VC2008 and use
25 | * yet another define (_CRT_SECURE_NO_WARNINGS) instead. Bastards.
26 | */
27 |
28 | #define _CRT_SECURE_NO_DEPRECATE
29 | #define _CRT_SECURE_NO_WARNINGS
30 |
31 |
32 | /*
33 | * Include necessary headers...
34 | */
35 |
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 |
43 |
44 | /*
45 | * Microsoft also renames the POSIX functions to _name, and introduces
46 | * a broken compatibility layer using the original names. As a result,
47 | * random crashes can occur when, for example, strdup() allocates memory
48 | * from a different heap than used by malloc() and free().
49 | *
50 | * To avoid moronic problems like this, we #define the POSIX function
51 | * names to the corresponding non-standard Microsoft names.
52 | */
53 |
54 | #define close _close
55 | #define open _open
56 | #define read _read
57 | #define snprintf _snprintf
58 | #define strdup _strdup
59 | #define vsnprintf _vsnprintf
60 | #define write _write
61 |
62 |
63 | /*
64 | * Version number...
65 | */
66 |
67 | #define MXML_VERSION "Mini-XML v2.8"
68 |
69 |
70 | /*
71 | * Inline function support...
72 | */
73 |
74 | #define inline _inline
75 |
76 |
77 | /*
78 | * Long long support...
79 | */
80 |
81 | #define HAVE_LONG_LONG 1
82 |
83 |
84 | /*
85 | * Do we have the snprintf() and vsnprintf() functions?
86 | */
87 |
88 | #define HAVE_SNPRINTF 1
89 | #define HAVE_VSNPRINTF 1
90 |
91 |
92 | /*
93 | * Do we have the strXXX() functions?
94 | */
95 |
96 | #define HAVE_STRDUP 1
97 |
98 |
99 | /*
100 | * Define prototypes for string functions as needed...
101 | */
102 |
103 | # ifndef HAVE_STRDUP
104 | extern char *_mxml_strdup(const char *);
105 | # define strdup _mxml_strdup
106 | # endif /* !HAVE_STRDUP */
107 |
108 | extern char *_mxml_strdupf(const char *, ...);
109 | extern char *_mxml_vstrdupf(const char *, va_list);
110 |
111 | # ifndef HAVE_SNPRINTF
112 | extern int _mxml_snprintf(char *, size_t, const char *, ...);
113 | # define snprintf _mxml_snprintf
114 | # endif /* !HAVE_SNPRINTF */
115 |
116 | # ifndef HAVE_VSNPRINTF
117 | extern int _mxml_vsnprintf(char *, size_t, const char *, va_list);
118 | # define vsnprintf _mxml_vsnprintf
119 | # endif /* !HAVE_VSNPRINTF */
120 |
121 | /*
122 | * End of "$Id$".
123 | */
124 |
--------------------------------------------------------------------------------
/vcnet/mxml.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 10.00
2 | # Visual Studio 2008
3 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mxmldoc", "mxmldoc.vcproj", "{D909892E-520A-4322-9A47-DAEBDA9CC7A7}"
4 | ProjectSection(ProjectDependencies) = postProject
5 | {E5AA9476-9751-4654-8109-B1A2112D5E73} = {E5AA9476-9751-4654-8109-B1A2112D5E73}
6 | EndProjectSection
7 | EndProject
8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mxml1", "mxml1.vcproj", "{E5AA9476-9751-4654-8109-B1A2112D5E73}"
9 | EndProject
10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testmxml", "testmxml.vcproj", "{75CAC6C4-A6BC-4935-A3C9-8F0AE0744227}"
11 | ProjectSection(ProjectDependencies) = postProject
12 | {E5AA9476-9751-4654-8109-B1A2112D5E73} = {E5AA9476-9751-4654-8109-B1A2112D5E73}
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Win32 = Debug|Win32
18 | Debug|x64 = Debug|x64
19 | Release|Win32 = Release|Win32
20 | Release|x64 = Release|x64
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {D909892E-520A-4322-9A47-DAEBDA9CC7A7}.Debug|Win32.ActiveCfg = Debug|Win32
24 | {D909892E-520A-4322-9A47-DAEBDA9CC7A7}.Debug|Win32.Build.0 = Debug|Win32
25 | {D909892E-520A-4322-9A47-DAEBDA9CC7A7}.Debug|x64.ActiveCfg = Debug|x64
26 | {D909892E-520A-4322-9A47-DAEBDA9CC7A7}.Debug|x64.Build.0 = Debug|x64
27 | {D909892E-520A-4322-9A47-DAEBDA9CC7A7}.Release|Win32.ActiveCfg = Release|Win32
28 | {D909892E-520A-4322-9A47-DAEBDA9CC7A7}.Release|Win32.Build.0 = Release|Win32
29 | {D909892E-520A-4322-9A47-DAEBDA9CC7A7}.Release|x64.ActiveCfg = Release|x64
30 | {D909892E-520A-4322-9A47-DAEBDA9CC7A7}.Release|x64.Build.0 = Release|x64
31 | {E5AA9476-9751-4654-8109-B1A2112D5E73}.Debug|Win32.ActiveCfg = Debug|Win32
32 | {E5AA9476-9751-4654-8109-B1A2112D5E73}.Debug|Win32.Build.0 = Debug|Win32
33 | {E5AA9476-9751-4654-8109-B1A2112D5E73}.Debug|x64.ActiveCfg = Debug|x64
34 | {E5AA9476-9751-4654-8109-B1A2112D5E73}.Debug|x64.Build.0 = Debug|x64
35 | {E5AA9476-9751-4654-8109-B1A2112D5E73}.Release|Win32.ActiveCfg = Release|Win32
36 | {E5AA9476-9751-4654-8109-B1A2112D5E73}.Release|Win32.Build.0 = Release|Win32
37 | {E5AA9476-9751-4654-8109-B1A2112D5E73}.Release|x64.ActiveCfg = Release|x64
38 | {E5AA9476-9751-4654-8109-B1A2112D5E73}.Release|x64.Build.0 = Release|x64
39 | {75CAC6C4-A6BC-4935-A3C9-8F0AE0744227}.Debug|Win32.ActiveCfg = Debug|Win32
40 | {75CAC6C4-A6BC-4935-A3C9-8F0AE0744227}.Debug|Win32.Build.0 = Debug|Win32
41 | {75CAC6C4-A6BC-4935-A3C9-8F0AE0744227}.Debug|x64.ActiveCfg = Debug|x64
42 | {75CAC6C4-A6BC-4935-A3C9-8F0AE0744227}.Debug|x64.Build.0 = Debug|x64
43 | {75CAC6C4-A6BC-4935-A3C9-8F0AE0744227}.Release|Win32.ActiveCfg = Release|Win32
44 | {75CAC6C4-A6BC-4935-A3C9-8F0AE0744227}.Release|Win32.Build.0 = Release|Win32
45 | {75CAC6C4-A6BC-4935-A3C9-8F0AE0744227}.Release|x64.ActiveCfg = Release|x64
46 | {75CAC6C4-A6BC-4935-A3C9-8F0AE0744227}.Release|x64.Build.0 = Release|x64
47 | EndGlobalSection
48 | GlobalSection(SolutionProperties) = preSolution
49 | HideSolutionNode = FALSE
50 | EndGlobalSection
51 | EndGlobal
52 |
--------------------------------------------------------------------------------
/vcnet/mxml1.def:
--------------------------------------------------------------------------------
1 | LIBRARY "MXML1"
2 | EXPORTS
3 | _mxml_strdupf
4 | _mxml_vstrdupf
5 | mxml_ignore_cb
6 | mxml_integer_cb
7 | mxml_opaque_cb
8 | mxml_real_cb
9 | mxmlAdd
10 | mxmlDelete
11 | mxmlElementDeleteAttr
12 | mxmlElementGetAttr
13 | mxmlElementSetAttr
14 | mxmlElementSetAttrf
15 | mxmlEntityAddCallback
16 | mxmlEntityGetName
17 | mxmlEntityGetValue
18 | mxmlEntityRemoveCallback
19 | mxmlFindElement
20 | mxmlFindPath
21 | mxmlGetCDATA
22 | mxmlGetCustom
23 | mxmlGetElement
24 | mxmlGetFirstChild
25 | mxmlGetInteger
26 | mxmlGetLastChild
27 | mxmlGetNextSibling
28 | mxmlGetOpaque
29 | mxmlGetParent
30 | mxmlGetPrevSibling
31 | mxmlGetReal
32 | mxmlGetRefCount
33 | mxmlGetText
34 | mxmlGetType
35 | mxmlGetUserData
36 | mxmlIndexDelete
37 | mxmlIndexEnum
38 | mxmlIndexFind
39 | mxmlIndexGetCount
40 | mxmlIndexNew
41 | mxmlIndexReset
42 | mxmlLoadFd
43 | mxmlLoadFile
44 | mxmlLoadString
45 | mxmlNewCDATA
46 | mxmlNewCustom
47 | mxmlNewElement
48 | mxmlNewInteger
49 | mxmlNewOpaque
50 | mxmlNewReal
51 | mxmlNewText
52 | mxmlNewTextf
53 | mxmlNewXML
54 | mxmlRelease
55 | mxmlRemove
56 | mxmlRetain
57 | mxmlSaveAllocString
58 | mxmlSaveFd
59 | mxmlSaveFile
60 | mxmlSaveString
61 | mxmlSAXLoadFd
62 | mxmlSAXLoadFile
63 | mxmlSAXLoadString
64 | mxmlSetCDATA
65 | mxmlSetCustom
66 | mxmlSetCustomHandlers
67 | mxmlSetElement
68 | mxmlSetErrorCallback
69 | mxmlSetInteger
70 | mxmlSetOpaque
71 | mxmlSetReal
72 | mxmlSetText
73 | mxmlSetTextf
74 | mxmlSetUserData
75 | mxmlSetWrapMargin
76 | mxmlWalkNext
77 | mxmlWalkPrev
78 |
--------------------------------------------------------------------------------
/www/.htaccess:
--------------------------------------------------------------------------------
1 | RewriteEngine Off
2 |
--------------------------------------------------------------------------------
/www/0.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chuckatkins/MiniXML/b20d77251f8d2242dbf8eb731a0cdb18edd1e7c6/www/0.gif
--------------------------------------------------------------------------------
/www/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chuckatkins/MiniXML/b20d77251f8d2242dbf8eb731a0cdb18edd1e7c6/www/1.gif
--------------------------------------------------------------------------------
/www/2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chuckatkins/MiniXML/b20d77251f8d2242dbf8eb731a0cdb18edd1e7c6/www/2.gif
--------------------------------------------------------------------------------
/www/3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chuckatkins/MiniXML/b20d77251f8d2242dbf8eb731a0cdb18edd1e7c6/www/3.gif
--------------------------------------------------------------------------------
/www/4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chuckatkins/MiniXML/b20d77251f8d2242dbf8eb731a0cdb18edd1e7c6/www/4.gif
--------------------------------------------------------------------------------
/www/A.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chuckatkins/MiniXML/b20d77251f8d2242dbf8eb731a0cdb18edd1e7c6/www/A.gif
--------------------------------------------------------------------------------
/www/B.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chuckatkins/MiniXML/b20d77251f8d2242dbf8eb731a0cdb18edd1e7c6/www/B.gif
--------------------------------------------------------------------------------
/www/C.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chuckatkins/MiniXML/b20d77251f8d2242dbf8eb731a0cdb18edd1e7c6/www/C.gif
--------------------------------------------------------------------------------
/www/D.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chuckatkins/MiniXML/b20d77251f8d2242dbf8eb731a0cdb18edd1e7c6/www/D.gif
--------------------------------------------------------------------------------
/www/data/.htaccess:
--------------------------------------------------------------------------------
1 | Order deny,allow
2 | Allow from none
3 |
4 |
--------------------------------------------------------------------------------
/www/data/makedb:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if test -f mxml.db; then
4 | rm -f mxml.db.old
5 | mv mxml.db mxml.db.old
6 | fi
7 |
8 | sqlite mxml.db
2 |
3 |
4 | Mini-XML Programmers Manual, Version 2.7
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
25 |
26 |
27 | Contents
28 | Previous
29 | Next
30 |
31 |
Building, Installing, and
33 | Packaging Mini-XML
34 |
This chapter describes how to build, install, and package Mini-XML on
35 | your system from the source archive. You will need an ANSI/ISO-C
36 | compatible compiler to build Mini-XML - GCC works, as do most vendors'
37 | C compilers. If you are building Mini-XML on Windows, we recommend
38 | using the Visual C++ environment with the supplied solution file. For
39 | other operating systems, you'll need a POSIX-compatible shell and
40 | make program in addition to the C compiler.
Mini-XML comes with both an autoconf-based configure script and a
43 | Visual C++ solution that can be used to compile the library and
44 | associated tools.
Open the mxml.sln solution in the vcnet folder.
47 | Choose the desired build configuration, "Debug" (the default) or
48 | "Release", and then choose Build Solution from the
49 | Build menu.
Type the following command to configure the Mini-XML source code for
52 | your system:
53 |
54 | ./configure ENTER
55 |
56 |
The default install prefix is /usr/local, which can be
57 | overridden using the --prefix option:
58 |
59 | ./configure --prefix=/foo ENTER
60 |
61 |
Other configure options can be found using the --help
62 | option:
63 |
64 | ./configure --help ENTER
65 |
66 |
Once you have configured the software, use the make(1)
67 | program to do the build and run the test program to verify that things
68 | are working, as follows:
Mini-XML includes two files that can be used to create binary
83 | packages. The first file is mxml.spec which is used by the
84 | rpmbuild(8) software to create Red Hat Package Manager ("RPM")
85 | packages which are commonly used on Linux. Since rpmbuild
86 | wants to compile the software on its own, you can provide it with the
87 | Mini-XML tar file to build the package:
88 |
89 | rpmbuild -ta mxml-version.tar.gz ENTER
90 |
91 |
The second file is mxml.list which is used by the
92 | epm(1) program to create software packages in a variety of formats.
93 | The epm program is available from the following URL:
Use the make command with the epm target to
98 | create portable and native packages for your system:
99 |
100 | make epm ENTER
101 |
102 |
The packages are stored in a subdirectory named dist for
103 | your convenience. The portable packages utilize scripts and tar files
104 | to install the software on the target system. After extracting the
105 | package archive, use the mxml.install script to install the
106 | software.
107 |
The native packages will be in the local OS's native format: RPM for
108 | Red Hat Linux, DPKG for Debian Linux, PKG for Solaris, and so forth.
109 | Use the corresponding commands to install the native packages.
This programmers manual describes Mini-XML version 2.7, a small XML
32 | parsing library that you can use to read and write XML data files in
33 | your C and C++ applications.
34 |
Mini-XML was initially developed for the
35 | Gutenprint project to replace the rather large and unwieldy
36 | libxml2 library with something substantially smaller and
37 | easier-to-use. It all began one morning in June of 2003 when Robert
38 | posted the following sentence to the developer's list:
39 |
It's bad enough that we require libxml2, but rolling our
40 | own XML parser is a bit more than we can handle.
41 |
I then replied with:
42 |
Given the limited scope of what you use in XML, it
43 | should be trivial to code a mini-XML API in a few hundred lines of
44 | code.
45 |
I took my own challenge and coded furiously for two days to produced
46 | the initial public release of Mini-XML, total lines of code: 696.
47 | Robert promptly integrated Mini-XML into Gutenprint and removed
48 | libxml2.
49 |
Thanks to lots of feedback and support from various developers,
50 | Mini-XML has evolved since then to provide a more complete XML
51 | implementation and now stands at a whopping 3,965 lines of code,
52 | compared to 103,893 lines of code for libxml2 version 2.6.9.
53 |
Aside from Gutenprint, Mini-XML is used for the following
54 | projects/software applications:
Please email me (mxml @ easysw . com) if you would like your project
60 | added or removed from this list, or if you have any comments/quotes you
61 | would like me to publish about your experiences with Mini-XML.
Originally developed to generate the Mini-XML and CUPS API
37 | documentation, mxmldoc is now a general-purpose utility which
38 | scans C and C++ source files to produce HTML and man page documentation
39 | along with an XML file representing the functions, types, and
40 | definitions in those source files. Unlike popular documentation
41 | generators like Doxygen or Javadoc, mxmldoc uses in-line
42 | comments rather than comment headers, allowing for more "natural" code
43 | documentation.
44 |
By default, mxmldoc produces HTML documentation. For
45 | example, the following command will scan all of the C source and header
46 | files in the current directory and produce a HTML documentation file
47 | called filename.html:
48 |
49 | mxmldoc *.h *.c >filename.html ENTER
50 |
51 |
You can also specify an XML file to create which contains all of the
52 | information from the source files. For example, the following command
53 | creates an XML file called filename.xml in addition to the
54 | HTML file:
55 |
56 | mxmldoc filename.xml *.h *.c >filename.html ENTER
57 |
58 |
The --no-output option disables the normal HTML output:
59 |
60 | mxmldoc --no-output filename.xml *.h *.c ENTER
61 |
62 |
You can then run mxmldoc again with the XML file alone to
63 | generate the HTML documentation:
64 |
65 | mxmldoc filename.xml >filename.html ENTER
66 |
As noted previously, mxmldoc looks for in-line comments to
88 | describe the functions, types, and constants in your code. Mxmldoc
89 | will document all public names it finds in your source files - any
90 | names starting with the underscore character (_) or names that are
91 | documented with the @private@ directive are
92 | treated as private and are not documented.
93 |
Comments appearing directly before a function or type definition are
94 | used to document that function or type. Comments appearing after
95 | argument, definition, return type, or variable declarations are used to
96 | document that argument, definition, return type, or variable. For
97 | example, the following code excerpt defines a key/value structure and a
98 | function that creates a new instance of that structure:
99 |
100 | /* A key/value pair. This is used with the
101 | dictionary structure. */
102 |
103 | struct keyval
104 | {
105 | char *key; /* Key string */
106 | char *val; /* Value string */
107 | };
108 |
109 | /* Create a new key/value pair. */
110 |
111 | struct keyval * /* New key/value pair */
112 | new_keyval(
113 | const char *key, /* Key string */
114 | const char *val) /* Value string */
115 | {
116 | ...
117 | }
118 |
119 |
Mxmldoc also knows to remove extra asterisks (*) from the
120 | comment string, so the comment string:
121 |
122 | /*
123 | * Compute the value of PI.
124 | *
125 | * The function connects to an Internet server
126 | * that streams audio of mathematical monks
127 | * chanting the first 100 digits of PI.
128 | */
129 |
130 |
will be shown as:
131 |
132 | Compute the value of PI.
133 |
134 | The function connects to an Internet server
135 | that streams audio of mathematical monks
136 | chanting the first 100 digits of PI.
137 |
138 |
Comments can also include the following
139 | special @name ...@ directive strings:
140 |
141 |
@deprecated@ - flags the item as deprecated to discourage
142 | its use
143 |
@private@ - flags the item as private so it will not be
144 | included in the documentation
145 |
@since ...@ - flags the item as new since a particular
146 | release. The text following the @since up to the closing @
147 | is highlighted in the generated documentation, e.g. @since Mini-XML
148 | 2.7@.
Mxmldoc also provides options to set the title, section, and
154 | introduction text for the generated documentation. The --title text
155 | option specifies the title for the documentation. The title string is
156 | usually put in quotes:
157 |
158 | mxmldoc filename.xml \
159 | --title "My Famous Documentation" \
160 | >filename.html ENTER
161 |
162 |
The --section name option specifies the section for the
163 | documentation. For HTML documentation, the name is placed in a HTML
164 | comment such as:
165 |
166 | <!-- SECTION: name -->
167 |
168 |
For man pages, the section name is usually just a number ("3"), or a
169 | number followed by a vendor name ("3acme"). The section name is used in
170 | the .TH directive in the man page:
171 |
172 | .TH mylibrary 3acme "My Title" ...
173 |
174 |
The default section name for man page output is "3". There is no
175 | default section name for HTML output.
176 |
Finally, the --intro filename option specifies a file to
177 | embed after the title and section but before the generated
178 | documentation. For HTML documentation, the file must consist of valid
179 | HTML without the usual DOCTYPE, html, and body
180 | elements. For man page documentation, the file must consist of valid
181 | nroff(1) text.
Mini-XML is a small XML library that you can use to read and write XML and
33 | XML-like data files in your application without requiring large non-standard
34 | libraries. Mini-XML only requires an ANSI C compatible compiler (GCC works, as
35 | do most vendors' ANSI C compilers) and a 'make' program.
36 |
37 |
Mini-XML supports reading of UTF-8 and UTF-16 and writing of UTF-8 encoded
38 | XML files and strings. Data is stored in a linked-list tree structure,
39 | preserving the XML data hierarchy, and arbitrary element names, attributes,
40 | and attribute values are supported with no preset limits, just available
41 | memory.
If you are a not registered $PROJECT_NAME developer, please fill "
204 | ."in the form below to register. An email will be sent to the "
205 | ."address you supply to confirm the registration: