Annotation of coherent/a/usr/bob/korn/table.c, revision 1.1

1.1     ! root        1: static char *RCSid = "$Header: table.c,v 3.1 88/11/03 09:17:53 egisin Exp $";
        !             2: 
        !             3: /*
        !             4:  * dynamic hashed associative table for commands and variables
        !             5:  */
        !             6: 
        !             7: #include <stddef.h>
        !             8: #include <stdlib.h>
        !             9: #include <errno.h>
        !            10: #include <setjmp.h>
        !            11: #include "sh.h"
        !            12: #include "table.h"
        !            13: 
        !            14: #define        INIT_TBLS       8       /* initial table size (power of 2) */
        !            15: 
        !            16: static struct tstate {
        !            17:        int left;
        !            18:        struct tbl **next;
        !            19: } tstate;
        !            20: 
        !            21: static void texpand();
        !            22: 
        !            23: unsigned int
        !            24: hash(n)
        !            25:        register char * n;
        !            26: {
        !            27:        register unsigned int h = 0;
        !            28: 
        !            29:        while (*n != '\0')
        !            30:                h = 2*h + *n++;
        !            31:        return h * (unsigned)32821L;    /* scatter bits */
        !            32: }
        !            33: 
        !            34: #if 0
        !            35: phash(s) char *s; {
        !            36:        printf("%2d: %s\n", hash(s)%32, s);
        !            37: }
        !            38: #endif
        !            39: 
        !            40: void
        !            41: tinit(tp, ap)
        !            42:        register struct table *tp;
        !            43:        register Area *ap;
        !            44: {
        !            45:        tp->areap = ap;
        !            46:        tp->size = tp->free = 0;
        !            47:        tp->tbls = NULL;
        !            48: }
        !            49: 
        !            50: static void
        !            51: texpand(tp, nsize)
        !            52:        register struct table *tp;
        !            53:        int nsize;
        !            54: {
        !            55:        register int i;
        !            56:        register struct tbl *tblp, **p;
        !            57:        register struct tbl **ntblp, **otblp = tp->tbls;
        !            58:        int osize = tp->size;
        !            59: 
        !            60:        ntblp = alloc(sizeofN(struct tbl *, nsize), tp->areap);
        !            61:        for (i = 0; i < nsize; i++)
        !            62:                ntblp[i] = NULL;
        !            63:        tp->size = nsize;
        !            64:        tp->free = 8*nsize/10;  /* table can get 80% full */
        !            65:        tp->tbls = ntblp;
        !            66:        if (otblp == NULL)
        !            67:                return;
        !            68:        for (i = 0; i < osize; i++)
        !            69:                if ((tblp = otblp[i]) != NULL)
        !            70:                        if ((tblp->flag&DEFINED)) {
        !            71:                                for (p = &ntblp[hash(tblp->name) & tp->size-1];
        !            72:                                     *p != NULL; p--)
        !            73:                                        if (p == ntblp) /* wrap */
        !            74:                                                p += tp->size;
        !            75:                                *p = tblp;
        !            76:                                tp->free--;
        !            77:                        } else {
        !            78:                                afree((Void*)tblp, tp->areap);
        !            79:                        }
        !            80:        afree((Void*)otblp, tp->areap);
        !            81: }
        !            82: 
        !            83: struct tbl *
        !            84: tsearch(tp, n, h)
        !            85:        register struct table *tp;      /* table */
        !            86:        register char *n;               /* name to enter */
        !            87:        unsigned int h;                 /* hash(n) */
        !            88: {
        !            89:        register struct tbl **pp, *p;
        !            90: 
        !            91:        if (tp->size == 0)
        !            92:                return NULL;
        !            93: 
        !            94:        /* search for name in hashed table */
        !            95:        for (pp = &tp->tbls[h & tp->size-1]; (p = *pp) != NULL; pp--) {
        !            96:                if (*p->name == *n && strcmp(p->name, n) == 0
        !            97:                    && (p->flag&DEFINED))
        !            98:                        return p;
        !            99:                if (pp == tp->tbls) /* wrap */
        !           100:                        pp += tp->size;
        !           101:        }
        !           102: 
        !           103:        return NULL;
        !           104: }
        !           105: 
        !           106: struct tbl *
        !           107: tenter(tp, n, h)
        !           108:        register struct table *tp;      /* table */
        !           109:        register char *n;               /* name to enter */
        !           110:        unsigned int h;                 /* hash(n) */
        !           111: {
        !           112:        register struct tbl **pp, *p;
        !           113:        register char *cp;
        !           114: 
        !           115:        if (tp->size == 0)
        !           116:                texpand(tp, INIT_TBLS);
        !           117:   Search:
        !           118:        /* search for name in hashed table */
        !           119:        for (pp = &tp->tbls[h & tp->size-1]; (p = *pp) != NULL; pp--) {
        !           120:                if (*p->name == *n && strcmp(p->name, n) == 0)
        !           121:                        return p;       /* found */
        !           122:                if (pp == tp->tbls) /* wrap */
        !           123:                        pp += tp->size;
        !           124:        }
        !           125: 
        !           126:        if (tp->free <= 0) {    /* too full */
        !           127:                texpand(tp, 2*tp->size);
        !           128:                goto Search;
        !           129:        }
        !           130: 
        !           131:        /* create new tbl entry */
        !           132:        for (cp = n; *cp != '\0'; cp++)
        !           133:                ;
        !           134:        p = (struct tbl *) alloc(offsetof(struct tbl, name[(cp-n)+1]), tp->areap);
        !           135:        p->flag = 0;
        !           136:        p->type = 0;
        !           137:        for (cp = p->name; *n != '\0';)
        !           138:                *cp++ = *n++;
        !           139:        *cp = '\0';
        !           140: 
        !           141:        /* enter in tp->tbls */
        !           142:        tp->free--;
        !           143:        *pp = p;
        !           144:        return p;
        !           145: }
        !           146: 
        !           147: void
        !           148: tdelete(p)
        !           149:        register struct tbl *p;
        !           150: {
        !           151:        p->flag = 0;
        !           152: }
        !           153: 
        !           154: void
        !           155: twalk(tp)
        !           156:        register struct table *tp;
        !           157: {
        !           158:        tstate.left = tp->size;
        !           159:        tstate.next = tp->tbls;
        !           160: }
        !           161: 
        !           162: struct tbl *
        !           163: tnext()
        !           164: {
        !           165:        while (--tstate.left >= 0) {
        !           166:                struct tbl *p = *tstate.next++;
        !           167:                if (p != NULL && (p->flag&DEFINED))
        !           168:                        return p;
        !           169:        }
        !           170:        return NULL;
        !           171: }
        !           172: 
        !           173: static int
        !           174: tnamecmp(p1, p2)
        !           175:        Void *p1, *p2;
        !           176: {
        !           177:        return strcmp(((struct tbl *)p1)->name, ((struct tbl *)p2)->name);
        !           178: }
        !           179: 
        !           180: struct tbl **
        !           181: tsort(tp)
        !           182:        register struct table *tp;
        !           183: {
        !           184:        register int i;
        !           185:        register struct tbl **p, **sp, **dp;
        !           186: 
        !           187:        p = (struct tbl **)alloc(sizeofN(struct tbl *, tp->size+1), ATEMP);
        !           188:        sp = tp->tbls;          /* source */
        !           189:        dp = p;                 /* dest */
        !           190:        for (i = 0; i < tp->size; i++)
        !           191:                if ((*dp = *sp++) != NULL && ((*dp)->flag&DEFINED))
        !           192:                        dp++;
        !           193:        i = dp - p;
        !           194:        qsortp((Void**)p, (size_t)i, tnamecmp);
        !           195:        p[i] = NULL;
        !           196:        return p;
        !           197: }
        !           198: 

unix.superglobalmegacorp.com

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