| @ -0,0 +1,84 @@ | |||||
| #include <stdio.h> | |||||
| #include <stdlib.h> | |||||
| #include "dict.h" | |||||
| void *dictionary_not_found; | |||||
| dictionary *dictionary_new(void) { | |||||
| static int dnf; | |||||
| if (!dictionary_not_found) { | |||||
| dictionary_not_found = &dnf; | |||||
| } | |||||
| dictionary *out = malloc(sizeof(dictionary)); | |||||
| if(out != NULL) { | |||||
| *out = (dictionary) {}; | |||||
| } else { | |||||
| fprintf(stderr, "Out of memory.\n"); | |||||
| abort(); | |||||
| } | |||||
| return out; | |||||
| } | |||||
| static void dictionary_add_keyval(dictionary *in, keyval *kv) { | |||||
| in->length++; | |||||
| in->pairs = realloc(in->pairs, sizeof(keyval*) * in->length); | |||||
| if(in->pairs != NULL) { | |||||
| in->pairs[in->length-1] = kv; | |||||
| } else { | |||||
| fprintf(stderr, "Out of memory.\n"); | |||||
| abort(); | |||||
| } | |||||
| } | |||||
| void dictionary_add(dictionary *in, char *key, void *value) { | |||||
| if(key == NULL) { | |||||
| fprintf(stderr, "NULL is not a valid key.\n"); | |||||
| abort(); | |||||
| } | |||||
| dictionary_add_keyval(in, keyval_new(key, value)); | |||||
| } | |||||
| void *dictionary_find(const dictionary *in, const char *key) { | |||||
| for (size_t i = 0; i < in->length; i++) { | |||||
| if (keyval_matches(in->pairs[i], key)) { | |||||
| return in->pairs[i]->value; | |||||
| } | |||||
| } | |||||
| return dictionary_not_found; | |||||
| } | |||||
| dictionary *dictionary_copy(dictionary *in) { | |||||
| dictionary *out = dictionary_new(); | |||||
| for (size_t i = 0; i < in->length; i++) { | |||||
| dictionary_add_keyval(out, keyval_copy(in->pairs[i])); | |||||
| } | |||||
| return out; | |||||
| } | |||||
| void dictionary_free(dictionary *in) { | |||||
| for (size_t i = 0; i < in->length; i++) { | |||||
| keyval_free(in->pairs[i]); | |||||
| } | |||||
| free(in); | |||||
| } | |||||
| @ -0,0 +1,17 @@ | |||||
| #include "keyval.h" | |||||
| extern void *dictionary_not_found; | |||||
| typedef struct dictionary { | |||||
| keyval **pairs; | |||||
| size_t length; | |||||
| } dictionary; | |||||
| dictionary *dictionary_new(void); | |||||
| dictionary *dictionary_copy(dictionary *in); | |||||
| void dictionary_free(dictionary *in); | |||||
| void dictionary_add(dictionary *in, char *key, void *value); | |||||
| void *dictionary_find(const dictionary *in, const char *key); | |||||
| @ -0,0 +1,23 @@ | |||||
| #include <stdio.h> | |||||
| #include "dict.h" | |||||
| int main() { | |||||
| int zero = 0; | |||||
| float one = 1.0; | |||||
| char two[] = "two"; | |||||
| dictionary *d = dictionary_new(); | |||||
| dictionary_add(d, "an int", &zero); | |||||
| dictionary_add(d, "a float", &one); | |||||
| dictionary_add(d, "a string", &two); | |||||
| printf("The integer I recorded was: %i\n", *(int*) dictionary_find(d, "an int")); | |||||
| printf("The string I recorded was: %s\n", (char*) dictionary_find(d, "a string")); | |||||
| dictionary_free(d); | |||||
| } | |||||
| @ -0,0 +1,53 @@ | |||||
| #include <stdio.h> | |||||
| #include <stdlib.h> | |||||
| #include <strings.h> | |||||
| #include "keyval.h" | |||||
| /* | |||||
| Create a new key/value pair. | |||||
| */ | |||||
| keyval *keyval_new(char *key, void *value) { | |||||
| keyval *out = malloc(sizeof(keyval)); | |||||
| if(out != NULL) { | |||||
| *out = (keyval){.key = key, .value = value}; | |||||
| } else { | |||||
| fprintf(stderr, "Out of memory.\n"); | |||||
| abort(); | |||||
| } | |||||
| return out; | |||||
| } | |||||
| /* | |||||
| Copy a key/value pair. The new pair has pointers to | |||||
| the values in the old pair, not copies of their data. | |||||
| */ | |||||
| keyval *keyval_copy(const keyval *in) { | |||||
| keyval *out = malloc(sizeof(keyval)); | |||||
| if(out != NULL) { | |||||
| *out = *in; | |||||
| } else { | |||||
| fprintf(stderr, "Out of memory.\n"); | |||||
| abort(); | |||||
| } | |||||
| return out; | |||||
| } | |||||
| /* | |||||
| Free a existing key/value pair. | |||||
| */ | |||||
| void keyval_free(keyval *in) { | |||||
| if(in != NULL) { | |||||
| free(in); | |||||
| } | |||||
| } | |||||
| /* | |||||
| Check if key of key/value pair matches given key. | |||||
| */ | |||||
| int keyval_matches(const keyval *in, const char *key) { | |||||
| return !strcasecmp(in->key, key); | |||||
| } | |||||
| @ -0,0 +1,10 @@ | |||||
| typedef struct keyval { | |||||
| char *key; | |||||
| void *value; | |||||
| } keyval; | |||||
| keyval *keyval_new(char *key, void *value); | |||||
| keyval *keyval_copy(const keyval *in); | |||||
| void keyval_free(keyval *in); | |||||
| int keyval_matches(const keyval *in, const char *key); | |||||