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

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