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