Annotation of src/usr.bin/mandoc/mdoc_hash.c, Revision 1.5
1.5 ! schwarze 1: /* $Id: mdoc_hash.c,v 1.4 2009/07/26 01:08:13 schwarze Exp $ */
1.1 kristaps 2: /*
1.2 schwarze 3: * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
1.1 kristaps 4: *
5: * Permission to use, copy, modify, and distribute this software for any
1.2 schwarze 6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
1.1 kristaps 8: *
1.2 schwarze 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.
1.1 kristaps 16: */
1.5 ! schwarze 17: #include <sys/types.h>
! 18:
1.1 kristaps 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:
1.4 schwarze 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:
1.1 kristaps 54:
55: void
56: mdoc_hash_free(void *htab)
57: {
58:
59: free(htab);
60: }
61:
62:
1.4 schwarze 63:
1.1 kristaps 64: void *
65: mdoc_hash_alloc(void)
66: {
67: int i, major, minor, ind;
68: const void **htab;
69:
1.4 schwarze 70: htab = calloc(26 * 3 * 52, sizeof(struct mdoc_macro *));
1.1 kristaps 71: if (NULL == htab)
72: return(NULL);
73:
1.3 schwarze 74: for (i = 0; i < MDOC_MAX; i++) {
1.1 kristaps 75: major = mdoc_macronames[i][0];
1.4 schwarze 76: assert(isalpha((u_char)major) || 37 == major);
1.1 kristaps 77:
1.4 schwarze 78: ADJUST_MAJOR(major);
1.1 kristaps 79:
80: minor = mdoc_macronames[i][1];
1.4 schwarze 81: assert(isalpha((u_char)minor) || 49 == minor);
1.1 kristaps 82:
1.4 schwarze 83: ADJUST_MINOR(minor);
1.1 kristaps 84:
1.4 schwarze 85: ind = INDEX(major, minor);
1.1 kristaps 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:
1.4 schwarze 114: if (0 == (major = tmp[0]))
1.1 kristaps 115: return(MDOC_MAX);
1.4 schwarze 116: if (0 == (minor = tmp[1]))
117: return(MDOC_MAX);
118:
1.1 kristaps 119: if (tmp[2] && tmp[3])
120: return(MDOC_MAX);
121:
1.4 schwarze 122: if (37 != major && ! isalpha((u_char)major))
1.1 kristaps 123: return(MDOC_MAX);
1.4 schwarze 124: if (49 != minor && ! isalpha((u_char)minor))
1.1 kristaps 125: return(MDOC_MAX);
126:
1.4 schwarze 127: ADJUST_MAJOR(major);
128: ADJUST_MINOR(minor);
1.1 kristaps 129:
1.4 schwarze 130: ind = INDEX(major, minor);
1.1 kristaps 131:
1.4 schwarze 132: if (ind < 0 || ind >= 26 * 3 * 52)
1.1 kristaps 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);
1.4 schwarze 140: if (SLOTCMP(slot, tmp))
1.1 kristaps 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);
1.4 schwarze 150: if (SLOTCMP(slot, tmp))
1.1 kristaps 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);
1.4 schwarze 161: if (SLOTCMP(slot, tmp))
1.1 kristaps 162: return(slot);
163:
164: return(MDOC_MAX);
165: }
166: