1241675Suqs/* $Id: mdoc_hash.c,v 1.18 2011/07/24 18:15:14 kristaps Exp $ */ 2241675Suqs/* 3241675Suqs * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv> 4241675Suqs * 5241675Suqs * Permission to use, copy, modify, and distribute this software for any 6241675Suqs * purpose with or without fee is hereby granted, provided that the above 7241675Suqs * copyright notice and this permission notice appear in all copies. 8241675Suqs * 9241675Suqs * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10241675Suqs * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11241675Suqs * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12241675Suqs * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13241675Suqs * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14241675Suqs * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15241675Suqs * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16241675Suqs */ 17241675Suqs#ifdef HAVE_CONFIG_H 18241675Suqs#include "config.h" 19241675Suqs#endif 20241675Suqs 21241675Suqs#include <sys/types.h> 22241675Suqs 23241675Suqs#include <assert.h> 24241675Suqs#include <ctype.h> 25241675Suqs#include <limits.h> 26241675Suqs#include <stdlib.h> 27241675Suqs#include <stdio.h> 28241675Suqs#include <string.h> 29241675Suqs 30241675Suqs#include "mdoc.h" 31241675Suqs#include "mandoc.h" 32241675Suqs#include "libmdoc.h" 33241675Suqs 34241675Suqsstatic unsigned char table[27 * 12]; 35241675Suqs 36241675Suqs/* 37241675Suqs * XXX - this hash has global scope, so if intended for use as a library 38241675Suqs * with multiple callers, it will need re-invocation protection. 39241675Suqs */ 40241675Suqsvoid 41241675Suqsmdoc_hash_init(void) 42241675Suqs{ 43241675Suqs int i, j, major; 44241675Suqs const char *p; 45241675Suqs 46241675Suqs memset(table, UCHAR_MAX, sizeof(table)); 47241675Suqs 48241675Suqs for (i = 0; i < (int)MDOC_MAX; i++) { 49241675Suqs p = mdoc_macronames[i]; 50241675Suqs 51241675Suqs if (isalpha((unsigned char)p[1])) 52241675Suqs major = 12 * (tolower((unsigned char)p[1]) - 97); 53241675Suqs else 54241675Suqs major = 12 * 26; 55241675Suqs 56241675Suqs for (j = 0; j < 12; j++) 57241675Suqs if (UCHAR_MAX == table[major + j]) { 58241675Suqs table[major + j] = (unsigned char)i; 59241675Suqs break; 60241675Suqs } 61241675Suqs 62241675Suqs assert(j < 12); 63241675Suqs } 64241675Suqs} 65241675Suqs 66241675Suqsenum mdoct 67241675Suqsmdoc_hash_find(const char *p) 68241675Suqs{ 69241675Suqs int major, i, j; 70241675Suqs 71241675Suqs if (0 == p[0]) 72241675Suqs return(MDOC_MAX); 73241675Suqs if ( ! isalpha((unsigned char)p[0]) && '%' != p[0]) 74241675Suqs return(MDOC_MAX); 75241675Suqs 76241675Suqs if (isalpha((unsigned char)p[1])) 77241675Suqs major = 12 * (tolower((unsigned char)p[1]) - 97); 78241675Suqs else if ('1' == p[1]) 79241675Suqs major = 12 * 26; 80241675Suqs else 81241675Suqs return(MDOC_MAX); 82241675Suqs 83241675Suqs if (p[2] && p[3]) 84241675Suqs return(MDOC_MAX); 85241675Suqs 86241675Suqs for (j = 0; j < 12; j++) { 87241675Suqs if (UCHAR_MAX == (i = table[major + j])) 88241675Suqs break; 89241675Suqs if (0 == strcmp(p, mdoc_macronames[i])) 90241675Suqs return((enum mdoct)i); 91241675Suqs } 92241675Suqs 93241675Suqs return(MDOC_MAX); 94241675Suqs} 95