1294113Sbapt/*	$Id: mdoc_hash.c,v 1.26 2015/10/06 18:32:19 schwarze Exp $ */
2241675Suqs/*
3241675Suqs * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
4294113Sbapt * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
5241675Suqs *
6241675Suqs * Permission to use, copy, modify, and distribute this software for any
7241675Suqs * purpose with or without fee is hereby granted, provided that the above
8241675Suqs * copyright notice and this permission notice appear in all copies.
9241675Suqs *
10241675Suqs * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11241675Suqs * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12241675Suqs * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13241675Suqs * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14241675Suqs * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15241675Suqs * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16241675Suqs * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17241675Suqs */
18241675Suqs#include "config.h"
19241675Suqs
20241675Suqs#include <sys/types.h>
21241675Suqs
22241675Suqs#include <assert.h>
23241675Suqs#include <ctype.h>
24241675Suqs#include <limits.h>
25241675Suqs#include <stdlib.h>
26241675Suqs#include <stdio.h>
27241675Suqs#include <string.h>
28241675Suqs
29294113Sbapt#include "roff.h"
30241675Suqs#include "mdoc.h"
31241675Suqs#include "libmdoc.h"
32241675Suqs
33241675Suqsstatic	unsigned char	 table[27 * 12];
34241675Suqs
35274880Sbapt
36241675Suqsvoid
37241675Suqsmdoc_hash_init(void)
38241675Suqs{
39241675Suqs	int		 i, j, major;
40241675Suqs	const char	*p;
41241675Suqs
42294113Sbapt	if (*table != '\0')
43294113Sbapt		return;
44294113Sbapt
45241675Suqs	memset(table, UCHAR_MAX, sizeof(table));
46241675Suqs
47241675Suqs	for (i = 0; i < (int)MDOC_MAX; i++) {
48241675Suqs		p = mdoc_macronames[i];
49241675Suqs
50241675Suqs		if (isalpha((unsigned char)p[1]))
51241675Suqs			major = 12 * (tolower((unsigned char)p[1]) - 97);
52241675Suqs		else
53241675Suqs			major = 12 * 26;
54241675Suqs
55241675Suqs		for (j = 0; j < 12; j++)
56241675Suqs			if (UCHAR_MAX == table[major + j]) {
57241675Suqs				table[major + j] = (unsigned char)i;
58241675Suqs				break;
59241675Suqs			}
60241675Suqs
61241675Suqs		assert(j < 12);
62241675Suqs	}
63241675Suqs}
64241675Suqs
65294113Sbaptint
66241675Suqsmdoc_hash_find(const char *p)
67241675Suqs{
68241675Suqs	int		  major, i, j;
69241675Suqs
70241675Suqs	if (0 == p[0])
71294113Sbapt		return TOKEN_NONE;
72241675Suqs	if ( ! isalpha((unsigned char)p[0]) && '%' != p[0])
73294113Sbapt		return TOKEN_NONE;
74241675Suqs
75241675Suqs	if (isalpha((unsigned char)p[1]))
76241675Suqs		major = 12 * (tolower((unsigned char)p[1]) - 97);
77241675Suqs	else if ('1' == p[1])
78241675Suqs		major = 12 * 26;
79274880Sbapt	else
80294113Sbapt		return TOKEN_NONE;
81241675Suqs
82241675Suqs	if (p[2] && p[3])
83294113Sbapt		return TOKEN_NONE;
84241675Suqs
85241675Suqs	for (j = 0; j < 12; j++) {
86241675Suqs		if (UCHAR_MAX == (i = table[major + j]))
87241675Suqs			break;
88241675Suqs		if (0 == strcmp(p, mdoc_macronames[i]))
89294113Sbapt			return i;
90241675Suqs	}
91241675Suqs
92294113Sbapt	return TOKEN_NONE;
93241675Suqs}
94