[BACK]Return to mdoc_hash.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Annotation of mandoc/mdoc_hash.c, Revision 1.7

1.7     ! kristaps    1: /*     $Id: mdoc_hash.c,v 1.6 2009/07/17 10:56:27 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:
1.7     ! kristaps  130:        if (ind < 0 || ind >= 26 * 3 * 52)
        !           131:                return(MDOC_MAX);
        !           132:
1.1       kristaps  133:        if (htab[ind]) {
                    134:                slot = htab[ind] - /* LINTED */
                    135:                        (void *)mdoc_macros;
                    136:                assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
                    137:                slot /= sizeof(struct mdoc_macro);
1.6       kristaps  138:                if (SLOTCMP(slot, tmp))
1.1       kristaps  139:                        return(slot);
                    140:                ind++;
                    141:        }
                    142:
                    143:        if (htab[ind]) {
                    144:                slot = htab[ind] - /* LINTED */
                    145:                        (void *)mdoc_macros;
                    146:                assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
                    147:                slot /= sizeof(struct mdoc_macro);
1.6       kristaps  148:                if (SLOTCMP(slot, tmp))
1.1       kristaps  149:                        return(slot);
                    150:                ind++;
                    151:        }
                    152:
                    153:        if (NULL == htab[ind])
                    154:                return(MDOC_MAX);
                    155:        slot = htab[ind] - /* LINTED */
                    156:                (void *)mdoc_macros;
                    157:        assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
                    158:        slot /= sizeof(struct mdoc_macro);
1.6       kristaps  159:        if (SLOTCMP(slot, tmp))
1.1       kristaps  160:                return(slot);
                    161:
                    162:        return(MDOC_MAX);
                    163: }
                    164:

CVSweb