-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdlist.c
152 lines (120 loc) · 3.57 KB
/
dlist.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
* Author: Nicu Pavel <[email protected]>
* Copyright (c) 2021 Green Electronics LLC
* The MIT License (MIT)
*
*/
#include "dlist.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void dlist_init(DList *list, void (*destroy)(void *data), int max_size) {
list->size = 0;
list->max_size = max_size;
list->destroy = destroy;
list->head = NULL;
list->tail = NULL;
return;
}
void dlist_clear(DList *list) {
while (list->size > 0) {
if (dlist_remove(list, dlist_tail(list)) != 0) {
fprintf(stderr, " Error removing element at list size: %d\n",
list->size);
}
}
memset(list, 0, sizeof(DList));
return;
}
void dlist_resize(DList *list, unsigned int new_size) {
list->max_size = new_size;
if (new_size >= list->size || list->size == 0) return;
unsigned int to_remove = list->size - new_size;
while (list->size > 0 && to_remove > 0) {
if (dlist_remove(list, dlist_tail(list)) != 0) {
fprintf(stderr, " Error removing element at list size: %d\n",
list->size);
}
to_remove--;
}
}
int dlist_insert(DList *list, DListElmt *element, const void *data) {
DListElmt *new_element;
if ((new_element = (DListElmt *)malloc(sizeof(DListElmt))) == NULL)
return -1;
new_element->data = (void *)data;
if (element == NULL && dlist_size(list) != 0) {
element = list->head;
}
if (list->size == 0) {
list->head = new_element;
list->head->prev = NULL;
list->head->next = NULL;
list->tail = new_element;
} else {
if (element == list->head) {
new_element->prev = NULL;
new_element->next = element;
element->prev = new_element;
list->head = new_element;
} else {
new_element->prev = element;
new_element->next = element->next;
if (element->next == NULL)
list->tail = new_element;
else
element->next->prev = new_element;
element->next = new_element;
}
}
list->size++;
if (list->max_size > 0 && list->size > list->max_size) {
//fprintf(stdout, "List over specified size: %d\n", list->max_size);
// New Element is tail remove head, otherwise remove tail
if (new_element == list->tail) {
dlist_remove(list, list->head);
} else {
dlist_remove(list, list->tail);
}
}
return 0;
}
int dlist_remove(DList *list, DListElmt *element) {
if (element == NULL || dlist_size(list) == 0) return -1;
if (list->destroy) {
list->destroy(element->data);
}
if (element == list->head) {
list->head = element->next;
if (list->head == NULL)
list->tail = NULL;
else
element->next->prev = NULL;
} else {
element->prev->next = element->next;
if (element->next == NULL)
list->tail = element->prev;
else
element->next->prev = element->prev;
}
free(element);
list->size--;
return 0;
}
void dlist_print(const DList *list) {
DListElmt *element;
int *data;
fprintf(stdout, "List size is %d\n", dlist_size(list));
int i = 0;
element = dlist_head(list);
while (1) {
data = dlist_data(element);
fprintf(stdout, "list[%03d]=%03d\n", i, *data);
i++;
if (dlist_is_tail(element))
break;
else
element = dlist_next(element);
}
return;
}