-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlinked_list.c
105 lines (98 loc) · 2.65 KB
/
linked_list.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
#include "linked_list.h"
// This is a convenience function to quickly inspect the contents
// of a linked list
void
print_linked_list(linked_list *list)
{
int i = 0;
char *element_template = "Element #%d: {key:\"%s\", value: \"%s\"}\n";
while((list)){
printf(element_template, i, list->kv.key, list->kv.value);
list = list->next;
i++;
}
}
// This function tries to find the parameter "key" in the parameter "list"
// It either returns a linked_list* pointer for subsequent deletes/puts/gets
// or a NULL value if the key cannot be found
linked_list**
find_key(linked_list **list, char *key)
{
linked_list **current = list;
while(*current && strcmp((*current)->kv.key, key)){
current = &((*current)->next);
}
return current;
}
// This function tries to find the key/value pair identified by "key"
// and returns either either:
// - LL_VALUE_FOUND if the key was found in the linked list "l", in which case
// it also assigns the associated value to "value" before returning
// - LL_VALUE_NOT_FOUND if the "key" parameter can not be found in
// the linked list, in which case NULL is assigned to "value"
ll_status_code
linked_list_get(linked_list *l, char *key, char **value)
{
linked_list **found = find_key(&l, key);
if(*found){
*value = (*found)->kv.value;
return LL_VALUE_FOUND;
}
else{
*value = NULL;
return LL_VALUE_NOT_FOUND;
}
}
// This function can either
// - INSERT a new key/value pair into a linked list
// - UPDATE/PATCH an existing key/value pair with a new value
//
// Returns either:
// - LL_PUT_OK on a successful UPDATE/PATCH
// -v LL_ENOMEM if it fails to allocate sufficient memory for a
// new key/value pair
ll_status_code
linked_list_put(linked_list **list, key_value kv)
{
char *key = strdup(kv.key);
if(! key)
goto bad;
char *value = strdup(kv.value);
if(! value)
goto bad;
linked_list **found = find_key(list, kv.key);
if(*found){
free((*found)->kv.value);
(*found)->kv.value = strdup(kv.value);
return LL_PUT_OK;
}
else{
// Just insert the new key/value at HEAD
linked_list *tmp = *list;
*list = malloc(sizeof **list);
if(! *list)
goto bad;
else {
(*list)->kv.key = key;
(*list)->kv.value = value;
(*list)->next = tmp;
return LL_PUT_OK;
}
}
bad:
// TODO: free the memory if needed
return LL_ENOMEM;
}
ll_status_code
linked_list_delete(linked_list **list, char *key){
linked_list **found = find_key(list, key);
linked_list *cleaner;
if (*found) {
cleaner = *found;
*found = (*found)->next;
free(cleaner->kv.value);
free(cleaner->kv.key);
free(cleaner);
}
return LL_DELETE_OK;
}