[BACK]Return to mdoc_hash.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mandoc

Annotation of src/usr.bin/mandoc/mdoc_hash.c, Revision 1.5

1.5     ! schwarze    1: /*     $Id: mdoc_hash.c,v 1.4 2009/07/26 01:08:13 schwarze Exp $ */
1.1       kristaps    2: /*
1.2       schwarze    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.2       schwarze    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.2       schwarze    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:  */
1.5     ! schwarze   17: #include <sys/types.h>
        !            18:
1.1       kristaps   19: #include <assert.h>
                     20: #include <ctype.h>
                     21: #include <stdlib.h>
                     22: #include <stdio.h>
                     23: #include <string.h>
                     24:
                     25: #include "libmdoc.h"
                     26:
1.4       schwarze   27: #define        ADJUST_MAJOR(x)                                         \
                     28:        do if (37 == (x))                                       \
                     29:                (x) = 0;                /* %   -> 00 */         \
                     30:        else if (91 > (x))                                      \
                     31:                (x) -= 64;              /* A-Z -> 01 - 26 */    \
                     32:        else                                                    \
                     33:                (x) -= 70;              /* a-z -> 27 - 52 */    \
                     34:        while (/*CONSTCOND*/0)
                     35:
                     36: #define ADJUST_MINOR(y)                                                \
                     37:        do if (49 == (y))                                       \
                     38:                (y) = 0;                /* 1   -> 00 */         \
                     39:        else if (91 > (y))                                      \
                     40:                (y) -= 65;              /* A-Z -> 00 - 25 */    \
                     41:        else                                                    \
                     42:                (y) -= 97;              /* a-z -> 00 - 25 */    \
                     43:        while (/*CONSTCOND*/0)
                     44:
                     45: #define INDEX(maj, min)                                        \
                     46:        ((maj) * 26 * 3) + ((min) * 3)
                     47:
                     48: #define        SLOTCMP(slot, val)                                      \
                     49:        (mdoc_macronames[(slot)][0] == (val)[0] &&              \
                     50:         mdoc_macronames[(slot)][1] == (val)[1] &&              \
                     51:         (0 == (val)[2] ||                                      \
                     52:          mdoc_macronames[(slot)][2] == (val)[2]))
                     53:
1.1       kristaps   54:
                     55: void
                     56: mdoc_hash_free(void *htab)
                     57: {
                     58:
                     59:        free(htab);
                     60: }
                     61:
                     62:
1.4       schwarze   63:
1.1       kristaps   64: void *
                     65: mdoc_hash_alloc(void)
                     66: {
                     67:        int               i, major, minor, ind;
                     68:        const void      **htab;
                     69:
1.4       schwarze   70:        htab = calloc(26 * 3 * 52, sizeof(struct mdoc_macro *));
1.1       kristaps   71:        if (NULL == htab)
                     72:                return(NULL);
                     73:
1.3       schwarze   74:        for (i = 0; i < MDOC_MAX; i++) {
1.1       kristaps   75:                major = mdoc_macronames[i][0];
1.4       schwarze   76:                assert(isalpha((u_char)major) || 37 == major);
1.1       kristaps   77:
1.4       schwarze   78:                ADJUST_MAJOR(major);
1.1       kristaps   79:
                     80:                minor = mdoc_macronames[i][1];
1.4       schwarze   81:                assert(isalpha((u_char)minor) || 49 == minor);
1.1       kristaps   82:
1.4       schwarze   83:                ADJUST_MINOR(minor);
1.1       kristaps   84:
1.4       schwarze   85:                ind = INDEX(major, minor);
1.1       kristaps   86:
                     87:                if (NULL == htab[ind]) {
                     88:                        htab[ind] = &mdoc_macros[i];
                     89:                        continue;
                     90:                }
                     91:
                     92:                if (NULL == htab[++ind]) {
                     93:                        htab[ind] = &mdoc_macros[i];
                     94:                        continue;
                     95:                }
                     96:
                     97:                assert(NULL == htab[++ind]);
                     98:                htab[ind] = &mdoc_macros[i];
                     99:        }
                    100:
                    101:        return((void *)htab);
                    102: }
                    103:
                    104:
                    105: int
                    106: mdoc_hash_find(const void *arg, const char *tmp)
                    107: {
                    108:        int               major, minor, ind, slot;
                    109:        const void      **htab;
                    110:
                    111:        htab = /* LINTED */
                    112:                (const void **)arg;
                    113:
1.4       schwarze  114:        if (0 == (major = tmp[0]))
1.1       kristaps  115:                return(MDOC_MAX);
1.4       schwarze  116:        if (0 == (minor = tmp[1]))
                    117:                return(MDOC_MAX);
                    118:
1.1       kristaps  119:        if (tmp[2] && tmp[3])
                    120:                return(MDOC_MAX);
                    121:
1.4       schwarze  122:        if (37 != major && ! isalpha((u_char)major))
1.1       kristaps  123:                return(MDOC_MAX);
1.4       schwarze  124:        if (49 != minor && ! isalpha((u_char)minor))
1.1       kristaps  125:                return(MDOC_MAX);
                    126:
1.4       schwarze  127:        ADJUST_MAJOR(major);
                    128:        ADJUST_MINOR(minor);
1.1       kristaps  129:
1.4       schwarze  130:        ind = INDEX(major, minor);
1.1       kristaps  131:
1.4       schwarze  132:        if (ind < 0 || ind >= 26 * 3 * 52)
1.1       kristaps  133:                return(MDOC_MAX);
                    134:
                    135:        if (htab[ind]) {
                    136:                slot = htab[ind] - /* LINTED */
                    137:                        (void *)mdoc_macros;
                    138:                assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
                    139:                slot /= sizeof(struct mdoc_macro);
1.4       schwarze  140:                if (SLOTCMP(slot, tmp))
1.1       kristaps  141:                        return(slot);
                    142:                ind++;
                    143:        }
                    144:
                    145:        if (htab[ind]) {
                    146:                slot = htab[ind] - /* LINTED */
                    147:                        (void *)mdoc_macros;
                    148:                assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
                    149:                slot /= sizeof(struct mdoc_macro);
1.4       schwarze  150:                if (SLOTCMP(slot, tmp))
1.1       kristaps  151:                        return(slot);
                    152:                ind++;
                    153:        }
                    154:
                    155:        if (NULL == htab[ind])
                    156:                return(MDOC_MAX);
                    157:        slot = htab[ind] - /* LINTED */
                    158:                (void *)mdoc_macros;
                    159:        assert(0 == (size_t)slot % sizeof(struct mdoc_macro));
                    160:        slot /= sizeof(struct mdoc_macro);
1.4       schwarze  161:        if (SLOTCMP(slot, tmp))
1.1       kristaps  162:                return(slot);
                    163:
                    164:        return(MDOC_MAX);
                    165: }
                    166: