@ -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); |