1 /***************************************************************************
2 begin : Thu Jul 04 2019
3 copyright : (C) 2019 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 "tree2_p.h"
33 #include <gwenhywfar/misc.h>
34 #include <gwenhywfar/debug.h>
35
36
37
38
GWEN_Tree2Element_new(void * d)39 GWEN_TREE2_ELEMENT *GWEN_Tree2Element_new(void *d)
40 {
41 GWEN_TREE2_ELEMENT *el;
42
43 GWEN_NEW_OBJECT(GWEN_TREE2_ELEMENT, el);
44 el->data=d;
45
46 return el;
47 }
48
49
50
GWEN_Tree2Element_free(GWEN_TREE2_ELEMENT * el)51 void GWEN_Tree2Element_free(GWEN_TREE2_ELEMENT *el)
52 {
53 if (el) {
54 if (el->firstChild) {
55 DBG_ERROR(GWEN_LOGDOMAIN, "Tree element still has children");
56 assert(0);
57 }
58 GWEN_FREE_OBJECT(el);
59 }
60 }
61
62
63
GWEN_Tree2_Unlink(GWEN_TREE2_ELEMENT * el)64 void GWEN_Tree2_Unlink(GWEN_TREE2_ELEMENT *el)
65 {
66
67 /* unlink from previous */
68 if (el->prevElement)
69 el->prevElement->nextElement=el->nextElement;
70
71 /* unlink from next */
72 if (el->nextElement)
73 el->nextElement->prevElement=el->prevElement;
74
75 /* unlink from parent */
76 if (el->parent) {
77 if (el->parent->firstChild==el)
78 el->parent->firstChild=el->nextElement;
79 if (el->parent->lastChild==el)
80 el->parent->lastChild=el->prevElement;
81 }
82
83 el->nextElement=NULL;
84 el->prevElement=NULL;
85 el->parent=NULL;
86 }
87
88
89
GWEN_Tree2_Replace(GWEN_TREE2_ELEMENT * elToReplace,GWEN_TREE2_ELEMENT * elReplacement)90 void GWEN_Tree2_Replace(GWEN_TREE2_ELEMENT *elToReplace, GWEN_TREE2_ELEMENT *elReplacement)
91 {
92 elReplacement->nextElement=NULL;
93 elReplacement->prevElement=NULL;
94 elReplacement->parent=NULL;
95
96 /* relink with previous */
97 if (elToReplace->prevElement)
98 elToReplace->prevElement->nextElement=elReplacement;
99 elReplacement->prevElement=elToReplace->prevElement;
100
101 /* relink with next */
102 if (elToReplace->nextElement)
103 elToReplace->nextElement->prevElement=elReplacement;
104 elReplacement->nextElement=elToReplace->nextElement;
105
106 /* relink with parent */
107 if (elToReplace->parent) {
108 elReplacement->parent=elToReplace->parent;
109 if (elToReplace->parent->firstChild==elToReplace)
110 elToReplace->parent->firstChild=elReplacement;
111 if (elToReplace->parent->lastChild==elToReplace)
112 elToReplace->parent->lastChild=elReplacement;
113 }
114
115 elToReplace->nextElement=NULL;
116 elToReplace->prevElement=NULL;
117 elToReplace->parent=NULL;
118 }
119
120
121
GWEN_Tree2_AddChild(GWEN_TREE2_ELEMENT * where,GWEN_TREE2_ELEMENT * el)122 void GWEN_Tree2_AddChild(GWEN_TREE2_ELEMENT *where, GWEN_TREE2_ELEMENT *el)
123 {
124 if (where->firstChild==NULL)
125 where->firstChild=el;
126
127 el->prevElement=where->lastChild;
128 if (where->lastChild)
129 where->lastChild->nextElement=el;
130 where->lastChild=el;
131
132 el->parent=where;
133 }
134
135
136
GWEN_Tree2_InsertChild(GWEN_TREE2_ELEMENT * where,GWEN_TREE2_ELEMENT * el)137 void GWEN_Tree2_InsertChild(GWEN_TREE2_ELEMENT *where, GWEN_TREE2_ELEMENT *el)
138 {
139 el->nextElement=where->firstChild;
140 where->firstChild=el;
141
142 if (where->lastChild==NULL)
143 where->lastChild=el;
144
145 el->parent=where;
146 }
147
148
149
GWEN_Tree2Element_GetPrevious(const GWEN_TREE2_ELEMENT * el)150 void *GWEN_Tree2Element_GetPrevious(const GWEN_TREE2_ELEMENT *el)
151 {
152 if (el->prevElement)
153 return el->prevElement->data;
154 return 0;
155 }
156
157
158
GWEN_Tree2Element_GetNext(const GWEN_TREE2_ELEMENT * el)159 void *GWEN_Tree2Element_GetNext(const GWEN_TREE2_ELEMENT *el)
160 {
161 if (el->nextElement)
162 return el->nextElement->data;
163 return 0;
164 }
165
166
167
GWEN_Tree2Element_GetBelow(const GWEN_TREE2_ELEMENT * el)168 void *GWEN_Tree2Element_GetBelow(const GWEN_TREE2_ELEMENT *el)
169 {
170 if (el->firstChild) /* look down */
171 return el->firstChild->data;
172 else if (el->nextElement) /* look right */
173 return el->nextElement->data;
174 else {
175 /* look for a parent which has a right neighbour */
176 while (el && el->parent) {
177 if (el->parent->nextElement) /* look right of parent */
178 return el->parent->nextElement->data;
179 /* parent has no right neighbour, consult its parent */
180 el=el->parent;
181 }
182 }
183
184 return NULL;
185 }
186
187
188
GWEN_Tree2Element_GetFirstChild(const GWEN_TREE2_ELEMENT * el)189 void *GWEN_Tree2Element_GetFirstChild(const GWEN_TREE2_ELEMENT *el)
190 {
191 if (el->firstChild)
192 return el->firstChild->data;
193 return NULL;
194 }
195
196
197
GWEN_Tree2Element_GetLastChild(const GWEN_TREE2_ELEMENT * el)198 void *GWEN_Tree2Element_GetLastChild(const GWEN_TREE2_ELEMENT *el)
199 {
200 if (el->lastChild)
201 return el->lastChild->data;
202 return NULL;
203 }
204
205
206
GWEN_Tree2Element_GetParent(const GWEN_TREE2_ELEMENT * el)207 void *GWEN_Tree2Element_GetParent(const GWEN_TREE2_ELEMENT *el)
208 {
209 if (el->parent)
210 return el->parent->data;
211 return NULL;
212 }
213
214
215
216