]>
git.cameronkatri.com Git - mandoc.git/blob - hash.c
1 /* $Id: hash.c,v 1.7 2009/03/08 11:41:22 kristaps Exp $ */
3 * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
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
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.
29 * Routines for the perfect-hash hashtable used by the parser to look up
30 * tokens by their string-ified names (`.Fl' -> MDOC_Fl). The
31 * allocation penalty for this is 27 * 26 * sizeof(ptr).
35 mdoc_tokhash_free(void *htab
)
43 mdoc_tokhash_alloc(void)
45 int i
, major
, minor
, ind
;
48 htab
= calloc(27 * 26, sizeof(struct mdoc_macro
*));
52 for (i
= 1; i
< MDOC_MAX
; i
++) {
53 major
= mdoc_macronames
[i
][0];
54 assert((major
>= 65 && major
<= 90) ||
62 minor
= mdoc_macronames
[i
][1];
63 assert((minor
>= 65 && minor
<= 90) ||
65 (minor
>= 97 && minor
<= 122));
74 assert(major
>= 0 && major
< 27);
75 assert(minor
>= 0 && minor
< 26);
77 ind
= (major
* 27) + minor
;
79 assert(NULL
== htab
[ind
]);
80 htab
[ind
] = &mdoc_macros
[i
];
88 mdoc_tokhash_find(const void *arg
, const char *tmp
)
90 int major
, minor
, ind
, slot
;
96 if (0 == tmp
[0] || 0 == tmp
[1])
99 if ( ! (tmp
[0] == 37 || (tmp
[0] >= 65 && tmp
[0] <= 90)))
102 if ( ! ((tmp
[1] >= 65 && tmp
[1] <= 90) ||
104 (tmp
[1] >= 97 && tmp
[1] <= 122)))
114 else if (tmp
[1] <= 90)
119 ind
= (major
* 27) + minor
;
120 if (ind
< 0 || ind
>= (27 * 26))
123 if (NULL
== htab
[ind
])
126 slot
= htab
[ind
] - /* LINTED */
128 assert(0 == (size_t)slot
% sizeof(struct mdoc_macro
));
129 slot
/= sizeof(struct mdoc_macro
);
132 * FIXME: is this necessary, or do we only need to check the
133 * remaining characters (2+)?
136 if (0 != strcmp(mdoc_macronames
[slot
], tmp
))