midi.c has better error checking and better error messages.
[cantaveria.git] / list.c
blob2019a4707ef053ef84c1dccbbbc30a0368d62cfd
1 #include <stdlib.h>
2 #include <stdio.h>
5 #include <list.h>
7 list* freelist = NULL;
10 list* make_new(list* next, void* item){
11 list* ptr;
13 if(freelist == NULL){
14 ptr = malloc(sizeof(struct list));
16 else{
17 ptr = freelist;
18 freelist = ptr->next;
21 ptr->next = next;
22 ptr->item = item;
23 return ptr;
26 void remove_from_list(list* prev, list* node){
27 prev->next = node->next;
28 node->item = NULL;
29 node->next = freelist;
30 freelist = node;
34 list* empty(){
35 return make_new(NULL, NULL);
38 void push(list* L, void* item){
39 list* ptr = make_new(L->next, item);
40 L->next = ptr;
43 void* pop(list* L){
44 if(L->next){
45 void* item = L->next->item;
46 remove_from_list(L, L->next);
47 return item;
49 else{
50 return NULL;
54 void append(list* L, void* item){
55 list* ptr = L;
56 while(ptr->next){
57 ptr = ptr->next;
59 ptr->next = make_new(NULL, item);
62 void recycle(list* L){
63 list* ptr = L;
64 while(ptr->next){
65 ptr->next->item = NULL;
66 ptr = ptr->next;
68 ptr->next = freelist;
69 freelist = L;
72 int length(list* L){
73 list* ptr = L->next;
74 int c = 0;
75 while(ptr){
76 c += 1;
77 ptr = ptr->next;
79 return c;
83 /* merge sort */
84 static void split(list* L, list** left, list** right){
85 list* ptr = L;
86 int c = 0;
88 if(L == NULL){
89 *left = NULL;
90 *right = NULL;
93 while(ptr){
94 c++;
95 ptr = ptr->next;
98 ptr = L;
99 c /= 2;
100 c -= 1;
101 while(c > 0){
102 c--;
103 ptr = ptr->next;
106 *left = L;
107 *right = ptr->next;
108 ptr->next = NULL;
111 static list* merge(list* left, list* right, compare_func cmp){
112 /* merges right into left */
113 list* tmp;
114 list* ptr;
116 if(left == NULL) return right;
118 if(right && cmp(right->item, left->item) > 0){
119 tmp = right;
120 right = right->next;
121 tmp->next = left;
122 left = tmp;
125 ptr = left;
126 while(right && ptr->next){
127 if(cmp(right->item, ptr->next->item) > 0){
128 tmp = right;
129 right = right->next;
130 tmp->next = ptr->next;
131 ptr->next = tmp;
132 ptr = ptr->next;
134 else{
135 ptr = ptr->next;
139 if(ptr->next == NULL)
140 ptr->next = right;
142 return left;
145 static list* merge_sort(list* L, compare_func cmp){
146 list* left;
147 list* right;
149 if(L == NULL) return NULL;
150 if(L->next == NULL) return L;
152 split(L, &left, &right);
154 return merge(
155 merge_sort(left, cmp),
156 merge_sort(right, cmp),
161 void sort(list* L, compare_func cmp){
162 L->next = merge_sort(L->next, cmp);
164 /* end merge sort */
167 void print_list(list* L, void (*print)(void* item)){
168 list* ptr = L->next;
169 printf("(");
170 while(ptr){
171 print(ptr->item);
172 if(ptr->next)
173 printf(", ");
174 ptr = ptr->next;
176 printf(")");
179 void println_list(list* L, void (*print)(void* item)){
180 print_list(L, print);
181 printf("\n");
184 void list_print_free(){
185 list* ptr = freelist;
186 printf("(");
187 while(ptr){
188 printf("_");
189 if(ptr->next){
190 printf(", ");
192 ptr = ptr->next;
194 printf(")\n");
197 void print(void* item){
198 char* s = item;
199 printf("%s", s);