mxml-attr.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: mxml-attr.c 308 2007-09-15 20:04:56Z mike $"
00003  *
00004  * Attribute support code for Mini-XML, a small XML-like file parsing library.
00005  *
00006  * Copyright 2003-2007 by Michael Sweet.
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Library General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2, or (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * Contents:
00019  *
00020  *   mxmlElementDeleteAttr() - Delete an attribute.
00021  *   mxmlElementGetAttr()    - Get an attribute.
00022  *   mxmlElementSetAttr()    - Set an attribute.
00023  *   mxmlElementSetAttrf()   - Set an attribute with a formatted value.
00024  *   mxml_set_attr()         - Set or add an attribute name/value pair.
00025  */
00026 
00027 /*
00028  * Include necessary headers...
00029  */
00030 
00031 #include "config.h"
00032 #include "mxml.h"
00033 
00034 
00035 /*
00036  * Local functions...
00037  */
00038 
00039 static int  mxml_set_attr(mxml_node_t *node, const char *name,
00040                       char *value);
00041 
00042 
00043 /*
00044  * 'mxmlElementDeleteAttr()' - Delete an attribute.
00045  *
00046  * @since Mini-XML 2.4@
00047  */
00048 
00049 void
00050 mxmlElementDeleteAttr(mxml_node_t *node,/* I - Element */
00051                       const char  *name)/* I - Attribute name */
00052 {
00053   int       i;          /* Looping var */
00054   mxml_attr_t   *attr;          /* Cirrent attribute */
00055 
00056 
00057 #ifdef DEBUG
00058   fprintf(stderr, "mxmlElementDeleteAttr(node=%p, name=\"%s\")\n",
00059           node, name ? name : "(null)");
00060 #endif /* DEBUG */
00061 
00062  /*
00063   * Range check input...
00064   */
00065 
00066   if (!node || node->type != MXML_ELEMENT || !name)
00067     return;
00068 
00069  /*
00070   * Look for the attribute...
00071   */
00072 
00073   for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
00074        i > 0;
00075        i --, attr ++)
00076   {
00077 #ifdef DEBUG
00078     printf("    %s=\"%s\"\n", attr->name, attr->value);
00079 #endif /* DEBUG */
00080 
00081     if (!strcmp(attr->name, name))
00082     {
00083      /*
00084       * Delete this attribute...
00085       */
00086 
00087       free(attr->name);
00088       free(attr->value);
00089 
00090       i --;
00091       if (i > 0)
00092         memmove(attr, attr + 1, i * sizeof(mxml_attr_t));
00093 
00094       node->value.element.num_attrs --;
00095       return;
00096     }
00097   }
00098 }
00099 
00100 
00101 /*
00102  * 'mxmlElementGetAttr()' - Get an attribute.
00103  *
00104  * This function returns NULL if the node is not an element or the
00105  * named attribute does not exist.
00106  */
00107 
00108 const char *                /* O - Attribute value or NULL */
00109 mxmlElementGetAttr(mxml_node_t *node,   /* I - Element node */
00110                    const char  *name)   /* I - Name of attribute */
00111 {
00112   int       i;          /* Looping var */
00113   mxml_attr_t   *attr;          /* Cirrent attribute */
00114 
00115 
00116 #ifdef DEBUG
00117   fprintf(stderr, "mxmlElementGetAttr(node=%p, name=\"%s\")\n",
00118           node, name ? name : "(null)");
00119 #endif /* DEBUG */
00120 
00121  /*
00122   * Range check input...
00123   */
00124 
00125   if (!node || node->type != MXML_ELEMENT || !name)
00126     return (NULL);
00127 
00128  /*
00129   * Look for the attribute...
00130   */
00131 
00132   for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
00133        i > 0;
00134        i --, attr ++)
00135   {
00136 #ifdef DEBUG
00137     printf("    %s=\"%s\"\n", attr->name, attr->value);
00138 #endif /* DEBUG */
00139 
00140     if (!strcmp(attr->name, name))
00141     {
00142 #ifdef DEBUG
00143       printf("    Returning \"%s\"!\n", attr->value);
00144 #endif /* DEBUG */
00145       return (attr->value);
00146     }
00147   }
00148 
00149  /*
00150   * Didn't find attribute, so return NULL...
00151   */
00152 
00153 #ifdef DEBUG
00154   puts("    Returning NULL!\n");
00155 #endif /* DEBUG */
00156 
00157   return (NULL);
00158 }
00159 
00160 
00161 /*
00162  * 'mxmlElementSetAttr()' - Set an attribute.
00163  *
00164  * If the named attribute already exists, the value of the attribute
00165  * is replaced by the new string value. The string value is copied
00166  * into the element node. This function does nothing if the node is
00167  * not an element.
00168  */
00169 
00170 void
00171 mxmlElementSetAttr(mxml_node_t *node,   /* I - Element node */
00172                    const char  *name,   /* I - Name of attribute */
00173                    const char  *value)  /* I - Attribute value */
00174 {
00175   char  *valuec;            /* Copy of value */
00176 
00177 
00178 #ifdef DEBUG
00179   fprintf(stderr, "mxmlElementSetAttr(node=%p, name=\"%s\", value=\"%s\")\n",
00180           node, name ? name : "(null)", value ? value : "(null)");
00181 #endif /* DEBUG */
00182 
00183  /*
00184   * Range check input...
00185   */
00186 
00187   if (!node || node->type != MXML_ELEMENT || !name)
00188     return;
00189 
00190   if (value)
00191     valuec = strdup(value);
00192   else
00193     valuec = NULL;
00194 
00195   if (mxml_set_attr(node, name, valuec))
00196     free(valuec);
00197 }
00198 
00199 
00200 /*
00201  * 'mxmlElementSetAttrf()' - Set an attribute with a formatted value.
00202  *
00203  * If the named attribute already exists, the value of the attribute
00204  * is replaced by the new formatted string. The formatted string value is
00205  * copied into the element node. This function does nothing if the node
00206  * is not an element.
00207  *
00208  * @since Mini-XML 2.3@
00209  */
00210 
00211 void
00212 mxmlElementSetAttrf(mxml_node_t *node,  /* I - Element node */
00213                     const char  *name,  /* I - Name of attribute */
00214                     const char  *format,/* I - Printf-style attribute value */
00215             ...)        /* I - Additional arguments as needed */
00216 {
00217   va_list   ap;         /* Argument pointer */
00218   char      *value;         /* Value */
00219 
00220 
00221 #ifdef DEBUG
00222   fprintf(stderr,
00223           "mxmlElementSetAttrf(node=%p, name=\"%s\", format=\"%s\", ...)\n",
00224           node, name ? name : "(null)", format ? format : "(null)");
00225 #endif /* DEBUG */
00226 
00227  /*
00228   * Range check input...
00229   */
00230 
00231   if (!node || node->type != MXML_ELEMENT || !name || !format)
00232     return;
00233 
00234  /*
00235   * Format the value...
00236   */
00237 
00238   va_start(ap, format);
00239   value = _mxml_vstrdupf(format, ap);
00240   va_end(ap);
00241 
00242   if (!value)
00243     mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
00244                name, node->value.element.name);
00245   else if (mxml_set_attr(node, name, value))
00246     free(value);
00247 }
00248 
00249 
00250 /*
00251  * 'mxml_set_attr()' - Set or add an attribute name/value pair.
00252  */
00253 
00254 static int              /* O - 0 on success, -1 on failure */
00255 mxml_set_attr(mxml_node_t *node,    /* I - Element node */
00256               const char  *name,    /* I - Attribute name */
00257               char        *value)   /* I - Attribute value */
00258 {
00259   int       i;          /* Looping var */
00260   mxml_attr_t   *attr;          /* New attribute */
00261 
00262 
00263  /*
00264   * Look for the attribute...
00265   */
00266 
00267   for (i = node->value.element.num_attrs, attr = node->value.element.attrs;
00268        i > 0;
00269        i --, attr ++)
00270     if (!strcmp(attr->name, name))
00271     {
00272      /*
00273       * Free the old value as needed...
00274       */
00275 
00276       if (attr->value)
00277         free(attr->value);
00278 
00279       attr->value = value;
00280 
00281       return (0);
00282     }
00283 
00284  /*
00285   * Add a new attribute...
00286   */
00287 
00288   if (node->value.element.num_attrs == 0)
00289     attr = malloc(sizeof(mxml_attr_t));
00290   else
00291     attr = realloc(node->value.element.attrs,
00292                    (node->value.element.num_attrs + 1) * sizeof(mxml_attr_t));
00293 
00294   if (!attr)
00295   {
00296     mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
00297                name, node->value.element.name);
00298     return (-1);
00299   }
00300 
00301   node->value.element.attrs = attr;
00302   attr += node->value.element.num_attrs;
00303 
00304   if ((attr->name = strdup(name)) == NULL)
00305   {
00306     mxml_error("Unable to allocate memory for attribute '%s' in element %s!",
00307                name, node->value.element.name);
00308     return (-1);
00309   }
00310 
00311   attr->value = value;
00312 
00313   node->value.element.num_attrs ++;
00314 
00315   return (0);
00316 }

Generated by  doxygen 1.6.2