Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 andreas 1
/*
2
 * Node set functions for Mini-XML, a small XML file parsing library.
3
 *
4
 * https://www.msweet.org/mxml
5
 *
6
 * Copyright © 2003-2019 by Michael R Sweet.
7
 *
8
 * Licensed under Apache License v2.0.  See the file "LICENSE" for more
9
 * information.
10
 */
11
 
12
/*
13
 * Include necessary headers...
14
 */
15
 
16
#include "config.h"
17
#include "mxml-private.h"
18
 
19
 
20
/*
21
 * 'mxmlSetCDATA()' - Set the element name of a CDATA node.
22
 *
23
 * The node is not changed if it (or its first child) is not a CDATA element node.
24
 *
25
 * @since Mini-XML 2.3@
26
 */
27
 
28
int					/* O - 0 on success, -1 on failure */
29
mxmlSetCDATA(mxml_node_t *node,		/* I - Node to set */
30
             const char  *data)		/* I - New data string */
31
{
32
  char	*s;				/* String pointer */
33
 
34
 
35
 /*
36
  * Range check input...
37
  */
38
 
39
  if (node && node->type == MXML_ELEMENT &&
40
      strncmp(node->value.element.name, "![CDATA[", 8) &&
41
      node->child && node->child->type == MXML_ELEMENT &&
42
      !strncmp(node->child->value.element.name, "![CDATA[", 8))
43
    node = node->child;
44
 
45
  if (!node || node->type != MXML_ELEMENT || !data ||
46
      strncmp(node->value.element.name, "![CDATA[", 8))
47
    return (-1);
48
 
49
  if (data == (node->value.element.name + 8))
50
    return (0);
51
 
52
 /*
53
  * Allocate the new value, free any old element value, and set the new value...
54
  */
55
 
56
  s = _mxml_strdupf("![CDATA[%s", data);
57
 
58
  if (node->value.element.name)
59
    free(node->value.element.name);
60
 
61
  node->value.element.name = s;
62
 
63
  return (0);
64
}
65
 
66
 
67
/*
68
 * 'mxmlSetCustom()' - Set the data and destructor of a custom data node.
69
 *
70
 * The node is not changed if it (or its first child) is not a custom node.
71
 *
72
 * @since Mini-XML 2.1@
73
 */
74
 
75
int					/* O - 0 on success, -1 on failure */
76
mxmlSetCustom(
77
    mxml_node_t              *node,	/* I - Node to set */
78
    void                     *data,	/* I - New data pointer */
79
    mxml_custom_destroy_cb_t destroy)	/* I - New destructor function */
80
{
81
 /*
82
  * Range check input...
83
  */
84
 
85
  if (node && node->type == MXML_ELEMENT &&
86
      node->child && node->child->type == MXML_CUSTOM)
87
    node = node->child;
88
 
89
  if (!node || node->type != MXML_CUSTOM)
90
    return (-1);
91
 
92
  if (data == node->value.custom.data)
93
  {
94
    node->value.custom.destroy = destroy;
95
    return (0);
96
  }
97
 
98
 /*
99
  * Free any old element value and set the new value...
100
  */
101
 
102
  if (node->value.custom.data && node->value.custom.destroy)
103
    (*(node->value.custom.destroy))(node->value.custom.data);
104
 
105
  node->value.custom.data    = data;
106
  node->value.custom.destroy = destroy;
107
 
108
  return (0);
109
}
110
 
111
 
112
/*
113
 * 'mxmlSetElement()' - Set the name of an element node.
114
 *
115
 * The node is not changed if it is not an element node.
116
 */
117
 
118
int					/* O - 0 on success, -1 on failure */
119
mxmlSetElement(mxml_node_t *node,	/* I - Node to set */
120
               const char  *name)	/* I - New name string */
121
{
122
 /*
123
  * Range check input...
124
  */
125
 
126
  if (!node || node->type != MXML_ELEMENT || !name)
127
    return (-1);
128
 
129
  if (name == node->value.element.name)
130
    return (0);
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
 
151
int					/* O - 0 on success, -1 on failure */
152
mxmlSetInteger(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
 
182
int					/* O - 0 on success, -1 on failure */
183
mxmlSetOpaque(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
  if (node->value.opaque == opaque)
198
    return (0);
199
 
200
 /*
201
  * Free any old opaque value and set the new value...
202
  */
203
 
204
  if (node->value.opaque)
205
    free(node->value.opaque);
206
 
207
  node->value.opaque = strdup(opaque);
208
 
209
  return (0);
210
}
211
 
212
 
213
/*
214
 * 'mxmlSetOpaquef()' - Set the value of an opaque string node to a formatted string.
215
 *
216
 * The node is not changed if it (or its first child) is not an opaque node.
217
 *
218
 * @since Mini-XML 2.11@
219
 */
220
 
221
int					/* O - 0 on success, -1 on failure */
222
mxmlSetOpaquef(mxml_node_t *node,	/* I - Node to set */
223
               const char  *format,	/* I - Printf-style format string */
224
	       ...)			/* I - Additional arguments as needed */
225
{
226
  va_list	ap;			/* Pointer to arguments */
227
  char		*s;			/* Temporary string */
228
 
229
 
230
 /*
231
  * Range check input...
232
  */
233
 
234
  if (node && node->type == MXML_ELEMENT &&
235
      node->child && node->child->type == MXML_OPAQUE)
236
    node = node->child;
237
 
238
  if (!node || node->type != MXML_OPAQUE || !format)
239
    return (-1);
240
 
241
 /*
242
  * Format the new string, free any old string value, and set the new value...
243
  */
244
 
245
  va_start(ap, format);
246
  s = _mxml_vstrdupf(format, ap);
247
  va_end(ap);
248
 
249
  if (node->value.opaque)
250
    free(node->value.opaque);
251
 
252
  node->value.opaque = s;
253
 
254
  return (0);
255
}
256
 
257
 
258
/*
259
 * 'mxmlSetReal()' - Set the value of a real number node.
260
 *
261
 * The node is not changed if it (or its first child) is not a real number node.
262
 */
263
 
264
int					/* O - 0 on success, -1 on failure */
265
mxmlSetReal(mxml_node_t *node,		/* I - Node to set */
266
            double      real)		/* I - Real number value */
267
{
268
 /*
269
  * Range check input...
270
  */
271
 
272
  if (node && node->type == MXML_ELEMENT &&
273
      node->child && node->child->type == MXML_REAL)
274
    node = node->child;
275
 
276
  if (!node || node->type != MXML_REAL)
277
    return (-1);
278
 
279
 /*
280
  * Set the new value and return...
281
  */
282
 
283
  node->value.real = real;
284
 
285
  return (0);
286
}
287
 
288
 
289
/*
290
 * 'mxmlSetText()' - Set the value of a text node.
291
 *
292
 * The node is not changed if it (or its first child) is not a text node.
293
 */
294
 
295
int					/* O - 0 on success, -1 on failure */
296
mxmlSetText(mxml_node_t *node,		/* I - Node to set */
297
            int         whitespace,	/* I - 1 = leading whitespace, 0 = no whitespace */
298
	    const char  *string)	/* I - String */
299
{
300
 /*
301
  * Range check input...
302
  */
303
 
304
  if (node && node->type == MXML_ELEMENT &&
305
      node->child && node->child->type == MXML_TEXT)
306
    node = node->child;
307
 
308
  if (!node || node->type != MXML_TEXT || !string)
309
    return (-1);
310
 
311
  if (string == node->value.text.string)
312
  {
313
    node->value.text.whitespace = whitespace;
314
    return (0);
315
  }
316
 
317
 /*
318
  * Free any old string value and set the new value...
319
  */
320
 
321
  if (node->value.text.string)
322
    free(node->value.text.string);
323
 
324
  node->value.text.whitespace = whitespace;
325
  node->value.text.string     = strdup(string);
326
 
327
  return (0);
328
}
329
 
330
 
331
/*
332
 * 'mxmlSetTextf()' - Set the value of a text node to a formatted string.
333
 *
334
 * The node is not changed if it (or its first child) is not a text node.
335
 */
336
 
337
int					/* O - 0 on success, -1 on failure */
338
mxmlSetTextf(mxml_node_t *node,		/* I - Node to set */
339
             int         whitespace,	/* I - 1 = leading whitespace, 0 = no whitespace */
340
             const char  *format,	/* I - Printf-style format string */
341
	     ...)			/* I - Additional arguments as needed */
342
{
343
  va_list	ap;			/* Pointer to arguments */
344
  char		*s;			/* Temporary string */
345
 
346
 
347
 /*
348
  * Range check input...
349
  */
350
 
351
  if (node && node->type == MXML_ELEMENT &&
352
      node->child && node->child->type == MXML_TEXT)
353
    node = node->child;
354
 
355
  if (!node || node->type != MXML_TEXT || !format)
356
    return (-1);
357
 
358
 /*
359
  * Free any old string value and set the new value...
360
  */
361
 
362
  va_start(ap, format);
363
  s = _mxml_vstrdupf(format, ap);
364
  va_end(ap);
365
 
366
  if (node->value.text.string)
367
    free(node->value.text.string);
368
 
369
  node->value.text.whitespace = whitespace;
370
  node->value.text.string     = s;
371
 
372
  return (0);
373
}
374
 
375
 
376
/*
377
 * 'mxmlSetUserData()' - Set the user data pointer for a node.
378
 *
379
 * @since Mini-XML 2.7@
380
 */
381
 
382
int					/* O - 0 on success, -1 on failure */
383
mxmlSetUserData(mxml_node_t *node,	/* I - Node to set */
384
                void        *data)	/* I - User data pointer */
385
{
386
 /*
387
  * Range check input...
388
  */
389
 
390
  if (!node)
391
    return (-1);
392
 
393
 /*
394
  * Set the user data pointer and return...
395
  */
396
 
397
  node->user_data = data;
398
  return (0);
399
}