[BACK]Return to mdoc_hash.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/Attic/mdoc_hash.c between version 1.3 and 1.11

version 1.3, 2009/04/12 19:45:26 version 1.11, 2009/09/17 07:41:28
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@openbsd.org>   * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 14 
Line 14 
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */   */
   #include <sys/types.h>
   
 #include <assert.h>  #include <assert.h>
 #include <ctype.h>  #include <ctype.h>
   #include <limits.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <stdio.h>  #include <stdio.h>
 #include <string.h>  #include <string.h>
   
 #include "libmdoc.h"  #include "libmdoc.h"
   
   static  u_char           table[27 * 12];
   
 /*  /*
  * Routines for the perfect-hash hashtable used by the parser to look up   * XXX - this hash has global scope, so if intended for use as a library
  * tokens by their string-ified names (`.Fl' -> MDOC_Fl).  The   * with multiple callers, it will need re-invocation protection.
  * allocation penalty for this is 27 * 26 * sizeof(ptr).  
  */   */
   
 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));
 }  
   
           for (i = 0; i < MDOC_MAX; i++) {
                   p = mdoc_macronames[i];
   
 void *                  if (isalpha((u_char)p[1]))
 mdoc_hash_alloc(void)                          major = 12 * (tolower((u_char)p[1]) - 97);
 {  
         int               i, major, minor, ind;  
         const void      **htab;  
   
         htab = calloc(27 * 26 * 3, sizeof(struct mdoc_macro *));  
         if (NULL == htab)  
                 return(NULL);  
   
         for (i = 1; i < MDOC_MAX; i++) {  
                 major = mdoc_macronames[i][0];  
                 assert((major >= 65 && major <= 90) ||  
                                 major == 37);  
   
                 if (major == 37)  
                         major = 0;  
                 else                  else
                         major -= 64;                          major = 12 * 26;
   
                 minor = mdoc_macronames[i][1];                  for (j = 0; j < 12; j++)
                 assert((minor >= 65 && minor <= 90) ||                          if (UCHAR_MAX == table[major + j]) {
                                 (minor == 49) ||                                  table[major + j] = (u_char)i;
                                 (minor >= 97 && minor <= 122));                                  break;
                           }
   
                 if (minor == 49)                  assert(j < 12);
                         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);  
   
                 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);  
 }  }
   
   
 int  int
 mdoc_hash_find(const void *arg, const char *tmp)  mdoc_hash_find(const char *p)
 {  {
         int               major, minor, ind, slot;          int               major, i, j;
         const void      **htab;  
   
         htab = /* LINTED */          if (0 == p[0])
                 (const void **)arg;  
   
         if (0 == tmp[0] || 0 == tmp[1])  
                 return(MDOC_MAX);                  return(MDOC_MAX);
         if (tmp[2] && tmp[3])          if ( ! isalpha((u_char)p[0]) && '%' != p[0])
                 return(MDOC_MAX);                  return(MDOC_MAX);
   
         if ( ! (tmp[0] == 37 || (tmp[0] >= 65 && tmp[0] <= 90)))          if (isalpha((u_char)p[1]))
                   major = 12 * (tolower((u_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) ||          if (p[2] && p[3])
                                 (tmp[1] == 49) ||  
                                 (tmp[1] >= 97 && tmp[1] <= 122)))  
                 return(MDOC_MAX);                  return(MDOC_MAX);
   
         if (tmp[0] == 37)          for (j = 0; j < 12; j++) {
                 major = 0;                  if (UCHAR_MAX == (i = table[major + j]))
         else                          break;
                 major = tmp[0] - 64;                  if (0 == strcmp(p, mdoc_macronames[i]))
                           return(i);
         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++;  
         }  
   
         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);
 }  }
   

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.11

CVSweb