libgimpprint API Reference: src/main/mxml-node.c Source File

Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

# src/main/mxml-node.c

Go to the documentation of this file.

    00001 /*
    00002  * "$Id: mxml-node_8c-source.html,v 1.1.1.2 2004/12/22 23:49:05 jlovell Exp $"
    00003  *
    00004  * Node support code for mini-XML, a small XML-like file parsing library.
    00005  *
    00006  * Copyright 2003 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  *   stp_mxmlAdd()        - Add a node to a tree.
    00021  *   stp_mxmlDelete()     - Delete a node and all of its children.
    00022  *   stp_mxmlNewElement() - Create a new element node.
    00023  *   stp_mxmlNewInteger() - Create a new integer node.
    00024  *   stp_mxmlNewOpaque()  - Create a new opaque string.
    00025  *   stp_mxmlNewReal()    - Create a new real number node.
    00026  *   stp_mxmlNewText()    - Create a new text fragment node.
    00027  *   stp_mxmlRemove()     - Remove a node from its parent.
    00028  *   mxml_new()       - Create a new node.
    00029  */
    00030
    00031 /*
    00032  * Include necessary headers...
    00033  */
    00034
    00035 #include <gimp-print/mxml.h>
    00036 #include "config.h"
    00037
    00038
    00039 /*
    00040  * Local functions...
    00041  */
    00042
    00043 static stp_mxml_node_t  *mxml_new(stp_mxml_node_t *parent, stp_mxml_type_t type);
    00044
    00045
    00046 /*
    00047  * 'stp_mxmlAdd()' - Add a node to a tree.
    00048  *
    00049  * Adds the specified node to the parent. If the child argument is not
    00050  * NULL, puts the new node before or after the specified child depending
    00051  * on the value of the where argument. If the child argument is NULL,
    00052  * puts the new node at the beginning of the child list (STP_MXML_ADD_BEFORE)
    00053  * or at the end of the child list (STP_MXML_ADD_AFTER). The constant
    00054  * STP_MXML_ADD_TO_PARENT can be used to specify a NULL child pointer.
    00055  */
    00056
    00057 void
    00058 stp_mxmlAdd(stp_mxml_node_t *parent,            /* I - Parent node */
    00059         int         where,              /* I - Where to add, STP_MXML_ADD_BEFORE or STP_MXML_ADD_AFTER */
    00060         stp_mxml_node_t *child,         /* I - Child node for where or STP_MXML_ADD_TO_PARENT */
    00061         stp_mxml_node_t *node)          /* I - Node to add */
    00062 {
    00063 /*  fprintf(stderr, "stp_mxmlAdd(parent=%p, where=%d, child=%p, node=%p)\n", parent,
    00064          where, child, node);*/
    00065
    00066  /*
    00067   * Range check input...
    00068   */
    00069
    00070   if (!parent || !node)
    00071     return;
    00072
    00073  /*
    00074   * Remove the node from any existing parent...
    00075   */
    00076
    00077   if (node->parent)
    00078     stp_mxmlRemove(node);
    00079
    00080  /*
    00081   * Reset pointers...
    00082   */
    00083
    00084   node->parent = parent;
    00085
    00086   switch (where)
    00087   {
    00088     case STP_MXML_ADD_BEFORE :
    00089         if (!child || child == parent->child || child->parent != parent)
    00090         {
    00091          /*
    00092           * Insert as first node under parent...
    00093           */
    00094
    00095           node->next = parent->child;
    00096
    00097           if (parent->child)
    00098             parent->child->prev = node;
    00099           else
    00100             parent->last_child = node;
    00101
    00102           parent->child = node;
    00103         }
    00104         else
    00105         {
    00106          /*
    00107           * Insert node before this child...
    00108           */
    00109
    00110           node->next = child;
    00111           node->prev = child->prev;
    00112
    00113           if (child->prev)
    00114             child->prev->next = node;
    00115           else
    00116             parent->child = node;
    00117
    00118           child->prev = node;
    00119         }
    00120         break;
    00121
    00122     case STP_MXML_ADD_AFTER :
    00123         if (!child || child == parent->last_child || child->parent != parent)
    00124         {
    00125          /*
    00126           * Insert as last node under parent...
    00127           */
    00128
    00129           node->parent = parent;
    00130           node->prev   = parent->last_child;
    00131
    00132           if (parent->last_child)
    00133             parent->last_child->next = node;
    00134           else
    00135             parent->child = node;
    00136
    00137           parent->last_child = node;
    00138         }
    00139         else
    00140         {
    00141          /*
    00142           * Insert node after this child...
    00143           */
    00144
    00145           node->prev = child;
    00146           node->next = child->next;
    00147
    00148           if (child->next)
    00149             child->next->prev = node;
    00150           else
    00151             parent->last_child = node;
    00152
    00153           child->next = node;
    00154         }
    00155         break;
    00156   }
    00157 }
    00158
    00159
    00160 /*
    00161  * 'stp_mxmlDelete()' - Delete a node and all of its children.
    00162  *
    00163  * If the specified node has a parent, this function first removes the
    00164  * node from its parent using the stp_mxmlRemove() function.
    00165  */
    00166
    00167 void
    00168 stp_mxmlDelete(stp_mxml_node_t *node)           /* I - Node to delete */
    00169 {
    00170   int   i;                              /* Looping var */
    00171
    00172
    00173 /*  fprintf(stderr, "stp_mxmlDelete(node=%p)\n", node);*/
    00174
    00175  /*
    00176   * Range check input...
    00177   */
    00178
    00179   if (!node)
    00180     return;
    00181
    00182  /*
    00183   * Remove the node from its parent, if any...
    00184   */
    00185
    00186   stp_mxmlRemove(node);
    00187
    00188  /*
    00189   * Delete children...
    00190   */
    00191
    00192   while (node->child)
    00193     stp_mxmlDelete(node->child);
    00194
    00195  /*
    00196   * Now delete any node data...
    00197   */
    00198
    00199   switch (node->type)
    00200   {
    00201     case STP_MXML_ELEMENT :
    00202         if (node->value.element.name)
    00203           free(node->value.element.name);
    00204
    00205         if (node->value.element.num_attrs)
    00206         {
    00207           for (i = 0; i < node->value.element.num_attrs; i ++)
    00208           {
    00209             if (node->value.element.attrs[i].name)
    00210               free(node->value.element.attrs[i].name);
    00211             if (node->value.element.attrs[i].value)
    00212               free(node->value.element.attrs[i].value);
    00213           }
    00214
    00215           free(node->value.element.attrs);
    00216         }
    00217         break;
    00218     case STP_MXML_INTEGER :
    00219        /* Nothing to do */
    00220         break;
    00221     case STP_MXML_OPAQUE :
    00222         if (node->value.opaque)
    00223           free(node->value.opaque);
    00224         break;
    00225     case STP_MXML_REAL :
    00226        /* Nothing to do */
    00227         break;
    00228     case STP_MXML_TEXT :
    00229         if (node->value.text.string)
    00230           free(node->value.text.string);
    00231         break;
    00232   }
    00233
    00234  /*
    00235   * Free this node...
    00236   */
    00237
    00238   free(node);
    00239 }
    00240
    00241
    00242 /*
    00243  * 'stp_mxmlNewElement()' - Create a new element node.
    00244  *
    00245  * The new element node is added to the end of the specified parent's child
    00246  * list. The constant STP_MXML_NO_PARENT can be used to specify that the new
    00247  * element node has no parent.
    00248  */
    00249
    00250 stp_mxml_node_t *                               /* O - New node */
    00251 stp_mxmlNewElement(stp_mxml_node_t *parent,     /* I - Parent node or STP_MXML_NO_PARENT */
    00252                const char  *name)       /* I - Name of element */
    00253 {
    00254   stp_mxml_node_t       *node;                  /* New node */
    00255
    00256
    00257  /*
    00258   * Range check input...
    00259   */
    00260
    00261   if (!name)
    00262     return (NULL);
    00263
    00264  /*
    00265   * Create the node and set the element name...
    00266   */
    00267
    00268   if ((node = mxml_new(parent, STP_MXML_ELEMENT)) != NULL)
    00269     node->value.element.name = strdup(name);
    00270
    00271   return (node);
    00272 }
    00273
    00274
    00275 /*
    00276  * 'stp_mxmlNewInteger()' - Create a new integer node.
    00277  *
    00278  * The new integer node is added to the end of the specified parent's child
    00279  * list. The constant STP_MXML_NO_PARENT can be used to specify that the new
    00280  * integer node has no parent.
    00281  */
    00282
    00283 stp_mxml_node_t *                               /* O - New node */
    00284 stp_mxmlNewInteger(stp_mxml_node_t *parent,     /* I - Parent node or STP_MXML_NO_PARENT */
    00285                int         integer)     /* I - Integer value */
    00286 {
    00287   stp_mxml_node_t       *node;                  /* New node */
    00288
    00289
    00290  /*
    00291   * Range check input...
    00292   */
    00293
    00294   if (!parent)
    00295     return (NULL);
    00296
    00297  /*
    00298   * Create the node and set the element name...
    00299   */
    00300
    00301   if ((node = mxml_new(parent, STP_MXML_INTEGER)) != NULL)
    00302     node->value.integer = integer;
    00303
    00304   return (node);
    00305 }
    00306
    00307
    00308 /*
    00309  * 'stp_mxmlNewOpaque()' - Create a new opaque string.
    00310  *
    00311  * The new opaque node is added to the end of the specified parent's child
    00312  * list. The constant STP_MXML_NO_PARENT can be used to specify that the new
    00313  * opaque node has no parent. The opaque string must be nul-terminated and
    00314  * is copied into the new node.
    00315  */
    00316
    00317 stp_mxml_node_t *                               /* O - New node */
    00318 stp_mxmlNewOpaque(stp_mxml_node_t *parent,      /* I - Parent node or STP_MXML_NO_PARENT */
    00319               const char  *opaque)      /* I - Opaque string */
    00320 {
    00321   stp_mxml_node_t       *node;                  /* New node */
    00322
    00323
    00324  /*
    00325   * Range check input...
    00326   */
    00327
    00328   if (!parent || !opaque)
    00329     return (NULL);
    00330
    00331  /*
    00332   * Create the node and set the element name...
    00333   */
    00334
    00335   if ((node = mxml_new(parent, STP_MXML_OPAQUE)) != NULL)
    00336     node->value.opaque = strdup(opaque);
    00337
    00338   return (node);
    00339 }
    00340
    00341
    00342 /*
    00343  * 'stp_mxmlNewReal()' - Create a new real number node.
    00344  *
    00345  * The new real number node is added to the end of the specified parent's
    00346  * child list. The constant STP_MXML_NO_PARENT can be used to specify that
    00347  * the new real number node has no parent.
    00348  */
    00349
    00350 stp_mxml_node_t *                               /* O - New node */
    00351 stp_mxmlNewReal(stp_mxml_node_t *parent,        /* I - Parent node or STP_MXML_NO_PARENT */
    00352             double      real)           /* I - Real number value */
    00353 {
    00354   stp_mxml_node_t       *node;                  /* New node */
    00355
    00356
    00357  /*
    00358   * Range check input...
    00359   */
    00360
    00361   if (!parent)
    00362     return (NULL);
    00363
    00364  /*
    00365   * Create the node and set the element name...
    00366   */
    00367
    00368   if ((node = mxml_new(parent, STP_MXML_REAL)) != NULL)
    00369     node->value.real = real;
    00370
    00371   return (node);
    00372 }
    00373
    00374
    00375 /*
    00376  * 'stp_mxmlNewText()' - Create a new text fragment node.
    00377  *
    00378  * The new text node is added to the end of the specified parent's child
    00379  * list. The constant STP_MXML_NO_PARENT can be used to specify that the new
    00380  * text node has no parent. The whitespace parameter is used to specify
    00381  * whether leading whitespace is present before the node. The text
    00382  * string must be nul-terminated and is copied into the new node.
    00383  */
    00384
    00385 stp_mxml_node_t *                               /* O - New node */
    00386 stp_mxmlNewText(stp_mxml_node_t *parent,        /* I - Parent node or STP_MXML_NO_PARENT */
    00387             int         whitespace,     /* I - 1 = leading whitespace, 0 = no whitespace */
    00388             const char  *string)        /* I - String */
    00389 {
    00390   stp_mxml_node_t       *node;                  /* New node */
    00391
    00392
    00393  /*
    00394   * Range check input...
    00395   */
    00396
    00397   if (!parent || !string)
    00398     return (NULL);
    00399
    00400  /*
    00401   * Create the node and set the text value...
    00402   */
    00403
    00404   if ((node = mxml_new(parent, STP_MXML_TEXT)) != NULL)
    00405   {
    00406     node->value.text.whitespace = whitespace;
    00407     node->value.text.string     = strdup(string);
    00408   }
    00409
    00410   return (node);
    00411 }
    00412
    00413
    00414 /*
    00415  * 'stp_mxmlRemove()' - Remove a node from its parent.
    00416  *
    00417  * Does not free memory used by the node - use stp_mxmlDelete() for that.
    00418  * This function does nothing if the node has no parent.
    00419  */
    00420
    00421 void
    00422 stp_mxmlRemove(stp_mxml_node_t *node)           /* I - Node to remove */
    00423 {
    00424  /*
    00425   * Range check input...
    00426   */
    00427
    00428 /*  fprintf(stderr, "stp_mxmlRemove(node=%p)\n", node);*/
    00429
    00430   if (!node || !node->parent)
    00431     return;
    00432
    00433  /*
    00434   * Remove from parent...
    00435   */
    00436
    00437   if (node->prev)
    00438     node->prev->next = node->next;
    00439   else
    00440     node->parent->child = node->next;
    00441
    00442   if (node->next)
    00443     node->next->prev = node->prev;
    00444   else
    00445     node->parent->last_child = node->prev;
    00446
    00447   node->parent = NULL;
    00448   node->prev   = NULL;
    00449   node->next   = NULL;
    00450 }
    00451
    00452
    00453 /*
    00454  * 'mxml_new()' - Create a new node.
    00455  */
    00456
    00457 static stp_mxml_node_t *                        /* O - New node */
    00458 mxml_new(stp_mxml_node_t *parent,               /* I - Parent node */
    00459          stp_mxml_type_t type)          /* I - Node type */
    00460 {
    00461   stp_mxml_node_t       *node;                  /* New node */
    00462
    00463
    00464  /*
    00465   * Allocate memory for the node...
    00466   */
    00467
    00468   if ((node = calloc(1, sizeof(stp_mxml_node_t))) == NULL)
    00469     return (NULL);
    00470
    00471  /*
    00472   * Set the node type...
    00473   */
    00474
    00475   node->type = type;
    00476
    00477  /*
    00478   * Add to the parent if present...
    00479   */
    00480
    00481   if (parent)
    00482     stp_mxmlAdd(parent, STP_MXML_ADD_AFTER, STP_MXML_ADD_TO_PARENT, node);
    00483
    00484  /*
    00485   * Return the new node...
    00486   */
    00487
    00488   return (node);
    00489 }
    00490
    00491
    00492 /*
    00493  * End of "$Id: mxml-node_8c-source.html,v 1.1.1.2 2004/12/22 23:49:05 jlovell Exp $".
    00494  */