]> git.cameronkatri.com Git - mandoc.git/blob - hash.c
Actions and validations properly added.
[mandoc.git] / hash.c
1 /* $Id: hash.c,v 1.3 2008/12/23 05:30:49 kristaps Exp $ */
2 /*
3 * Copyright (c) 2008 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
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19 #include <assert.h>
20 #include <ctype.h>
21 #include <err.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "private.h"
27
28
29 void
30 mdoc_tokhash_free(void *htab)
31 {
32
33 free(htab);
34 }
35
36
37 void *
38 mdoc_tokhash_alloc(void)
39 {
40 int i, major, minor, ind;
41 const void **htab;
42
43 htab = calloc(27 * 26, sizeof(struct mdoc_macro *));
44 if (NULL == htab)
45 err(1, "calloc");
46
47 for (i = 1; i < MDOC_MAX; i++) {
48 major = mdoc_macronames[i][0];
49 assert((major >= 65 && major <= 90) ||
50 major == 37);
51
52 if (major == 37)
53 major = 0;
54 else
55 major -= 64;
56
57 minor = mdoc_macronames[i][1];
58 assert((minor >= 65 && minor <= 90) ||
59 (minor == 49) ||
60 (minor >= 97 && minor <= 122));
61
62 if (minor == 49)
63 minor = 0;
64 else if (minor <= 90)
65 minor -= 65;
66 else
67 minor -= 97;
68
69 assert(major >= 0 && major < 27);
70 assert(minor >= 0 && minor < 26);
71
72 ind = (major * 27) + minor;
73
74 assert(NULL == htab[ind]);
75 htab[ind] = &mdoc_macros[i];
76 }
77
78 return((void *)htab);
79 }
80
81
82 int
83 mdoc_tokhash_find(const void *arg, const char *tmp)
84 {
85 int major, minor, ind, slot;
86 const void **htab;
87
88 htab = /* LINTED */
89 (const void **)arg;
90
91 if (0 == tmp[0] || 0 == tmp[1])
92 return(MDOC_MAX);
93
94 if ( ! (tmp[0] == 37 || (tmp[0] >= 65 && tmp[0] <= 90)))
95 return(MDOC_MAX);
96
97 if ( ! ((tmp[1] >= 65 && tmp[1] <= 90) ||
98 (tmp[1] == 49) ||
99 (tmp[1] >= 97 && tmp[1] <= 122)))
100 return(MDOC_MAX);
101
102 if (tmp[0] == 37)
103 major = 0;
104 else
105 major = tmp[0] - 64;
106
107 if (tmp[1] == 49)
108 minor = 0;
109 else if (tmp[1] <= 90)
110 minor = tmp[1] - 65;
111 else
112 minor = tmp[1] - 97;
113
114 ind = (major * 27) + minor;
115
116 if (NULL == htab[ind])
117 return(MDOC_MAX);
118
119 slot = htab[ind] - /* LINTED */
120 (void *)mdoc_macros;
121 assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
122 slot /= sizeof(struct mdoc_macro);
123
124 if (0 != strcmp(mdoc_macronames[slot], tmp))
125 return(MDOC_MAX);
126 return(slot);
127 }
128