forked from nick-jn/uni-project-20465
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclist.c
executable file
·132 lines (103 loc) · 3.09 KB
/
clist.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
/*Generic circular linked list.*/
#include <stdio.h>
#include <stdlib.h>
#include "clist.h"
/*Adds a new item to the list. The last node of the list must be provided.
If the last node is null, this, in effect, creates the first node of
the list.*/
void add_clist(c_list **last_node, void *item) {
c_list *new_node;
new_node = malloc(sizeof(c_list));
if (new_node == NULL) {
fprintf(stderr, "Malloc failure in add_clist.");
exit(1);
}
new_node->item = item;
if (*last_node == NULL) {
new_node->next = new_node;
} else {
new_node->next = (*last_node)->next;
(*last_node)->next = new_node;
}
*last_node = new_node;
}
/*Frees the given list. Requires the appropriate item_destroyer function.
The last_node pointer contents will be set to NULL at the end to prevent
a dangling pointer.*/
void destroy_clist(c_list **last_node, void(*item_destroyer)(void *)) {
c_list *cur_node;
c_list *next_node;
if (*last_node == NULL) {
return;
}
/*converts to singly linked list for ease of use*/
cur_node = (*last_node)->next;
(*last_node)->next = NULL;
while (cur_node != NULL) {
next_node = cur_node->next;
(*item_destroyer)(cur_node->item);
free(cur_node);
cur_node = next_node;
}
*last_node = NULL;
}
/*Finds a string in a given list. Requires the appropriate item_finder
function.*/
void *find_clist_str(c_list *last_node, void*(*item_finder)(void *, char*),
char *str) {
c_list *cur_node;
void *found_item;
if (last_node == NULL) {
return NULL;
}
cur_node = last_node->next;
do {
if ((found_item = (*item_finder)(cur_node->item, str)) != NULL) {
return found_item;
}
cur_node = cur_node->next;
} while (cur_node != last_node->next);
return NULL;
}
/*DEBUG*/
void print_clist(c_list *last_node, void(*item_printer)(void *)) {
c_list *cur_node;
if (last_node == NULL) {
return;
}
cur_node = last_node->next;
do {
item_printer(cur_node->item);
cur_node = cur_node->next;
} while (cur_node != last_node->next);
}
/*DEBUG*/
void print_clist_range(c_list *last_node, int start, int length,
void(*item_printer)(void *)) {
c_list *cur_node;
int counter = start;
if (last_node == NULL) {
return;
}
cur_node = last_node->next;
if (start != 0) {
do {
cur_node = cur_node->next;
start--;
} while (cur_node != last_node->next && start != 0);
}
if (start != 0) {
printf("print_clist_range out of bounds: start\n");
return;
}
do {
printf("%d\t", counter);
item_printer(cur_node->item);
cur_node = cur_node->next;
length--;
counter++;
} while (cur_node != last_node->next && length != 0);
if (start != 0) {
printf("print_clist_range out of bounds: length\n");
}
}