📄 mxml-node.c
字号:
/* * "$Id: mxml-node.c 22267 2006-04-24 17:11:45Z kpfleming $" * * Node support code for Mini-XML, a small XML-like file parsing library. * * Copyright 2003-2005 by Michael Sweet. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * 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. * mxmlNewTextf() - Create a new formatted text fragment node. * mxmlRemove() - Remove a node from its parent. * mxml_new() - Create a new node. *//* * Include necessary headers... */#include "config.h"#include "mxml.h"/* * Local functions... */static mxml_node_t *mxml_new(mxml_node_t *parent, mxml_type_t type);/* * 'mxmlAdd()' - Add a node to a tree. * * Adds the specified node to the parent. If the child argument is not * NULL, puts the new node before or after the specified child depending * on the value of the where argument. If the child argument is NULL, * puts the new node at the beginning of the child list (MXML_ADD_BEFORE) * or at the end of the child list (MXML_ADD_AFTER). The constant * MXML_ADD_TO_PARENT can be used to specify a NULL child pointer. */voidmxmlAdd(mxml_node_t *parent, /* I - Parent node */ int where, /* I - Where to add, MXML_ADD_BEFORE or MXML_ADD_AFTER */ mxml_node_t *child, /* I - Child node for where or MXML_ADD_TO_PARENT */ mxml_node_t *node) /* I - Node to add */{#ifdef DEBUG fprintf(stderr, "mxmlAdd(parent=%p, where=%d, child=%p, node=%p)\n", parent, where, child, node);#endif /* DEBUG */ /* * Range check input... */ if (!parent || !node) return;#if DEBUG > 1 fprintf(stderr, " BEFORE: node->parent=%p\n", node->parent); if (parent) { fprintf(stderr, " BEFORE: parent->child=%p\n", parent->child); fprintf(stderr, " BEFORE: parent->last_child=%p\n", parent->last_child); fprintf(stderr, " BEFORE: parent->prev=%p\n", parent->prev); fprintf(stderr, " BEFORE: parent->next=%p\n", parent->next); }#endif /* DEBUG > 1 */ /* * Remove the node from any existing parent... */ if (node->parent) mxmlRemove(node); /* * Reset pointers... */ 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; }#if DEBUG > 1 fprintf(stderr, " AFTER: node->parent=%p\n", node->parent); if (parent) { fprintf(stderr, " AFTER: parent->child=%p\n", parent->child); fprintf(stderr, " AFTER: parent->last_child=%p\n", parent->last_child); fprintf(stderr, " AFTER: parent->prev=%p\n", parent->prev); fprintf(stderr, " AFTER: parent->next=%p\n", parent->next); }#endif /* DEBUG > 1 */}/* * 'mxmlDelete()' - Delete a node and all of its children. * * If the specified node has a parent, this function first removes the * node from its parent using the mxmlRemove() function. */voidmxmlDelete(mxml_node_t *node) /* I - Node to delete */{ int i; /* Looping var */#ifdef DEBUG fprintf(stderr, "mxmlDelete(node=%p)\n", node);#endif /* DEBUG */ /* * Range check input... */ if (!node) return; /* * Remove the node from its parent, if any... */ mxmlRemove(node); /* * Delete children... */ while (node->child) mxmlDelete(node->child); /* * Now delete any node data... */ switch (node->type) { case MXML_ELEMENT : if (node->value.element.name) free(node->value.element.name); if (node->value.element.num_attrs) { for (i = 0; i < node->value.element.num_attrs; i ++) { if (node->value.element.attrs[i].name) free(node->value.element.attrs[i].name); if (node->value.element.attrs[i].value) free(node->value.element.attrs[i].value); } free(node->value.element.attrs); } break; case MXML_INTEGER : /* Nothing to do */ break; case MXML_OPAQUE : if (node->value.opaque) free(node->value.opaque); break; case MXML_REAL : /* Nothing to do */ break; case MXML_TEXT : if (node->value.text.string) free(node->value.text.string); break; case MXML_CUSTOM : if (node->value.custom.data && node->value.custom.destroy) (*(node->value.custom.destroy))(node->value.custom.data); break; } /* * Free this node... */ free(node);}/* * 'mxmlNewCustom()' - Create a new custom data node. * * The new custom node is added to the end of the specified parent's child * list. The constant MXML_NO_PARENT can be used to specify that the new * element node has no parent. NULL can be passed when the data in the * node is not dynamically allocated or is separately managed. */mxml_node_t * /* O - New node */mxmlNewCustom(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ void *data, /* I - Pointer to data */ void (*destroy)(void *)) /* I - Function to destroy data */{ mxml_node_t *node; /* New node */#ifdef DEBUG fprintf(stderr, "mxmlNewCustom(parent=%p, data=%p, destroy=%p)\n", parent, data, destroy);#endif /* DEBUG */ /* * Create the node and set the value... */ if ((node = mxml_new(parent, MXML_CUSTOM)) != NULL) { node->value.custom.data = data; node->value.custom.destroy = destroy; } return (node);}/* * 'mxmlNewElement()' - Create a new element node. * * The new element node is added to the end of the specified parent's child * list. The constant MXML_NO_PARENT can be used to specify that the new * element node has no parent. */mxml_node_t * /* O - New node */mxmlNewElement(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ const char *name) /* I - Name of element */{ mxml_node_t *node; /* New node */#ifdef DEBUG fprintf(stderr, "mxmlNewElement(parent=%p, name=\"%s\")\n", parent, name ? name : "(null)");#endif /* DEBUG */ /* * Range check input... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -