=================================================================== RCS file: /cvs/mandoc/Attic/hash.c,v retrieving revision 1.1 retrieving revision 1.11 diff -u -p -r1.1 -r1.11 --- mandoc/Attic/hash.c 2008/12/15 01:54:58 1.1 +++ mandoc/Attic/hash.c 2009/03/16 23:37:28 1.11 @@ -1,6 +1,6 @@ -/* $Id: hash.c,v 1.1 2008/12/15 01:54:58 kristaps Exp $ */ +/* $Id: hash.c,v 1.11 2009/03/16 23:37:28 kristaps Exp $ */ /* - * Copyright (c) 2008 Kristaps Dzonsons + * Copyright (c) 2008, 2009 Kristaps Dzonsons * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the @@ -25,9 +25,14 @@ #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); @@ -35,12 +40,12 @@ mdoc_hash_free(void *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 *)); + htab = calloc(27 * 26 * 3, sizeof(struct mdoc_macro *)); if (NULL == htab) err(1, "calloc"); @@ -69,10 +74,20 @@ mdoc_hash_alloc(void) assert(major >= 0 && major < 27); assert(minor >= 0 && minor < 26); - index = (major * 27) + minor; + ind = (major * 27 * 3) + (minor * 3); - assert(NULL == htab[index]); - htab[index] = &mdoc_macros[i]; + if (NULL == htab[ind]) { + htab[ind] = &mdoc_macros[i]; + continue; + } + + if (NULL == htab[++ind]) { + htab[ind] = &mdoc_macros[i]; + continue; + } + + assert(NULL == htab[++ind]); + htab[ind] = &mdoc_macros[i]; } return((void *)htab); @@ -80,15 +95,18 @@ mdoc_hash_alloc(void) 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); + if (tmp[2] && tmp[3]) + return(MDOC_MAX); if ( ! (tmp[0] == 37 || (tmp[0] >= 65 && tmp[0] <= 90))) return(MDOC_MAX); @@ -110,17 +128,48 @@ mdoc_hash_find(const void *arg, const char *tmp) else minor = tmp[1] - 97; - index = (major * 27) + minor; - - if (NULL == htab[index]) + ind = (major * 27 * 3) + (minor * 3); + if (ind < 0 || ind >= (27 * 26 * 3)) return(MDOC_MAX); - slot = htab[index] - (void *)mdoc_macros; - assert(0 == slot % sizeof(struct mdoc_macro)); - slot /= sizeof(struct mdoc_macro); + if (htab[ind]) { + slot = htab[ind] - /* LINTED */ + (void *)mdoc_macros; + assert(0 == (size_t)slot % sizeof(struct mdoc_macro)); + slot /= sizeof(struct mdoc_macro); + if (mdoc_macronames[slot][0] == tmp[0] && + mdoc_macronames[slot][1] == tmp[1] && + (0 == tmp[2] || + mdoc_macronames[slot][2] == tmp[2])) + return(slot); + ind++; + } - if (0 != strcmp(mdoc_macronames[slot], tmp)) + if (htab[ind]) { + slot = htab[ind] - /* LINTED */ + (void *)mdoc_macros; + assert(0 == (size_t)slot % sizeof(struct mdoc_macro)); + slot /= sizeof(struct mdoc_macro); + if (mdoc_macronames[slot][0] == tmp[0] && + mdoc_macronames[slot][1] == tmp[1] && + (0 == tmp[2] || + mdoc_macronames[slot][2] == tmp[2])) + return(slot); + ind++; + } + + if (NULL == htab[ind]) return(MDOC_MAX); - return(slot); + slot = htab[ind] - /* LINTED */ + (void *)mdoc_macros; + assert(0 == (size_t)slot % sizeof(struct mdoc_macro)); + slot /= sizeof(struct mdoc_macro); + if (mdoc_macronames[slot][0] == tmp[0] && + mdoc_macronames[slot][1] == tmp[1] && + (0 == tmp[2] || + mdoc_macronames[slot][2] == tmp[2])) + return(slot); + + return(MDOC_MAX); }