gwenhywfar  5.10.1
tree.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Fri Jan 02 2009
3  copyright : (C) 2009 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library 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 GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #define DISABLE_DEBUGLOG
31 
32 #include "tree_p.h"
33 #include <gwenhywfar/misc.h>
34 #include <gwenhywfar/debug.h>
35 
36 
37 
38 
40 {
41  GWEN_TREE *l;
42 
44  return l;
45 }
46 
47 
49 {
50  if (l) {
52  }
53 }
54 
55 
56 
58 {
59  assert(l);
60  return l->count;
61 }
62 
63 
64 
66 {
67  assert(l);
68  assert(el);
69  if (el->treePtr) {
70  /* element is already part of another list */
71  DBG_ERROR(GWEN_LOGDOMAIN, "Element is already part of a list");
72  assert(0);
73  }
74  else {
75  if (l->firstElement==0)
76  l->firstElement=el;
77 
78  el->prevElement=l->lastElement;
79  if (l->lastElement)
80  l->lastElement->nextElement=el;
81  l->lastElement=el;
82 
83  el->treePtr=l;
84  el->parent=NULL;
85  l->count++;
86  }
87 }
88 
89 
90 
92 {
94 
95  assert(dest);
96  assert(l);
97 
98  while ((el=l->firstElement)) {
99  GWEN_Tree_Del(el);
100  GWEN_Tree_Add(dest, el);
101  }
102 }
103 
104 
105 
107 {
108  assert(l);
109  assert(el);
110  if (el->treePtr) {
111  /* element is already part of another list */
112  DBG_ERROR(GWEN_LOGDOMAIN, "Element is already part of a list");
113  }
114  else {
115  el->nextElement=l->firstElement;
116  l->firstElement=el;
117 
118  if (l->lastElement==0)
119  l->lastElement=el;
120 
121  el->treePtr=l;
122  el->parent=NULL;
123  l->count++;
124  }
125 }
126 
127 
128 
130 {
131  GWEN_TREE *l;
132 
133  l=el->treePtr;
134 
135  if (l==0) {
136  /* not part of any list */
137  DBG_ERROR(GWEN_LOGDOMAIN, "Element is not part of any list");
138  }
139  else {
140  /* unlink from previous */
141  if (el->prevElement)
142  el->prevElement->nextElement=el->nextElement;
143 
144  /* unlink from next */
145  if (el->nextElement)
146  el->nextElement->prevElement=el->prevElement;
147 
148  /* unlink from list */
149  if (l->firstElement==el)
150  l->firstElement=el->nextElement;
151  if (l->lastElement==el)
152  l->lastElement=el->prevElement;
153  l->count--;
154 
155  /* unlink from parent */
156  if (el->parent) {
157  if (el->parent->firstChild==el)
158  el->parent->firstChild=el->nextElement;
159  if (el->parent->lastChild==el)
160  el->parent->lastChild=el->prevElement;
161  el->parent->count--;
162  }
163 
164  el->nextElement=NULL;
165  el->prevElement=NULL;
166  el->parent=NULL;
167  el->treePtr=NULL;
168  }
169 }
170 
171 
172 
173 void GWEN_Tree_Replace(GWEN_TREE_ELEMENT *elToReplace, GWEN_TREE_ELEMENT *elReplacement)
174 {
175  GWEN_TREE *l;
176 
177  l=elToReplace->treePtr;
178 
179  if (l==0) {
180  /* not part of any list */
181  DBG_ERROR(GWEN_LOGDOMAIN, "Element is not part of any tree");
182  assert(0);
183  }
184  else {
185  if (elReplacement->treePtr!=NULL) {
186  /* replacement already is a part of another tree */
187  DBG_ERROR(GWEN_LOGDOMAIN, "Replacement element already is part of a tree");
188  assert(0);
189  }
190  else {
191  elReplacement->nextElement=NULL;
192  elReplacement->prevElement=NULL;
193  elReplacement->parent=NULL;
194 
195  elReplacement->treePtr=elToReplace->treePtr;
196 
197  /* relink with previous */
198  if (elToReplace->prevElement)
199  elToReplace->prevElement->nextElement=elReplacement;
200 
201  /* relink with next */
202  if (elToReplace->nextElement)
203  elToReplace->nextElement->prevElement=elReplacement;
204 
205  /* relink with tree */
206  if (l->firstElement==elToReplace)
207  l->firstElement=elReplacement;
208  if (l->lastElement==elToReplace)
209  l->lastElement=elReplacement;
210  l->count-=(elToReplace->count)+1;
211  l->count+=(elReplacement->count)+1;
212 
213  /* relink with parent */
214  if (elToReplace->parent) {
215  elReplacement->parent=elToReplace->parent;
216  if (elToReplace->parent->firstChild==elToReplace)
217  elToReplace->parent->firstChild=elToReplace;
218  if (elToReplace->parent->lastChild==elToReplace)
219  elToReplace->parent->lastChild=elToReplace;
220  elToReplace->count-=(elToReplace->count)+1;
221  elToReplace->count+=(elReplacement->count)+1;
222  }
223 
224  elToReplace->nextElement=NULL;
225  elToReplace->prevElement=NULL;
226  elToReplace->parent=NULL;
227  elToReplace->treePtr=NULL;
228  }
229  }
230 }
231 
232 
233 
235 {
236  if (el->treePtr) {
237  /* element is already part of another tree */
238  DBG_ERROR(GWEN_LOGDOMAIN, "Element is already part of a tree");
239  assert(0);
240  }
241  else {
242  if (where->firstChild==0)
243  where->firstChild=el;
244 
245  el->prevElement=where->lastChild;
246  if (where->lastChild)
247  where->lastChild->nextElement=el;
248  where->lastChild=el;
249 
250  el->parent=where;
251 
252  el->treePtr=where->treePtr;
253  el->treePtr->count++;
254  where->count++;
255  }
256 }
257 
258 
259 
261 {
262  if (el->treePtr) {
263  /* element is already part of another list */
264  DBG_ERROR(GWEN_LOGDOMAIN, "Element is already part of a tree");
265  assert(0);
266  }
267  else {
268  el->nextElement=where->firstChild;
269  where->firstChild=el;
270 
271  if (where->lastChild==NULL)
272  where->lastChild=el;
273 
274  el->parent=where;
275 
276  el->treePtr=where->treePtr;
277  el->treePtr->count++;
278  where->count++;
279  }
280 }
281 
282 
283 
285 {
286  if (l->firstElement)
287  return l->firstElement->data;
288  return 0;
289 }
290 
291 
292 
294 {
295  if (l->lastElement)
296  return l->lastElement->data;
297  return 0;
298 }
299 
300 
301 
302 
303 
305 {
306  GWEN_TREE_ELEMENT *el;
307 
309  el->data=d;
310 
311  return el;
312 }
313 
314 
315 
317 {
318  if (el) {
319  if (el->treePtr)
320  GWEN_Tree_Del(el);
321  if (el->firstChild) {
322  DBG_ERROR(GWEN_LOGDOMAIN, "Tree element still has children");
323  assert(0);
324  }
325  GWEN_FREE_OBJECT(el);
326  }
327 }
328 
329 
330 
332 {
333  if (el->prevElement)
334  return el->prevElement->data;
335  return 0;
336 }
337 
338 
339 
341 {
342  if (el->nextElement)
343  return el->nextElement->data;
344  return 0;
345 }
346 
347 
348 
350 {
351  if (el->firstChild) /* look down */
352  return el->firstChild->data;
353  else if (el->nextElement) /* look right */
354  return el->nextElement->data;
355  else {
356  /* look for a parent which has a right neighbour */
357  while (el && el->parent) {
358  if (el->parent->nextElement) /* look right of parent */
359  return el->parent->nextElement->data;
360  /* parent has no right neighbour, consult its parent */
361  el=el->parent;
362  }
363  }
364 
365  return NULL;
366 }
367 
368 
369 
371 {
372  if (el->firstChild)
373  return el->firstChild->data;
374  return NULL;
375 }
376 
377 
378 
380 {
381  if (el->lastChild)
382  return el->lastChild->data;
383  return NULL;
384 }
385 
386 
387 
389 {
390  if (el->parent)
391  return el->parent->data;
392  return NULL;
393 }
394 
395 
396 
398 {
399  assert(el);
400  return el->count;
401 }
402 
403 
404 
405 
406 
407 
408 
409 
void * GWEN_TreeElement_GetLastChild(const GWEN_TREE_ELEMENT *el)
Definition: tree.c:379
struct GWEN_TREE_ELEMENT GWEN_TREE_ELEMENT
Definition: tree.h:156
void * GWEN_Tree_GetFirst(const GWEN_TREE *l)
Definition: tree.c:284
void * GWEN_TreeElement_GetParent(const GWEN_TREE_ELEMENT *el)
Definition: tree.c:388
void GWEN_Tree_AddList(GWEN_TREE *dest, GWEN_TREE *l)
Definition: tree.c:91
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
int GWEN_Tree_GetCount(const GWEN_TREE *l)
Definition: tree.c:57
void GWEN_Tree_free(GWEN_TREE *l)
Definition: tree.c:48
void * GWEN_TreeElement_GetFirstChild(const GWEN_TREE_ELEMENT *el)
Definition: tree.c:370
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void GWEN_Tree_InsertChild(GWEN_TREE_ELEMENT *where, GWEN_TREE_ELEMENT *el)
Definition: tree.c:260
void * GWEN_Tree_GetLast(const GWEN_TREE *l)
Definition: tree.c:293
void GWEN_Tree_Del(GWEN_TREE_ELEMENT *el)
Definition: tree.c:129
void * GWEN_TreeElement_GetNext(const GWEN_TREE_ELEMENT *el)
Definition: tree.c:340
void * GWEN_TreeElement_GetPrevious(const GWEN_TREE_ELEMENT *el)
Definition: tree.c:331
GWEN_TREE_ELEMENT * GWEN_TreeElement_new(void *d)
Definition: tree.c:304
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
void GWEN_Tree_Replace(GWEN_TREE_ELEMENT *elToReplace, GWEN_TREE_ELEMENT *elReplacement)
Definition: tree.c:173
void GWEN_Tree_AddChild(GWEN_TREE_ELEMENT *where, GWEN_TREE_ELEMENT *el)
Definition: tree.c:234
uint32_t GWEN_TreeElement_GetChildrenCount(const GWEN_TREE_ELEMENT *el)
Definition: tree.c:397
GWEN_TREE * GWEN_Tree_new(void)
Definition: tree.c:39
void GWEN_Tree_Insert(GWEN_TREE *l, GWEN_TREE_ELEMENT *el)
Definition: tree.c:106
struct GWEN_TREE GWEN_TREE
Definition: tree.h:155
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
void * GWEN_TreeElement_GetBelow(const GWEN_TREE_ELEMENT *el)
Definition: tree.c:349
void GWEN_TreeElement_free(GWEN_TREE_ELEMENT *el)
Definition: tree.c:316
void GWEN_Tree_Add(GWEN_TREE *l, GWEN_TREE_ELEMENT *el)
Definition: tree.c:65