uxmltree.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * Copyright (C) 2008 by egnite GmbH. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  21. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  25. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  27. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * For additional information see http://www.ethernut.de/
  31. *
  32. */
  33. /*
  34. * \file pro/uxmltree.c
  35. * \brief Micro XML tree support functions.
  36. *
  37. * \verbatim
  38. * $Id: uxmltree.c 5513 2014-01-07 10:41:32Z haraldkipp $
  39. * \endverbatim
  40. */
  41. #include <sys/types.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include <memdebug.h>
  45. #include <pro/uxml.h>
  46. /*!
  47. * \addtogroup xgUXML
  48. */
  49. /*@{*/
  50. /*!
  51. * \brief Allocate a new tree node.
  52. *
  53. * \param name Name of the node to add.
  54. *
  55. * \return Pointer to the new node. In case of an error, NULL is returned.
  56. */
  57. UXML_NODE *UxmlNodeCreate(char *name)
  58. {
  59. UXML_NODE *node;
  60. size_t nlen;
  61. if ((node = malloc(sizeof(UXML_NODE))) != NULL) {
  62. memset(node, 0, sizeof(UXML_NODE));
  63. nlen = strlen(name) + 1;
  64. if ((node->xmln_name = malloc(nlen)) != NULL) {
  65. memcpy(node->xmln_name, name, nlen);
  66. }
  67. }
  68. return node;
  69. }
  70. /*!
  71. * \brief Add an attribute to the specified node.
  72. *
  73. * \param node The attribute is added to this node.
  74. * \param name Attribute's name.
  75. * \param value Attribute's value.
  76. *
  77. * \return 0 on success, -1 otherwise.
  78. */
  79. int UxmlNodeAddAttrib(UXML_NODE * node, char *name, char *value)
  80. {
  81. UXML_ATTRIB *attr;
  82. UXML_ATTRIB *ap;
  83. attr = malloc(sizeof(UXML_ATTRIB));
  84. if (attr) {
  85. attr->xmla_next = NULL;
  86. attr->xmla_name = strdup(name);
  87. if (attr->xmla_name) {
  88. attr->xmla_value = strdup(value);
  89. if (attr->xmla_value) {
  90. if (node->xmln_attribs == NULL) {
  91. node->xmln_attribs = attr;
  92. } else {
  93. ap = node->xmln_attribs;
  94. for (;;) {
  95. if (ap->xmla_next == NULL) {
  96. ap->xmla_next = attr;
  97. break;
  98. }
  99. ap = ap->xmla_next;
  100. }
  101. }
  102. return 0;
  103. }
  104. free(attr->xmla_name);
  105. }
  106. free(attr);
  107. }
  108. return -1;
  109. }
  110. static void UxmlNodeDestroy(UXML_NODE * node)
  111. {
  112. UXML_ATTRIB *ap;
  113. UXML_ATTRIB *attr;
  114. if (node) {
  115. free(node->xmln_name);
  116. #ifndef UXML_IGNORE_CONTENT
  117. free(node->xmln_content);
  118. #endif
  119. ap = node->xmln_attribs;
  120. while (ap) {
  121. attr = ap;
  122. ap = ap->xmla_next;
  123. free(attr->xmla_name);
  124. free(attr->xmla_value);
  125. free(attr);
  126. }
  127. free(node);
  128. }
  129. }
  130. /*!
  131. * \brief Add a sibling to the specified node.
  132. *
  133. * \param node The sibling is added to this node.
  134. * \param child Sibling to add.
  135. *
  136. * \return Pointer to the sibling node.
  137. */
  138. UXML_NODE *UxmlTreeAddSibling(UXML_NODE * node, UXML_NODE * sibling)
  139. {
  140. for (;;) {
  141. if (node->xmln_next == NULL) {
  142. node->xmln_next = sibling;
  143. sibling->xmln_parent = node->xmln_parent;
  144. break;
  145. }
  146. node = node->xmln_next;
  147. }
  148. return sibling;
  149. }
  150. /*!
  151. * \brief Add a child to the specified node.
  152. *
  153. * \param node The child is added to this node.
  154. * \param child Child to add.
  155. *
  156. * \return Pointer to the child node.
  157. */
  158. UXML_NODE *UxmlTreeAddChild(UXML_NODE * node, UXML_NODE * child)
  159. {
  160. if (node->xmln_child == NULL) {
  161. node->xmln_child = child;
  162. child->xmln_parent = node;
  163. } else {
  164. UxmlTreeAddSibling(node->xmln_child, child);
  165. }
  166. return child;
  167. }
  168. /*!
  169. * \brief Release all memory of an XML tree structure.
  170. *
  171. * \param node Pointer to the root entry.
  172. */
  173. void UxmlTreeDestroy(UXML_NODE * node)
  174. {
  175. UXML_NODE *np = node;
  176. while (np) {
  177. node = np;
  178. np = np->xmln_next;
  179. if (node->xmln_child) {
  180. UxmlTreeDestroy(node->xmln_child);
  181. }
  182. UxmlNodeDestroy(node);
  183. }
  184. }
  185. /*@}*/