1 /**********************************************************************
2 linkedlist.c
3 **********************************************************************
4
5 linkedlist - Linked list implementation (singly- and doubly- linked).
6 Copyright ©2000-2004, Stewart Adcock <stewart@linux-domain.com>
7 All rights reserved.
8
9 The latest version of this program should be available at:
10 http://gaul.sourceforge.net/
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version. Alternatively, if your project
16 is incompatible with the GPL, I will probably agree to requests
17 for permission to use the terms of any other license.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY WHATSOEVER.
21
22 A full copy of the GNU General Public License should be in the file
23 "COPYING" provided with this distribution; if not, see:
24 http://www.gnu.org/
25
26 **********************************************************************
27
28 Synopsis: Linked list implementations.
29
30 Single-linked list functions are named slink_*().
31 Double-linked list functions are named dlink_*().
32
33 MP-safe.
34
35 For OpenMP code, USE_OPENMP must be defined and
36 linkedlist_init_openmp() must be called prior to any
37 other function.
38
39 To do: Add sorting functions.
40 Functions for inserting/appending lists etc. (i.e. slink_append_list() )
41 Converting slists to dlists, and visa versa.
42 Equivalent of avltree_destroy().
43 ?link_unlink_data() etc like delete functions, except without freeing the element(s).
44
45 To compile: gcc linkedlist.c -DLINKEDLIST_COMPILE_MAIN -g -L . -lstuff
46
47 **********************************************************************/
48
49 #include "gaul/linkedlist.h"
50
51 #ifdef LINKEDLIST_COMPILE_MAIN
52 #include <stdio.h>
53 #include <string.h>
54 #endif
55
56
57 THREAD_LOCK_DEFINE_STATIC(slist_chunk_lock);
58 THREAD_LOCK_DEFINE_STATIC(dlist_chunk_lock);
59 static MemChunk *slist_chunk = NULL;
60 static MemChunk *dlist_chunk = NULL;
61
62 #if USE_OPENMP == 1
63 static boolean linkedlist_openmp_initialised = FALSE;
64 #endif
65
66 /*
67 * This function must be called before any other functions is OpenMP
68 * code is to be used. Can be safely called when OpenMP code is not
69 * being used, and can be safely called more than once.
70 */
linkedlist_init_openmp(void)71 void linkedlist_init_openmp(void)
72 {
73
74 #if USE_OPENMP == 1
75 if (linkedlist_openmp_initialised == FALSE)
76 {
77 omp_init_lock(&slist_chunk_lock);
78 omp_init_lock(&dlist_chunk_lock);
79 linkedlist_openmp_initialised = TRUE;
80 }
81 #endif
82
83 return;
84 }
85
86
slink_new(void)87 SLList *slink_new(void)
88 {
89 SLList *element;
90
91 THREAD_LOCK(slist_chunk_lock);
92 if (!slist_chunk)
93 slist_chunk = mem_chunk_new(sizeof(SLList), 512);
94
95 element = (SLList *)mem_chunk_alloc(slist_chunk);
96 THREAD_UNLOCK(slist_chunk_lock);
97
98 element->next = NULL;
99 element->data = NULL;
100
101 return element;
102 }
103
104
slink_free_all(SLList * list)105 void slink_free_all(SLList *list)
106 {
107 SLList *element;
108
109 THREAD_LOCK(slist_chunk_lock);
110 while (list)
111 {
112 element = list->next;
113 mem_chunk_free(slist_chunk, list);
114 list = element;
115 }
116
117 if (mem_chunk_isempty(slist_chunk))
118 {
119 mem_chunk_destroy(slist_chunk);
120 slist_chunk = NULL;
121 }
122 THREAD_UNLOCK(slist_chunk_lock);
123
124 return;
125 }
126
127
slink_free(SLList * list)128 void slink_free(SLList *list)
129 {
130 if (!list) return;
131
132 THREAD_LOCK(slist_chunk_lock);
133 mem_chunk_free(slist_chunk, list);
134
135 if (mem_chunk_isempty(slist_chunk))
136 {
137 mem_chunk_destroy(slist_chunk);
138 slist_chunk = NULL;
139 }
140 THREAD_UNLOCK(slist_chunk_lock);
141
142 return;
143 }
144
145
slink_append(SLList * list,vpointer data)146 SLList *slink_append(SLList *list, vpointer data)
147 {
148 SLList *new_element;
149 SLList *last;
150
151 new_element = slink_new();
152 new_element->data = data;
153
154 if (!list) return new_element;
155
156 last = slink_last(list);
157 last->next = new_element;
158
159 return list;
160 }
161
162
slink_prepend(SLList * list,vpointer data)163 SLList *slink_prepend(SLList *list, vpointer data)
164 {
165 SLList *new_element;
166
167 new_element = slink_new();
168 new_element->data = data;
169 new_element->next = list;
170
171 return new_element;
172 }
173
174
slink_insert_next(SLList * list,vpointer data)175 SLList *slink_insert_next(SLList *list, vpointer data)
176 {
177 SLList *new_element;
178 SLList *next;
179
180 new_element = slink_new();
181 new_element->data = data;
182
183 if (!list) return new_element;
184
185 next = list->next;
186 list->next = new_element;
187 new_element->next = next;
188
189 return list;
190 }
191
192
slink_insert_index(SLList * list,vpointer data,int index)193 SLList *slink_insert_index(SLList *list, vpointer data, int index)
194 {
195 SLList *prev_list;
196 SLList *this_list;
197 SLList *new_element;
198
199 new_element = slink_new();
200 new_element->data = data;
201
202 if (!list) return new_element;
203
204 prev_list = NULL;
205 this_list = list;
206
207 while ((index-- > 0) && this_list)
208 {
209 prev_list = this_list;
210 this_list = this_list->next;
211 }
212
213 if (!prev_list)
214 {
215 new_element->next = list;
216 return new_element;
217 }
218
219 new_element->next = prev_list->next;
220 prev_list->next = new_element;
221
222 return list;
223 }
224
225
slink_delete_data(SLList * list,vpointer data)226 SLList *slink_delete_data(SLList *list, vpointer data)
227 {
228 SLList *tmp = list;
229 SLList *prev = NULL;
230
231 while (tmp)
232 {
233 if (tmp->data == data)
234 {
235 if (prev) prev->next = tmp->next;
236 if (list == tmp) list = list->next;
237
238 slink_free(tmp);
239
240 return list;
241 }
242
243 prev = tmp;
244 tmp = tmp->next;
245 }
246
247 return list;
248 }
249
250
slink_delete_all_data(SLList * list,vpointer data)251 SLList *slink_delete_all_data(SLList *list, vpointer data)
252 {
253 SLList *tmp = list;
254 SLList *prev = NULL;
255
256 while (tmp)
257 {
258 if (tmp->data == data)
259 {
260 if (prev) prev->next = tmp->next;
261 if (list == tmp) list = list->next;
262
263 slink_free(tmp);
264 }
265 else
266 {
267 prev = tmp;
268 tmp = tmp->next;
269 }
270 }
271
272 return list;
273 }
274
275
slink_delete_link(SLList * list,SLList * link)276 SLList *slink_delete_link(SLList *list, SLList *link)
277 {
278 SLList *tmp = list;
279 SLList *prev = NULL;
280
281 while (tmp)
282 {
283 if (tmp == link)
284 {
285 if (prev) prev->next = tmp->next;
286 if (list == tmp) list = list->next;
287
288 slink_free(tmp);
289
290 return list;
291 }
292
293 prev = tmp;
294 tmp = tmp->next;
295 }
296
297 return list;
298 }
299
300
slink_clone(SLList * list)301 SLList *slink_clone(SLList *list)
302 {
303 SLList *new_element = NULL;
304 SLList *last;
305
306 if (!list) return NULL;
307
308 new_element = slink_new();
309 new_element->data = list->data;
310 last = new_element;
311 list = list->next;
312 while (list)
313 {
314 last->next = slink_new();
315 last = last->next;
316 last->data = list->data;
317 list = list->next;
318 }
319
320 return new_element;
321 }
322
323
slink_reverse(SLList * list)324 SLList *slink_reverse(SLList *list)
325 {
326 SLList *element;
327 SLList *prev = NULL;
328 SLList *last = NULL;
329
330 while (list)
331 {
332 last = list;
333 element = list->next;
334 list->next = prev;
335 prev = list;
336 list = element;
337 }
338
339 return last;
340 }
341
342
slink_nth(SLList * list,const int index)343 SLList *slink_nth(SLList *list, const int index)
344 {
345 int i=index;
346
347 while (i > 0 && list)
348 {
349 list = list->next;
350 i--;
351 }
352
353 return list;
354 }
355
356
slink_nth_data(SLList * list,const int index)357 vpointer slink_nth_data(SLList *list, const int index)
358 {
359 list = slink_nth(list, index);
360
361 return list?list->data:NULL;
362 }
363
364
slink_find(SLList * list,vpointer data)365 SLList *slink_find(SLList *list, vpointer data)
366 {
367 while (list && list->data != data) list = list->next;
368
369 return list;
370 }
371
372
slink_find_custom(SLList * list,vpointer data,LLCompareFunc func)373 SLList *slink_find_custom(SLList *list, vpointer data, LLCompareFunc func)
374 {
375 if (!func) die("Null pointer to LLCompareFunc passed.");
376
377 while (list && func(list->data, data)==FALSE)
378 list = list->next;
379
380 return list;
381 }
382
383
slink_index_link(SLList * list,SLList * link)384 int slink_index_link(SLList *list, SLList *link)
385 {
386 int i=0;
387
388 while (list)
389 {
390 if (list == link) return i;
391 i++;
392 list = list->next;
393 }
394
395 return -1;
396 }
397
398
slink_index_data(SLList * list,vpointer data)399 int slink_index_data(SLList *list, vpointer data)
400 {
401 int i=0;
402
403 while (list)
404 {
405 if (list->data == data) return i;
406 i++;
407 list = list->next;
408 }
409
410 return -1;
411 }
412
413
slink_last(SLList * list)414 SLList *slink_last(SLList *list)
415 {
416 if (!list) return NULL;
417
418 while (list->next) list = list->next;
419
420 return list;
421 }
422
423
slink_size(SLList * list)424 int slink_size(SLList *list)
425 {
426 int size=0;
427
428 while (list)
429 {
430 size++;
431 list = list->next;
432 }
433
434 return size;
435 }
436
437
slink_foreach(SLList * list,LLForeachFunc func,vpointer userdata)438 boolean slink_foreach(SLList *list, LLForeachFunc func, vpointer userdata)
439 {
440
441 if (!func) die("Null pointer to LLForeachFunc passed.");
442
443 while (list)
444 {
445 if ((*func)(list->data, userdata)) return TRUE;
446 list = list->next;
447 }
448
449 return FALSE;
450 }
451
452
slink_insert_sorted(SLList * list,vpointer data,LLCompareFunc func)453 SLList *slink_insert_sorted(SLList *list, vpointer data, LLCompareFunc func)
454 {
455 SLList *prev_list;
456 SLList *this_list;
457 SLList *new_element;
458
459 if (!func) die("Null pointer to LLCompareFunc passed.");
460
461 new_element = slink_new();
462 new_element->data = data;
463
464 if (!list) return new_element;
465
466 prev_list = NULL;
467 this_list = list;
468
469 while (this_list && func(this_list->data, data)<0)
470 {
471 prev_list = this_list;
472 this_list = this_list->next;
473 }
474
475 if (!prev_list)
476 {
477 new_element->next = list;
478 return new_element;
479 }
480
481 new_element->next = prev_list->next;
482 prev_list->next = new_element;
483
484 return list;
485 }
486
487
dlink_new(void)488 DLList *dlink_new(void)
489 {
490 DLList *element;
491
492 THREAD_LOCK(dlist_chunk_lock);
493 if (!dlist_chunk)
494 dlist_chunk = mem_chunk_new(sizeof(DLList), 512);
495
496 element = (DLList *)mem_chunk_alloc(dlist_chunk);
497 THREAD_UNLOCK(dlist_chunk_lock);
498
499 element->prev = NULL;
500 element->next = NULL;
501 element->data = NULL;
502
503 return element;
504 }
505
506
dlink_free_all(DLList * list)507 void dlink_free_all(DLList *list)
508 {
509 DLList *list2;
510 DLList *element;
511
512 if (!list) return;
513
514 list2 = list->prev;
515
516 THREAD_LOCK(dlist_chunk_lock);
517 while (list)
518 {
519 element = list->next;
520 mem_chunk_free(dlist_chunk, list);
521 list = element;
522 }
523
524 while (list2)
525 {
526 element = list2->prev;
527 mem_chunk_free(dlist_chunk, list2);
528 list2 = element;
529 }
530
531 if (mem_chunk_isempty(dlist_chunk))
532 {
533 mem_chunk_destroy(dlist_chunk);
534 dlist_chunk = NULL;
535 }
536 THREAD_UNLOCK(dlist_chunk_lock);
537
538 return;
539 }
540
541
dlink_free(DLList * list)542 void dlink_free(DLList *list)
543 {
544 if (!list) return;
545
546 THREAD_LOCK(dlist_chunk_lock);
547 mem_chunk_free(dlist_chunk, list);
548
549 if (mem_chunk_isempty(dlist_chunk))
550 {
551 mem_chunk_destroy(dlist_chunk);
552 dlist_chunk = NULL;
553 }
554 THREAD_UNLOCK(dlist_chunk_lock);
555
556 return;
557 }
558
559
dlink_append(DLList * list,vpointer data)560 DLList *dlink_append(DLList *list, vpointer data)
561 {
562 DLList *new_element;
563 DLList *last;
564
565 new_element = dlink_new();
566 new_element->data = data;
567
568 if (!list) return new_element;
569
570 last = dlink_last(list);
571 last->next = new_element;
572 new_element->prev = last;
573
574 return list;
575 }
576
577
dlink_prepend(DLList * list,vpointer data)578 DLList *dlink_prepend(DLList *list, vpointer data)
579 {
580 DLList *new_element;
581
582 new_element = dlink_new();
583 new_element->data = data;
584
585 if (!list) return new_element;
586
587 if (list->prev)
588 {
589 list->prev->next = new_element;
590 new_element->prev = list->prev;
591 }
592
593 list->prev = new_element;
594 new_element->next = list;
595
596 return new_element;
597 }
598
599
dlink_insert_next(DLList * list,vpointer data)600 DLList *dlink_insert_next(DLList *list, vpointer data)
601 {
602 DLList *new_element;
603 DLList *next;
604
605 new_element = dlink_new();
606 new_element->data = data;
607
608 if (!list) return new_element;
609
610 next = list->next;
611 if (next)
612 {
613 new_element->next = next;
614 next->prev = new_element;
615 }
616 list->next = new_element;
617 new_element->prev = list;
618
619 return list;
620 }
621
622
dlink_insert_prev(DLList * list,vpointer data)623 DLList *dlink_insert_prev(DLList *list, vpointer data)
624 {
625 DLList *new_element;
626 DLList *prev;
627
628 new_element = dlink_new();
629 new_element->data = data;
630
631 if (!list) return new_element;
632
633 prev = list->prev;
634 if (prev)
635 {
636 new_element->prev = prev;
637 prev->next = new_element;
638 }
639 list->prev = new_element;
640 new_element->next = list;
641
642 return new_element;
643 }
644
645
dlink_insert_index(DLList * list,vpointer data,int index)646 DLList *dlink_insert_index(DLList *list, vpointer data, int index)
647 {
648 DLList *new_element;
649 DLList *this_list;
650
651 if (index < 0)
652 {
653 /* FIXME: Prehaps I should insert from end of list instead? */
654 return dlink_append(list, data);
655 }
656 else if (index == 0)
657 {
658 return dlink_prepend(list, data);
659 }
660
661 this_list = dlink_nth(list, index);
662 if (!this_list)
663 return dlink_append(list, data);
664
665 new_element = dlink_new();
666 new_element->data = data;
667
668 if (this_list->prev)
669 {
670 this_list->prev->next = new_element;
671 new_element->prev = this_list->prev;
672 }
673 new_element->next = this_list;
674 this_list->prev = new_element;
675
676 if (this_list == list)
677 return new_element;
678 else
679 return list;
680 }
681
682
dlink_delete_all_data(DLList * list,vpointer data)683 DLList *dlink_delete_all_data(DLList *list, vpointer data)
684 {
685 DLList *tmp=list;
686
687 while (tmp)
688 {
689 if (tmp->data == data)
690 {
691 if (tmp->prev) tmp->prev->next = tmp->next;
692 if (tmp->next) tmp->next->prev = tmp->prev;
693
694 if (list == tmp) list = list->next;
695
696 dlink_free(tmp);
697 }
698
699 tmp = tmp->next;
700 }
701
702 return list;
703 }
704
705
dlink_delete_data(DLList * list,vpointer data)706 DLList *dlink_delete_data(DLList *list, vpointer data)
707 {
708 DLList *tmp=list;
709
710 while (tmp)
711 {
712 if (tmp->data == data)
713 {
714 if (tmp->prev) tmp->prev->next = tmp->next;
715 if (tmp->next) tmp->next->prev = tmp->prev;
716
717 if (list == tmp) list = list->next;
718
719 dlink_free(tmp);
720
721 return list;
722 }
723
724 tmp = tmp->next;
725 }
726
727 return list;
728 }
729
730
dlink_delete_link(DLList * list,DLList * link)731 DLList *dlink_delete_link(DLList *list, DLList *link)
732 {
733 if (!link) return NULL;
734
735 if (link->prev) link->prev->next = link->next;
736 if (link->next) link->next->prev = link->prev;
737
738 if (link == list) list = list->next;
739
740 link->prev = NULL;
741 link->next = NULL;
742
743 return list;
744 }
745
746
dlink_clone(DLList * list)747 DLList *dlink_clone(DLList *list)
748 {
749 DLList *new_element = NULL;
750 DLList *last;
751
752 if (!list) return NULL;
753
754 new_element = dlink_new();
755 new_element->data = list->data;
756 last = new_element;
757 list = list->next;
758 while (list)
759 {
760 last->next = dlink_new();
761 last->next->prev = last;
762 last = last->next;
763 last->data = list->data;
764 list = list->next;
765 }
766
767 return new_element;
768 }
769
770
dlink_reverse(DLList * list)771 DLList *dlink_reverse(DLList *list)
772 {
773 DLList *last=NULL;
774
775 while (list)
776 {
777 last = list;
778 list = last->next;
779 last->next = last->prev;
780 last->prev = list;
781 }
782
783 return last;
784 }
785
786
dlink_nth(DLList * list,const int index)787 DLList *dlink_nth(DLList *list, const int index)
788 {
789 int i=index;
790
791 while (i > 0 && list)
792 {
793 list = list->next;
794 i--;
795 }
796
797 return list;
798 }
799
800
dlink_pth(DLList * list,const int index)801 DLList *dlink_pth(DLList *list, const int index)
802 {
803 int i=index;
804
805 while (i > 0 && list)
806 {
807 list = list->prev;
808 i--;
809 }
810
811 return list;
812 }
813
814
dlink_nth_data(DLList * list,const int index)815 vpointer dlink_nth_data(DLList *list, const int index)
816 {
817 list = dlink_nth(list, index);
818
819 return list?list->data:NULL;
820 }
821
822
dlink_pth_data(DLList * list,const int index)823 vpointer dlink_pth_data(DLList *list, const int index)
824 {
825 list = dlink_pth(list, index);
826
827 return list?list->data:NULL;
828 }
829
830
dlink_find(DLList * list,vpointer data)831 DLList *dlink_find(DLList *list, vpointer data)
832 {
833 while (list && list->data != data)
834 list = list->next;
835
836 return list;
837 }
838
839
dlink_find_custom(DLList * list,vpointer data,LLCompareFunc func)840 DLList *dlink_find_custom(DLList *list, vpointer data, LLCompareFunc func)
841 {
842 if (!func) die("Null pointer to LLCompareFunc passed.");
843
844 while (list && func(list->data, data)==FALSE)
845 list = list->next;
846
847 return list;
848 }
849
850
dlink_index_link(DLList * list,DLList * link)851 int dlink_index_link(DLList *list, DLList *link)
852 {
853 int i=0;
854
855 while (list)
856 {
857 if (list == link) return i;
858 i++;
859 list = list->next;
860 }
861
862 return -1;
863 }
864
865
dlink_index_data(DLList * list,vpointer data)866 int dlink_index_data(DLList *list, vpointer data)
867 {
868 int i=0;
869
870 while (list)
871 {
872 if (list->data == data) return i;
873 i++;
874 list = list->next;
875 }
876
877 return -1;
878 }
879
880
dlink_last(DLList * list)881 DLList *dlink_last(DLList *list)
882 {
883 if (!list) return NULL;
884
885 while (list->next)
886 list = list->next;
887
888 return list;
889 }
890
891
dlink_first(DLList * list)892 DLList *dlink_first(DLList *list)
893 {
894 if (!list) return NULL;
895
896 while (list->prev) list = list->prev;
897
898 return list;
899 }
900
901
dlink_size(DLList * list)902 int dlink_size(DLList *list)
903 {
904 int size=0;
905
906 while (list)
907 {
908 size++;
909 list = list->next;
910 }
911
912 return size;
913 }
914
915
dlink_foreach(DLList * list,LLForeachFunc func,vpointer userdata)916 boolean dlink_foreach(DLList *list, LLForeachFunc func, vpointer userdata)
917 {
918
919 if (!func) die("Null pointer to LLForeachFunc passed.");
920
921 while (list)
922 {
923 if ((*func)(list->data, userdata)) return TRUE;
924 list = list->next;
925 }
926
927 return FALSE;
928 }
929
930
dlink_foreach_reverse(DLList * list,LLForeachFunc func,vpointer userdata)931 boolean dlink_foreach_reverse(DLList *list, LLForeachFunc func, vpointer userdata)
932 {
933
934 if (!func) die("Null pointer to LLForeachFunc passed.");
935
936 while (list)
937 {
938 if ((*func)(list->data, userdata)) return TRUE;
939 list = list->prev;
940 }
941
942 return FALSE;
943 }
944
945
dlink_insert_sorted(DLList * list,vpointer data,LLCompareFunc func)946 DLList *dlink_insert_sorted(DLList *list, vpointer data, LLCompareFunc func)
947 {
948 DLList *this_list;
949 DLList *prev_list;
950 DLList *new_element;
951
952 if (!func) die("Null pointer to LLCompareFunc passed.");
953
954 new_element = dlink_new();
955 new_element->data = data;
956
957 if (!list) return new_element;
958
959 this_list = list;
960 prev_list = NULL;
961
962 while (this_list && func(this_list->data, data)<0)
963 {
964 prev_list = this_list;
965 this_list = this_list->next;
966 }
967
968 new_element->prev = prev_list;
969 new_element->next = this_list;
970
971 if (this_list)
972 {
973 this_list->prev = new_element;
974 if (!prev_list) return new_element;
975 }
976
977 prev_list->next = new_element;
978
979 return list;
980 }
981
982
983 /*
984 * Testing:
985 */
986
linkedlist_diagnostics(void)987 void linkedlist_diagnostics(void)
988 {
989 printf("=== Linked list diagnostics ==================================\n");
990 printf("Version: %s\n", GA_VERSION_STRING);
991 printf("Build date: %s\n", GA_BUILD_DATE_STRING);
992 printf("Compilation machine characteristics:\n%s\n", GA_UNAME_STRING);
993
994 printf("--------------------------------------------------------------\n");
995 printf("structure sizeof\n");
996 printf("SLList %lu\n", (unsigned long) sizeof(SLList));
997 printf("DLList %lu\n", (unsigned long) sizeof(DLList));
998 printf("==============================================================\n");
999
1000 return;
1001 }
1002
1003
1004
test_list_print(vpointer a,vpointer b)1005 static boolean test_list_print(vpointer a, vpointer b)
1006 {
1007 int val = *((int*)a);
1008 printf("%d ", val);
1009 return FALSE;
1010 }
1011
1012
test_list_compare_one(constvpointer a,constvpointer b)1013 static int test_list_compare_one(constvpointer a, constvpointer b)
1014 {
1015 int one = *((const int*)a);
1016 int two = *((const int*)b);
1017 return one-two;
1018 }
1019
1020
test_list_compare_two(constvpointer a,constvpointer b)1021 static int test_list_compare_two(constvpointer a, constvpointer b)
1022 {
1023 int one = *((const int*)a);
1024 int two = *((const int*)b);
1025 return two-one;
1026 }
1027
1028
1029 /*
1030 * This function is 'borrowed' from glib.
1031 * This shows that the glib-emulation works.
1032 */
1033 #ifdef LINKEDLIST_COMPILE_MAIN
main(int argc,char ** argv)1034 int main(int argc, char **argv)
1035 #else
1036 boolean linkedlist_test(void)
1037 #endif
1038
1039 #ifdef LINKEDLIST_EMULATE_GLIST
1040 {
1041 DLList *list, *t;
1042 SLList *slist, *st;
1043 int sorteddata[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
1044 int data[10] = { 8, 9, 7, 0, 3, 2, 5, 1, 4, 6 };
1045 int i;
1046
1047 printf("Checking doubly linked lists...\n");
1048
1049 list = NULL;
1050 for (i = 0; i < 10; i++)
1051 list = g_list_append(list, &sorteddata[i]);
1052 list = g_list_reverse(list);
1053
1054 for (i = 0; i < 10; i++)
1055 {
1056 t = g_list_nth (list, i);
1057 if (*((int*) t->data) != (9 - i))
1058 printf("Regular insert failed\n");
1059 }
1060
1061 for (i = 0; i < 10; i++)
1062 if(g_list_position(list, g_list_nth (list, i)) != i)
1063 printf("g_list_position does not seem to be the inverse of g_list_nth\n");
1064
1065 g_list_free(list);
1066 list = NULL;
1067
1068 for (i = 0; i < 10; i++)
1069 list = g_list_insert_sorted(list, &data[i], test_list_compare_one);
1070
1071 g_list_foreach(list, test_list_print, NULL);
1072 printf("\n");
1073
1074 for (i = 0; i < 10; i++)
1075 {
1076 t = g_list_nth(list, i);
1077 if (*((int*) t->data) != i)
1078 printf("Sorted insert failed\n");
1079 }
1080
1081 g_list_free(list);
1082 list = NULL;
1083
1084 for (i = 0; i < 10; i++)
1085 list = g_list_insert_sorted(list, &data[i], test_list_compare_two);
1086
1087 g_list_foreach(list, test_list_print, NULL);
1088 printf("\n");
1089
1090 for (i = 0; i < 10; i++)
1091 {
1092 t = g_list_nth(list, i);
1093 if (*((int*) t->data) != (9 - i))
1094 printf("Sorted insert failed\n");
1095 }
1096
1097 g_list_free(list);
1098
1099 printf ("ok\n");
1100
1101 printf ("Checking singly linked lists...\n");
1102
1103 slist = NULL;
1104 for (i = 0; i < 10; i++)
1105 slist = g_slist_append(slist, &sorteddata[i]);
1106 slist = g_slist_reverse(slist);
1107
1108 for (i = 0; i < 10; i++)
1109 {
1110 st = g_slist_nth(slist, i);
1111 if (*((int*) st->data) != (9 - i))
1112 printf ("failed\n");
1113 }
1114
1115 g_slist_free(slist);
1116 slist = NULL;
1117
1118 for (i = 0; i < 10; i++)
1119 slist = g_slist_insert_sorted(slist, &data[i], test_list_compare_one);
1120
1121 g_slist_foreach(slist, test_list_print, NULL);
1122 printf("\n");
1123
1124 for (i = 0; i < 10; i++)
1125 {
1126 st = g_slist_nth (slist, i);
1127 if (*((int*) st->data) != i)
1128 printf ("Sorted insert failed\n");
1129 }
1130
1131 g_slist_free(slist);
1132 slist = NULL;
1133
1134 for (i = 0; i < 10; i++)
1135 slist = g_slist_insert_sorted(slist, &data[i], test_list_compare_two);
1136
1137 g_slist_foreach(slist, test_list_print, NULL);
1138 printf("\n");
1139
1140 for (i = 0; i < 10; i++)
1141 {
1142 st = g_slist_nth(slist, i);
1143 if (*((int*) st->data) != (9 - i))
1144 printf("Sorted insert failed\n");
1145 }
1146
1147 g_slist_free(slist);
1148
1149 printf("ok\n");
1150
1151 #else
1152 {
1153 DLList *list, *t;
1154 SLList *slist, *st;
1155 int sorteddata[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
1156 int data[10] = { 8, 9, 7, 0, 3, 2, 5, 1, 4, 6 };
1157 int i;
1158
1159 printf("Checking doubly linked lists...\n");
1160
1161 list = NULL;
1162 for (i = 0; i < 10; i++)
1163 list = dlink_append(list, &sorteddata[i]);
1164 list = dlink_reverse(list);
1165
1166 for (i = 0; i < 10; i++)
1167 {
1168 t = dlink_nth(list, i);
1169 if (*((int*) t->data) != (9 - i))
1170 printf("Regular insert failed\n");
1171 }
1172
1173 for (i = 0; i < 10; i++)
1174 if(dlink_index_link(list, dlink_nth(list, i)) != (int) i)
1175 printf("dlink_index_link does not seem to be the inverse of dlink_nth_data\n");
1176
1177 dlink_free_all(list);
1178 list = NULL;
1179
1180 for (i = 0; i < 10; i++)
1181 list = dlink_insert_sorted(list, &data[i], test_list_compare_one);
1182
1183 dlink_foreach(list, test_list_print, NULL);
1184 printf("\n");
1185
1186 for (i = 0; i < 10; i++)
1187 {
1188 t = dlink_nth(list, i);
1189 if (*((int*) t->data) != i)
1190 printf("Sorted insert failed\n");
1191 }
1192
1193 dlink_free_all(list);
1194 list = NULL;
1195
1196 for (i = 0; i < 10; i++)
1197 list = dlink_insert_sorted(list, &data[i], test_list_compare_two);
1198
1199 dlink_foreach(list, test_list_print, NULL);
1200 printf("\n");
1201
1202 for (i = 0; i < 10; i++)
1203 {
1204 t = dlink_nth(list, i);
1205 if (*((int*) t->data) != (9 - i))
1206 printf("Sorted insert failed\n");
1207 }
1208
1209 dlink_free_all(list);
1210
1211 printf ("ok\n");
1212
1213 printf ("Checking singly linked lists...\n");
1214
1215 slist = NULL;
1216 for (i = 0; i < 10; i++)
1217 slist = slink_append(slist, &sorteddata[i]);
1218 slist = slink_reverse(slist);
1219
1220 for (i = 0; i < 10; i++)
1221 {
1222 st = slink_nth(slist, i);
1223 if (*((int*) st->data) != (9 - i))
1224 printf ("failed\n");
1225 }
1226
1227 slink_free_all(slist);
1228 slist = NULL;
1229
1230 for (i = 0; i < 10; i++)
1231 slist = slink_insert_sorted(slist, &data[i], test_list_compare_one);
1232
1233 slink_foreach(slist, test_list_print, NULL);
1234 printf("\n");
1235
1236 for (i = 0; i < 10; i++)
1237 {
1238 st = slink_nth(slist, i);
1239 if (*((int*) st->data) != (int) i)
1240 printf ("Sorted insert failed\n");
1241 }
1242
1243 slink_free_all(slist);
1244 slist = NULL;
1245
1246 for (i = 0; i < 10; i++)
1247 slist = slink_insert_sorted(slist, &data[i], test_list_compare_two);
1248
1249 slink_foreach(slist, test_list_print, NULL);
1250 printf("\n");
1251
1252 for (i = 0; i < 10; i++)
1253 {
1254 st = slink_nth(slist, i);
1255 if (*((int*) st->data) != (9 - i))
1256 printf("Sorted insert failed\n");
1257 }
1258
1259 slink_free_all(slist);
1260
1261 printf("ok\n");
1262 #endif
1263
1264 #ifdef LINKEDLIST_COMPILE_MAIN
1265 exit(EXIT_SUCCESS);
1266 #else
1267 return TRUE;
1268 #endif
1269 }
1270
1271