Process Hacker
mxml-attr.c
Go to the documentation of this file.
1 /*
2  * "$Id: mxml-attr.c 308 2007-09-15 20:04:56Z mike $"
3  *
4  * Attribute support code for Mini-XML, a small XML-like file parsing library.
5  *
6  * Copyright 2003-2007 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  * Contents:
19  *
20  * mxmlElementDeleteAttr() - Delete an attribute.
21  * mxmlElementGetAttr() - Get an attribute.
22  * mxmlElementSetAttr() - Set an attribute.
23  * mxmlElementSetAttrf() - Set an attribute with a formatted value.
24  * mxml_set_attr() - Set or add an attribute name/value pair.
25  */
26 
27 /*
28  * Include necessary headers...
29  */
30 
31 #include <phbase.h>
32 #include "config.h"
33 #include "mxml.h"
34 
35 
36 /*
37  * Local functions...
38  */
39 
40 static int mxml_set_attr(mxml_node_t *node, const char *name,
41  char *value);
42 
43 
44 /*
45  * 'mxmlElementDeleteAttr()' - Delete an attribute.
46  *
47  * @since Mini-XML 2.4@
48  */
49 
50 void
51 mxmlElementDeleteAttr(mxml_node_t *node,/* I - Element */
52  const char *name)/* I - Attribute name */
53 {
54  int i; /* Looping var */
55  mxml_attr_t *attr; /* Cirrent attribute */
56 
57 
58 #ifdef DEBUG
59  fprintf(stderr, "mxmlElementDeleteAttr(node=%p, name=\"%s\")\n",
60  node, name ? name : "(null)");
61 #endif /* DEBUG */
62 
63  /*
64  * Range check input...
65  */
66 
67  if (!node || node->type != MXML_ELEMENT || !name)
68  return;
69 
70  /*
71  * Look for the attribute...
72  */
73 
74  for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
75  i > 0;
76  i --, attr ++)
77  {
78 #ifdef DEBUG
79  printf(" %s=\"%s\"\n", attr->name, attr->value);
80 #endif /* DEBUG */
81 
82  if (!strcmp(attr->name, name))
83  {
84  /*
85  * Delete this attribute...
86  */
87 
88  PhFree(attr->name);
89  PhFree(attr->value);
90 
91  i --;
92  if (i > 0)
93  memmove(attr, attr + 1, i * sizeof(mxml_attr_t));
94 
95  node->value.element.num_attrs --;
96  return;
97  }
98  }
99 }
100 
101 
102 /*
103  * 'mxmlElementGetAttr()' - Get an attribute.
104  *
105  * This function returns NULL if the node is not an element or the
106  * named attribute does not exist.
107  */
108 
109 const char * /* O - Attribute value or NULL */
110 mxmlElementGetAttr(mxml_node_t *node, /* I - Element node */
111  const char *name) /* I - Name of attribute */
112 {
113  int i; /* Looping var */
114  mxml_attr_t *attr; /* Cirrent attribute */
115 
116 
117 #ifdef DEBUG
118  fprintf(stderr, "mxmlElementGetAttr(node=%p, name=\"%s\")\n",
119  node, name ? name : "(null)");
120 #endif /* DEBUG */
121 
122  /*
123  * Range check input...
124  */
125 
126  if (!node || node->type != MXML_ELEMENT || !name)
127  return (NULL);
128 
129  /*
130  * Look for the attribute...
131  */
132 
133  for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
134  i > 0;
135  i --, attr ++)
136  {
137 #ifdef DEBUG
138  printf(" %s=\"%s\"\n", attr->name, attr->value);
139 #endif /* DEBUG */
140 
141  if (!strcmp(attr->name, name))
142  {
143 #ifdef DEBUG
144  printf(" Returning \"%s\"!\n", attr->value);
145 #endif /* DEBUG */
146  return (attr->value);
147  }
148  }
149 
150  /*
151  * Didn't find attribute, so return NULL...
152  */
153 
154 #ifdef DEBUG
155  fputs(" Returning NULL!\n", stderr);
156 #endif /* DEBUG */
157 
158  return (NULL);
159 }
160 
161 
162 /*
163  * 'mxmlElementSetAttr()' - Set an attribute.
164  *
165  * If the named attribute already exists, the value of the attribute
166  * is replaced by the new string value. The string value is copied
167  * into the element node. This function does nothing if the node is
168  * not an element.
169  */
170 
171 void
172 mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */
173  const char *name, /* I - Name of attribute */
174  const char *value) /* I - Attribute value */
175 {
176  char *valuec; /* Copy of value */
177 
178 
179 #ifdef DEBUG
180  fprintf(stderr, "mxmlElementSetAttr(node=%p, name=\"%s\", value=\"%s\")\n",
181  node, name ? name : "(null)", value ? value : "(null)");
182 #endif /* DEBUG */
183 
184  /*
185  * Range check input...
186  */
187 
188  if (!node || node->type != MXML_ELEMENT || !name)
189  return;
190 
191  if (value)
192  valuec = PhDuplicateBytesZSafe((char *)value);
193  else
194  valuec = NULL;
195 
196  if (mxml_set_attr(node, name, valuec))
197  PhFree(valuec);
198 }
199 
200 
201 /*
202  * 'mxmlElementSetAttrf()' - Set an attribute with a formatted value.
203  *
204  * If the named attribute already exists, the value of the attribute
205  * is replaced by the new formatted string. The formatted string value is
206  * copied into the element node. This function does nothing if the node
207  * is not an element.
208  *
209  * @since Mini-XML 2.3@
210  */
211 
212 void
213 mxmlElementSetAttrf(mxml_node_t *node, /* I - Element node */
214  const char *name, /* I - Name of attribute */
215  const char *format,/* I - Printf-style attribute value */
216  ...) /* I - Additional arguments as needed */
217 {
218  va_list ap; /* Argument pointer */
219  char *value; /* Value */
220 
221 
222 #ifdef DEBUG
223  fprintf(stderr,
224  "mxmlElementSetAttrf(node=%p, name=\"%s\", format=\"%s\", ...)\n",
225  node, name ? name : "(null)", format ? format : "(null)");
226 #endif /* DEBUG */
227 
228  /*
229  * Range check input...
230  */
231 
232  if (!node || node->type != MXML_ELEMENT || !name || !format)
233  return;
234 
235  /*
236  * Format the value...
237  */
238 
239  va_start(ap, format);
240  value = _mxml_vstrdupf(format, ap);
241  va_end(ap);
242 
243  if (!value)
244  mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
245  name, node->value.element.name);
246  else if (mxml_set_attr(node, name, value))
247  PhFree(value);
248 }
249 
250 
251 /*
252  * 'mxml_set_attr()' - Set or add an attribute name/value pair.
253  */
254 
255 static int /* O - 0 on success, -1 on failure */
256 mxml_set_attr(mxml_node_t *node, /* I - Element node */
257  const char *name, /* I - Attribute name */
258  char *value) /* I - Attribute value */
259 {
260  int i; /* Looping var */
261  mxml_attr_t *attr; /* New attribute */
262 
263 
264  /*
265  * Look for the attribute...
266  */
267 
268  for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
269  i > 0;
270  i --, attr ++)
271  if (!strcmp(attr->name, name))
272  {
273  /*
274  * Free the old value as needed...
275  */
276 
277  if (attr->value)
278  PhFree(attr->value);
279 
280  attr->value = value;
281 
282  return (0);
283  }
284 
285  /*
286  * Add a new attribute...
287  */
288 
289  if (node->value.element.num_attrs == 0)
290  attr = PhAllocateSafe(sizeof(mxml_attr_t));
291  else
292  attr = PhReAllocateSafe(node->value.element.attrs,
293  (node->value.element.num_attrs + 1) * sizeof(mxml_attr_t));
294 
295  if (!attr)
296  {
297  mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
298  name, node->value.element.name);
299  return (-1);
300  }
301 
302  node->value.element.attrs = attr;
303  attr += node->value.element.num_attrs;
304 
305  if ((attr->name = PhDuplicateBytesZSafe((char *)name)) == NULL)
306  {
307  mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
308  name, node->value.element.name);
309  return (-1);
310  }
311 
312  attr->value = value;
313 
314  node->value.element.num_attrs ++;
315 
316  return (0);
317 }
318 
319 
320 /*
321  * End of "$Id: mxml-attr.c 308 2007-09-15 20:04:56Z mike $".
322  */