Annotation of 43BSD/ucb/dbx/names.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: static char sccsid[] = "@(#)names.c    5.1 (Berkeley) 5/31/85";
        !             9: #endif not lint
        !            10: 
        !            11: static char rcsid[] = "$Header: names.c,v 1.4 84/12/26 10:40:47 linton Exp $";
        !            12: 
        !            13: /*
        !            14:  * Name are the internal representation for identifiers.
        !            15:  *
        !            16:  * A hash table is used to map identifiers to names.
        !            17:  */
        !            18: 
        !            19: #include "defs.h"
        !            20: #include "names.h"
        !            21: 
        !            22: #ifndef public
        !            23: typedef struct Name *Name;
        !            24: 
        !            25: /*
        !            26:  * Inline (for speed) function to return the identifier (string)
        !            27:  * associated with a name.  Because C cannot support both inlines
        !            28:  * and data hiding at the same time, the Name structure must be
        !            29:  * publicly visible.  It is not used explicitly, however, outside of this file.
        !            30:  */
        !            31: 
        !            32: struct Name {
        !            33:     char *identifier;
        !            34:     Name chain;
        !            35: };
        !            36: 
        !            37: #define ident(n) ((n == nil) ? "(noname)" : n->identifier)
        !            38: #endif
        !            39: 
        !            40: #define HASHTABLESIZE 2997
        !            41: 
        !            42: private Name nametable[HASHTABLESIZE];
        !            43: 
        !            44: /*
        !            45:  * Names are allocated in large chunks to avoid calls to malloc
        !            46:  * and to cluster names in memory so that tracing hash chains
        !            47:  * doesn't cause many a page fault.
        !            48:  */
        !            49: 
        !            50: #define CHUNKSIZE 200
        !            51: 
        !            52: typedef struct Namepool {
        !            53:     struct Name name[CHUNKSIZE];
        !            54:     struct Namepool *prevpool;
        !            55: } *Namepool;
        !            56: 
        !            57: private Namepool namepool = nil;
        !            58: private Integer nleft = 0;
        !            59: 
        !            60: /*
        !            61:  * Given an identifier, convert it to a name.
        !            62:  * If it's not in the hash table, then put it there.
        !            63:  *
        !            64:  * The second argument specifies whether the string should be copied
        !            65:  * into newly allocated space if not found.
        !            66:  *
        !            67:  * Pardon my use of goto's, but it seemed more efficient and less convoluted
        !            68:  * than adding a collection of boolean variables.  This routine is time
        !            69:  * critical when starting up the debugger on large programs.
        !            70:  */
        !            71: 
        !            72: public Name identname(s, isallocated)
        !            73: String s;
        !            74: Boolean isallocated;
        !            75: {
        !            76:     register unsigned h;
        !            77:     register Char *p, *q;
        !            78:     register Name n;
        !            79:     register Integer len;
        !            80:     Namepool newpool;
        !            81: 
        !            82:     h = 0;
        !            83:     for (p = s; *p != '\0'; p++) {
        !            84:        h = (h << 1) ^ (*p);
        !            85:     }
        !            86:     h = h mod HASHTABLESIZE;
        !            87:     len = p - s;
        !            88:     n = nametable[h];
        !            89:     while (n != nil) {
        !            90:        p = s;
        !            91:        q = n->identifier;
        !            92:        for (;;) {
        !            93:            if (*p != *q) {
        !            94:                goto nomatch;
        !            95:            } else if (*p == '\0') {
        !            96:                goto match;
        !            97:            }
        !            98:            ++p;
        !            99:            ++q;
        !           100:        }
        !           101:     nomatch:
        !           102:        n = n->chain;
        !           103:     }
        !           104: 
        !           105:     /*
        !           106:      * Now we know that name hasn't been found (otherwise we'd have jumped
        !           107:      * down to match), so we allocate a name, store the identifier, and
        !           108:      * enter it in the hash table.
        !           109:      */
        !           110:     if (nleft <= 0) {
        !           111:        newpool = new(Namepool);
        !           112:        bzero(newpool, sizeof(newpool));
        !           113:        newpool->prevpool = namepool;
        !           114:        namepool = newpool;
        !           115:        nleft = CHUNKSIZE;
        !           116:     }
        !           117:     --nleft;
        !           118:     n = &(namepool->name[nleft]);
        !           119:     if (isallocated) {
        !           120:        n->identifier = s;
        !           121:     } else {
        !           122:        n->identifier = newarr(char, len + 1);
        !           123:        p = s;
        !           124:        q = n->identifier;
        !           125:        while (*p != '\0') {
        !           126:            *q++ = *p++;
        !           127:        }
        !           128:        *q = '\0';
        !           129:     }
        !           130:     n->chain = nametable[h];
        !           131:     nametable[h] = n;
        !           132: 
        !           133:     /*
        !           134:      * The two possibilities (name known versus unknown) rejoin.
        !           135:      */
        !           136: match:
        !           137:     return n;
        !           138: }
        !           139: 
        !           140: /*
        !           141:  * Deallocate the name table.
        !           142:  */
        !           143: 
        !           144: public names_free()
        !           145: {
        !           146:     Namepool n, m;
        !           147:     register integer i;
        !           148: 
        !           149:     n = namepool;
        !           150:     while (n != nil) {
        !           151:        m = n->prevpool;
        !           152:        dispose(n);
        !           153:        n = m;
        !           154:     }
        !           155:     for (i = 0; i < HASHTABLESIZE; i++) {
        !           156:        nametable[i] = nil;
        !           157:     }
        !           158:     namepool = nil;
        !           159:     nleft = 0;
        !           160: }

unix.superglobalmegacorp.com

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