=================================================================== RCS file: /cvs/mandoc/compat_ohash.c,v retrieving revision 1.1 retrieving revision 1.5 diff -u -p -r1.1 -r1.5 --- mandoc/compat_ohash.c 2012/06/09 11:00:13 1.1 +++ mandoc/compat_ohash.c 2014/08/10 23:54:41 1.5 @@ -1,6 +1,4 @@ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif #ifdef HAVE_OHASH @@ -8,17 +6,35 @@ int dummy; #else -/* $OpenBSD: compat_ohash.c,v 1.1 2012/06/09 11:00:13 kristaps Exp $ */ +/* $OpenBSD: compat_ohash.c,v 1.5 2014/08/10 23:54:41 schwarze Exp $ */ +/* Copyright (c) 1999, 2004 Marc Espie + * + * 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 AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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 #include "compat_ohash.h" struct _ohash_record { - u_int32_t hv; - const char *p; + uint32_t hv; + const char *p; }; #define DELETED ((const char *)h) @@ -27,26 +43,11 @@ struct _ohash_record { /* Don't bother changing the hash table if the change is small enough. */ #define MINSIZE (1UL << 4) #define MINDELETED 4 -/* $OpenBSD: compat_ohash.c,v 1.1 2012/06/09 11:00:13 kristaps Exp $ */ -/* ex:ts=8 sw=4: - */ -/* Copyright (c) 1999, 2004 Marc Espie - * - * 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 AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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. - */ +static void ohash_resize(struct ohash *); -/* This handles the common case of variable length keys, where the + +/* This handles the common case of variable length keys, where the * key is stored at the end of the record. */ void * @@ -58,37 +59,38 @@ ohash_create_entry(struct ohash_info *i, const char *s *end = start + strlen(start); p = (i->alloc)(i->key_offset + (*end - start) + 1, i->data); if (p) { - memcpy(p+i->key_offset, start, *end-start); - p[i->key_offset + (*end - start)] = '\0'; + memcpy(p+i->key_offset, start, *end-start); + p[i->key_offset + (*end - start)] = '\0'; } return (void *)p; } /* hash_delete only frees the hash structure. Use hash_first/hash_next * to free entries as well. */ -void +void ohash_delete(struct ohash *h) { - (h->info.hfree)(h->t, sizeof(struct _ohash_record) * h->size, - h->info.data); + (h->info.free)(h->t, h->info.data); #ifndef NDEBUG h->t = NULL; #endif } -static void ohash_resize(struct ohash *); - -static void +static void ohash_resize(struct ohash *h) { struct _ohash_record *n; - unsigned int ns, j; + size_t ns; + unsigned int j; unsigned int i, incr; - if (4 * h->deleted < h->total) - ns = h->size << 1; - else if (3 * h->deleted > 2 * h->total) - ns = h->size >> 1; + if (4 * h->deleted < h->total) { + if (h->size >= (UINT_MAX >> 1U)) + ns = UINT_MAX; + else + ns = h->size << 1U; + } else if (3 * h->deleted > 2 * h->total) + ns = h->size >> 1U; else ns = h->size; if (ns < MINSIZE) @@ -97,7 +99,8 @@ ohash_resize(struct ohash *h) STAT_HASH_EXPAND++; STAT_HASH_SIZE += ns - h->size; #endif - n = (h->info.halloc)(sizeof(struct _ohash_record) * ns, h->info.data); + + n = (h->info.calloc)(ns, sizeof(struct _ohash_record), h->info.data); if (!n) return; @@ -109,13 +112,12 @@ ohash_resize(struct ohash *h) i += incr; if (i >= ns) i -= ns; - } + } n[i].hv = h->t[j].hv; n[i].p = h->t[j].p; } } - (h->info.hfree)(h->t, sizeof(struct _ohash_record) * h->size, - h->info.data); + (h->info.free)(h->t, h->info.data); h->t = n; h->size = ns; h->total -= h->deleted; @@ -125,7 +127,7 @@ ohash_resize(struct ohash *h) void * ohash_remove(struct ohash *h, unsigned int i) { - void *result = (void *)h->t[i].p; + void *result = (void *)h->t[i].p; if (result == NULL || result == DELETED) return NULL; @@ -160,11 +162,11 @@ ohash_insert(struct ohash *h, unsigned int i, void *p) h->t[i].p = p; } else { h->t[i].p = p; - /* Arbitrary resize boundary. Tweak if not efficient enough. */ + /* Arbitrary resize boundary. Tweak if not efficient enough. */ if (++h->total * 4 > h->size * 3) ohash_resize(h); } - return p; + return p; } unsigned int @@ -179,17 +181,17 @@ ohash_first(struct ohash *h, unsigned int *pos) *pos = 0; return ohash_next(h, pos); } - + void * ohash_next(struct ohash *h, unsigned int *pos) { - for (; *pos < h->size; (*pos)++) - if (h->t[*pos].p != DELETED && h->t[*pos].p != NULL) + for (; *pos < h->size; (*pos)++) + if (h->t[*pos].p != DELETED && h->t[*pos].p != NULL) return (void *)h->t[(*pos)++].p; return NULL; } -void +void ohash_init(struct ohash *h, unsigned int size, struct ohash_info *info) { h->size = 1UL << size; @@ -201,12 +203,12 @@ ohash_init(struct ohash *h, unsigned int size, struct #endif /* Copy info so that caller may free it. */ h->info.key_offset = info->key_offset; - h->info.halloc = info->halloc; - h->info.hfree = info->hfree; + h->info.calloc = info->calloc; + h->info.free = info->free; h->info.alloc = info->alloc; h->info.data = info->data; - h->t = (h->info.halloc)(sizeof(struct _ohash_record) * h->size, - h->info.data); + h->t = (h->info.calloc)(h->size, sizeof(struct _ohash_record), + h->info.data); h->total = h->deleted = 0; } @@ -227,12 +229,12 @@ ohash_interval(const char *s, const char **e) } unsigned int -ohash_lookup_interval(struct ohash *h, const char *start, const char *end, +ohash_lookup_interval(struct ohash *h, const char *start, const char *end, uint32_t hv) { - unsigned int i, incr; + unsigned int i, incr; unsigned int empty; - + #ifdef STATS_HASH STAT_HASH_LOOKUP++; #endif @@ -246,11 +248,11 @@ ohash_lookup_interval(struct ohash *h, const char *sta if (h->t[i].p == DELETED) { if (empty == NONE) empty = i; - } else if (h->t[i].hv == hv && - strncmp(h->t[i].p+h->info.key_offset, start, - end - start) == 0 && + } else if (h->t[i].hv == hv && + strncmp(h->t[i].p+h->info.key_offset, start, + end - start) == 0 && (h->t[i].p+h->info.key_offset)[end-start] == '\0') { - if (empty != NONE) { + if (empty != NONE) { h->t[empty].hv = hv; h->t[empty].p = h->t[i].p; h->t[i].p = DELETED; @@ -263,12 +265,12 @@ ohash_lookup_interval(struct ohash *h, const char *sta } } i += incr; - if (i >= h->size) + if (i >= h->size) i -= h->size; } /* Found an empty position. */ - if (empty != NONE) + if (empty != NONE) i = empty; h->t[i].hv = hv; return i; @@ -279,7 +281,7 @@ ohash_lookup_memory(struct ohash *h, const char *k, si { unsigned int i, incr; unsigned int empty; - + #ifdef STATS_HASH STAT_HASH_LOOKUP++; #endif @@ -293,9 +295,9 @@ ohash_lookup_memory(struct ohash *h, const char *k, si if (h->t[i].p == DELETED) { if (empty == NONE) empty = i; - } else if (h->t[i].hv == hv && + } else if (h->t[i].hv == hv && memcmp(h->t[i].p+h->info.key_offset, k, size) == 0) { - if (empty != NONE) { + if (empty != NONE) { h->t[empty].hv = hv; h->t[empty].p = h->t[i].p; h->t[i].p = DELETED; @@ -307,12 +309,12 @@ ohash_lookup_memory(struct ohash *h, const char *k, si } return i; } i += incr; - if (i >= h->size) + if (i >= h->size) i -= h->size; } /* Found an empty position. */ - if (empty != NONE) + if (empty != NONE) i = empty; h->t[i].hv = hv; return i; @@ -328,7 +330,7 @@ ohash_qlookup(struct ohash *h, const char *s) unsigned int ohash_qlookupi(struct ohash *h, const char *s, const char **e) { - u_int32_t hv; + uint32_t hv; hv = ohash_interval(s, e); return ohash_lookup_interval(h, s, *e, hv);