version 1.4, 2009/06/10 20:18:43 |
version 1.6, 2009/07/17 10:56:27 |
|
|
|
|
#include "libmdoc.h" |
#include "libmdoc.h" |
|
|
/* |
#define ADJUST_MAJOR(x) \ |
* Routines for the perfect-hash hashtable used by the parser to look up |
do if (37 == (x)) \ |
* tokens by their string-ified names (`.Fl' -> MDOC_Fl). The |
(x) = 0; /* % -> 00 */ \ |
* allocation penalty for this is 27 * 26 * sizeof(ptr). |
else if (91 > (x)) \ |
*/ |
(x) -= 64; /* A-Z -> 01 - 26 */ \ |
|
else \ |
|
(x) -= 70; /* a-z -> 27 - 52 */ \ |
|
while (/*CONSTCOND*/0) |
|
|
|
#define ADJUST_MINOR(y) \ |
|
do if (49 == (y)) \ |
|
(y) = 0; /* 1 -> 00 */ \ |
|
else if (91 > (y)) \ |
|
(y) -= 65; /* A-Z -> 00 - 25 */ \ |
|
else \ |
|
(y) -= 97; /* a-z -> 00 - 25 */ \ |
|
while (/*CONSTCOND*/0) |
|
|
|
#define INDEX(maj, min) \ |
|
((maj) * 26 * 3) + ((min) * 3) |
|
|
|
#define SLOTCMP(slot, val) \ |
|
(mdoc_macronames[(slot)][0] == (val)[0] && \ |
|
mdoc_macronames[(slot)][1] == (val)[1] && \ |
|
(0 == (val)[2] || \ |
|
mdoc_macronames[(slot)][2] == (val)[2])) |
|
|
|
|
void |
void |
mdoc_hash_free(void *htab) |
mdoc_hash_free(void *htab) |
{ |
{ |
Line 36 mdoc_hash_free(void *htab) |
|
Line 58 mdoc_hash_free(void *htab) |
|
} |
} |
|
|
|
|
|
|
void * |
void * |
mdoc_hash_alloc(void) |
mdoc_hash_alloc(void) |
{ |
{ |
int i, major, minor, ind; |
int i, major, minor, ind; |
const void **htab; |
const void **htab; |
|
|
htab = calloc(27 * 26 * 3, sizeof(struct mdoc_macro *)); |
htab = calloc(26 * 3 * 52, sizeof(struct mdoc_macro *)); |
if (NULL == htab) |
if (NULL == htab) |
return(NULL); |
return(NULL); |
|
|
for (i = 1; i < MDOC_MAX; i++) { |
for (i = 0; i < MDOC_MAX; i++) { |
major = mdoc_macronames[i][0]; |
major = mdoc_macronames[i][0]; |
assert((major >= 65 && major <= 90) || |
assert(isalpha((u_char)major) || 37 == major); |
major == 37); |
|
|
|
if (major == 37) |
ADJUST_MAJOR(major); |
major = 0; |
|
else |
|
major -= 64; |
|
|
|
minor = mdoc_macronames[i][1]; |
minor = mdoc_macronames[i][1]; |
assert((minor >= 65 && minor <= 90) || |
assert(isalpha((u_char)minor) || 49 == minor); |
(minor == 49) || |
|
(minor >= 97 && minor <= 122)); |
|
|
|
if (minor == 49) |
ADJUST_MINOR(minor); |
minor = 0; |
|
else if (minor <= 90) |
|
minor -= 65; |
|
else |
|
minor -= 97; |
|
|
|
assert(major >= 0 && major < 27); |
ind = INDEX(major, minor); |
assert(minor >= 0 && minor < 26); |
|
|
|
ind = (major * 27 * 3) + (minor * 3); |
|
|
|
if (NULL == htab[ind]) { |
if (NULL == htab[ind]) { |
htab[ind] = &mdoc_macros[i]; |
htab[ind] = &mdoc_macros[i]; |
continue; |
continue; |
Line 100 mdoc_hash_find(const void *arg, const char *tmp) |
|
Line 109 mdoc_hash_find(const void *arg, const char *tmp) |
|
htab = /* LINTED */ |
htab = /* LINTED */ |
(const void **)arg; |
(const void **)arg; |
|
|
if (0 == tmp[0] || 0 == tmp[1]) |
if (0 == (major = tmp[0])) |
return(MDOC_MAX); |
return(MDOC_MAX); |
if (tmp[2] && tmp[3]) |
if (0 == (minor = tmp[1])) |
return(MDOC_MAX); |
return(MDOC_MAX); |
|
|
if ( ! (tmp[0] == 37 || (tmp[0] >= 65 && tmp[0] <= 90))) |
if (tmp[2] && tmp[3]) |
return(MDOC_MAX); |
return(MDOC_MAX); |
|
|
if ( ! ((tmp[1] >= 65 && tmp[1] <= 90) || |
if (37 != major && ! isalpha((u_char)major)) |
(tmp[1] == 49) || |
|
(tmp[1] >= 97 && tmp[1] <= 122))) |
|
return(MDOC_MAX); |
return(MDOC_MAX); |
|
if (49 != minor && ! isalpha((u_char)minor)) |
|
return(MDOC_MAX); |
|
|
if (tmp[0] == 37) |
ADJUST_MAJOR(major); |
major = 0; |
ADJUST_MINOR(minor); |
else |
|
major = tmp[0] - 64; |
|
|
|
if (tmp[1] == 49) |
ind = INDEX(major, minor); |
minor = 0; |
|
else if (tmp[1] <= 90) |
|
minor = tmp[1] - 65; |
|
else |
|
minor = tmp[1] - 97; |
|
|
|
ind = (major * 27 * 3) + (minor * 3); |
|
if (ind < 0 || ind >= (27 * 26 * 3)) |
|
return(MDOC_MAX); |
|
|
|
if (htab[ind]) { |
if (htab[ind]) { |
slot = htab[ind] - /* LINTED */ |
slot = htab[ind] - /* LINTED */ |
(void *)mdoc_macros; |
(void *)mdoc_macros; |
assert(0 == (size_t)slot % sizeof(struct mdoc_macro)); |
assert(0 == (size_t)slot % sizeof(struct mdoc_macro)); |
slot /= sizeof(struct mdoc_macro); |
slot /= sizeof(struct mdoc_macro); |
if (mdoc_macronames[slot][0] == tmp[0] && |
if (SLOTCMP(slot, tmp)) |
mdoc_macronames[slot][1] == tmp[1] && |
|
(0 == tmp[2] || |
|
mdoc_macronames[slot][2] == tmp[2])) |
|
return(slot); |
return(slot); |
ind++; |
ind++; |
} |
} |
Line 147 mdoc_hash_find(const void *arg, const char *tmp) |
|
Line 142 mdoc_hash_find(const void *arg, const char *tmp) |
|
(void *)mdoc_macros; |
(void *)mdoc_macros; |
assert(0 == (size_t)slot % sizeof(struct mdoc_macro)); |
assert(0 == (size_t)slot % sizeof(struct mdoc_macro)); |
slot /= sizeof(struct mdoc_macro); |
slot /= sizeof(struct mdoc_macro); |
if (mdoc_macronames[slot][0] == tmp[0] && |
if (SLOTCMP(slot, tmp)) |
mdoc_macronames[slot][1] == tmp[1] && |
|
(0 == tmp[2] || |
|
mdoc_macronames[slot][2] == tmp[2])) |
|
return(slot); |
return(slot); |
ind++; |
ind++; |
} |
} |
Line 161 mdoc_hash_find(const void *arg, const char *tmp) |
|
Line 153 mdoc_hash_find(const void *arg, const char *tmp) |
|
(void *)mdoc_macros; |
(void *)mdoc_macros; |
assert(0 == (size_t)slot % sizeof(struct mdoc_macro)); |
assert(0 == (size_t)slot % sizeof(struct mdoc_macro)); |
slot /= sizeof(struct mdoc_macro); |
slot /= sizeof(struct mdoc_macro); |
if (mdoc_macronames[slot][0] == tmp[0] && |
if (SLOTCMP(slot, tmp)) |
mdoc_macronames[slot][1] == tmp[1] && |
|
(0 == tmp[2] || |
|
mdoc_macronames[slot][2] == tmp[2])) |
|
return(slot); |
return(slot); |
|
|
return(MDOC_MAX); |
return(MDOC_MAX); |