mirror of
https://github.com/michaelrsweet/mxml.git
synced 2024-11-24 11:25:30 +00:00
Add mxmlAdd() and mxmlRemove() functions.
Documentation updates. General cleanup.
This commit is contained in:
parent
438ded6568
commit
f830ffd6a5
14
CHANGES
14
CHANGES
@ -4,9 +4,13 @@ README - 06/04/2003
|
||||
|
||||
CHANGES IN Mini-XML 0.93
|
||||
|
||||
- Added mxmlAdd() and mxmlRemove() functions to add and
|
||||
remove nodes from a tree. This provides more
|
||||
flexibility over where the nodes are inserted and
|
||||
allows nodes to be moved within the tree as needed.
|
||||
- mxmlLoadFile() now correctly handles comments.
|
||||
- mxmlLoadFile() now supports the "gt" and "nbsp"
|
||||
character entities.
|
||||
- mxmlLoadFile() now supports the required "gt", "quot",
|
||||
and "nbsp" character entities.
|
||||
- mxmlSaveFile() now uses newlines as whitespace
|
||||
when valid to do so.
|
||||
- mxmlFindElement() now also takes attribute name and
|
||||
@ -19,7 +23,11 @@ CHANGES IN Mini-XML 0.93
|
||||
now all provide "descend" arguments to control whether
|
||||
they descend into child nodes in the tree.
|
||||
- Fixed some whitespace issues in mxmlLoadFile().
|
||||
- Fixed Unicode output issues in mxmlSaveFile().
|
||||
- Fixed Unicode output and whitespace issues in
|
||||
mxmlSaveFile().
|
||||
- mxmlSaveFile() now supports a whitespace callback to
|
||||
provide more human-readable XML output under program
|
||||
control.
|
||||
|
||||
|
||||
CHANGES IN Mini-XML 0.92
|
||||
|
26
README
26
README
@ -13,9 +13,27 @@ INTRODUCTION
|
||||
requires an ANSI C compatible compiler (GCC works, as do
|
||||
most vendors' ANSI C compilers) and a "make" program.
|
||||
|
||||
Mini-XML was created to support the basic hierarchy provided
|
||||
by XML and some simple data types, but doesn't do validation
|
||||
or other types of processing on the data.
|
||||
Mini-XML provides the following functionality:
|
||||
|
||||
- Reading and writing of UTF-8 encoded XML files.
|
||||
- Data is stored in a linked-list tree structure,
|
||||
preserving the XML data hierarchy.
|
||||
- Supports arbitrary element names, attributes, and
|
||||
attribute values with no preset limits, just available
|
||||
memory.
|
||||
- Supports integer, real, opaque ("cdata"), and text
|
||||
data types in "leaf" nodes.
|
||||
- Functions for creating and managing trees of data.
|
||||
- "Find" and "walk" functions for easily locating and
|
||||
navigating trees of data.
|
||||
|
||||
Mini-XML doesn't do validation or other types of processing
|
||||
on the data based upon schema files or other sources of
|
||||
definition information, nor does it support character
|
||||
entities other than those required by the XML
|
||||
specification. Also, since Mini-XML does not support the
|
||||
UTF-16 encoding, it is technically not a conforming XML
|
||||
consumer/client.
|
||||
|
||||
|
||||
BUILDING Mini-XML
|
||||
@ -86,7 +104,7 @@ DOCUMENTATION
|
||||
mxml_node_t *tree;
|
||||
|
||||
fp = fopen("filename.xml", "w");
|
||||
mxmlSaveFile(tree, fp);
|
||||
mxmlSaveFile(tree, fp, MXML_NO_CALLBACK);
|
||||
fclose(fp);
|
||||
|
||||
You can find a named element/node using the
|
||||
|
27
index.html
27
index.html
@ -29,9 +29,28 @@ requiring large non-standard libraries. Mini-XML only requires
|
||||
an ANSI C compatible compiler (GCC works, as do most vendors'
|
||||
ANSI C compilers) and a "make" program.</p>
|
||||
|
||||
<p>Mini-XML was created to support the basic hierarchy provided
|
||||
by XML and some simple data types, but doesn't do validation or
|
||||
other types of processing on the data.</p>
|
||||
<p>Mini-XML provides the following functionality:</p>
|
||||
|
||||
<ul>
|
||||
<li>Reading and writing of UTF-8 encoded XML files.</li>
|
||||
<li>Data is stored in a linked-list tree structure,
|
||||
preserving the XML data hierarchy.</li>
|
||||
<li>Supports arbitrary element names, attributes, and
|
||||
attribute values with no preset limits, just available
|
||||
memory.</li>
|
||||
<li>Supports integer, real, opaque ("cdata"), and text
|
||||
data types in "leaf" nodes.</li>
|
||||
<li>Functions for creating and managing trees of data.</li>
|
||||
<li>"Find" and "walk" functions for easily locating and
|
||||
navigating trees of data.</li>
|
||||
</ul>
|
||||
|
||||
<p>Mini-XML doesn't do validation or other types of processing
|
||||
on the data based upon schema files or other sources of
|
||||
definition information, nor does it support character entities
|
||||
other than those required by the XML specification. Also, since
|
||||
Mini-XML does not support the UTF-16 encoding, it is technically
|
||||
not a conforming XML consumer/client.</p>
|
||||
|
||||
<h2>Building Mini-XML</h2>
|
||||
|
||||
@ -113,7 +132,7 @@ function:</p>
|
||||
mxml_node_t *tree;
|
||||
|
||||
fp = fopen("filename.xml", "w");
|
||||
mxmlSaveFile(tree, fp);
|
||||
mxmlSaveFile(tree, fp, MXML_NO_CALLBACK);
|
||||
fclose(fp);
|
||||
</pre>
|
||||
|
||||
|
61
mxml-file.c
61
mxml-file.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: mxml-file.c,v 1.6 2003/06/04 16:30:40 mike Exp $"
|
||||
* "$Id: mxml-file.c,v 1.7 2003/06/04 17:37:23 mike Exp $"
|
||||
*
|
||||
* File loading code for mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
@ -36,7 +36,8 @@
|
||||
*/
|
||||
|
||||
static int mxml_parse_element(mxml_node_t *node, FILE *fp);
|
||||
static int mxml_write_node(mxml_node_t *node, FILE *fp, int col);
|
||||
static int mxml_write_node(mxml_node_t *node, FILE *fp,
|
||||
int (*cb)(mxml_node_t *, int), int col);
|
||||
static int mxml_write_string(const char *s, FILE *fp);
|
||||
|
||||
|
||||
@ -367,7 +368,7 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
||||
{
|
||||
/*
|
||||
* Add character entity to current buffer... Currently we only
|
||||
* support <, &, >, , &#nnn;, and &#xXXXX;...
|
||||
* support <, &, >, , ", &#nnn;, and &#xXXXX;...
|
||||
*/
|
||||
|
||||
char entity[64], /* Entity string */
|
||||
@ -413,6 +414,8 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
||||
ch = '<';
|
||||
else if (!strcmp(entity, " "))
|
||||
ch = 0xa0;
|
||||
else if (!strcmp(entity, """))
|
||||
ch = '\"';
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Entity name \"%s;\" not supported under parent <%s>!\n",
|
||||
@ -507,17 +510,23 @@ mxmlLoadFile(mxml_node_t *top, /* I - Top node */
|
||||
|
||||
int /* O - 0 on success, -1 on error */
|
||||
mxmlSaveFile(mxml_node_t *node, /* I - Node to write */
|
||||
FILE *fp) /* I - File to write to */
|
||||
FILE *fp, /* I - File to write to */
|
||||
int (*cb)(mxml_node_t *, int))
|
||||
/* I - Whitespace callback */
|
||||
{
|
||||
int col; /* Final column */
|
||||
|
||||
|
||||
/*
|
||||
* Write the node...
|
||||
*/
|
||||
|
||||
if (mxml_write_node(node, fp, 0) < 0)
|
||||
if ((col = mxml_write_node(node, fp, cb, 0)) < 0)
|
||||
return (-1);
|
||||
|
||||
if (putc('\n', fp) < 0)
|
||||
return (-1);
|
||||
if (col > 0)
|
||||
if (putc('\n', fp) < 0)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Return 0 (success)...
|
||||
@ -688,9 +697,12 @@ mxml_parse_element(mxml_node_t *node, /* I - Element node */
|
||||
static int /* O - Column or -1 on error */
|
||||
mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
FILE *fp, /* I - File to write to */
|
||||
int (*cb)(mxml_node_t *, int),
|
||||
/* I - Whitespace callback */
|
||||
int col) /* I - Current column */
|
||||
{
|
||||
int i; /* Looping var */
|
||||
int ch; /* Whitespace character */
|
||||
int n; /* Chars written */
|
||||
mxml_attr_t *attr; /* Current attribute */
|
||||
|
||||
@ -704,6 +716,18 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
switch (node->type)
|
||||
{
|
||||
case MXML_ELEMENT :
|
||||
if (cb && (ch = (*cb)(node, MXML_SAVE_OPEN_TAG)) != 0)
|
||||
{
|
||||
if (putc(ch, fp) < 0)
|
||||
return (-1);
|
||||
else if (ch == '\n')
|
||||
col = 0;
|
||||
else if (ch == '\t')
|
||||
col += 8;
|
||||
else
|
||||
col ++;
|
||||
}
|
||||
|
||||
if ((n = fprintf(fp, "<%s", node->value.element.name)) < 0)
|
||||
return (-1);
|
||||
|
||||
@ -752,7 +776,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
else
|
||||
col ++;
|
||||
|
||||
if ((col = mxml_write_node(node->child, fp, col)) < 0)
|
||||
if ((col = mxml_write_node(node->child, fp, cb, col)) < 0)
|
||||
return (-1);
|
||||
|
||||
if (node->value.element.name[0] != '?' &&
|
||||
@ -775,6 +799,18 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
return (-1);
|
||||
else
|
||||
col += 2;
|
||||
|
||||
if (cb && (ch = (*cb)(node, MXML_SAVE_CLOSE_TAG)) != 0)
|
||||
{
|
||||
if (putc(ch, fp) < 0)
|
||||
return (-1);
|
||||
else if (ch == '\n')
|
||||
col = 0;
|
||||
else if (ch == '\t')
|
||||
col += 8;
|
||||
else
|
||||
col ++;
|
||||
}
|
||||
break;
|
||||
|
||||
case MXML_INTEGER :
|
||||
@ -829,7 +865,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
|
||||
break;
|
||||
|
||||
case MXML_TEXT :
|
||||
if (node->value.text.whitespace)
|
||||
if (node->value.text.whitespace && col > 0)
|
||||
{
|
||||
if (col > MXML_WRAP)
|
||||
{
|
||||
@ -887,6 +923,11 @@ mxml_write_string(const char *s, /* I - String to write */
|
||||
if (fputs(">", fp) < 0)
|
||||
return (-1);
|
||||
}
|
||||
else if (*s == '\"')
|
||||
{
|
||||
if (fputs(""", fp) < 0)
|
||||
return (-1);
|
||||
}
|
||||
else if (*s & 128)
|
||||
{
|
||||
/*
|
||||
@ -933,5 +974,5 @@ mxml_write_string(const char *s, /* I - String to write */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: mxml-file.c,v 1.6 2003/06/04 16:30:40 mike Exp $".
|
||||
* End of "$Id: mxml-file.c,v 1.7 2003/06/04 17:37:23 mike Exp $".
|
||||
*/
|
||||
|
165
mxml-node.c
165
mxml-node.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: mxml-node.c,v 1.1 2003/06/03 19:46:30 mike Exp $"
|
||||
* "$Id: mxml-node.c,v 1.2 2003/06/04 17:37:23 mike Exp $"
|
||||
*
|
||||
* Node support code for mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
@ -17,12 +17,14 @@
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* mxmlAdd() - Add a node to a tree.
|
||||
* mxmlDelete() - Delete a node and all of its children.
|
||||
* mxmlNewElement() - Create a new element node.
|
||||
* mxmlNewInteger() - Create a new integer node.
|
||||
* mxmlNewOpaque() - Create a new opaque string.
|
||||
* mxmlNewReal() - Create a new real number node.
|
||||
* mxmlNewText() - Create a new text fragment node.
|
||||
* mxmlRemove() - Remove a node from its parent.
|
||||
* mxml_new() - Create a new node.
|
||||
*/
|
||||
|
||||
@ -40,6 +42,98 @@
|
||||
static mxml_node_t *mxml_new(mxml_node_t *parent, mxml_type_t type);
|
||||
|
||||
|
||||
/*
|
||||
* 'mxmlAdd()' - Add a node to a tree.
|
||||
*/
|
||||
|
||||
void
|
||||
mxmlAdd(mxml_node_t *parent, /* I - Parent node */
|
||||
int where, /* I - Where to add */
|
||||
mxml_node_t *child, /* I - Child node for where */
|
||||
mxml_node_t *node) /* I - Node to add */
|
||||
{
|
||||
if (!parent)
|
||||
return;
|
||||
|
||||
if (node->parent)
|
||||
mxmlRemove(node);
|
||||
|
||||
node->parent = parent;
|
||||
|
||||
switch (where)
|
||||
{
|
||||
case MXML_ADD_BEFORE :
|
||||
if (!child || child == parent->child || child->parent != parent)
|
||||
{
|
||||
/*
|
||||
* Insert as first node under parent...
|
||||
*/
|
||||
|
||||
node->next = parent->child;
|
||||
|
||||
if (parent->child)
|
||||
parent->child->prev = node;
|
||||
else
|
||||
parent->last_child = node;
|
||||
|
||||
parent->child = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Insert node before this child...
|
||||
*/
|
||||
|
||||
node->next = child;
|
||||
node->prev = child->prev;
|
||||
|
||||
if (child->prev)
|
||||
child->prev->next = node;
|
||||
else
|
||||
parent->child = node;
|
||||
|
||||
child->prev = node;
|
||||
}
|
||||
break;
|
||||
|
||||
case MXML_ADD_AFTER :
|
||||
if (!child || child == parent->last_child || child->parent != parent)
|
||||
{
|
||||
/*
|
||||
* Insert as last node under parent...
|
||||
*/
|
||||
|
||||
node->parent = parent;
|
||||
node->prev = parent->last_child;
|
||||
|
||||
if (parent->last_child)
|
||||
parent->last_child->next = node;
|
||||
else
|
||||
parent->child = node;
|
||||
|
||||
parent->last_child = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Insert node after this child...
|
||||
*/
|
||||
|
||||
node->prev = child;
|
||||
node->next = child->next;
|
||||
|
||||
if (child->next)
|
||||
child->next->prev = node;
|
||||
else
|
||||
parent->last_child = node;
|
||||
|
||||
child->next = node;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'mxmlDelete()' - Delete a node and all of its children.
|
||||
*/
|
||||
@ -58,7 +152,13 @@ mxmlDelete(mxml_node_t *node) /* I - Node */
|
||||
return;
|
||||
|
||||
/*
|
||||
* Delete children first...
|
||||
* Remove the node from its parent, if any...
|
||||
*/
|
||||
|
||||
mxmlRemove(node);
|
||||
|
||||
/*
|
||||
* Delete children...
|
||||
*/
|
||||
|
||||
while (node->child)
|
||||
@ -103,23 +203,6 @@ mxmlDelete(mxml_node_t *node) /* I - Node */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove from parent, if any...
|
||||
*/
|
||||
|
||||
if (node->parent)
|
||||
{
|
||||
if (node->prev)
|
||||
node->prev->next = node->next;
|
||||
else
|
||||
node->parent->child = node->next;
|
||||
|
||||
if (node->next)
|
||||
node->next->prev = node->prev;
|
||||
else
|
||||
node->parent->last_child = node->prev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free this node...
|
||||
*/
|
||||
@ -277,6 +360,36 @@ mxmlNewText(mxml_node_t *parent, /* I - Parent node */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'mxmlRemove()' - Remove a node from its parent.
|
||||
*/
|
||||
|
||||
void
|
||||
mxmlRemove(mxml_node_t *node) /* I - Node to remove */
|
||||
{
|
||||
/*
|
||||
* Range check input...
|
||||
*/
|
||||
|
||||
if (!node || !node->parent)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Remove from parent...
|
||||
*/
|
||||
|
||||
if (node->prev)
|
||||
node->prev->next = node->next;
|
||||
else
|
||||
node->parent->child = node->next;
|
||||
|
||||
if (node->next)
|
||||
node->next->prev = node->prev;
|
||||
else
|
||||
node->parent->last_child = node->prev;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'mxml_new()' - Create a new node.
|
||||
*/
|
||||
@ -306,17 +419,7 @@ mxml_new(mxml_node_t *parent, /* I - Parent node */
|
||||
*/
|
||||
|
||||
if (parent)
|
||||
{
|
||||
node->parent = parent;
|
||||
node->prev = parent->last_child;
|
||||
|
||||
if (parent->last_child)
|
||||
parent->last_child->next = node;
|
||||
else
|
||||
parent->child = node;
|
||||
|
||||
parent->last_child = node;
|
||||
}
|
||||
mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node);
|
||||
|
||||
/*
|
||||
* Return the new node...
|
||||
@ -327,5 +430,5 @@ mxml_new(mxml_node_t *parent, /* I - Parent node */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: mxml-node.c,v 1.1 2003/06/03 19:46:30 mike Exp $".
|
||||
* End of "$Id: mxml-node.c,v 1.2 2003/06/04 17:37:23 mike Exp $".
|
||||
*/
|
||||
|
21
mxml.h
21
mxml.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: mxml.h,v 1.5 2003/06/04 16:30:40 mike Exp $"
|
||||
* "$Id: mxml.h,v 1.6 2003/06/04 17:37:23 mike Exp $"
|
||||
*
|
||||
* Header file for mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
@ -38,14 +38,21 @@
|
||||
* Constants...
|
||||
*/
|
||||
|
||||
# define MXML_NO_CALLBACK (mxml_type_t (*)(mxml_node_t *))0
|
||||
/* Don't use a type callback */
|
||||
# define MXML_NO_CALLBACK 0 /* Don't use a type callback */
|
||||
# define MXML_WRAP 72 /* Wrap XML output at this column position */
|
||||
|
||||
# define MXML_DESCEND 1 /* Descend when finding/walking */
|
||||
# define MXML_NO_DESCEND 0 /* Don't descend when finding/walking */
|
||||
# define MXML_DESCEND_FIRST -1 /* Descend for first find */
|
||||
|
||||
# define MXML_SAVE_OPEN_TAG 0 /* Callback for open tag */
|
||||
# define MXML_SAVE_CLOSE_TAG 1 /* Callback for close tag */
|
||||
|
||||
|
||||
# define MXML_ADD_BEFORE 0 /* Add node before specified node */
|
||||
# define MXML_ADD_AFTER 1 /* Add node after specified node */
|
||||
# define MXML_ADD_TO_PARENT NULL /* Add node relative to parent */
|
||||
|
||||
|
||||
/*
|
||||
* Data types...
|
||||
@ -110,6 +117,8 @@ extern "C" {
|
||||
* Prototypes...
|
||||
*/
|
||||
|
||||
extern void mxmlAdd(mxml_node_t *parent, int where,
|
||||
mxml_node_t *child, mxml_node_t *node);
|
||||
extern void mxmlDelete(mxml_node_t *node);
|
||||
extern const char *mxmlElementGetAttr(mxml_node_t *node, const char *name);
|
||||
extern void mxmlElementSetAttr(mxml_node_t *node, const char *name,
|
||||
@ -125,7 +134,9 @@ extern mxml_node_t *mxmlNewOpaque(mxml_node_t *parent, const char *opaque);
|
||||
extern mxml_node_t *mxmlNewReal(mxml_node_t *parent, double real);
|
||||
extern mxml_node_t *mxmlNewText(mxml_node_t *parent, int whitespace,
|
||||
const char *string);
|
||||
extern int mxmlSaveFile(mxml_node_t *node, FILE *fp);
|
||||
extern void mxmlRemove(mxml_node_t *node);
|
||||
extern int mxmlSaveFile(mxml_node_t *node, FILE *fp,
|
||||
int (*cb)(mxml_node_t *, int));
|
||||
extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top,
|
||||
int descend);
|
||||
extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top,
|
||||
@ -143,5 +154,5 @@ extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top,
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: mxml.h,v 1.5 2003/06/04 16:30:40 mike Exp $".
|
||||
* End of "$Id: mxml.h,v 1.6 2003/06/04 17:37:23 mike Exp $".
|
||||
*/
|
||||
|
75
mxmldoc.c
75
mxmldoc.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: mxmldoc.c,v 1.2 2003/06/04 16:30:40 mike Exp $"
|
||||
* "$Id: mxmldoc.c,v 1.3 2003/06/04 17:37:23 mike Exp $"
|
||||
*
|
||||
* Documentation generator using mini-XML, a small XML-like file parsing
|
||||
* library.
|
||||
@ -102,9 +102,9 @@
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
static void insert_node(mxml_node_t *tree, mxml_node_t *func);
|
||||
static int scan_file(const char *filename, FILE *fp,
|
||||
mxml_node_t *doc);
|
||||
static void sort_node(mxml_node_t *tree, mxml_node_t *func);
|
||||
|
||||
|
||||
/*
|
||||
@ -193,7 +193,7 @@ main(int argc, /* I - Number of command-line args */
|
||||
* Write over the existing XML file...
|
||||
*/
|
||||
|
||||
if (mxmlSaveFile(doc, fp))
|
||||
if (mxmlSaveFile(doc, fp, MXML_NO_CALLBACK))
|
||||
{
|
||||
fprintf(stderr, "Unable to write the XML documentation file \"%s\": %s!\n",
|
||||
argv[1], strerror(errno));
|
||||
@ -223,12 +223,24 @@ main(int argc, /* I - Number of command-line args */
|
||||
|
||||
|
||||
/*
|
||||
* 'insert_node()' - Insert a node into a tree.
|
||||
* 'scan_file()' - Scan a source file.
|
||||
*/
|
||||
|
||||
static int /* O - 0 on success, -1 on error */
|
||||
scan_file(const char *filename, /* I - Filename */
|
||||
FILE *fp, /* I - File to scan */
|
||||
mxml_node_t *tree) /* I - Function tree */
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'sort_node()' - Insert a node sorted into a tree.
|
||||
*/
|
||||
|
||||
static void
|
||||
insert_node(mxml_node_t *tree, /* I - Tree to insert into */
|
||||
mxml_node_t *node) /* I - Node to add */
|
||||
sort_node(mxml_node_t *tree, /* I - Tree to sort into */
|
||||
mxml_node_t *node) /* I - Node to add */
|
||||
{
|
||||
mxml_node_t *temp; /* Current node */
|
||||
const char *tempname, /* Name of current node */
|
||||
@ -242,7 +254,7 @@ insert_node(mxml_node_t *tree, /* I - Tree to insert into */
|
||||
nodename = mxmlElementGetAttr(node, "name");
|
||||
|
||||
/*
|
||||
* Delete an existing definition, if one exists...
|
||||
* Delete any existing definition at this level, if one exists...
|
||||
*/
|
||||
|
||||
if ((temp = mxmlFindElement(tree, tree, node->value.element.name,
|
||||
@ -250,7 +262,7 @@ insert_node(mxml_node_t *tree, /* I - Tree to insert into */
|
||||
mxmlDelete(temp);
|
||||
|
||||
/*
|
||||
* Insert the node into the tree...
|
||||
* Add the node into the tree at the proper place...
|
||||
*/
|
||||
|
||||
for (temp = tree->child; temp; temp = temp->next)
|
||||
@ -262,53 +274,10 @@ insert_node(mxml_node_t *tree, /* I - Tree to insert into */
|
||||
break;
|
||||
}
|
||||
|
||||
if (temp)
|
||||
{
|
||||
/*
|
||||
* Insert node before this temp...
|
||||
*/
|
||||
|
||||
node->next = temp;
|
||||
node->prev = temp->prev;
|
||||
|
||||
if (temp->prev)
|
||||
temp->prev->next = node;
|
||||
else
|
||||
tree->child = node;
|
||||
|
||||
temp->prev = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Append node to the end...
|
||||
*/
|
||||
|
||||
node->prev = tree->last_child;
|
||||
|
||||
if (tree->last_child)
|
||||
tree->last_child->next = node;
|
||||
else
|
||||
tree->last_child = node;
|
||||
|
||||
if (!tree->child)
|
||||
tree->child = node;
|
||||
}
|
||||
mxmlAdd(tree, MXML_ADD_AFTER, temp, node);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'scan_file()' - Scan a source file.
|
||||
*/
|
||||
|
||||
static int /* O - 0 on success, -1 on error */
|
||||
scan_file(const char *filename, /* I - Filename */
|
||||
FILE *fp, /* I - File to scan */
|
||||
mxml_node_t *tree) /* I - Function tree */
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: mxmldoc.c,v 1.2 2003/06/04 16:30:40 mike Exp $".
|
||||
* End of "$Id: mxmldoc.c,v 1.3 2003/06/04 17:37:23 mike Exp $".
|
||||
*/
|
||||
|
56
testmxml.c
56
testmxml.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* "$Id: testmxml.c,v 1.5 2003/06/04 16:30:40 mike Exp $"
|
||||
* "$Id: testmxml.c,v 1.6 2003/06/04 17:37:23 mike Exp $"
|
||||
*
|
||||
* Test program for mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
@ -17,8 +17,10 @@
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* main() - Main entry for test program.
|
||||
* type_cb() - XML data type callback for mxmlLoadFile()...
|
||||
* main() - Main entry for test program.
|
||||
* type_cb() - XML data type callback for mxmlLoadFile()...
|
||||
* whitespace_cb() - Let the mxmlSaveFile() function know when to insert
|
||||
* newlines and tabs...
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -33,6 +35,7 @@
|
||||
*/
|
||||
|
||||
mxml_type_t type_cb(mxml_node_t *node);
|
||||
int whitespace_cb(mxml_node_t *node, int where);
|
||||
|
||||
|
||||
/*
|
||||
@ -110,8 +113,7 @@ main(int argc, /* I - Number of command-line args */
|
||||
* Print the XML tree...
|
||||
*/
|
||||
|
||||
mxmlSaveFile(tree, stdout);
|
||||
puts("");
|
||||
mxmlSaveFile(tree, stdout, whitespace_cb);
|
||||
|
||||
/*
|
||||
* Delete the tree and return...
|
||||
@ -142,8 +144,7 @@ type_cb(mxml_node_t *node) /* I - Element node */
|
||||
|
||||
if (!strcmp(type, "integer"))
|
||||
return (MXML_INTEGER);
|
||||
else if (!strcmp(type, "opaque") ||
|
||||
!strcmp(type, "pre") || !strcmp(type, "PRE"))
|
||||
else if (!strcmp(type, "opaque") || !strcmp(type, "pre"))
|
||||
return (MXML_OPAQUE);
|
||||
else if (!strcmp(type, "real"))
|
||||
return (MXML_REAL);
|
||||
@ -153,5 +154,44 @@ type_cb(mxml_node_t *node) /* I - Element node */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: testmxml.c,v 1.5 2003/06/04 16:30:40 mike Exp $".
|
||||
* 'whitespace_cb()' - Let the mxmlSaveFile() function know when to insert
|
||||
* newlines and tabs...
|
||||
*/
|
||||
|
||||
int /* O - Whitespace char or 0 */
|
||||
whitespace_cb(mxml_node_t *node, /* I - Element node */
|
||||
int where) /* I - Open or close tag? */
|
||||
{
|
||||
const char *name; /* Name of element */
|
||||
|
||||
/*
|
||||
* We can conditionally break to a new line before or after any element.
|
||||
* These are just common HTML elements...
|
||||
*/
|
||||
|
||||
name = node->value.element.name;
|
||||
|
||||
if (!strcmp(name, "html") || !strcmp(name, "head") || !strcmp(name, "body") ||
|
||||
!strcmp(name, "pre") || !strcmp(name, "p") ||
|
||||
!strcmp(name, "h1") || !strcmp(name, "h2") || !strcmp(name, "h3") ||
|
||||
!strcmp(name, "h4") || !strcmp(name, "h5") || !strcmp(name, "h6"))
|
||||
return ('\n');
|
||||
else if (!strcmp(name, "li"))
|
||||
{
|
||||
/*
|
||||
* Put a tab before <li>'s and a newline after </li>'s...
|
||||
*/
|
||||
|
||||
if (where == MXML_SAVE_OPEN_TAG)
|
||||
return ('\t');
|
||||
else
|
||||
return ('\n');
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: testmxml.c,v 1.6 2003/06/04 17:37:23 mike Exp $".
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user