]> git.cameronkatri.com Git - mandoc.git/blob - mdoc_hash.c
`An' gives correct error message in encountering arguments/parameters.
[mandoc.git] / mdoc_hash.c
1 /* $Id: mdoc_hash.c,v 1.8 2009/07/20 20:49:22 kristaps Exp $ */
2 /*
3 * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17 #include <sys/types.h>
18
19 #include <assert.h>
20 #include <ctype.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 #include "libmdoc.h"
26
27 #define ADJUST_MAJOR(x) \
28 do if (37 == (x)) \
29 (x) = 0; /* % -> 00 */ \
30 else if (91 > (x)) \
31 (x) -= 64; /* A-Z -> 01 - 26 */ \
32 else \
33 (x) -= 70; /* a-z -> 27 - 52 */ \
34 while (/*CONSTCOND*/0)
35
36 #define ADJUST_MINOR(y) \
37 do if (49 == (y)) \
38 (y) = 0; /* 1 -> 00 */ \
39 else if (91 > (y)) \
40 (y) -= 65; /* A-Z -> 00 - 25 */ \
41 else \
42 (y) -= 97; /* a-z -> 00 - 25 */ \
43 while (/*CONSTCOND*/0)
44
45 #define INDEX(maj, min) \
46 ((maj) * 26 * 3) + ((min) * 3)
47
48 #define SLOTCMP(slot, val) \
49 (mdoc_macronames[(slot)][0] == (val)[0] && \
50 mdoc_macronames[(slot)][1] == (val)[1] && \
51 (0 == (val)[2] || \
52 mdoc_macronames[(slot)][2] == (val)[2]))
53
54
55 void
56 mdoc_hash_free(void *htab)
57 {
58
59 free(htab);
60 }
61
62
63
64 void *
65 mdoc_hash_alloc(void)
66 {
67 int i, major, minor, ind;
68 const void **htab;
69
70 htab = calloc(26 * 3 * 52, sizeof(struct mdoc_macro *));
71 if (NULL == htab)
72 return(NULL);
73
74 for (i = 0; i < MDOC_MAX; i++) {
75 major = mdoc_macronames[i][0];
76 assert(isalpha((u_char)major) || 37 == major);
77
78 ADJUST_MAJOR(major);
79
80 minor = mdoc_macronames[i][1];
81 assert(isalpha((u_char)minor) || 49 == minor);
82
83 ADJUST_MINOR(minor);
84
85 ind = INDEX(major, minor);
86
87 if (NULL == htab[ind]) {
88 htab[ind] = &mdoc_macros[i];
89 continue;
90 }
91
92 if (NULL == htab[++ind]) {
93 htab[ind] = &mdoc_macros[i];
94 continue;
95 }
96
97 assert(NULL == htab[++ind]);
98 htab[ind] = &mdoc_macros[i];
99 }
100
101 return((void *)htab);
102 }
103
104
105 int
106 mdoc_hash_find(const void *arg, const char *tmp)
107 {
108 int major, minor, ind, slot;
109 const void **htab;
110
111 htab = /* LINTED */
112 (const void **)arg;
113
114 if (0 == (major = tmp[0]))
115 return(MDOC_MAX);
116 if (0 == (minor = tmp[1]))
117 return(MDOC_MAX);
118
119 if (tmp[2] && tmp[3])
120 return(MDOC_MAX);
121
122 if (37 != major && ! isalpha((u_char)major))
123 return(MDOC_MAX);
124 if (49 != minor && ! isalpha((u_char)minor))
125 return(MDOC_MAX);
126
127 ADJUST_MAJOR(major);
128 ADJUST_MINOR(minor);
129
130 ind = INDEX(major, minor);
131
132 if (ind < 0 || ind >= 26 * 3 * 52)
133 return(MDOC_MAX);
134
135 if (htab[ind]) {
136 slot = htab[ind] - /* LINTED */
137 (void *)mdoc_macros;
138 assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
139 slot /= sizeof(struct mdoc_macro);
140 if (SLOTCMP(slot, tmp))
141 return(slot);
142 ind++;
143 }
144
145 if (htab[ind]) {
146 slot = htab[ind] - /* LINTED */
147 (void *)mdoc_macros;
148 assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
149 slot /= sizeof(struct mdoc_macro);
150 if (SLOTCMP(slot, tmp))
151 return(slot);
152 ind++;
153 }
154
155 if (NULL == htab[ind])
156 return(MDOC_MAX);
157 slot = htab[ind] - /* LINTED */
158 (void *)mdoc_macros;
159 assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
160 slot /= sizeof(struct mdoc_macro);
161 if (SLOTCMP(slot, tmp))
162 return(slot);
163
164 return(MDOC_MAX);
165 }
166