version 1.6, 2009/07/17 10:56:27 |
version 1.26, 2015/10/06 18:32:19 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> |
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv> |
|
* Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
*/ |
*/ |
|
#include "config.h" |
|
|
|
#include <sys/types.h> |
|
|
#include <assert.h> |
#include <assert.h> |
#include <ctype.h> |
#include <ctype.h> |
|
#include <limits.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <string.h> |
#include <string.h> |
|
|
|
#include "roff.h" |
|
#include "mdoc.h" |
#include "libmdoc.h" |
#include "libmdoc.h" |
|
|
#define ADJUST_MAJOR(x) \ |
static unsigned char table[27 * 12]; |
do if (37 == (x)) \ |
|
(x) = 0; /* % -> 00 */ \ |
|
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_init(void) |
{ |
{ |
|
int i, j, major; |
|
const char *p; |
|
|
free(htab); |
if (*table != '\0') |
} |
return; |
|
|
|
memset(table, UCHAR_MAX, sizeof(table)); |
|
|
|
for (i = 0; i < (int)MDOC_MAX; i++) { |
|
p = mdoc_macronames[i]; |
|
|
void * |
if (isalpha((unsigned char)p[1])) |
mdoc_hash_alloc(void) |
major = 12 * (tolower((unsigned char)p[1]) - 97); |
{ |
else |
int i, major, minor, ind; |
major = 12 * 26; |
const void **htab; |
|
|
|
htab = calloc(26 * 3 * 52, sizeof(struct mdoc_macro *)); |
for (j = 0; j < 12; j++) |
if (NULL == htab) |
if (UCHAR_MAX == table[major + j]) { |
return(NULL); |
table[major + j] = (unsigned char)i; |
|
break; |
|
} |
|
|
for (i = 0; i < MDOC_MAX; i++) { |
assert(j < 12); |
major = mdoc_macronames[i][0]; |
|
assert(isalpha((u_char)major) || 37 == major); |
|
|
|
ADJUST_MAJOR(major); |
|
|
|
minor = mdoc_macronames[i][1]; |
|
assert(isalpha((u_char)minor) || 49 == minor); |
|
|
|
ADJUST_MINOR(minor); |
|
|
|
ind = INDEX(major, minor); |
|
|
|
if (NULL == htab[ind]) { |
|
htab[ind] = &mdoc_macros[i]; |
|
continue; |
|
} |
|
|
|
if (NULL == htab[++ind]) { |
|
htab[ind] = &mdoc_macros[i]; |
|
continue; |
|
} |
|
|
|
assert(NULL == htab[++ind]); |
|
htab[ind] = &mdoc_macros[i]; |
|
} |
} |
|
|
return((void *)htab); |
|
} |
} |
|
|
|
|
int |
int |
mdoc_hash_find(const void *arg, const char *tmp) |
mdoc_hash_find(const char *p) |
{ |
{ |
int major, minor, ind, slot; |
int major, i, j; |
const void **htab; |
|
|
|
htab = /* LINTED */ |
if (0 == p[0]) |
(const void **)arg; |
return TOKEN_NONE; |
|
if ( ! isalpha((unsigned char)p[0]) && '%' != p[0]) |
|
return TOKEN_NONE; |
|
|
if (0 == (major = tmp[0])) |
if (isalpha((unsigned char)p[1])) |
return(MDOC_MAX); |
major = 12 * (tolower((unsigned char)p[1]) - 97); |
if (0 == (minor = tmp[1])) |
else if ('1' == p[1]) |
return(MDOC_MAX); |
major = 12 * 26; |
|
else |
|
return TOKEN_NONE; |
|
|
if (tmp[2] && tmp[3]) |
if (p[2] && p[3]) |
return(MDOC_MAX); |
return TOKEN_NONE; |
|
|
if (37 != major && ! isalpha((u_char)major)) |
for (j = 0; j < 12; j++) { |
return(MDOC_MAX); |
if (UCHAR_MAX == (i = table[major + j])) |
if (49 != minor && ! isalpha((u_char)minor)) |
break; |
return(MDOC_MAX); |
if (0 == strcmp(p, mdoc_macronames[i])) |
|
return i; |
ADJUST_MAJOR(major); |
|
ADJUST_MINOR(minor); |
|
|
|
ind = INDEX(major, minor); |
|
|
|
if (htab[ind]) { |
|
slot = htab[ind] - /* LINTED */ |
|
(void *)mdoc_macros; |
|
assert(0 == (size_t)slot % sizeof(struct mdoc_macro)); |
|
slot /= sizeof(struct mdoc_macro); |
|
if (SLOTCMP(slot, tmp)) |
|
return(slot); |
|
ind++; |
|
} |
} |
|
|
if (htab[ind]) { |
return TOKEN_NONE; |
slot = htab[ind] - /* LINTED */ |
|
(void *)mdoc_macros; |
|
assert(0 == (size_t)slot % sizeof(struct mdoc_macro)); |
|
slot /= sizeof(struct mdoc_macro); |
|
if (SLOTCMP(slot, tmp)) |
|
return(slot); |
|
ind++; |
|
} |
|
|
|
if (NULL == htab[ind]) |
|
return(MDOC_MAX); |
|
slot = htab[ind] - /* LINTED */ |
|
(void *)mdoc_macros; |
|
assert(0 == (size_t)slot % sizeof(struct mdoc_macro)); |
|
slot /= sizeof(struct mdoc_macro); |
|
if (SLOTCMP(slot, tmp)) |
|
return(slot); |
|
|
|
return(MDOC_MAX); |
|
} |
} |
|
|