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

Annotation of mandoc/mdoc_hash.c, Revision 1.8

1.8     ! kristaps    1: /*     $Id: mdoc_hash.c,v 1.7 2009/07/17 11:00:18 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:  */
1.8     ! kristaps   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.6       kristaps   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
1.2       kristaps   56: mdoc_hash_free(void *htab)
1.1       kristaps   57: {
                     58:
                     59:        free(htab);
                     60: }
                     61:
                     62:
1.6       kristaps   63:
1.1       kristaps   64: void *
1.2       kristaps   65: mdoc_hash_alloc(void)
1.1       kristaps   66: {
                     67:        int               i, major, minor, ind;
                     68:        const void      **htab;
                     69:
1.6       kristaps   70:        htab = calloc(26 * 3 * 52, sizeof(struct mdoc_macro *));
1.1       kristaps   71:        if (NULL == htab)
1.2       kristaps   72:                return(NULL);
1.1       kristaps   73:
1.5       kristaps   74:        for (i = 0; i < MDOC_MAX; i++) {
1.1       kristaps   75:                major = mdoc_macronames[i][0];
1.6       kristaps   76:                assert(isalpha((u_char)major) || 37 == major);
1.1       kristaps   77:
1.6       kristaps   78:                ADJUST_MAJOR(major);
1.1       kristaps   79:
                     80:                minor = mdoc_macronames[i][1];
1.6       kristaps   81:                assert(isalpha((u_char)minor) || 49 == minor);
1.1       kristaps   82:
1.6       kristaps   83:                ADJUST_MINOR(minor);
1.1       kristaps   84:
1.6       kristaps   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
1.2       kristaps  106: mdoc_hash_find(const void *arg, const char *tmp)
1.1       kristaps  107: {
                    108:        int               major, minor, ind, slot;
                    109:        const void      **htab;
                    110:
                    111:        htab = /* LINTED */
                    112:                (const void **)arg;
                    113:
1.6       kristaps  114:        if (0 == (major = tmp[0]))
                    115:                return(MDOC_MAX);
                    116:        if (0 == (minor = tmp[1]))
1.1       kristaps  117:                return(MDOC_MAX);
1.6       kristaps  118:
1.1       kristaps  119:        if (tmp[2] && tmp[3])
                    120:                return(MDOC_MAX);
                    121:
1.6       kristaps  122:        if (37 != major && ! isalpha((u_char)major))
1.1       kristaps  123:                return(MDOC_MAX);
1.6       kristaps  124:        if (49 != minor && ! isalpha((u_char)minor))
1.1       kristaps  125:                return(MDOC_MAX);
                    126:
1.6       kristaps  127:        ADJUST_MAJOR(major);
                    128:        ADJUST_MINOR(minor);
1.1       kristaps  129:
1.6       kristaps  130:        ind = INDEX(major, minor);
1.1       kristaps  131:
1.7       kristaps  132:        if (ind < 0 || ind >= 26 * 3 * 52)
                    133:                return(MDOC_MAX);
                    134:
1.1       kristaps  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.6       kristaps  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.6       kristaps  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.6       kristaps  161:        if (SLOTCMP(slot, tmp))
1.1       kristaps  162:                return(slot);
                    163:
                    164:        return(MDOC_MAX);
                    165: }
                    166:

CVSweb