Annotation of mandoc/mdoc_hash.c, Revision 1.6
1.6 ! kristaps 1: /* $Id: mdoc_hash.c,v 1.5 2009/06/16 19:55:28 kristaps Exp $ */
1.1 kristaps 2: /*
1.4 kristaps 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.3 kristaps 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.3 kristaps 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: */
17: #include <assert.h>
18: #include <ctype.h>
19: #include <stdlib.h>
20: #include <stdio.h>
21: #include <string.h>
22:
23: #include "libmdoc.h"
24:
1.6 ! kristaps 25: #define ADJUST_MAJOR(x) \
! 26: do if (37 == (x)) \
! 27: (x) = 0; /* % -> 00 */ \
! 28: else if (91 > (x)) \
! 29: (x) -= 64; /* A-Z -> 01 - 26 */ \
! 30: else \
! 31: (x) -= 70; /* a-z -> 27 - 52 */ \
! 32: while (/*CONSTCOND*/0)
! 33:
! 34: #define ADJUST_MINOR(y) \
! 35: do if (49 == (y)) \
! 36: (y) = 0; /* 1 -> 00 */ \
! 37: else if (91 > (y)) \
! 38: (y) -= 65; /* A-Z -> 00 - 25 */ \
! 39: else \
! 40: (y) -= 97; /* a-z -> 00 - 25 */ \
! 41: while (/*CONSTCOND*/0)
! 42:
! 43: #define INDEX(maj, min) \
! 44: ((maj) * 26 * 3) + ((min) * 3)
! 45:
! 46: #define SLOTCMP(slot, val) \
! 47: (mdoc_macronames[(slot)][0] == (val)[0] && \
! 48: mdoc_macronames[(slot)][1] == (val)[1] && \
! 49: (0 == (val)[2] || \
! 50: mdoc_macronames[(slot)][2] == (val)[2]))
! 51:
1.1 kristaps 52:
53: void
1.2 kristaps 54: mdoc_hash_free(void *htab)
1.1 kristaps 55: {
56:
57: free(htab);
58: }
59:
60:
1.6 ! kristaps 61:
1.1 kristaps 62: void *
1.2 kristaps 63: mdoc_hash_alloc(void)
1.1 kristaps 64: {
65: int i, major, minor, ind;
66: const void **htab;
67:
1.6 ! kristaps 68: htab = calloc(26 * 3 * 52, sizeof(struct mdoc_macro *));
1.1 kristaps 69: if (NULL == htab)
1.2 kristaps 70: return(NULL);
1.1 kristaps 71:
1.5 kristaps 72: for (i = 0; i < MDOC_MAX; i++) {
1.1 kristaps 73: major = mdoc_macronames[i][0];
1.6 ! kristaps 74: assert(isalpha((u_char)major) || 37 == major);
1.1 kristaps 75:
1.6 ! kristaps 76: ADJUST_MAJOR(major);
1.1 kristaps 77:
78: minor = mdoc_macronames[i][1];
1.6 ! kristaps 79: assert(isalpha((u_char)minor) || 49 == minor);
1.1 kristaps 80:
1.6 ! kristaps 81: ADJUST_MINOR(minor);
1.1 kristaps 82:
1.6 ! kristaps 83: ind = INDEX(major, minor);
1.1 kristaps 84:
85: if (NULL == htab[ind]) {
86: htab[ind] = &mdoc_macros[i];
87: continue;
88: }
89:
90: if (NULL == htab[++ind]) {
91: htab[ind] = &mdoc_macros[i];
92: continue;
93: }
94:
95: assert(NULL == htab[++ind]);
96: htab[ind] = &mdoc_macros[i];
97: }
98:
99: return((void *)htab);
100: }
101:
102:
103: int
1.2 kristaps 104: mdoc_hash_find(const void *arg, const char *tmp)
1.1 kristaps 105: {
106: int major, minor, ind, slot;
107: const void **htab;
108:
109: htab = /* LINTED */
110: (const void **)arg;
111:
1.6 ! kristaps 112: if (0 == (major = tmp[0]))
! 113: return(MDOC_MAX);
! 114: if (0 == (minor = tmp[1]))
1.1 kristaps 115: return(MDOC_MAX);
1.6 ! kristaps 116:
1.1 kristaps 117: if (tmp[2] && tmp[3])
118: return(MDOC_MAX);
119:
1.6 ! kristaps 120: if (37 != major && ! isalpha((u_char)major))
1.1 kristaps 121: return(MDOC_MAX);
1.6 ! kristaps 122: if (49 != minor && ! isalpha((u_char)minor))
1.1 kristaps 123: return(MDOC_MAX);
124:
1.6 ! kristaps 125: ADJUST_MAJOR(major);
! 126: ADJUST_MINOR(minor);
1.1 kristaps 127:
1.6 ! kristaps 128: ind = INDEX(major, minor);
1.1 kristaps 129:
130: if (htab[ind]) {
131: slot = htab[ind] - /* LINTED */
132: (void *)mdoc_macros;
133: assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
134: slot /= sizeof(struct mdoc_macro);
1.6 ! kristaps 135: if (SLOTCMP(slot, tmp))
1.1 kristaps 136: return(slot);
137: ind++;
138: }
139:
140: if (htab[ind]) {
141: slot = htab[ind] - /* LINTED */
142: (void *)mdoc_macros;
143: assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
144: slot /= sizeof(struct mdoc_macro);
1.6 ! kristaps 145: if (SLOTCMP(slot, tmp))
1.1 kristaps 146: return(slot);
147: ind++;
148: }
149:
150: if (NULL == htab[ind])
151: return(MDOC_MAX);
152: slot = htab[ind] - /* LINTED */
153: (void *)mdoc_macros;
154: assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
155: slot /= sizeof(struct mdoc_macro);
1.6 ! kristaps 156: if (SLOTCMP(slot, tmp))
1.1 kristaps 157: return(slot);
158:
159: return(MDOC_MAX);
160: }
161:
CVSweb