ACSE 2.0.3
Advanced Compiler System for Education
Loading...
Searching...
No Matches
list.c
Go to the documentation of this file.
1
3
4#include <stdlib.h>
5#include <assert.h>
6#include "list.h"
7#include "errors.h"
8
9
10static t_listNode *newListNode(void *data)
11{
12 t_listNode *result = (t_listNode *)malloc(sizeof(t_listNode));
13 if (result == NULL)
14 fatalError("out of memory");
15 result->data = data;
16 result->prev = NULL;
17 result->next = NULL;
18 return result;
19}
20
21
22static t_listNode *listInsertNodeAfter(
23 t_listNode *list, t_listNode *listPos, t_listNode *newElem)
24{
25 if (listPos == NULL) {
26 // Add at the beginning of the list.
27 if (list != NULL) {
28 list->prev = newElem;
29 newElem->next = list;
30 }
31 return newElem;
32 }
33
34 newElem->next = listPos->next;
35 newElem->prev = listPos;
36 listPos->next = newElem;
37 if (newElem->next)
38 newElem->next->prev = newElem;
39
40 return list;
41}
42
43
44t_listNode *listInsertAfter(t_listNode *list, t_listNode *listPos, void *data)
45{
46 t_listNode *newElem = newListNode(data);
47 return listInsertNodeAfter(list, listPos, newElem);
48}
49
50
52{
53 if (list == NULL)
54 return NULL;
55 while (list->next != NULL)
56 list = list->next;
57 return list;
58}
59
60
61t_listNode *listInsertBefore(t_listNode *list, t_listNode *listPos, void *data)
62{
63 if (!listPos) {
64 // Add at the end of the list.
65 return listInsertAfter(list, listGetLastNode(list), data);
66 }
67 return listInsertAfter(list, listPos->prev, data);
68}
69
70
71t_listNode *listGetNodeAt(t_listNode *list, unsigned int position)
72{
73 if (list == NULL)
74 return NULL;
75
76 t_listNode *curNode = list;
77 unsigned int i = 0;
78 while ((curNode != NULL) && (i < position)) {
79 curNode = curNode->next;
80 i++;
81 }
82 return curNode;
83}
84
85
86t_listNode *listInsert(t_listNode *list, void *data, int pos)
87{
88 t_listNode *prev;
89
90 if (pos < 0) {
91 // Add last.
92 prev = NULL;
93 } else {
94 prev = listGetNodeAt(list, (unsigned int)pos);
95 }
96 return listInsertBefore(list, prev, data);
97}
98
99
101 t_listNode *list, void *data, int (*compareFunc)(void *a, void *b))
102{
103 t_listNode *prevNode = NULL;
104 t_listNode *curNode = list;
105 while (curNode != NULL) {
106 void *curData = curNode->data;
107
108 if (compareFunc(curData, data) >= 0)
109 return listInsertBefore(list, curNode, data);
110
111 prevNode = curNode;
112 curNode = curNode->next;
113 }
114
115 return listInsertAfter(list, prevNode, data);
116}
117
118
119static bool listDataDefaultCompareFunc(void *a, void *b)
120{
121 return a == b;
122}
123
125 t_listNode *list, void *data, bool (*compareFunc)(void *a, void *b))
126{
127 if (compareFunc == NULL)
128 compareFunc = listDataDefaultCompareFunc;
129 if (list == NULL)
130 return NULL;
131
132 t_listNode *curNode = list;
133 while (curNode != NULL) {
134 if (compareFunc(curNode->data, data))
135 break;
136 curNode = curNode->next;
137 }
138 return curNode;
139}
140
141
142t_listNode *listFind(t_listNode *list, void *data)
143{
144 return listFindWithCallback(list, data, NULL);
145}
146
147
149{
150 if (list == NULL || element == NULL)
151 return list;
152 assert(list->prev == NULL && "prev link of head of list not NULL");
153 if ((element->prev == NULL) && (element != list))
154 return list;
155
156 if (element->prev != NULL) {
157 // In the middle or at the end of the list.
158 element->prev->next = element->next;
159 if (element->next != NULL)
160 element->next->prev = element->prev;
161 } else {
162 // Head of the list.
163 assert(list == element && "element to remove not belonging to the list");
164
165 if (element->next != NULL) {
166 element->next->prev = NULL;
167
168 // Update the new head of the list.
169 list = element->next;
170 } else
171 list = NULL;
172 }
173
174 free(element);
175 // Return the new head of the list.
176 return list;
177}
178
179
181{
182 t_listNode *curNode = listFind(list, data);
183 if (curNode)
184 list = listRemoveNode(list, curNode);
185 return list;
186}
187
188
190{
191 while (list != NULL)
192 list = listRemoveNode(list, list);
193 return NULL;
194}
195
196
198{
199 if (list == NULL || element == NULL)
200 return -1;
201
202 int counter = 0;
203 while (list != NULL && list != element) {
204 counter++;
205 list = list->next;
206 }
207
208 if (list == NULL)
209 return -1;
210 return counter;
211}
212
213
215{
216 int counter = 0;
217 while (list != NULL) {
218 counter++;
219 list = list->next;
220 }
221 return counter;
222}
223
224
226{
227 t_listNode *curSrc = elements;
228 t_listNode *curDest = listGetLastNode(list);
229
230 while (curSrc != NULL) {
231 t_listNode *newNode = newListNode(curSrc->data);
232 list = listInsertNodeAfter(list, curDest, newNode);
233 curDest = newNode;
234 curSrc = curSrc->next;
235 }
236
237 return list;
238}
239
241{
242 return listAppendList(NULL, list);
243}
Error logging utilities.
void fatalError(const char *format,...)
Definition errors.c:32
struct t_listNode * next
Definition list.h:40
struct t_listNode * prev
Definition list.h:42
void * data
Pointer to the data associated to this node.
Definition list.h:44
t_listNode * listGetNodeAt(t_listNode *list, unsigned int position)
Definition list.c:71
t_listNode * listInsertBefore(t_listNode *list, t_listNode *listPos, void *data)
Definition list.c:61
t_listNode * listFindAndRemove(t_listNode *list, void *data)
Definition list.c:180
int listNodePosition(t_listNode *list, t_listNode *element)
Definition list.c:197
t_listNode * listInsertAfter(t_listNode *list, t_listNode *listPos, void *data)
Definition list.c:44
t_listNode * listClone(t_listNode *list)
Definition list.c:240
t_listNode * listInsert(t_listNode *list, void *data, int pos)
Definition list.c:86
t_listNode * listFind(t_listNode *list, void *data)
Definition list.c:142
int listLength(t_listNode *list)
Definition list.c:214
t_listNode * deleteList(t_listNode *list)
Definition list.c:189
t_listNode * listFindWithCallback(t_listNode *list, void *data, bool(*compareFunc)(void *a, void *b))
Definition list.c:124
t_listNode * listRemoveNode(t_listNode *list, t_listNode *element)
Definition list.c:148
t_listNode * listAppendList(t_listNode *list, t_listNode *elements)
Definition list.c:225
t_listNode * listInsertSorted(t_listNode *list, void *data, int(*compareFunc)(void *a, void *b))
Definition list.c:100
t_listNode * listGetLastNode(t_listNode *list)
Definition list.c:51
A node belonging a list.
Definition list.h:39
A double-linked list.