Annotation of researchv10dc/cmd/tsort/subs.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include "ts.h"
        !             3: 
        !             4: #define HSIZE 307
        !             5: #define ALSIZE 2040
        !             6: 
        !             7: static struct obj **objhash, *cobj = 0, *lastobj;
        !             8: static struct ref **refhash;
        !             9: static struct group **grouphash, *group0;
        !            10: struct ref *undefrefs = 0, *defedrefs = 0;
        !            11: struct group *cgroup = 0; /* current group */
        !            12: struct obj *obj0 = 0; /* special null object */
        !            13: 
        !            14: unsigned lasthash = 0, ngroup = 0, nrefc = 0;
        !            15: int nextseq;
        !            16: 
        !            17: char *malloc(), *strcpy();
        !            18: extern char *progname;
        !            19: extern int cyclep, verbose, verify;
        !            20: 
        !            21: init(){
        !            22:        int i;
        !            23: 
        !            24:        objhash = (struct obj **) malloc(HSIZE*sizeof(struct obj *));
        !            25:        refhash = (struct ref **) malloc(HSIZE*sizeof(struct ref *));
        !            26:        grouphash = (struct group **) malloc(HSIZE*sizeof(struct group *));
        !            27:        if (!objhash || !refhash || !grouphash)
        !            28:                scream("initial mallocs fail\n","");
        !            29:        for (i = 0; i < HSIZE; i++)
        !            30:                { objhash[i] = 0; refhash[i] = 0; grouphash[i] = 0;}
        !            31:        cgroup = 0;
        !            32:        newgroup("");
        !            33:        group0 = cgroup;
        !            34:        newobj("",1);
        !            35:        obj0 = cobj;
        !            36:        }
        !            37: 
        !            38: unsigned
        !            39: hash(s)
        !            40: unsigned char *s;
        !            41: {
        !            42:        unsigned x = 0;
        !            43:        unsigned char c;
        !            44: 
        !            45:        while(c = *s++) x = (x<<1) + c;
        !            46:        return x % HSIZE;
        !            47:        }
        !            48: 
        !            49: char *
        !            50: newstruct(n)
        !            51: unsigned n;
        !            52: {
        !            53:        static char *next = 0, *last = 0;
        !            54:        char *s;
        !            55: 
        !            56:        if (next + n > last) {
        !            57:                next = malloc(ALSIZE);
        !            58:                if (!next) scream("malloc fails in newstruct\n","");
        !            59:                last = next + ALSIZE;
        !            60:                }
        !            61:        s = next;
        !            62:        next += n;
        !            63:        return s;
        !            64:        }
        !            65: 
        !            66: char *
        !            67: newstring(s)
        !            68: char *s;
        !            69: {
        !            70:        static char *next = 0, *last = 0;
        !            71:        char *s1;
        !            72:        unsigned n, strlen();
        !            73: 
        !            74:        n = strlen(s) + 1;
        !            75:        if (next + n > last) {
        !            76:                next = malloc(ALSIZE);
        !            77:                if (!next) scream("malloc fails in newstring\n","");
        !            78:                last = next + ALSIZE;
        !            79:                }
        !            80:        s1 = next;
        !            81:        next += n;
        !            82:        strcpy(s1,s);
        !            83:        return s1;
        !            84:        }
        !            85: 
        !            86: newgroup(s)
        !            87: char *s;
        !            88: {
        !            89:        struct group *g, *gnext = 0, *gprev;
        !            90: 
        !            91:        cobj = 0;
        !            92:        gprev = (struct group *) &grouphash[hash(s)];
        !            93:        g = gprev->next;
        !            94:        for(;; gprev = g, g = g->next) {
        !            95:                if (!g) {
        !            96:                        g = (struct group *)
        !            97:                                newstruct(sizeof(struct group));
        !            98:                        g->name = newstring(s);
        !            99:                        g->next = 0;
        !           100:                        g->gseq = ngroup++;
        !           101:                        gprev->next = g;
        !           102:                        break;
        !           103:                        }
        !           104:                if (!strcmp(s,g->name)) break;
        !           105:                }
        !           106:        cgroup = g;
        !           107:        }
        !           108: 
        !           109: struct ref *
        !           110: lookup(s,add)
        !           111: char *s;
        !           112: int add;
        !           113: {
        !           114:        struct ref *h, *hprev;
        !           115: 
        !           116:        hprev = (struct ref *) &refhash[lasthash = hash(s)];
        !           117:        h = hprev->next;
        !           118:        while(h) {
        !           119:                if (!strcmp(h->name,s)) return h;
        !           120:                hprev = h;
        !           121:                h = h->next;
        !           122:                }
        !           123:        if (add) {
        !           124:                h = (struct ref *) newstruct(sizeof(struct ref));
        !           125:                hprev->next = h;
        !           126:                h->next = 0;
        !           127:                h->name = cobj && !strcmp(cobj->name,s) ? cobj->name : newstring(s);
        !           128:                h->robj = 0;
        !           129:                }
        !           130:        return h;
        !           131:        }
        !           132: 
        !           133: newobj(s,dup)
        !           134: char *s;
        !           135: int dup;
        !           136: {
        !           137:        struct obj *h, *hnext = 0, *hprev, *o;
        !           138:        struct ref *r1;
        !           139: 
        !           140:        hprev = (struct obj *) &objhash[hash(s)];
        !           141:        h = hprev->next;
        !           142:        while(h) {
        !           143:                if (!strcmp(h->name,s) && h->ogroup == cgroup) {
        !           144:                        if (dup || h == obj0) { cobj = h; return; }
        !           145:                        if (verbose) {
        !           146:                                fprintf(stderr, "duplicate %s", s);
        !           147:                                if (*cgroup->name) fprintf(stderr, " in %s", cgroup->name);
        !           148:                                fputs(" ignored\n", stderr);
        !           149:                                }
        !           150:                        cobj = 0;
        !           151:                        return;
        !           152:                        }
        !           153:                hprev = h;
        !           154:                h = h->next;
        !           155:                }
        !           156:        cobj = o = (struct obj *) newstruct(sizeof(struct obj));
        !           157:        hprev->next = o;
        !           158:        o->next = hnext;
        !           159:        r1 = lookup(s,0);
        !           160:        o->name = r1 ? r1->name : newstring(s);
        !           161:        o->ogroup = cgroup;
        !           162:        o->seq = o->iptr = o->jct = 0;
        !           163:        }
        !           164: 
        !           165: defobjref(s,dup)
        !           166: char *s;
        !           167: int dup;
        !           168: {
        !           169:        rdefobjref(lookup(s,1), s, dup);
        !           170:        }
        !           171: 
        !           172: rdefobjref(r,s,dup)
        !           173: struct ref *r;
        !           174: char *s;
        !           175: int dup;
        !           176: {
        !           177:        struct obj *o;
        !           178: 
        !           179:        if (o = r->robj) {
        !           180:                newobj(s,dup);
        !           181:                if (!dup || o->ogroup != cgroup) dupmsg(0,r,s);
        !           182:                }
        !           183:        else {
        !           184:                r->robj = cobj = o = (struct obj *) newstruct(sizeof(struct obj));
        !           185:                o->next = objhash[lasthash];
        !           186:                objhash[lasthash] = o;
        !           187:                o->name = r->name;
        !           188:                o->ogroup = cgroup;
        !           189:                o->seq = o->iptr = o->jct = 0;
        !           190:                }
        !           191:        }
        !           192: 
        !           193: dupmsg(oprt,r,s)
        !           194: int oprt;
        !           195: struct ref *r;
        !           196: char *s;
        !           197: {
        !           198:        struct obj *o = r->robj;
        !           199:        char *in;
        !           200: 
        !           201:        if (verbose && o != obj0) {
        !           202:                fprintf(stderr, "def of %s", s);
        !           203:                if (oprt && strcmp(s,cobj->name)) {
        !           204:                        fprintf(stderr, " in %s", cobj->name);
        !           205:                        in = "of";
        !           206:                        }
        !           207:                else in = "in";
        !           208:                if (*cgroup->name) fprintf(stderr, " %s lib %s", in, cgroup->name);
        !           209:                else in = "of";
        !           210:                fprintf(stderr, " ignored; first defined in %s", o->name);
        !           211:                if (*(s = o->ogroup->name)) fprintf(stderr, " of lib %s", s);
        !           212:                putc('\n', stderr);
        !           213:                }
        !           214:        }
        !           215: 
        !           216: 
        !           217: newref(s)
        !           218: char *s;
        !           219: { newrefr(lookup(s,1)); }
        !           220: 
        !           221: newrefr(r)
        !           222: struct ref *r;
        !           223: {
        !           224:        struct refc rc;
        !           225:        struct obj *o1;
        !           226:        unsigned i;
        !           227: 
        !           228:        if (!cobj) return;
        !           229:        if (verify && r->robj && cobj != obj0) {
        !           230:                fputs(cobj->name, stderr);
        !           231:                if (cgroup != group0) fprintf(stderr, " of %s", cgroup->name);
        !           232:                fprintf(stderr, " needs %s\n", r->name);
        !           233:                }
        !           234:        rc.rcnext = cobj->iptr;
        !           235:        rc.rcref = r;
        !           236:        o1 = rc.rcref->robj;
        !           237:        if (o1 != cobj && o1 != obj0) { /* discard self references */
        !           238:                                                                        /* and refs to null object */
        !           239:                i = cobj->iptr = ++nrefc;
        !           240:                refstore(i, &rc);
        !           241:                }
        !           242:        }
        !           243: 
        !           244: defref(s)
        !           245: char *s;
        !           246: { defrefr(lookup(s,1), s); }
        !           247: 
        !           248: defrefr(r,s)
        !           249: struct ref *r;
        !           250: char *s;
        !           251: {
        !           252:        if (!cobj) return;
        !           253:        if (r->robj) dupmsg(1,r,s);
        !           254:        else r->robj = cobj;
        !           255:        }
        !           256: 
        !           257: struct obj *
        !           258: ts0()
        !           259: {
        !           260:        int i;
        !           261:        struct obj *firstobj, *o, *onext;
        !           262:        struct ref *r, *rnext;
        !           263: 
        !           264:        /* chain objects together */
        !           265: 
        !           266:        firstobj = 0;
        !           267:        for (i = 0; i < HSIZE; i++) {
        !           268:                for(o = objhash[i]; o; o = onext) {
        !           269:                        onext = o->next;
        !           270:                        o->next = firstobj;
        !           271:                        firstobj = o;
        !           272:                        }
        !           273:                }
        !           274: 
        !           275:        /* chain undefined refs together */
        !           276: 
        !           277:        defedrefs = undefrefs = 0;
        !           278:        for (i = 0; i < HSIZE; i++) {
        !           279:                for (r = refhash[i]; r; r = rnext) {
        !           280:                        rnext = r->next;
        !           281:                        if (!r->robj) { r->next = undefrefs; undefrefs = r; }
        !           282:                        else { r->next = defedrefs; defedrefs = r; }
        !           283:                        }
        !           284:                }
        !           285: 
        !           286:        free((char *) grouphash);
        !           287:        free((char *) refhash);
        !           288:        free((char *) objhash);
        !           289:        return firstobj;
        !           290:        }
        !           291: 
        !           292: struct obj *
        !           293: ts(all)
        !           294: {
        !           295:        int i, i0, k;
        !           296:        unsigned j;
        !           297:        struct obj *firstobj, *o, *o1, *onext, *oprev, **ready, **rs;
        !           298:        struct refc rc;
        !           299: 
        !           300:        firstobj = ts0();
        !           301: 
        !           302:        /* do depth-first search (to break cycles) */
        !           303: 
        !           304:        nextseq = 1;
        !           305:        for (o = firstobj; o; o = o->next)
        !           306:                if (!o->seq && (all || o->ogroup == group0)) dfs(1,o);
        !           307: 
        !           308:        /* discard unreached objects */
        !           309: 
        !           310:        if (!all) {
        !           311:                oprev = (struct obj *) &firstobj;
        !           312:                for (o = firstobj; o; o = o->next)
        !           313:                        if (o->seq) { oprev->next = o; oprev = o; }
        !           314:                oprev->next = 0;
        !           315:                }
        !           316: 
        !           317:        /* set up for funny breadth-first search */
        !           318: 
        !           319:        ready = (struct obj **) malloc(ngroup * sizeof(struct obj *));
        !           320:        if (!ready) scream("malloc of ready list fails\n","");
        !           321:        
        !           322:        obj0->jct = 0; /* force initial inclusion of obj0 */
        !           323:        for (i = 0; i < ngroup; i++) ready[i] = 0;
        !           324:        for (o = firstobj; o; o = onext) {
        !           325:                onext = o->next;
        !           326:                if (!o->jct) {
        !           327:                        rs = ready + o->ogroup->gseq;
        !           328:                        o->next = *rs;
        !           329:                        *rs = o;
        !           330:                        }
        !           331:                }
        !           332:        firstobj = lastobj = 0;
        !           333:        i = i0 = 0;
        !           334:        for(;;) {
        !           335:                if (!(o = ready[i])) {
        !           336:                        i = i0;
        !           337:                        while(!(o = ready[i]))
        !           338:                                if (++i >= ngroup) {
        !           339:                                        if (lastobj) lastobj->next = 0;
        !           340:                                        return firstobj;
        !           341:                                        }
        !           342:                        i0 = i;
        !           343:                        }
        !           344:                ready[i] = o->next;
        !           345:                if (!lastobj) firstobj = o;
        !           346:                else lastobj->next = o;
        !           347:                lastobj = o;
        !           348:                for (j = o->iptr; j; ) {
        !           349:                        reffetch(j, &rc);
        !           350:                        j = rc.rcnext;
        !           351:                        if (j >= nrefc) { j -= nrefc; continue; }
        !           352:                        o1 = rc.rcref->robj;
        !           353:                        if (!o1) continue;
        !           354:                        if (!--o1->jct) {
        !           355:                                k = o1->ogroup->gseq;
        !           356:                                o1->next = ready[k];
        !           357:                                ready[k] = o1;
        !           358:                                if (i0 > k) i0 = k;
        !           359:                                }
        !           360:                        }
        !           361:                }
        !           362:        }
        !           363: 
        !           364: dfs(level, o)
        !           365: int level;
        !           366: struct obj *o;
        !           367: {
        !           368:        struct refc rc;
        !           369:        struct obj *o1;
        !           370:        int level0, s;
        !           371:        static int cycle = 0;
        !           372:        unsigned i, nextrc;
        !           373: 
        !           374:        o->seq = -level;
        !           375:        level0 = -(level + 1);
        !           376:        for (i = o->iptr; i; i = nextrc) {
        !           377:                reffetch(i, &rc);
        !           378:                nextrc = rc.rcnext;
        !           379:                o1 = rc.rcref->robj;
        !           380:                if (!o1 || o == o1 || o1 == obj0) continue;
        !           381:                s = o1->seq;
        !           382:                if (s >= 0) {
        !           383:                        o1->jct++;
        !           384:                        if (s > 0) continue; /* cross link */
        !           385:                        s = dfs(level+1, o1);
        !           386:                        }
        !           387:                else { /* back link */
        !           388:                        if (cyclep && !cycle) {
        !           389:                                fprintf(stderr, "%s: cycle...\n", progname);
        !           390:                                cycle = 1;
        !           391:                                }
        !           392:                        rc.rcnext += nrefc;
        !           393:                        refstore(i, &rc);
        !           394:                        }
        !           395:                if (level0 < s) level0 = s;
        !           396:                }
        !           397:        o->seq = nextseq;
        !           398:        level = -level;
        !           399:        if (level <= level0 && cyclep) {
        !           400:                fprintf(stderr, "%s\n", o->name);
        !           401:                if (level == level0) { cycle = 0; putc('\n',stderr); }
        !           402:                else cycle = 1;
        !           403:                }
        !           404:        if (level > level0 || level == -1) { nextseq++; level0 = level; }
        !           405:        return level0;
        !           406:        }
        !           407: 
        !           408: scream(s, s1)
        !           409: char *s, *s1;
        !           410: {
        !           411:        fprintf(stderr, "%s: ", progname);
        !           412:        fprintf(stderr, s, s1);
        !           413:        exit(1);
        !           414:        }
        !           415: 
        !           416: undef(s,infile)
        !           417: char *s;
        !           418: FILE *infile;
        !           419: {
        !           420:        newgroup("");
        !           421:        newobj("", 1);
        !           422:        newref(s);
        !           423:        }

unix.superglobalmegacorp.com

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