Process Hacker
mxml-search.c
Go to the documentation of this file.
1 /*
2  * "$Id: mxml-search.c 297 2007-09-09 07:16:52Z mike $"
3  *
4  * Search/navigation functions for Mini-XML, a small XML-like file
5  * parsing library.
6  *
7  * Copyright 2003-2007 by Michael Sweet.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * Contents:
20  *
21  * mxmlFindElement() - Find the named element.
22  * mxmlWalkNext() - Walk to the next logical node in the tree.
23  * mxmlWalkPrev() - Walk to the previous logical node in the tree.
24  */
25 
26 /*
27  * Include necessary headers...
28  */
29 
30 #include "config.h"
31 #include "mxml.h"
32 
33 
34 /*
35  * 'mxmlFindElement()' - Find the named element.
36  *
37  * The search is constrained by the name, attribute name, and value; any
38  * NULL names or values are treated as wildcards, so different kinds of
39  * searches can be implemented by looking for all elements of a given name
40  * or all elements with a specific attribute. The descend argument determines
41  * whether the search descends into child nodes; normally you will use
42  * MXML_DESCEND_FIRST for the initial search and MXML_NO_DESCEND to find
43  * additional direct descendents of the node. The top node argument
44  * constrains the search to a particular node's children.
45  */
46 
47 mxml_node_t * /* O - Element node or NULL */
48 mxmlFindElement(mxml_node_t *node, /* I - Current node */
49  mxml_node_t *top, /* I - Top node */
50  const char *name, /* I - Element name or NULL for any */
51  const char *attr, /* I - Attribute name, or NULL for none */
52  const char *value, /* I - Attribute value, or NULL for any */
53  int descend) /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */
54 {
55  const char *temp; /* Current attribute value */
56 
57 
58  /*
59  * Range check input...
60  */
61 
62  if (!node || !top || (!attr && value))
63  return (NULL);
64 
65  /*
66  * Start with the next node...
67  */
68 
69  node = mxmlWalkNext(node, top, descend);
70 
71  /*
72  * Loop until we find a matching element...
73  */
74 
75  while (node != NULL)
76  {
77  /*
78  * See if this node matches...
79  */
80 
81  if (node->type == MXML_ELEMENT &&
82  node->value.element.name &&
83  (!name || !strcmp(node->value.element.name, name)))
84  {
85  /*
86  * See if we need to check for an attribute...
87  */
88 
89  if (!attr)
90  return (node); /* No attribute search, return it... */
91 
92  /*
93  * Check for the attribute...
94  */
95 
96  if ((temp = mxmlElementGetAttr(node, attr)) != NULL)
97  {
98  /*
99  * OK, we have the attribute, does it match?
100  */
101 
102  if (!value || !strcmp(value, temp))
103  return (node); /* Yes, return it... */
104  }
105  }
106 
107  /*
108  * No match, move on to the next node...
109  */
110 
111  if (descend == MXML_DESCEND)
112  node = mxmlWalkNext(node, top, MXML_DESCEND);
113  else
114  node = node->next;
115  }
116 
117  return (NULL);
118 }
119 
120 
121 /*
122  * 'mxmlWalkNext()' - Walk to the next logical node in the tree.
123  *
124  * The descend argument controls whether the first child is considered
125  * to be the next node. The top node argument constrains the walk to
126  * the node's children.
127  */
128 
129 mxml_node_t * /* O - Next node or NULL */
130 mxmlWalkNext(mxml_node_t *node, /* I - Current node */
131  mxml_node_t *top, /* I - Top node */
132  int descend) /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */
133 {
134  if (!node)
135  return (NULL);
136  else if (node->child && descend)
137  return (node->child);
138  else if (node == top)
139  return (NULL);
140  else if (node->next)
141  return (node->next);
142  else if (node->parent && node->parent != top)
143  {
144  node = node->parent;
145 
146  while (!node->next)
147  if (node->parent == top || !node->parent)
148  return (NULL);
149  else
150  node = node->parent;
151 
152  return (node->next);
153  }
154  else
155  return (NULL);
156 }
157 
158 
159 /*
160  * 'mxmlWalkPrev()' - Walk to the previous logical node in the tree.
161  *
162  * The descend argument controls whether the previous node's last child
163  * is considered to be the previous node. The top node argument constrains
164  * the walk to the node's children.
165  */
166 
167 mxml_node_t * /* O - Previous node or NULL */
168 mxmlWalkPrev(mxml_node_t *node, /* I - Current node */
169  mxml_node_t *top, /* I - Top node */
170  int descend) /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */
171 {
172  if (!node || node == top)
173  return (NULL);
174  else if (node->prev)
175  {
176  if (node->prev->last_child && descend)
177  {
178  /*
179  * Find the last child under the previous node...
180  */
181 
182  node = node->prev->last_child;
183 
184  while (node->last_child)
185  node = node->last_child;
186 
187  return (node);
188  }
189  else
190  return (node->prev);
191  }
192  else if (node->parent != top)
193  return (node->parent);
194  else
195  return (NULL);
196 }
197 
198 
199 /*
200  * End of "$Id: mxml-search.c 297 2007-09-09 07:16:52Z mike $".
201  */