blob: b0bd52790b2eeecf83ddef48acd8a65322032e0c [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
2 * "$Id: mxml-set.c 441 2011-12-09 23:49:00Z mike $"
3 *
4 * Node set functions for Mini-XML, a small XML-like file parsing library.
5 *
6 * Copyright 2003-2011 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.minixml.org/
15 *
16 * Contents:
17 *
18 * mxmlSetCDATA() - Set the element name of a CDATA node.
19 * mxmlSetCustom() - Set the data and destructor of a custom data node.
20 * mxmlSetElement() - Set the name of an element node.
21 * mxmlSetInteger() - Set the value of an integer node.
22 * mxmlSetOpaque() - Set the value of an opaque node.
23 * mxmlSetReal() - Set the value of a real number node.
24 * mxmlSetText() - Set the value of a text node.
25 * mxmlSetTextf() - Set the value of a text node to a formatted string.
26 * mxmlSetUserData() - Set the user data pointer for a node.
27 */
28
29/*
30 * Include necessary headers...
31 */
32
33#include "config.h"
34#include "mxml.h"
35
36
37/*
38 * 'mxmlSetCDATA()' - Set the element name of a CDATA node.
39 *
40 * The node is not changed if it (or its first child) is not a CDATA element node.
41 *
42 * @since Mini-XML 2.3@
43 */
44
45int /* O - 0 on success, -1 on failure */
46mxmlSetCDATA(mxml_node_t *node, /* I - Node to set */
47 const char *data) /* I - New data string */
48{
49 /*
50 * Range check input...
51 */
52
53 if (node && node->type == MXML_ELEMENT &&
54 strncmp(node->value.element.name, "![CDATA[", 8) &&
55 node->child && node->child->type == MXML_ELEMENT &&
56 !strncmp(node->child->value.element.name, "![CDATA[", 8))
57 node = node->child;
58
59 if (!node || node->type != MXML_ELEMENT || !data ||
60 strncmp(node->value.element.name, "![CDATA[", 8))
61 return (-1);
62
63 /*
64 * Free any old element value and set the new value...
65 */
66
67 if (node->value.element.name)
68 free(node->value.element.name);
69
70 node->value.element.name = _mxml_strdupf("![CDATA[%s]]", data);
71
72 return (0);
73}
74
75
76/*
77 * 'mxmlSetCustom()' - Set the data and destructor of a custom data node.
78 *
79 * The node is not changed if it (or its first child) is not a custom node.
80 *
81 * @since Mini-XML 2.1@
82 */
83
84int /* O - 0 on success, -1 on failure */
85mxmlSetCustom(
86 mxml_node_t *node, /* I - Node to set */
87 void *data, /* I - New data pointer */
88 mxml_custom_destroy_cb_t destroy) /* I - New destructor function */
89{
90 /*
91 * Range check input...
92 */
93
94 if (node && node->type == MXML_ELEMENT &&
95 node->child && node->child->type == MXML_CUSTOM)
96 node = node->child;
97
98 if (!node || node->type != MXML_CUSTOM)
99 return (-1);
100
101 /*
102 * Free any old element value and set the new value...
103 */
104
105 if (node->value.custom.data && node->value.custom.destroy)
106 (*(node->value.custom.destroy))(node->value.custom.data);
107
108 node->value.custom.data = data;
109 node->value.custom.destroy = destroy;
110
111 return (0);
112}
113
114
115/*
116 * 'mxmlSetElement()' - Set the name of an element node.
117 *
118 * The node is not changed if it is not an element node.
119 */
120
121int /* O - 0 on success, -1 on failure */
122mxmlSetElement(mxml_node_t *node, /* I - Node to set */
123 const char *name) /* I - New name string */
124{
125 /*
126 * Range check input...
127 */
128
129 if (!node || node->type != MXML_ELEMENT || !name)
130 return (-1);
131
132 /*
133 * Free any old element value and set the new value...
134 */
135
136 if (node->value.element.name)
137 free(node->value.element.name);
138
139 node->value.element.name = strdup(name);
140
141 return (0);
142}
143
144
145/*
146 * 'mxmlSetInteger()' - Set the value of an integer node.
147 *
148 * The node is not changed if it (or its first child) is not an integer node.
149 */
150
151int /* O - 0 on success, -1 on failure */
152mxmlSetInteger(mxml_node_t *node, /* I - Node to set */
153 int integer) /* I - Integer value */
154{
155 /*
156 * Range check input...
157 */
158
159 if (node && node->type == MXML_ELEMENT &&
160 node->child && node->child->type == MXML_INTEGER)
161 node = node->child;
162
163 if (!node || node->type != MXML_INTEGER)
164 return (-1);
165
166 /*
167 * Set the new value and return...
168 */
169
170 node->value.integer = integer;
171
172 return (0);
173}
174
175
176/*
177 * 'mxmlSetOpaque()' - Set the value of an opaque node.
178 *
179 * The node is not changed if it (or its first child) is not an opaque node.
180 */
181
182int /* O - 0 on success, -1 on failure */
183mxmlSetOpaque(mxml_node_t *node, /* I - Node to set */
184 const char *opaque) /* I - Opaque string */
185{
186 /*
187 * Range check input...
188 */
189
190 if (node && node->type == MXML_ELEMENT &&
191 node->child && node->child->type == MXML_OPAQUE)
192 node = node->child;
193
194 if (!node || node->type != MXML_OPAQUE || !opaque)
195 return (-1);
196
197 /*
198 * Free any old opaque value and set the new value...
199 */
200
201 if (node->value.opaque)
202 free(node->value.opaque);
203
204 node->value.opaque = strdup(opaque);
205
206 return (0);
207}
208
209
210/*
211 * 'mxmlSetReal()' - Set the value of a real number node.
212 *
213 * The node is not changed if it (or its first child) is not a real number node.
214 */
215
216int /* O - 0 on success, -1 on failure */
217mxmlSetReal(mxml_node_t *node, /* I - Node to set */
218 double real) /* I - Real number value */
219{
220 /*
221 * Range check input...
222 */
223
224 if (node && node->type == MXML_ELEMENT &&
225 node->child && node->child->type == MXML_REAL)
226 node = node->child;
227
228 if (!node || node->type != MXML_REAL)
229 return (-1);
230
231 /*
232 * Set the new value and return...
233 */
234
235 node->value.real = real;
236
237 return (0);
238}
239
240
241/*
242 * 'mxmlSetText()' - Set the value of a text node.
243 *
244 * The node is not changed if it (or its first child) is not a text node.
245 */
246
247int /* O - 0 on success, -1 on failure */
248mxmlSetText(mxml_node_t *node, /* I - Node to set */
249 int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */
250 const char *string) /* I - String */
251{
252 /*
253 * Range check input...
254 */
255
256 if (node && node->type == MXML_ELEMENT &&
257 node->child && node->child->type == MXML_TEXT)
258 node = node->child;
259
260 if (!node || node->type != MXML_TEXT || !string)
261 return (-1);
262
263 /*
264 * Free any old string value and set the new value...
265 */
266
267 if (node->value.text.string)
268 free(node->value.text.string);
269
270 node->value.text.whitespace = whitespace;
271 node->value.text.string = strdup(string);
272
273 return (0);
274}
275
276
277/*
278 * 'mxmlSetTextf()' - Set the value of a text node to a formatted string.
279 *
280 * The node is not changed if it (or its first child) is not a text node.
281 */
282
283int /* O - 0 on success, -1 on failure */
284mxmlSetTextf(mxml_node_t *node, /* I - Node to set */
285 int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */
286 const char *format, /* I - Printf-style format string */
287 ...) /* I - Additional arguments as needed */
288{
289 va_list ap; /* Pointer to arguments */
290
291
292 /*
293 * Range check input...
294 */
295
296 if (node && node->type == MXML_ELEMENT &&
297 node->child && node->child->type == MXML_TEXT)
298 node = node->child;
299
300 if (!node || node->type != MXML_TEXT || !format)
301 return (-1);
302
303 /*
304 * Free any old string value and set the new value...
305 */
306
307 if (node->value.text.string)
308 free(node->value.text.string);
309
310 va_start(ap, format);
311
312 node->value.text.whitespace = whitespace;
313 node->value.text.string = _mxml_strdupf(format, ap);
314
315 va_end(ap);
316
317 return (0);
318}
319
320
321/*
322 * 'mxmlSetUserData()' - Set the user data pointer for a node.
323 *
324 * @since Mini-XML 2.7@
325 */
326
327int /* O - 0 on success, -1 on failure */
328mxmlSetUserData(mxml_node_t *node, /* I - Node to set */
329 void *data) /* I - User data pointer */
330{
331 /*
332 * Range check input...
333 */
334
335 if (!node)
336 return (-1);
337
338 /*
339 * Set the user data pointer and return...
340 */
341
342 node->user_data = data;
343 return (0);
344}
345
346
347/*
348 * End of "$Id: mxml-set.c 441 2011-12-09 23:49:00Z mike $".
349 */