/tools/gator/daemon/mxml/mxml-attr.c

https://gitlab.com/pine64-android/linux-3.10 · C · 314 lines · 152 code · 70 blank · 92 comment · 37 complexity · 18a93ae9b3b7ef5959461df75c17ba6c MD5 · raw file

  1. /*
  2. * "$Id: mxml-attr.c 451 2014-01-04 21:50:06Z msweet $"
  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. * Include necessary headers...
  18. */
  19. #include "config.h"
  20. #include "mxml.h"
  21. /*
  22. * Local functions...
  23. */
  24. static int mxml_set_attr(mxml_node_t *node, const char *name,
  25. char *value);
  26. /*
  27. * 'mxmlElementDeleteAttr()' - Delete an attribute.
  28. *
  29. * @since Mini-XML 2.4@
  30. */
  31. void
  32. mxmlElementDeleteAttr(mxml_node_t *node,/* I - Element */
  33. const char *name)/* I - Attribute name */
  34. {
  35. int i; /* Looping var */
  36. mxml_attr_t *attr; /* Cirrent attribute */
  37. #ifdef DEBUG
  38. fprintf(stderr, "mxmlElementDeleteAttr(node=%p, name=\"%s\")\n",
  39. node, name ? name : "(null)");
  40. #endif /* DEBUG */
  41. /*
  42. * Range check input...
  43. */
  44. if (!node || node->type != MXML_ELEMENT || !name)
  45. return;
  46. /*
  47. * Look for the attribute...
  48. */
  49. for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
  50. i > 0;
  51. i --, attr ++)
  52. {
  53. #ifdef DEBUG
  54. printf(" %s=\"%s\"\n", attr->name, attr->value);
  55. #endif /* DEBUG */
  56. if (!strcmp(attr->name, name))
  57. {
  58. /*
  59. * Delete this attribute...
  60. */
  61. free(attr->name);
  62. free(attr->value);
  63. i --;
  64. if (i > 0)
  65. memmove(attr, attr + 1, i * sizeof(mxml_attr_t));
  66. node->value.element.num_attrs --;
  67. if (node->value.element.num_attrs == 0)
  68. free(node->value.element.attrs);
  69. return;
  70. }
  71. }
  72. }
  73. /*
  74. * 'mxmlElementGetAttr()' - Get an attribute.
  75. *
  76. * This function returns NULL if the node is not an element or the
  77. * named attribute does not exist.
  78. */
  79. const char * /* O - Attribute value or NULL */
  80. mxmlElementGetAttr(mxml_node_t *node, /* I - Element node */
  81. const char *name) /* I - Name of attribute */
  82. {
  83. int i; /* Looping var */
  84. mxml_attr_t *attr; /* Cirrent attribute */
  85. #ifdef DEBUG
  86. fprintf(stderr, "mxmlElementGetAttr(node=%p, name=\"%s\")\n",
  87. node, name ? name : "(null)");
  88. #endif /* DEBUG */
  89. /*
  90. * Range check input...
  91. */
  92. if (!node || node->type != MXML_ELEMENT || !name)
  93. return (NULL);
  94. /*
  95. * Look for the attribute...
  96. */
  97. for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
  98. i > 0;
  99. i --, attr ++)
  100. {
  101. #ifdef DEBUG
  102. printf(" %s=\"%s\"\n", attr->name, attr->value);
  103. #endif /* DEBUG */
  104. if (!strcmp(attr->name, name))
  105. {
  106. #ifdef DEBUG
  107. printf(" Returning \"%s\"!\n", attr->value);
  108. #endif /* DEBUG */
  109. return (attr->value);
  110. }
  111. }
  112. /*
  113. * Didn't find attribute, so return NULL...
  114. */
  115. #ifdef DEBUG
  116. puts(" Returning NULL!\n");
  117. #endif /* DEBUG */
  118. return (NULL);
  119. }
  120. /*
  121. * 'mxmlElementSetAttr()' - Set an attribute.
  122. *
  123. * If the named attribute already exists, the value of the attribute
  124. * is replaced by the new string value. The string value is copied
  125. * into the element node. This function does nothing if the node is
  126. * not an element.
  127. */
  128. void
  129. mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */
  130. const char *name, /* I - Name of attribute */
  131. const char *value) /* I - Attribute value */
  132. {
  133. char *valuec; /* Copy of value */
  134. #ifdef DEBUG
  135. fprintf(stderr, "mxmlElementSetAttr(node=%p, name=\"%s\", value=\"%s\")\n",
  136. node, name ? name : "(null)", value ? value : "(null)");
  137. #endif /* DEBUG */
  138. /*
  139. * Range check input...
  140. */
  141. if (!node || node->type != MXML_ELEMENT || !name)
  142. return;
  143. if (value)
  144. valuec = strdup(value);
  145. else
  146. valuec = NULL;
  147. if (mxml_set_attr(node, name, valuec))
  148. free(valuec);
  149. }
  150. /*
  151. * 'mxmlElementSetAttrf()' - Set an attribute with a formatted value.
  152. *
  153. * If the named attribute already exists, the value of the attribute
  154. * is replaced by the new formatted string. The formatted string value is
  155. * copied into the element node. This function does nothing if the node
  156. * is not an element.
  157. *
  158. * @since Mini-XML 2.3@
  159. */
  160. void
  161. mxmlElementSetAttrf(mxml_node_t *node, /* I - Element node */
  162. const char *name, /* I - Name of attribute */
  163. const char *format,/* I - Printf-style attribute value */
  164. ...) /* I - Additional arguments as needed */
  165. {
  166. va_list ap; /* Argument pointer */
  167. char *value; /* Value */
  168. #ifdef DEBUG
  169. fprintf(stderr,
  170. "mxmlElementSetAttrf(node=%p, name=\"%s\", format=\"%s\", ...)\n",
  171. node, name ? name : "(null)", format ? format : "(null)");
  172. #endif /* DEBUG */
  173. /*
  174. * Range check input...
  175. */
  176. if (!node || node->type != MXML_ELEMENT || !name || !format)
  177. return;
  178. /*
  179. * Format the value...
  180. */
  181. va_start(ap, format);
  182. value = _mxml_vstrdupf(format, ap);
  183. va_end(ap);
  184. if (!value)
  185. mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
  186. name, node->value.element.name);
  187. else if (mxml_set_attr(node, name, value))
  188. free(value);
  189. }
  190. /*
  191. * 'mxml_set_attr()' - Set or add an attribute name/value pair.
  192. */
  193. static int /* O - 0 on success, -1 on failure */
  194. mxml_set_attr(mxml_node_t *node, /* I - Element node */
  195. const char *name, /* I - Attribute name */
  196. char *value) /* I - Attribute value */
  197. {
  198. int i; /* Looping var */
  199. mxml_attr_t *attr; /* New attribute */
  200. /*
  201. * Look for the attribute...
  202. */
  203. for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
  204. i > 0;
  205. i --, attr ++)
  206. if (!strcmp(attr->name, name))
  207. {
  208. /*
  209. * Free the old value as needed...
  210. */
  211. if (attr->value)
  212. free(attr->value);
  213. attr->value = value;
  214. return (0);
  215. }
  216. /*
  217. * Add a new attribute...
  218. */
  219. if (node->value.element.num_attrs == 0)
  220. attr = malloc(sizeof(mxml_attr_t));
  221. else
  222. attr = realloc(node->value.element.attrs,
  223. (node->value.element.num_attrs + 1) * sizeof(mxml_attr_t));
  224. if (!attr)
  225. {
  226. mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
  227. name, node->value.element.name);
  228. return (-1);
  229. }
  230. node->value.element.attrs = attr;
  231. attr += node->value.element.num_attrs;
  232. if ((attr->name = strdup(name)) == NULL)
  233. {
  234. mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
  235. name, node->value.element.name);
  236. return (-1);
  237. }
  238. attr->value = value;
  239. node->value.element.num_attrs ++;
  240. return (0);
  241. }
  242. /*
  243. * End of "$Id: mxml-attr.c 451 2014-01-04 21:50:06Z msweet $".
  244. */