1 | /* $Id$ $Revision$ */ |
2 | /* vim:set shiftwidth=4 ts=8: */ |
3 | |
4 | /************************************************************************* |
5 | * Copyright (c) 2011 AT&T Intellectual Property |
6 | * All rights reserved. This program and the accompanying materials |
7 | * are made available under the terms of the Eclipse Public License v1.0 |
8 | * which accompanies this distribution, and is available at |
9 | * http://www.eclipse.org/legal/epl-v10.html |
10 | * |
11 | * Contributors: See CVS logs. Details at http://www.graphviz.org/ |
12 | *************************************************************************/ |
13 | |
14 | #include "LinkedList.h" |
15 | #include "memory.h" |
16 | #define MALLOC gmalloc |
17 | #define REALLOC grealloc |
18 | #define FREE free |
19 | #define MEMCPY memcpy |
20 | |
21 | |
22 | |
23 | SingleLinkedList SingleLinkedList_new(void *data){ |
24 | SingleLinkedList head; |
25 | head = GNEW(struct SingleLinkedList_struct); |
26 | head->data = data; |
27 | head->next = NULL; |
28 | return head; |
29 | } |
30 | |
31 | SingleLinkedList SingleLinkedList_new_int(int i){ |
32 | int *data; |
33 | data = malloc(sizeof(int)); |
34 | data[0] = i; |
35 | return SingleLinkedList_new((void*) data); |
36 | } |
37 | |
38 | |
39 | void SingleLinkedList_delete(SingleLinkedList head, void (*linklist_deallocator)(void*)){ |
40 | SingleLinkedList next; |
41 | |
42 | if (!head) return; |
43 | do { |
44 | next = head->next; |
45 | if (head->data) linklist_deallocator(head->data); |
46 | if (head) FREE(head); |
47 | head = next; |
48 | } while (head); |
49 | |
50 | } |
51 | |
52 | |
53 | SingleLinkedList SingleLinkedList_prepend(SingleLinkedList l, void *data){ |
54 | SingleLinkedList head = SingleLinkedList_new(data); |
55 | head->next = l; |
56 | return head; |
57 | } |
58 | |
59 | SingleLinkedList SingleLinkedList_prepend_int(SingleLinkedList l, int i){ |
60 | int *data; |
61 | data = malloc(sizeof(int)); |
62 | data[0] = i; |
63 | return SingleLinkedList_prepend(l, (void*) data); |
64 | } |
65 | |
66 | void* SingleLinkedList_get_data(SingleLinkedList l){ |
67 | return l->data; |
68 | } |
69 | |
70 | SingleLinkedList SingleLinkedList_get_next(SingleLinkedList l){ |
71 | return l->next; |
72 | } |
73 | void SingleLinkedList_print(SingleLinkedList head, void (*linkedlist_print)(void*)){ |
74 | |
75 | if (!head) return; |
76 | do { |
77 | if (head->data) linkedlist_print(head->data); |
78 | head = head->next; |
79 | } while (head); |
80 | |
81 | } |
82 | |
83 | |
84 | DoubleLinkedList DoubleLinkedList_new(void *data){ |
85 | DoubleLinkedList head; |
86 | head = GNEW(struct DoubleLinkedList_struct); |
87 | head->data = data; |
88 | head->next = NULL; |
89 | head->prev = NULL; |
90 | return head; |
91 | } |
92 | |
93 | void DoubleLinkedList_delete(DoubleLinkedList head, void (*linklist_deallocator)(void*)){ |
94 | DoubleLinkedList next; |
95 | |
96 | if (!head) return; |
97 | do { |
98 | next = head->next; |
99 | if (head->data) linklist_deallocator(head->data); |
100 | if (head) FREE(head); |
101 | head = next; |
102 | } while (head); |
103 | |
104 | } |
105 | |
106 | |
107 | DoubleLinkedList DoubleLinkedList_prepend(DoubleLinkedList l, void *data){ |
108 | DoubleLinkedList head = DoubleLinkedList_new(data); |
109 | if (l){ |
110 | head->next = l; |
111 | l->prev = head; |
112 | } |
113 | return head; |
114 | } |
115 | |
116 | void* DoubleLinkedList_get_data(DoubleLinkedList l){ |
117 | return l->data; |
118 | } |
119 | |
120 | DoubleLinkedList DoubleLinkedList_get_next(DoubleLinkedList l){ |
121 | return l->next; |
122 | } |
123 | |
124 | void DoubleLinkedList_print(DoubleLinkedList head, void (*linkedlist_print)(void*)){ |
125 | |
126 | if (!head) return; |
127 | do { |
128 | if (head->data) linkedlist_print(head->data); |
129 | head = head->next; |
130 | } while (head); |
131 | |
132 | } |
133 | |
134 | void DoubleLinkedList_delete_element(DoubleLinkedList l, void (*linklist_deallocator)(void*), DoubleLinkedList *head){ |
135 | /* delete an entry in the chain of linked list. If the head changes due to this (if l is the first element in the list), update */ |
136 | DoubleLinkedList next, prev; |
137 | |
138 | if (l){ |
139 | next = l->next; |
140 | prev = l->prev; |
141 | |
142 | if (l->data) linklist_deallocator(l->data); |
143 | FREE(l); |
144 | l = NULL; |
145 | |
146 | if (next) next->prev = prev; |
147 | if (prev) prev->next = next; |
148 | if (!prev) *head = next; |
149 | } |
150 | } |
151 | |
152 | |
153 | /* |
154 | static void print_int(void *d){ |
155 | int *i = (int*) d; |
156 | printf("%d\n",*i); |
157 | } |
158 | |
159 | main(){ |
160 | DoubleLinkedList l, ll; |
161 | |
162 | int i, *j; |
163 | |
164 | for (;;){ |
165 | j = malloc(sizeof(int)); |
166 | j[0] = -1; |
167 | l = DoubleLinkedList_new((void*) j); |
168 | |
169 | for (i = 0; i < 10; i++){ |
170 | j = malloc(sizeof(int)); |
171 | j[0] = i; |
172 | l = DoubleLinkedList_prepend(l, (void*) j); |
173 | |
174 | } |
175 | DoubleLinkedList_print(l, print_int); |
176 | |
177 | ll = DoubleLinkedList_get_next(l); |
178 | DoubleLinkedList_delete_element(ll, free, &l); |
179 | printf("after delete 8\n"); |
180 | DoubleLinkedList_print(l, print_int); |
181 | |
182 | DoubleLinkedList_delete_element(l, free, &l); |
183 | printf("after delete first elemnt\n"); |
184 | DoubleLinkedList_print(l, print_int); |
185 | |
186 | DoubleLinkedList_delete(l, free); |
187 | } |
188 | } |
189 | |
190 | */ |
191 | |