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

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

unix.superglobalmegacorp.com

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