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