mdoc_hash.c revision 303975
1234949Sbapt/* $Id: mdoc_hash.c,v 1.26 2015/10/06 18:32:19 schwarze Exp $ */ 2234949Sbapt/* 3234949Sbapt * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv> 4234949Sbapt * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> 5234949Sbapt * 6234949Sbapt * Permission to use, copy, modify, and distribute this software for any 7234949Sbapt * purpose with or without fee is hereby granted, provided that the above 8234949Sbapt * copyright notice and this permission notice appear in all copies. 9234949Sbapt * 10234949Sbapt * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11234949Sbapt * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12234949Sbapt * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13234949Sbapt * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14234949Sbapt * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15234949Sbapt * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16234949Sbapt * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17234949Sbapt */ 18234949Sbapt#include "config.h" 19234949Sbapt 20234949Sbapt#include <sys/types.h> 21234949Sbapt 22234949Sbapt#include <assert.h> 23234949Sbapt#include <ctype.h> 24234949Sbapt#include <limits.h> 25234949Sbapt#include <stdlib.h> 26234949Sbapt#include <stdio.h> 27234949Sbapt#include <string.h> 28234949Sbapt 29234949Sbapt#include "roff.h" 30234949Sbapt#include "mdoc.h" 31234949Sbapt#include "libmdoc.h" 32234949Sbapt 33234949Sbaptstatic unsigned char table[27 * 12]; 34234949Sbapt 35234949Sbapt 36234949Sbaptvoid 37234949Sbaptmdoc_hash_init(void) 38234949Sbapt{ 39234949Sbapt int i, j, major; 40234949Sbapt const char *p; 41234949Sbapt 42 if (*table != '\0') 43 return; 44 45 memset(table, UCHAR_MAX, sizeof(table)); 46 47 for (i = 0; i < (int)MDOC_MAX; i++) { 48 p = mdoc_macronames[i]; 49 50 if (isalpha((unsigned char)p[1])) 51 major = 12 * (tolower((unsigned char)p[1]) - 97); 52 else 53 major = 12 * 26; 54 55 for (j = 0; j < 12; j++) 56 if (UCHAR_MAX == table[major + j]) { 57 table[major + j] = (unsigned char)i; 58 break; 59 } 60 61 assert(j < 12); 62 } 63} 64 65int 66mdoc_hash_find(const char *p) 67{ 68 int major, i, j; 69 70 if (0 == p[0]) 71 return TOKEN_NONE; 72 if ( ! isalpha((unsigned char)p[0]) && '%' != p[0]) 73 return TOKEN_NONE; 74 75 if (isalpha((unsigned char)p[1])) 76 major = 12 * (tolower((unsigned char)p[1]) - 97); 77 else if ('1' == p[1]) 78 major = 12 * 26; 79 else 80 return TOKEN_NONE; 81 82 if (p[2] && p[3]) 83 return TOKEN_NONE; 84 85 for (j = 0; j < 12; j++) { 86 if (UCHAR_MAX == (i = table[major + j])) 87 break; 88 if (0 == strcmp(p, mdoc_macronames[i])) 89 return i; 90 } 91 92 return TOKEN_NONE; 93} 94