Annotation of 42BSD/ucb/pascal/src/hash.c, revision 1.1

1.1     ! root        1: /* Copyright (c) 1979 Regents of the University of California */
        !             2: 
        !             3: static char sccsid[] = "@(#)hash.c 1.4 8/29/82";
        !             4: 
        !             5: #include "whoami.h"
        !             6: #include "0.h"
        !             7: #include "yy.h"
        !             8: 
        !             9: /*
        !            10:  * The definition for the segmented hash tables.
        !            11:  */
        !            12: struct ht {
        !            13:        int     *ht_low;
        !            14:        int     *ht_high;
        !            15:        int     ht_used;
        !            16: } htab[MAXHASH];
        !            17: 
        !            18: /*
        !            19:  * This is the array of keywords and their
        !            20:  * token values, which are hashed into the table
        !            21:  * by inithash.
        !            22:  */
        !            23: struct kwtab yykey[] = {
        !            24:        "and",          YAND,
        !            25:        "array",        YARRAY,
        !            26:        "begin",        YBEGIN,
        !            27:        "case",         YCASE,
        !            28:        "const",        YCONST,
        !            29:        "div",          YDIV,
        !            30:        "do",           YDO,
        !            31:        "downto",       YDOWNTO,
        !            32:        "else",         YELSE,
        !            33:        "end",          YEND,
        !            34:        "file",         YFILE,
        !            35:        "for",          YFOR,
        !            36:        "forward",      YFORWARD,
        !            37:        "function",     YFUNCTION,
        !            38:        "goto",         YGOTO,
        !            39:        "if",           YIF,
        !            40:        "in",           YIN,
        !            41:        "label",        YLABEL,
        !            42:        "mod",          YMOD,
        !            43:        "nil",          YNIL,
        !            44:        "not",          YNOT,
        !            45:        "of",           YOF,
        !            46:        "or",           YOR,
        !            47:        "packed",       YPACKED,
        !            48:        "procedure",    YPROCEDURE,
        !            49:        "program",      YPROG,
        !            50:        "record",       YRECORD,
        !            51:        "repeat",       YREPEAT,
        !            52:        "set",          YSET,
        !            53:        "then",         YTHEN,
        !            54:        "to",           YTO,
        !            55:        "type",         YTYPE,
        !            56:        "until",        YUNTIL,
        !            57:        "var",          YVAR,
        !            58:        "while",        YWHILE,
        !            59:        "with",         YWITH,
        !            60:        0,              0,       /* the following keywords are non-standard */
        !            61:        "oct",          YOCT,
        !            62:        "hex",          YHEX,
        !            63:        "external",     YEXTERN,
        !            64:        0
        !            65: };
        !            66: 
        !            67: char *lastkey;
        !            68: 
        !            69: /*
        !            70:  * Inithash initializes the hash table routines
        !            71:  * by allocating the first hash table segment using
        !            72:  * an already existing memory slot.
        !            73:  */
        !            74: #ifndef PI0
        !            75: inithash()
        !            76: #else
        !            77: inithash(hshtab)
        !            78:        int *hshtab;
        !            79: #endif
        !            80: {
        !            81:        register int *ip;
        !            82: #ifndef PI0
        !            83:        static int hshtab[HASHINC];
        !            84: #endif
        !            85: 
        !            86:        htab[0].ht_low = hshtab;
        !            87:        htab[0].ht_high = &hshtab[HASHINC];
        !            88:        for (ip = yykey; *ip; ip += 2)
        !            89:                hash(ip[0], 0)[0] = ip;
        !            90:        /*
        !            91:         * If we are not running in "standard-only" mode,
        !            92:         * we load the non-standard keywords.
        !            93:         */
        !            94:        if (!opt('s'))
        !            95:                for (ip += 2; *ip; ip += 2)
        !            96:                        hash(ip[0], 0)[0] = ip;
        !            97:        lastkey = (char *)ip;
        !            98: }
        !            99: 
        !           100: /*
        !           101:  * Hash looks up the s(ymbol) argument
        !           102:  * in the string table, entering it if
        !           103:  * it is not found. If save is 0, then
        !           104:  * the argument string is already in
        !           105:  * a safe place. Otherwise, if hash is
        !           106:  * entering the symbol for the first time
        !           107:  * it will save the symbol in the string
        !           108:  * table using savestr.
        !           109:  */
        !           110: int *hash(s, save)
        !           111:        char *s;
        !           112:        int save;
        !           113: {
        !           114:        register int *h;
        !           115:        register i;
        !           116:        register char *cp;
        !           117:        int *sym;
        !           118:        struct ht *htp;
        !           119:        int sh;
        !           120: 
        !           121:        /*
        !           122:         * The hash function is a modular hash of
        !           123:         * the sum of the characters with the sum
        !           124:         * doubled before each successive character
        !           125:         * is added.
        !           126:         */
        !           127:        cp = s;
        !           128:        if (cp == NIL)
        !           129:                cp = token;     /* default symbol to be hashed */
        !           130:        i = 0;
        !           131:        while (*cp)
        !           132:                i = i*2 + *cp++;
        !           133:        sh = (i&077777) % HASHINC;
        !           134:        cp = s;
        !           135:        if (cp == NIL)
        !           136:                cp = token;
        !           137:        /*
        !           138:         * There are as many as MAXHASH active
        !           139:         * hash tables at any given point in time.
        !           140:         * The search starts with the first table
        !           141:         * and continues through the active tables
        !           142:         * as necessary.
        !           143:         */
        !           144:        for (htp = htab; htp < &htab[MAXHASH]; htp++) {
        !           145:                if (htp->ht_low == NIL) {
        !           146:                        cp = (char *) calloc(sizeof ( int * ), HASHINC);
        !           147:                        if (cp == 0) {
        !           148:                                yerror("Ran out of memory (hash)");
        !           149:                                pexit(DIED);
        !           150:                        }
        !           151:                        htp->ht_low = cp;
        !           152:                        htp->ht_high = htp->ht_low + HASHINC;
        !           153:                        cp = s;
        !           154:                        if (cp == NIL)
        !           155:                                cp = token;
        !           156:                }
        !           157:                h = htp->ht_low + sh;
        !           158:                /*
        !           159:                 * quadratic rehash increment
        !           160:                 * starts at 1 and incremented
        !           161:                 * by two each rehash.
        !           162:                 */
        !           163:                i = 1;
        !           164:                do {
        !           165:                        if (*h == 0) {
        !           166:                                if (htp->ht_used > (HASHINC * 3)/4)
        !           167:                                        break;
        !           168:                                htp->ht_used++;
        !           169:                                if (save != 0) {
        !           170:                                        *h = (int) savestr(cp);
        !           171:                                } else
        !           172:                                        *h = s;
        !           173:                                return (h);
        !           174:                        }
        !           175:                        sym = *h;
        !           176:                        if (sym < lastkey && sym >= yykey)
        !           177:                                sym = *sym;
        !           178:                        if (sym->pchar == *cp && strcmp(sym, cp) == 0)
        !           179:                                return (h);
        !           180:                        h += i;
        !           181:                        i += 2;
        !           182:                        if (h >= htp->ht_high)
        !           183:                                h -= HASHINC;
        !           184:                } while (i < HASHINC);
        !           185:        }
        !           186:        yerror("Ran out of hash tables");
        !           187:        pexit(DIED);
        !           188: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.