Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals  

src/main/mxml-search.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: mxml-search.c,v 1.6 2004/04/27 23:23:47 rlk Exp $"
00003  *
00004  * Search/navigation functions for mini-XML, a small XML-like file
00005  * parsing library.
00006  *
00007  * Copyright 2003 by Michael Sweet.
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Library General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * Contents:
00020  *
00021  *   stp_mxmlFindElement() - Find the named element.
00022  *   stp_mxmlWalkNext()    - Walk to the next logical node in the tree.
00023  *   stp_mxmlWalkPrev()    - Walk to the previous logical node in the tree.
00024  */
00025 
00026 /*
00027  * Include necessary headers...
00028  */
00029 
00030 #include <gimp-print/mxml.h>
00031 #include "config.h"
00032 
00033 
00034 /*
00035  * 'stp_mxmlFindElement()' - Find the named element.
00036  *
00037  * The search is constrained by the name, attribute name, and value; any
00038  * NULL names or values are treated as wildcards, so different kinds of
00039  * searches can be implemented by looking for all elements of a given name
00040  * or all elements with a specific attribute. The descend argument determines
00041  * whether the search descends into child nodes; normally you will use
00042  * STP_MXML_DESCEND_FIRST for the initial search and STP_MXML_NO_DESCEND to find
00043  * additional direct descendents of the node. The top node argument
00044  * constrains the search to a particular node's children.
00045  */
00046 
00047 stp_mxml_node_t *                               /* O - Element node or NULL */
00048 stp_mxmlFindElement(stp_mxml_node_t *node,      /* I - Current node */
00049                 stp_mxml_node_t *top,   /* I - Top node */
00050                 const char  *name,      /* I - Element name or NULL for any */
00051                 const char  *attr,      /* I - Attribute name, or NULL for none */
00052                 const char  *value,     /* I - Attribute value, or NULL for any */
00053                 int         descend)    /* I - Descend into tree - STP_MXML_DESCEND, STP_MXML_NO_DESCEND, or STP_MXML_DESCEND_FIRST */
00054 {
00055   const char    *temp;                  /* Current attribute value */
00056 
00057 
00058  /*
00059   * Range check input...
00060   */
00061 
00062   if (!node || !top || (!attr && value))
00063     return (NULL);
00064 
00065  /*
00066   * Start with the next node...
00067   */
00068 
00069   node = stp_mxmlWalkNext(node, top, descend);
00070 
00071  /*
00072   * Loop until we find a matching element...
00073   */
00074 
00075   while (node != NULL)
00076   {
00077    /*
00078     * See if this node matches...
00079     */
00080 
00081     if (node->type == STP_MXML_ELEMENT &&
00082         node->value.element.name &&
00083         (!name || !strcmp(node->value.element.name, name)))
00084     {
00085      /*
00086       * See if we need to check for an attribute...
00087       */
00088 
00089       if (!attr)
00090         return (node);                  /* No attribute search, return it... */
00091 
00092      /*
00093       * Check for the attribute...
00094       */
00095 
00096       if ((temp = stp_mxmlElementGetAttr(node, attr)) != NULL)
00097       {
00098        /*
00099         * OK, we have the attribute, does it match?
00100         */
00101 
00102         if (!value || !strcmp(value, temp))
00103           return (node);                /* Yes, return it... */
00104       }
00105     }
00106 
00107    /*
00108     * No match, move on to the next node...
00109     */
00110 
00111     if (descend == STP_MXML_DESCEND)
00112       node = stp_mxmlWalkNext(node, top, STP_MXML_DESCEND);
00113     else
00114       node = node->next;
00115   }
00116 
00117   return (NULL);
00118 }
00119 
00120 
00121 /*
00122  * 'stp_mxmlWalkNext()' - Walk to the next logical node in the tree.
00123  *
00124  * The descend argument controls whether the first child is considered
00125  * to be the next node. The top node argument constrains the walk to
00126  * the node's children.
00127  */
00128 
00129 stp_mxml_node_t *                               /* O - Next node or NULL */
00130 stp_mxmlWalkNext(stp_mxml_node_t *node,         /* I - Current node */
00131              stp_mxml_node_t *top,              /* I - Top node */
00132              int         descend)       /* I - Descend into tree - STP_MXML_DESCEND, STP_MXML_NO_DESCEND, or STP_MXML_DESCEND_FIRST */
00133 {
00134   if (!node)
00135     return (NULL);
00136   else if (node->child && descend)
00137     return (node->child);
00138   else if (node->next)
00139     return (node->next);
00140   else if (node->parent && node->parent != top)
00141   {
00142     node = node->parent;
00143 
00144     while (!node->next)
00145       if (node->parent == top || !node->parent)
00146         return (NULL);
00147       else
00148         node = node->parent;
00149 
00150     return (node->next);
00151   }
00152   else
00153     return (NULL);
00154 }
00155 
00156 
00157 /*
00158  * 'stp_mxmlWalkPrev()' - Walk to the previous logical node in the tree.
00159  *
00160  * The descend argument controls whether the previous node's last child
00161  * is considered to be the previous node. The top node argument constrains
00162  * the walk to the node's children.
00163  */
00164 
00165 stp_mxml_node_t *                               /* O - Previous node or NULL */
00166 stp_mxmlWalkPrev(stp_mxml_node_t *node,         /* I - Current node */
00167              stp_mxml_node_t *top,              /* I - Top node */
00168              int         descend)       /* I - Descend into tree - STP_MXML_DESCEND, STP_MXML_NO_DESCEND, or STP_MXML_DESCEND_FIRST */
00169 {
00170   if (!node)
00171     return (NULL);
00172   else if (node->prev)
00173   {
00174     if (node->prev->last_child && descend)
00175     {
00176      /*
00177       * Find the last child under the previous node...
00178       */
00179 
00180       node = node->prev->last_child;
00181 
00182       while (node->last_child)
00183         node = node->last_child;
00184 
00185       return (node);
00186     }
00187     else
00188       return (node->prev);
00189   }
00190   else if (node->parent != top)
00191     return (node->parent);
00192   else
00193     return (NULL);
00194 }
00195 
00196 
00197 /*
00198  * End of "$Id: mxml-search.c,v 1.6 2004/04/27 23:23:47 rlk Exp $".
00199  */

Generated on Wed May 12 20:21:29 2004 for libgimpprint API Reference by doxygen1.2.17