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