-/* $Id: hash.c,v 1.1 2008/12/15 01:54:58 kristaps Exp $ */
+/* $Id: hash.c,v 1.7 2009/03/08 11:41:22 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
#include "private.h"
+/*
+ * Routines for the perfect-hash hashtable used by the parser to look up
+ * tokens by their string-ified names (`.Fl' -> MDOC_Fl). The
+ * allocation penalty for this is 27 * 26 * sizeof(ptr).
+ */
void
-mdoc_hash_free(void *htab)
+mdoc_tokhash_free(void *htab)
{
free(htab);
void *
-mdoc_hash_alloc(void)
+mdoc_tokhash_alloc(void)
{
- int i, major, minor, index;
+ int i, major, minor, ind;
const void **htab;
htab = calloc(27 * 26, sizeof(struct mdoc_macro *));
assert(major >= 0 && major < 27);
assert(minor >= 0 && minor < 26);
- index = (major * 27) + minor;
+ ind = (major * 27) + minor;
- assert(NULL == htab[index]);
- htab[index] = &mdoc_macros[i];
+ assert(NULL == htab[ind]);
+ htab[ind] = &mdoc_macros[i];
}
return((void *)htab);
int
-mdoc_hash_find(const void *arg, const char *tmp)
+mdoc_tokhash_find(const void *arg, const char *tmp)
{
- int major, minor, index, slot;
+ int major, minor, ind, slot;
const void **htab;
- htab = (const void **)arg;
+ htab = /* LINTED */
+ (const void **)arg;
if (0 == tmp[0] || 0 == tmp[1])
return(MDOC_MAX);
else
minor = tmp[1] - 97;
- index = (major * 27) + minor;
+ ind = (major * 27) + minor;
+ if (ind < 0 || ind >= (27 * 26))
+ return(MDOC_MAX);
- if (NULL == htab[index])
+ if (NULL == htab[ind])
return(MDOC_MAX);
- slot = htab[index] - (void *)mdoc_macros;
- assert(0 == slot % sizeof(struct mdoc_macro));
+ slot = htab[ind] - /* LINTED */
+ (void *)mdoc_macros;
+ assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
slot /= sizeof(struct mdoc_macro);
+ /*
+ * FIXME: is this necessary, or do we only need to check the
+ * remaining characters (2+)?
+ */
+
if (0 != strcmp(mdoc_macronames[slot], tmp))
return(MDOC_MAX);
return(slot);