1/* $Id: mdoc_hash.c,v 1.26 2015/10/06 18:32:19 schwarze Exp $ */ 2/* 3 * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv> 4 * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18#include "config.h" 19 20#include <sys/types.h> 21 22#include <assert.h> 23#include <ctype.h> 24#include <limits.h> 25#include <stdlib.h> 26#include <stdio.h> 27#include <string.h> 28 29#include "roff.h" 30#include "mdoc.h" 31#include "libmdoc.h" 32 33static unsigned char table[27 * 12]; 34 35 36void 37mdoc_hash_init(void) 38{ 39 int i, j, major; 40 const char *p; 41 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