/
linked_lists.c
133 lines (109 loc) · 2.98 KB
/
linked_lists.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
/*
Author: John Gunderman
This file contains functions dealing with linked lists:
creation, deletion, appending, searching. These linked
lists have key-value pairs and are meant for use as
part of a symbol table for a C-like compiler.
*/
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "linked_lists.h"
/*
a and b are pointers to char (cast into pointers to void)
Returns 0 if *a=*b and a non-zero value otherwise.
*/
int cmp_string (const void *a, const void *b) {
if (a == NULL || b == NULL) return 1;
return strcmp ((char *) a,(char *) b);
}
/*
returns 0 if a == b and 1 if a != b
sort of redundant, but necissary in order to get a function
pointer for the linked lists.
*/
int cmp_double (const void *a, const void *b) {
return (*(double*)a != *(double*)b);
}
/*
Pretty prints the linked list *head where *keyp is a function
to print the key and *valuep is a function to print the value.
*/
void list_pretty_print (list_head_t *head, void (*keyp) (void *),
void (*valuep) (void *)) {
list_entry_t *current = head->list;
while (current != NULL) {
printf ("Key: ");
keyp (current->key);
printf ("\nValue: ");
valuep (current->value);
printf("\n\n");
current = current->next;
}
}
/*
Allocates a list head,
assigns the comparison function,
returns the list head.
new list should be empty
on error return NULL.
*/
list_head_t *list_init (int (*cmp) (const void *, const void *)) {
list_head_t *head = malloc (sizeof (list_head_t));
if (head == NULL) {
fprintf (stderr,"Failed malloc in list_init");
return NULL;
}
assert (cmp != NULL);
if (cmp == NULL) return NULL;
head->cmp = cmp;
head->list = NULL;
return head;
}
/*
Add a key and its corresponding value to the list.
Does NOT check whether the key is already present in the list.
Returns a pointer to the new entry on success, NULL on failure
*/
list_entry_t *list_insert (list_head_t *head, void *key, void *value) {
list_entry_t *entry = malloc (sizeof (list_entry_t));
if (entry == NULL) {
fprintf (stderr,"Failed malloc in list_insert");
return NULL;
}
entry->key = key;
entry->value = value;
entry->next = head->list;
head->list = entry;
return entry;
}
/*
search the list for an element whose key matches the second arg.
returns value of elem. or null if not found.
*/
void *list_search (list_head_t *head, void *key) {
list_entry_t *current = head->list;
while (current != NULL) {
if (head->cmp (current->key, key) == 0) {
return current->value;
} else {
current = current->next;
}
}
return NULL;
}
/*
De-allocates the list head as well as all of the list entries.
*/
//TODO: THIS IS BROKEN!!!!
void list_delete (list_head_t *head) {
list_entry_t *current = head->list;
list_entry_t *next;
free (head);
while (current != NULL) {
next = current->next;
free (current);
current = next;
}
}