GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/mandoc/man_hash.c Lines: 0 24 0.0 %
Date: 2016-12-06 Branches: 0 26 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: man_hash.c,v 1.25 2016/07/15 18:02:32 schwarze Exp $ */
2
/*
3
 * Copyright (c) 2008, 2009, 2010 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 <sys/types.h>
19
20
#include <assert.h>
21
#include <ctype.h>
22
#include <limits.h>
23
#include <string.h>
24
25
#include "mandoc.h"
26
#include "roff.h"
27
#include "man.h"
28
#include "libmandoc.h"
29
#include "libman.h"
30
31
#define	HASH_DEPTH	 6
32
33
#define	HASH_ROW(x) do { \
34
		if (isupper((unsigned char)(x))) \
35
			(x) -= 65; \
36
		else \
37
			(x) -= 97; \
38
		(x) *= HASH_DEPTH; \
39
	} while (/* CONSTCOND */ 0)
40
41
/*
42
 * Lookup table is indexed first by lower-case first letter (plus one
43
 * for the period, which is stored in the last row), then by lower or
44
 * uppercase second letter.  Buckets correspond to the index of the
45
 * macro (the integer value of the enum stored as a char to save a bit
46
 * of space).
47
 */
48
static	unsigned char	 table[26 * HASH_DEPTH];
49
50
51
void
52
man_hash_init(void)
53
{
54
	int		 i, j, x;
55
56
	if (*table != '\0')
57
		return;
58
59
	memset(table, UCHAR_MAX, sizeof(table));
60
61
	for (i = 0; i < (int)MAN_MAX; i++) {
62
		x = man_macronames[i][0];
63
64
		assert(isalpha((unsigned char)x));
65
66
		HASH_ROW(x);
67
68
		for (j = 0; j < HASH_DEPTH; j++)
69
			if (UCHAR_MAX == table[x + j]) {
70
				table[x + j] = (unsigned char)i;
71
				break;
72
			}
73
74
		assert(j < HASH_DEPTH);
75
	}
76
}
77
78
int
79
man_hash_find(const char *tmp)
80
{
81
	int		 x, y, i;
82
	int		 tok;
83
84
	if ('\0' == (x = tmp[0]))
85
		return TOKEN_NONE;
86
	if ( ! (isalpha((unsigned char)x)))
87
		return TOKEN_NONE;
88
89
	HASH_ROW(x);
90
91
	for (i = 0; i < HASH_DEPTH; i++) {
92
		if (UCHAR_MAX == (y = table[x + i]))
93
			return TOKEN_NONE;
94
95
		tok = y;
96
		if (0 == strcmp(tmp, man_macronames[tok]))
97
			return tok;
98
	}
99
100
	return TOKEN_NONE;
101
}