]> git.cameronkatri.com Git - mandoc.git/blobdiff - mdoc_hash.c
bugfix: make sure all variables are properly initialized
[mandoc.git] / mdoc_hash.c
index 013856bfa53e9c44f07b8b6273386630e9ce902b..1a5dcc4b2d6a386e25e56cd1f4c85ff14bdc2e67 100644 (file)
@@ -1,6 +1,6 @@
-/*     $Id: mdoc_hash.c,v 1.5 2009/06/16 19:55:28 kristaps Exp $ */
+/*     $Id: mdoc_hash.c,v 1.19 2014/03/23 11:25:26 schwarze Exp $ */
 /*
 /*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+
 #include <assert.h>
 #include <ctype.h>
 #include <assert.h>
 #include <ctype.h>
+#include <limits.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 
+#include "mdoc.h"
 #include "libmdoc.h"
 
 #include "libmdoc.h"
 
+static unsigned char    table[27 * 12];
+
 /*
 /*
- * 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). 
+ * XXX - this hash has global scope, so if intended for use as a library
+ * with multiple callers, it will need re-invocation protection.
  */
  */
-
 void
 void
-mdoc_hash_free(void *htab)
+mdoc_hash_init(void)
 {
 {
+       int              i, j, major;
+       const char      *p;
 
 
-       free(htab);
-}
-
+       memset(table, UCHAR_MAX, sizeof(table));
 
 
-void *
-mdoc_hash_alloc(void)
-{
-       int               i, major, minor, ind;
-       const void      **htab;
+       for (i = 0; i < (int)MDOC_MAX; i++) {
+               p = mdoc_macronames[i];
 
 
-       htab = calloc(27 * 26 * 3, sizeof(struct mdoc_macro *));
-       if (NULL == htab) 
-               return(NULL);
-
-       for (i = 0; i < MDOC_MAX; i++) {
-               major = mdoc_macronames[i][0];
-               assert((major >= 65 && major <= 90) ||
-                               major == 37);
-
-               if (major == 37) 
-                       major = 0;
+               if (isalpha((unsigned char)p[1]))
+                       major = 12 * (tolower((unsigned char)p[1]) - 97);
                else
                else
-                       major -= 64;
-
-               minor = mdoc_macronames[i][1];
-               assert((minor >= 65 && minor <= 90) ||
-                               (minor == 49) ||
-                               (minor >= 97 && minor <= 122));
-
-               if (minor == 49)
-                       minor = 0;
-               else if (minor <= 90)
-                       minor -= 65;
-               else 
-                       minor -= 97;
-
-               assert(major >= 0 && major < 27);
-               assert(minor >= 0 && minor < 26);
-
-               ind = (major * 27 * 3) + (minor * 3);
+                       major = 12 * 26;
 
 
-               if (NULL == htab[ind]) {
-                       htab[ind] = &mdoc_macros[i];
-                       continue;
-               }
+               for (j = 0; j < 12; j++)
+                       if (UCHAR_MAX == table[major + j]) {
+                               table[major + j] = (unsigned char)i;
+                               break;
+                       }
 
 
-               if (NULL == htab[++ind]) {
-                       htab[ind] = &mdoc_macros[i];
-                       continue;
-               }
-
-               assert(NULL == htab[++ind]);
-               htab[ind] = &mdoc_macros[i];
+               assert(j < 12);
        }
        }
-
-       return((void *)htab);
 }
 
 }
 
-
-int
-mdoc_hash_find(const void *arg, const char *tmp)
+enum mdoct
+mdoc_hash_find(const char *p)
 {
 {
-       int               major, minor, ind, slot;
-       const void      **htab;
-
-       htab = /* LINTED */
-               (const void **)arg;
+       int               major, i, j;
 
 
-       if (0 == tmp[0] || 0 == tmp[1])
+       if (0 == p[0])
                return(MDOC_MAX);
                return(MDOC_MAX);
-       if (tmp[2] && tmp[3])
+       if ( ! isalpha((unsigned char)p[0]) && '%' != p[0])
                return(MDOC_MAX);
 
                return(MDOC_MAX);
 
-       if ( ! (tmp[0] == 37 || (tmp[0] >= 65 && tmp[0] <= 90)))
+       if (isalpha((unsigned char)p[1]))
+               major = 12 * (tolower((unsigned char)p[1]) - 97);
+       else if ('1' == p[1])
+               major = 12 * 26;
+       else 
                return(MDOC_MAX);
 
                return(MDOC_MAX);
 
-       if ( ! ((tmp[1] >= 65 && tmp[1] <= 90) ||
-                               (tmp[1] == 49) ||
-                               (tmp[1] >= 97 && tmp[1] <= 122)))
+       if (p[2] && p[3])
                return(MDOC_MAX);
 
                return(MDOC_MAX);
 
-       if (tmp[0] == 37)
-               major = 0;
-       else
-               major = tmp[0] - 64;
-
-       if (tmp[1] == 49)
-               minor = 0;
-       else if (tmp[1] <= 90)
-               minor = tmp[1] - 65;
-       else
-               minor = tmp[1] - 97;
-
-       ind = (major * 27 * 3) + (minor * 3);
-       if (ind < 0 || ind >= (27 * 26 * 3))
-               return(MDOC_MAX);
-
-       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 (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++;
+       for (j = 0; j < 12; j++) {
+               if (UCHAR_MAX == (i = table[major + j]))
+                       break;
+               if (0 == strcmp(p, mdoc_macronames[i]))
+                       return((enum mdoct)i);
        }
 
        }
 
-       if (NULL == htab[ind]) 
-               return(MDOC_MAX);
-       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);
 }
        return(MDOC_MAX);
 }
-