Statistics
| Revision:

root / logic / trunk / src / mxml / mxml-attr.c @ 49

History | View | Annotate | Download (7.13 KB)

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 "config.h"
32
#include "mxml.h"
33

    
34

    
35
/*
36
 * Local functions...
37
 */
38

    
39
static int        mxml_set_attr(mxml_node_t *node, const char *name,
40
                              char *value);
41

    
42

    
43
/*
44
 * 'mxmlElementDeleteAttr()' - Delete an attribute.
45
 *
46
 * @since Mini-XML 2.4@
47
 */
48

    
49
void
50
mxmlElementDeleteAttr(mxml_node_t *node,/* I - Element */
51
                      const char  *name)/* I - Attribute name */
52
{
53
  int                i;                        /* Looping var */
54
  mxml_attr_t        *attr;                        /* Cirrent attribute */
55

    
56

    
57
#ifdef DEBUG
58
  fprintf(stderr, "mxmlElementDeleteAttr(node=%p, name=\"%s\")\n",
59
          node, name ? name : "(null)");
60
#endif /* DEBUG */
61

    
62
 /*
63
  * Range check input...
64
  */
65

    
66
  if (!node || node->type != MXML_ELEMENT || !name)
67
    return;
68

    
69
 /*
70
  * Look for the attribute...
71
  */
72

    
73
  for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
74
       i > 0;
75
       i --, attr ++)
76
  {
77
#ifdef DEBUG
78
    printf("    %s=\"%s\"\n", attr->name, attr->value);
79
#endif /* DEBUG */
80

    
81
    if (!strcmp(attr->name, name))
82
    {
83
     /*
84
      * Delete this attribute...
85
      */
86

    
87
      free(attr->name);
88
      free(attr->value);
89

    
90
      i --;
91
      if (i > 0)
92
        memmove(attr, attr + 1, i * sizeof(mxml_attr_t));
93

    
94
      node->value.element.num_attrs --;
95
      return;
96
    }
97
  }
98
}
99

    
100

    
101
/*
102
 * 'mxmlElementGetAttr()' - Get an attribute.
103
 *
104
 * This function returns NULL if the node is not an element or the
105
 * named attribute does not exist.
106
 */
107

    
108
const char *                                /* O - Attribute value or NULL */
109
mxmlElementGetAttr(mxml_node_t *node,        /* I - Element node */
110
                   const char  *name)        /* I - Name of attribute */
111
{
112
  int                i;                        /* Looping var */
113
  mxml_attr_t        *attr;                        /* Cirrent attribute */
114

    
115

    
116
#ifdef DEBUG
117
  fprintf(stderr, "mxmlElementGetAttr(node=%p, name=\"%s\")\n",
118
          node, name ? name : "(null)");
119
#endif /* DEBUG */
120

    
121
 /*
122
  * Range check input...
123
  */
124

    
125
  if (!node || node->type != MXML_ELEMENT || !name)
126
    return (NULL);
127

    
128
 /*
129
  * Look for the attribute...
130
  */
131

    
132
  for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
133
       i > 0;
134
       i --, attr ++)
135
  {
136
#ifdef DEBUG
137
    printf("    %s=\"%s\"\n", attr->name, attr->value);
138
#endif /* DEBUG */
139

    
140
    if (!strcmp(attr->name, name))
141
    {
142
#ifdef DEBUG
143
      printf("    Returning \"%s\"!\n", attr->value);
144
#endif /* DEBUG */
145
      return (attr->value);
146
    }
147
  }
148

    
149
 /*
150
  * Didn't find attribute, so return NULL...
151
  */
152

    
153
#ifdef DEBUG
154
  puts("    Returning NULL!\n");
155
#endif /* DEBUG */
156

    
157
  return (NULL);
158
}
159

    
160

    
161
/*
162
 * 'mxmlElementSetAttr()' - Set an attribute.
163
 *
164
 * If the named attribute already exists, the value of the attribute
165
 * is replaced by the new string value. The string value is copied
166
 * into the element node. This function does nothing if the node is
167
 * not an element.
168
 */
169

    
170
void
171
mxmlElementSetAttr(mxml_node_t *node,        /* I - Element node */
172
                   const char  *name,        /* I - Name of attribute */
173
                   const char  *value)        /* I - Attribute value */
174
{
175
  char        *valuec;                        /* Copy of value */
176

    
177

    
178
#ifdef DEBUG
179
  fprintf(stderr, "mxmlElementSetAttr(node=%p, name=\"%s\", value=\"%s\")\n",
180
          node, name ? name : "(null)", value ? value : "(null)");
181
#endif /* DEBUG */
182

    
183
 /*
184
  * Range check input...
185
  */
186

    
187
  if (!node || node->type != MXML_ELEMENT || !name)
188
    return;
189

    
190
  if (value)
191
    valuec = strdup(value);
192
  else
193
    valuec = NULL;
194

    
195
  if (mxml_set_attr(node, name, valuec))
196
    free(valuec);
197
}
198

    
199

    
200
/*
201
 * 'mxmlElementSetAttrf()' - Set an attribute with a formatted value.
202
 *
203
 * If the named attribute already exists, the value of the attribute
204
 * is replaced by the new formatted string. The formatted string value is
205
 * copied into the element node. This function does nothing if the node
206
 * is not an element.
207
 *
208
 * @since Mini-XML 2.3@
209
 */
210

    
211
void
212
mxmlElementSetAttrf(mxml_node_t *node,        /* I - Element node */
213
                    const char  *name,        /* I - Name of attribute */
214
                    const char  *format,/* I - Printf-style attribute value */
215
                    ...)                /* I - Additional arguments as needed */
216
{
217
  va_list        ap;                        /* Argument pointer */
218
  char                *value;                        /* Value */
219

    
220

    
221
#ifdef DEBUG
222
  fprintf(stderr,
223
          "mxmlElementSetAttrf(node=%p, name=\"%s\", format=\"%s\", ...)\n",
224
          node, name ? name : "(null)", format ? format : "(null)");
225
#endif /* DEBUG */
226

    
227
 /*
228
  * Range check input...
229
  */
230

    
231
  if (!node || node->type != MXML_ELEMENT || !name || !format)
232
    return;
233

    
234
 /*
235
  * Format the value...
236
  */
237

    
238
  va_start(ap, format);
239
  value = _mxml_vstrdupf(format, ap);
240
  va_end(ap);
241

    
242
  if (!value)
243
    mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
244
               name, node->value.element.name);
245
  else if (mxml_set_attr(node, name, value))
246
    free(value);
247
}
248

    
249

    
250
/*
251
 * 'mxml_set_attr()' - Set or add an attribute name/value pair.
252
 */
253

    
254
static int                                /* O - 0 on success, -1 on failure */
255
mxml_set_attr(mxml_node_t *node,        /* I - Element node */
256
              const char  *name,        /* I - Attribute name */
257
              char        *value)        /* I - Attribute value */
258
{
259
  int                i;                        /* Looping var */
260
  mxml_attr_t        *attr;                        /* New attribute */
261

    
262

    
263
 /*
264
  * Look for the attribute...
265
  */
266

    
267
  for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
268
       i > 0;
269
       i --, attr ++)
270
    if (!strcmp(attr->name, name))
271
    {
272
     /*
273
      * Free the old value as needed...
274
      */
275

    
276
      if (attr->value)
277
        free(attr->value);
278

    
279
      attr->value = value;
280

    
281
      return (0);
282
    }
283

    
284
 /*
285
  * Add a new attribute...
286
  */
287

    
288
  if (node->value.element.num_attrs == 0)
289
    attr = malloc(sizeof(mxml_attr_t));
290
  else
291
    attr = realloc(node->value.element.attrs,
292
                   (node->value.element.num_attrs + 1) * sizeof(mxml_attr_t));
293

    
294
  if (!attr)
295
  {
296
    mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
297
               name, node->value.element.name);
298
    return (-1);
299
  }
300

    
301
  node->value.element.attrs = attr;
302
  attr += node->value.element.num_attrs;
303

    
304
  if ((attr->name = strdup(name)) == NULL)
305
  {
306
    mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
307
               name, node->value.element.name);
308
    return (-1);
309
  }
310

    
311
  attr->value = value;
312

    
313
  node->value.element.num_attrs ++;
314

    
315
  return (0);
316
}
317

    
318

    
319
/*
320
 * End of "$Id: mxml-attr.c 308 2007-09-15 20:04:56Z mike $".
321
 */