/* $Id: dict.c,v 1.3 2015/02/13 15:35:15 schwarze Exp $ */ /* * Copyright (c) 2015 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #if HAVE_OHASH #include #else #include "compat_ohash.h" #endif #include "dict.h" struct dict_entry { enum mdoc_type t; char s[]; }; static void *dict_malloc(size_t, void *); static void *dict_calloc(size_t, size_t, void *); static void dict_free(void *, void *); static struct ohash dict_data; void dict_init(void) { struct ohash_info dict_info; dict_info.key_offset = offsetof(struct dict_entry, s); dict_info.data = NULL; dict_info.alloc = dict_malloc; dict_info.calloc = dict_calloc; dict_info.free = dict_free; ohash_init(&dict_data, 4, &dict_info); } enum mdoc_type dict_get(const char *s, size_t len) { struct dict_entry *entry; const char *end; unsigned int slot; if (len == 0) len = strlen(s); end = s + len; slot = ohash_qlookupi(&dict_data, s, &end); entry = ohash_find(&dict_data, slot); return(entry == NULL ? MDOC_MAX : entry->t); } void dict_put(const char *s, size_t len, enum mdoc_type t) { struct dict_entry *entry; const char *end; unsigned int slot; if (len == 0) len = strlen(s); end = s + len; slot = ohash_qlookupi(&dict_data, s, &end); entry = ohash_find(&dict_data, slot); if (entry == NULL) { entry = malloc(sizeof(*entry) + len + 1); if (entry == NULL) { perror(NULL); exit(1); } memcpy(entry->s, s, len); entry->s[len] = '\0'; ohash_insert(&dict_data, slot, entry); } entry->t = t; } void dict_destroy(void) { struct dict_entry *entry; unsigned int slot; entry = ohash_first(&dict_data, &slot); while (entry != NULL) { free(entry); entry = ohash_next(&dict_data, &slot); } ohash_delete(&dict_data); } static void * dict_malloc(size_t size, void *dummy) { return(malloc(size)); } static void * dict_calloc(size_t nmemb, size_t size, void *dummy) { return(calloc(nmemb, size)); } static void dict_free(void *ptr, void *dummy) { free(ptr); }