Created
February 13, 2021 20:28
-
-
Save begriffs/2bb6e45bdbf64bc99e97c45d76d19fa3 to your computer and use it in GitHub Desktop.
C dictionary based on POSIX tree
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "dict.h" | |
#include <stdlib.h> | |
#include <search.h> | |
/* XOPEN for strdup */ | |
#define _XOPEN_SOURCE 600 | |
#include <string.h> | |
struct dict_entry | |
{ | |
const char *key; | |
char *val; | |
}; | |
static int | |
_key_cmp(const void *a, const void* b) | |
{ | |
const struct dict_entry *u = a, *v = b; | |
return strcmp(u->key, v->key); | |
} | |
static int | |
_always_equal(const void *a, const void *b) | |
{ | |
(void) a; | |
(void) b; | |
return 0; | |
} | |
char *dict_get(void **d, const char *key) | |
{ | |
struct dict_entry y = { .key = (char *)key }, | |
**elt = tfind(&y, d, _key_cmp); | |
return elt ? (*elt)->val : NULL; | |
} | |
bool dict_set(void **d, const char *key, const char *val) | |
{ | |
struct dict_entry *probe, **found; | |
if (!(probe = malloc(sizeof *probe))) | |
return false; | |
*probe = (struct dict_entry){.key=key}; | |
if (!(found = tsearch(probe, d, _key_cmp))) | |
return false; | |
if (*found == probe) /* new entry */ | |
{ | |
char *newkey = strdup(key), *newval = strdup(val); | |
if (!newkey || !newval) | |
{ | |
tdelete(probe, d, _always_equal); | |
free(probe); | |
return false; | |
} | |
/* probe used arg pointers; assign copies */ | |
**found = (struct dict_entry){.key=newkey, .val=newval}; | |
} | |
else /* already existed */ | |
{ | |
char *newval = strdup(val); | |
if (!newval) | |
{ | |
free(probe); | |
return false; | |
} | |
free((*found)->val); | |
(*found)->val = newval; | |
free(probe); | |
} | |
return true; | |
} | |
void dict_free(void **d) | |
{ | |
while (*d) | |
{ | |
struct dict_entry *item = *(struct dict_entry **)*d; | |
tdelete(item, d, _always_equal); | |
free((char*)item->key); | |
free(item->val); | |
free(item); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef GRIFFS_DICT_H | |
#define GRIFFS_DICT_H | |
#include <stdbool.h> | |
char *dict_get(void **, const char *); | |
bool dict_set(void **, const char *, const char *); | |
void dict_free(void **); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment