1 /*****************************************************************************/
2 /* Obj.c - A library for object list. */
3 /* */
4 /* Obj.c Copyright (c) 2000 Sakai Hiroaki. */
5 /* All Rights Reserved. */
6 /*****************************************************************************/
7
8 #include "ObjP.h"
9
10 /*****************************************************************************/
11 /* ObjListData ������� */
12 /*****************************************************************************/
13
ObjListData_Create(Obj obj,Obj (* destructor)())14 static ObjListData ObjListData_Create(Obj obj, Obj (*destructor)())
15 {
16 ObjListData list_data;
17
18 list_data = (ObjListData)malloc(sizeof(_ObjListData));
19
20 list_data->obj = obj;
21 list_data->destructor = destructor;
22
23 return (list_data);
24 }
25
ObjListData_Destroy(ObjListData list_data)26 static ObjListData ObjListData_Destroy(ObjListData list_data)
27 {
28 if (list_data == NULL) return (NULL);
29
30 /* �ǥ��ȥ饯���μ¹� */
31 if (list_data->destructor)
32 (*(list_data->destructor))(list_data->obj);
33
34 free(list_data);
35
36 return (NULL);
37 }
38
39 /*****************************************************************************/
40 /* ObjList �����֥������Ȥ���� */
41 /*****************************************************************************/
42
ObjListData_GetObj(ObjListData data)43 Obj ObjListData_GetObj(ObjListData data)
44 {
45 if (data == NULL) return (NULL);
46 return (data->obj);
47 }
48
ObjListData_GetPrev(ObjListData data)49 Obj ObjListData_GetPrev(ObjListData data)
50 {
51 if (data == NULL) return (NULL);
52 return (data->prev);
53 }
54
ObjListData_GetNext(ObjListData data)55 Obj ObjListData_GetNext(ObjListData data)
56 {
57 if (data == NULL) return (NULL);
58 return (data->next);
59 }
60
ObjList_GetLength(ObjList list)61 int ObjList_GetLength(ObjList list)
62 {
63 if (list == NULL) return (-1);
64 return (list->length);
65 }
66
ObjList_GetStartEdge(ObjList list)67 ObjListData ObjList_GetStartEdge(ObjList list)
68 {
69 if (list == NULL) return (NULL);
70 return (list->start_edge);
71 }
72
ObjList_GetEndEdge(ObjList list)73 ObjListData ObjList_GetEndEdge(ObjList list)
74 {
75 if (list == NULL) return (NULL);
76 return (list->end_edge);
77 }
78
ObjList_GetStart(ObjList list)79 ObjListData ObjList_GetStart(ObjList list)
80 {
81 if (list == NULL) return (NULL);
82 return (list->start_edge->next);
83 }
84
ObjList_GetEnd(ObjList list)85 ObjListData ObjList_GetEnd(ObjList list)
86 {
87 if (list == NULL) return (NULL);
88 return (list->end_edge->prev);
89 }
90
ObjList_IsEmpty(ObjList list)91 int ObjList_IsEmpty(ObjList list)
92 {
93 if (list == NULL) return (1);
94 return (list->start_edge->next == list->end_edge);
95 }
96
ObjList_IsStartEdge(ObjList list,ObjListData data)97 int ObjList_IsStartEdge(ObjList list, ObjListData data)
98 {
99 if (list == NULL) return (0);
100 return (data == list->start_edge);
101 }
102
ObjList_IsEndEdge(ObjList list,ObjListData data)103 int ObjList_IsEndEdge(ObjList list, ObjListData data)
104 {
105 if (list == NULL) return (0);
106 return (data == list->end_edge);
107 }
108
ObjList_IsStart(ObjList list,ObjListData data)109 int ObjList_IsStart(ObjList list, ObjListData data)
110 {
111 if (list == NULL) return (0);
112 return (data == list->start_edge->next);
113 }
114
ObjList_IsEnd(ObjList list,ObjListData data)115 int ObjList_IsEnd(ObjList list, ObjListData data)
116 {
117 if (list == NULL) return (0);
118 return (data == list->end_edge->prev);
119 }
120
ObjList_InsertObjToPrev(ObjList list,ObjListData current,Obj obj,Obj (* destructor)())121 ObjListData ObjList_InsertObjToPrev(ObjList list, ObjListData current,
122 Obj obj, Obj (*destructor)())
123 {
124 ObjListData data;
125
126 if (list == NULL) return (NULL);
127 if (ObjList_IsStartEdge(list, current)) return (NULL);
128
129 data = ObjListData_Create(obj, destructor);
130 if (data == NULL) return (NULL);
131
132 data->prev = current->prev;
133 data->next = current;
134 current->prev->next = data;
135 current->prev = data;
136 (list->length)++;
137
138 return (data);
139 }
140
ObjList_InsertObjToNext(ObjList list,ObjListData current,Obj obj,Obj (* destructor)())141 ObjListData ObjList_InsertObjToNext(ObjList list, ObjListData current,
142 Obj obj, Obj (*destructor)())
143 {
144 ObjListData data;
145
146 if (list == NULL) return (NULL);
147 if (ObjList_IsEndEdge(list, current)) return (NULL);
148
149 data = ObjListData_Create(obj, destructor);
150 if (data == NULL) return (NULL);
151
152 data->next = current->next;
153 data->prev = current;
154 current->next->prev = data;
155 current->next = data;
156 (list->length)++;
157
158 return (data);
159 }
160
ObjList_InsertObjToStart(ObjList list,Obj obj,Obj (* destructor)())161 ObjListData ObjList_InsertObjToStart(ObjList list, Obj obj,
162 Obj (*destructor)())
163 {
164 ObjListData current;
165 current = ObjList_GetStart(list);
166 return (ObjList_InsertObjToPrev(list, current, obj, destructor));
167 }
168
ObjList_InsertObjToEnd(ObjList list,Obj obj,Obj (* destructor)())169 ObjListData ObjList_InsertObjToEnd(ObjList list, Obj obj,
170 Obj (*destructor)())
171 {
172 ObjListData current;
173 current = ObjList_GetEnd(list);
174 return (ObjList_InsertObjToNext(list, current, obj, destructor));
175 }
176
ObjList_DeleteObjToPrev(ObjList list,ObjListData current)177 ObjListData ObjList_DeleteObjToPrev(ObjList list, ObjListData current)
178 {
179 ObjListData ret;
180
181 if (list == NULL) return (NULL);
182 if (ObjList_IsStartEdge(list, current) || ObjList_IsEndEdge(list, current))
183 return (NULL);
184
185 current->prev->next = current->next;
186 current->next->prev = current->prev;
187
188 ret = current->prev;
189 ObjListData_Destroy(current);
190 (list->length)--;
191
192 return (ret);
193 }
194
ObjList_DeleteObjToNext(ObjList list,ObjListData current)195 ObjListData ObjList_DeleteObjToNext(ObjList list, ObjListData current)
196 {
197 ObjListData ret;
198
199 if (list == NULL) return (NULL);
200 if (ObjList_IsStartEdge(list, current) || ObjList_IsEndEdge(list, current))
201 return (NULL);
202
203 current->prev->next = current->next;
204 current->next->prev = current->prev;
205
206 ret = current->next;
207 ObjListData_Destroy(current);
208 (list->length)--;
209
210 return (ret);
211 }
212
ObjList_DeleteObjFromStart(ObjList list)213 ObjListData ObjList_DeleteObjFromStart(ObjList list)
214 {
215 ObjListData current;
216 if (list == NULL) return (NULL);
217 current = ObjList_GetStart(list);
218 return (ObjList_DeleteObjToNext(list, current));
219 }
220
ObjList_DeleteObjFromEnd(ObjList list)221 ObjListData ObjList_DeleteObjFromEnd(ObjList list)
222 {
223 ObjListData current;
224 if (list == NULL) return (NULL);
225 current = ObjList_GetEnd(list);
226 return (ObjList_DeleteObjToPrev(list, current));
227 }
228
ObjList_MoveObjToPrev(ObjList list,ObjListData current,ObjListData to)229 ObjListData ObjList_MoveObjToPrev(ObjList list,
230 ObjListData current,
231 ObjListData to)
232 {
233 if (list == NULL) return (NULL);
234 return (ObjList_MoveObjToPrevOfOtherList(list, current, list, to));
235 }
236
ObjList_MoveObjToNext(ObjList list,ObjListData current,ObjListData to)237 ObjListData ObjList_MoveObjToNext(ObjList list,
238 ObjListData current,
239 ObjListData to)
240 {
241 if (list == NULL) return (NULL);
242 return (ObjList_MoveObjToNextOfOtherList(list, current, list, to));
243 }
244
ObjList_MoveObjToStart(ObjList list,ObjListData current)245 ObjListData ObjList_MoveObjToStart(ObjList list, ObjListData current)
246 {
247 if (list == NULL) return (NULL);
248 return (ObjList_MoveObjToStartOfOtherList(list, current, list));
249 }
250
ObjList_MoveObjToEnd(ObjList list,ObjListData current)251 ObjListData ObjList_MoveObjToEnd(ObjList list, ObjListData current)
252 {
253 if (list == NULL) return (NULL);
254 return (ObjList_MoveObjToEndOfOtherList(list, current, list));
255 }
256
ObjList_Create()257 ObjList ObjList_Create() /* ObjList �����֥������Ȥ�������� */
258 {
259 ObjList list;
260
261 list = (ObjList)malloc(sizeof(_ObjList));
262 if (list == NULL) return (NULL);
263
264 list->start_edge = ObjListData_Create(NULL, NULL);
265 list->end_edge = ObjListData_Create(NULL, NULL);
266 list->length = 0; /* ����¸�ߤ��Ƥ���ǡ����ο� */
267
268 list->start_edge->prev = NULL;
269 list->start_edge->next = list->end_edge;
270 list->end_edge->prev = list->start_edge;
271 list->end_edge->next = NULL;
272
273 return (list);
274 }
275
ObjList_Destroy(ObjList list)276 ObjList ObjList_Destroy(ObjList list) /* */
277 {
278 if (list == NULL) return (NULL);
279
280 while (!ObjList_IsEmpty(list))
281 ObjList_DeleteObjFromStart(list);
282
283 if (list->start_edge)
284 list->start_edge = ObjListData_Destroy(list->start_edge);
285 if (list->end_edge)
286 list->end_edge = ObjListData_Destroy(list->end_edge);
287
288 free(list);
289
290 return (NULL);
291 }
292
293 /*===========================================================================*/
294 /* ʣ���Υꥹ�ȴ֤Ǥ���� */
295 /*===========================================================================*/
296
ObjList_MoveObjToPrevOfOtherList(ObjList list,ObjListData current,ObjList to_list,ObjListData to)297 ObjListData ObjList_MoveObjToPrevOfOtherList(ObjList list, ObjListData current,
298 ObjList to_list, ObjListData to)
299 {
300 if (list == NULL) return (NULL);
301 if (to_list == NULL) return (NULL);
302 if (ObjList_IsStartEdge(list, current) || ObjList_IsEndEdge(list, current))
303 return (NULL);
304
305 if (ObjList_IsStartEdge(to_list, to)) return (NULL);
306 if ((list == to_list) && (current == to)) return (current);
307
308 current->prev->next = current->next;
309 current->next->prev = current->prev;
310
311 current->prev = to->prev;
312 current->next = to;
313 to->prev->next = current;
314 to->prev = current;
315
316 (list->length)--;
317 (to_list->length)++;
318
319 return (current);
320 }
321
ObjList_MoveObjToNextOfOtherList(ObjList list,ObjListData current,ObjList to_list,ObjListData to)322 ObjListData ObjList_MoveObjToNextOfOtherList(ObjList list, ObjListData current,
323 ObjList to_list, ObjListData to)
324 {
325 if (list == NULL) return (NULL);
326 if (ObjList_IsStartEdge(list, current) || ObjList_IsEndEdge(list, current))
327 return (NULL);
328
329 if (ObjList_IsEndEdge(to_list, to)) return (NULL);
330 if ((list == to_list) && (current == to)) return (current);
331
332 current->prev->next = current->next;
333 current->next->prev = current->prev;
334
335 current->next = to->next;
336 current->prev = to;
337 to->next->prev = current;
338 to->next = current;
339
340 (list->length)--;
341 (to_list->length)++;
342
343 return (current);
344 }
345
ObjList_MoveObjToStartOfOtherList(ObjList list,ObjListData current,ObjList to_list)346 ObjListData ObjList_MoveObjToStartOfOtherList(ObjList list,
347 ObjListData current,
348 ObjList to_list)
349 {
350 ObjListData to;
351 if (list == NULL) return (NULL);
352 if (to_list == NULL) return (NULL);
353 to = ObjList_GetStart(to_list);
354 return (ObjList_MoveObjToPrevOfOtherList(list, current, to_list, to));
355 }
356
ObjList_MoveObjToEndOfOtherList(ObjList list,ObjListData current,ObjList to_list)357 ObjListData ObjList_MoveObjToEndOfOtherList(ObjList list,
358 ObjListData current,
359 ObjList to_list)
360 {
361 ObjListData to;
362 if (list == NULL) return (NULL);
363 if (to_list == NULL) return (NULL);
364 to = ObjList_GetEnd(to_list);
365 return (ObjList_MoveObjToNextOfOtherList(list, current, to_list, to));
366 }
367
ObjList_Concatenate(ObjList list1,ObjList list2)368 ObjList ObjList_Concatenate(ObjList list1, ObjList list2)
369 {
370 ObjListData tmp;
371
372 if (list1 == NULL) {
373 list1 = list2;
374 return (list1);
375 }
376 if (list2 == NULL) return (list1);
377
378 list1->end_edge->prev->next = list2->start_edge->next;
379 list2->start_edge->next->prev = list1->end_edge->prev;
380
381 tmp = list1->end_edge;
382 list1->end_edge = list2->end_edge;
383 list2->end_edge = tmp;
384
385 list2->start_edge->next = list2->end_edge;
386 list2->end_edge->prev = list2->start_edge;
387
388 list1->length += list2->length;
389 list2->length = 0;
390
391 ObjList_Destroy(list2);
392
393 return (list1);
394 }
395
396 /* End of File. */
397