]> git.cameronkatri.com Git - mandoc.git/blobdiff - compat_ohash.c
end of sentence detection after .ME and .UE, useful for some GNU manuals
[mandoc.git] / compat_ohash.c
index 17add25761642e868d37994ead91dac7669efbfc..cbd6052182f21cd1ceffa3bb48e11abb7db2738c 100644 (file)
@@ -1,24 +1,40 @@
-#ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
 
-#ifdef HAVE_OHASH
+#if HAVE_OHASH
 
 int dummy;
 
 #else
 
-/*     $OpenBSD: ohash_int.h,v 1.3 2006/01/16 15:52:25 espie Exp $     */
+/* $OpenBSD: ohash.c,v 1.1 2014/06/02 18:52:03 deraadt Exp $ */
+
+/* Copyright (c) 1999, 2004 Marc Espie <espie@openbsd.org>
+ *
+ * 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 <sys/types.h>
 
 #include <stddef.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
 #include "compat_ohash.h"
 
 struct _ohash_record {
        uint32_t        hv;
-       const char      *p;
+       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: ohash_create_entry.c,v 1.2 2004/06/22 20:00:16 espie Exp $ */
-/* ex:ts=8 sw=4: 
- */
 
-/* Copyright (c) 1999, 2004 Marc Espie <espie@openbsd.org>
- *
- * 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 *start, const char **end)
                *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 ohash_info *info)
 #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 *start, const char *end,
                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 *start, const char *end,
                        }
                }
                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, size_t size, uint32_t hv)
 {
        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, size_t size, uint32_t hv)
                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, size_t size, uint32_t hv)
                        }       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;