]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/mdocml/mdoc_hash.c
locks: fix compilation with KTR wihout KTR_LOCKS
[FreeBSD/FreeBSD.git] / contrib / mdocml / mdoc_hash.c
1 /*      $Id: mdoc_hash.c,v 1.27 2016/07/15 18:03:45 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 "mandoc.h"
30 #include "roff.h"
31 #include "mdoc.h"
32 #include "libmandoc.h"
33 #include "libmdoc.h"
34
35 static  unsigned char    table[27 * 12];
36
37
38 void
39 mdoc_hash_init(void)
40 {
41         int              i, j, major;
42         const char      *p;
43
44         if (*table != '\0')
45                 return;
46
47         memset(table, UCHAR_MAX, sizeof(table));
48
49         for (i = 0; i < (int)MDOC_MAX; i++) {
50                 p = mdoc_macronames[i];
51
52                 if (isalpha((unsigned char)p[1]))
53                         major = 12 * (tolower((unsigned char)p[1]) - 97);
54                 else
55                         major = 12 * 26;
56
57                 for (j = 0; j < 12; j++)
58                         if (UCHAR_MAX == table[major + j]) {
59                                 table[major + j] = (unsigned char)i;
60                                 break;
61                         }
62
63                 assert(j < 12);
64         }
65 }
66
67 int
68 mdoc_hash_find(const char *p)
69 {
70         int               major, i, j;
71
72         if (0 == p[0])
73                 return TOKEN_NONE;
74         if ( ! isalpha((unsigned char)p[0]) && '%' != p[0])
75                 return TOKEN_NONE;
76
77         if (isalpha((unsigned char)p[1]))
78                 major = 12 * (tolower((unsigned char)p[1]) - 97);
79         else if ('1' == p[1])
80                 major = 12 * 26;
81         else
82                 return TOKEN_NONE;
83
84         if (p[2] && p[3])
85                 return TOKEN_NONE;
86
87         for (j = 0; j < 12; j++) {
88                 if (UCHAR_MAX == (i = table[major + j]))
89                         break;
90                 if (0 == strcmp(p, mdoc_macronames[i]))
91                         return i;
92         }
93
94         return TOKEN_NONE;
95 }